//FIXME: This is super unsafe right now, as we can copy down into the FS. // This should be contained using kinds of destinations. private void InstallPackage(Upset package, TemporaryDirectory td, DependencyDefinition dependencyDefinition, bool updateLockfile = false) { GitIgnorer VCSHandler = new GitIgnorer(); using (LogAggregator LA = LogAggregator.InUnity( "Package {0} was successfully installed", "Package {0} was successfully installed but raised warnings", "An error occured while installing package {0}", package.PackageName )) { Upbring upbring = Upbring.Instance(); // Note: Full package is ALWAYS copied to the upackages directory right now string localPackagePath = GetRepositoryInstallPath(package); upbring.AddPackage(package); if (!Directory.Exists(localPackagePath)) { Directory.CreateDirectory(localPackagePath); } Uplift.Common.FileSystemUtil.CopyDirectory(td.Path, localPackagePath); upbring.AddLocation(package, InstallSpecType.Root, localPackagePath); VCSHandler.HandleDirectory(upfile.GetPackagesRootPath()); InstallSpecPath[] specArray; if (package.Configuration == null) { // If there is no Configuration present we assume // that the whole package is wrapped in "InstallSpecType.Base" InstallSpecPath wrapSpec = new InstallSpecPath { Path = "", Type = InstallSpecType.Base }; specArray = new[] { wrapSpec }; } else { specArray = package.Configuration; } foreach (InstallSpecPath spec in specArray) { if (dependencyDefinition.SkipInstall != null && dependencyDefinition.SkipInstall.Any(skip => skip.Type == spec.Type)) { continue; } var sourcePath = Uplift.Common.FileSystemUtil.JoinPaths(td.Path, spec.Path); PathConfiguration PH = upfile.GetDestinationFor(spec); if (dependencyDefinition.OverrideDestination != null && dependencyDefinition.OverrideDestination.Any(over => over.Type == spec.Type)) { PH.Location = Uplift.Common.FileSystemUtil.MakePathOSFriendly(dependencyDefinition.OverrideDestination.First(over => over.Type == spec.Type).Location); } var packageStructurePrefix = PH.SkipPackageStructure ? "" : GetPackageDirectory(package); var destination = Path.Combine(PH.Location, packageStructurePrefix); // Working with single file if (File.Exists(sourcePath)) { // Working with singular file if (!Directory.Exists(destination)) { Directory.CreateDirectory(destination); VCSHandler.HandleFile(destination); } if (Directory.Exists(destination)) { // we are copying a file into a directory destination = System.IO.Path.Combine(destination, System.IO.Path.GetFileName(sourcePath)); } File.Copy(sourcePath, destination); Uplift.Common.FileSystemUtil.TryCopyMeta(sourcePath, destination); if (destination.StartsWith("Assets")) { TryUpringAddGUID(upbring, sourcePath, package, spec.Type, destination); } else { upbring.AddLocation(package, spec.Type, destination); } } // Working with directory if (Directory.Exists(sourcePath)) { // Working with directory Uplift.Common.FileSystemUtil.CopyDirectoryWithMeta(sourcePath, destination); if (!PH.SkipPackageStructure) { VCSHandler.HandleDirectory(destination); } bool useGuid = destination.StartsWith("Assets"); foreach (var file in Uplift.Common.FileSystemUtil.RecursivelyListFiles(sourcePath, true)) { if (useGuid) { TryUpringAddGUID(upbring, file, package, spec.Type, destination); } else { upbring.AddLocation(package, spec.Type, Path.Combine(destination, file)); } if (PH.SkipPackageStructure) { VCSHandler.HandleFile(Path.Combine(destination, file)); } } } } upbring.SaveFile(); if (updateLockfile) { LockfileSnapshot snapshot = LoadLockfile(); int index; bool found = false; for (index = 0; index < snapshot.installableDependencies.Length; index++) { if (snapshot.installableDependencies[index].Package.PackageName == package.PackageName) { found = true; break; } } if (found) { snapshot.installableDependencies[index].Package = package; } else { Array.Resize <PackageRepo>(ref snapshot.installableDependencies, snapshot.installableDependencies.Length + 1); snapshot.installableDependencies[snapshot.installableDependencies.Length] = new PackageRepo { Package = package }; } GenerateLockfile(snapshot); } td.Dispose(); UnityHacks.BuildSettingsEnforcer.EnforceAssetSave(); } }
public void Nuke() { GitIgnorer ignorer = new GitIgnorer(); using (LogAggregator LA = LogAggregator.InUnity( "Package {0} was successfully nuked", "Package {0} was successfully nuked but raised warnings", "An error occured while installing package {0}", Name )) { var dirPaths = new List <string>(); foreach (InstallSpec spec in Install) { if (spec is InstallSpecPath) { InstallSpecPath specPath = spec as InstallSpecPath; var friendlyPath = Uplift.Common.FileSystemUtil.MakePathWindowsFriendly(specPath.Path); if (specPath.Type == InstallSpecType.Root) { // Removing Root package Directory.Delete(friendlyPath, true); } if (friendlyPath.Contains("gitignore")) { // Do not remove the file but rather the reference to the package if (!ignorer.TryRemoveFile(friendlyPath)) { Debug.LogFormat("The .gitignore at {0} cannot be deleted by Uplift. Please make sure it doesn't cause any kind of issue.", friendlyPath); } } else { try { File.Delete(friendlyPath); File.Delete(friendlyPath + ".meta"); // Removing meta files as well. } catch (FileNotFoundException) { Debug.Log("Warning, tracked file not found: " + friendlyPath); } catch (DirectoryNotFoundException) { Debug.Log("Warning, tracked directory not found: " + friendlyPath); } string dirName = Path.GetDirectoryName(friendlyPath); if (!string.IsNullOrEmpty(dirName)) { dirPaths.Add(dirName); } } } else if (spec is InstallSpecGUID) { InstallSpecGUID specGuid = spec as InstallSpecGUID; string guidPath = AssetDatabase.GUIDToAssetPath(specGuid.Guid); if (String.IsNullOrEmpty(guidPath)) { Debug.Log("Warning, tracked file not found: guid: " + specGuid.Guid + " " + specGuid.Type); return; } if (specGuid.Type == InstallSpecType.Root) { // Removing Root package Directory.Delete(guidPath, true); } else { try { File.Delete(guidPath); File.Delete(guidPath + ".meta"); // Removing meta files as well. } catch (FileNotFoundException) { Debug.Log("Warning, tracked file not found: " + guidPath); } catch (DirectoryNotFoundException) { Debug.Log("Warning, tracked directory not found: " + guidPath); } string dirName = Path.GetDirectoryName(guidPath); if (!string.IsNullOrEmpty(dirName)) { dirPaths.Add(dirName); } } } } // An itchy bit. // Paths can nest. Ordering of paths is not guaranteed. // So we'll loop over removing dirs to the point, where no action has been made. var actionsDone = 1; var loopCounter = 1; while (actionsDone != 0) { if (loopCounter > 5) { Debug.LogWarning( "Warning: Nuke Dependency Loop has done more than 5 rounds. This might or might not be error, depending on setup" ); } actionsDone = 0; loopCounter++; // We're recursively listing the directories we're keeping so that we can extract empty directories. var recursiveDirPaths = Uplift.Common.FileSystemUtil.RecursivelyDirPaths(dirPaths).Distinct().ToList(); foreach (var p in recursiveDirPaths) { if (string.IsNullOrEmpty(p)) { continue; } if (!Directory.Exists(p)) { continue; } var filesInDirectory = Directory.GetFiles(p).Length; var directoriesInDirectory = Directory.GetDirectories(p).Length; if (filesInDirectory + directoriesInDirectory > 0) { continue; } try { Directory.Delete(p, true); actionsDone += 1; File.Delete(p + ".meta"); // .meta file for directory might exist, remove it as well } catch (DirectoryNotFoundException) { } } } } }