private static void StartResolve() { var needToRefresh = false; var needToCheck = true; Log("Start dependency resolution."); PackageMeta.LoadGitLock(); AssetDatabase.StartAssetEditing(); while (needToCheck) { // Uninstall unused packages (for auto-installed packages) UninstallUnusedPackages(); // Collect all installed packages. PackageMeta[] installedPackages = GetInstalledPackages(); // Collect all dependencies. var dependencies = installedPackages .SelectMany(x => x.GetAllDependencies()) // Get all dependencies .Where(x => !string.IsNullOrEmpty(x.repository)) // path (url) is available .ToArray(); // Check all dependencies. var requestedPackages = new List <PackageMeta>(); foreach (var dependency in dependencies) { // Is the depended package installed already? var isInstalled = installedPackages .Concat(requestedPackages) .Any(x => dependency.name == x.name && (dependency.version != null && dependency.version <= x.version || x.version == null)); if (isInstalled) { continue; } // Install the depended package later. requestedPackages.RemoveAll(x => dependency.name == x.name); requestedPackages.Add(dependency); } var sb = new StringBuilder(); sb.AppendLine("############## StartResolve ##############"); sb.AppendLine("\n[ installedPackages ] "); installedPackages.ToList().ForEach(p => sb.AppendLine(p.ToString())); sb.AppendLine("\n[ dependencies ] "); dependencies.ToList().ForEach(p => sb.AppendLine(p.ToString())); sb.AppendLine("\n[ requestedPackages ] "); requestedPackages.ToList().ForEach(p => sb.AppendLine(p.ToString())); Log(sb.ToString()); // No packages is requested to install. if (requestedPackages.Count == 0) { break; } // Install all requested packages. for (var i = 0; i < requestedPackages.Count; i++) { PackageMeta package = requestedPackages[i]; DirUtils.Create(Path.Combine("Temp", "GitDependencies")); var clonePath = Path.Combine(Path.Combine("Temp", "GitDependencies"), Path.GetFileName(Path.GetTempFileName())); EditorUtility.DisplayProgressBar("Clone Package", string.Format("Cloning {0}@{1}", package.name, package.version), i / (float)requestedPackages.Count); Log("Cloning '{0}@{1}' ({2}, {3})", package.name, package.version, package.revision, package.path); var success = GitUtils.ClonePackage(package, clonePath); // Check cloned if (!success) { needToCheck = false; Error("Failed to install a package '{0}@{1}': Clone failed.", package.name, package.version); continue; } // Check package path (query) var pkgPath = package.GetPackagePath(clonePath); if (!Directory.Exists(pkgPath)) { Error("Failed to install a package '{0}@{1}': The package is not found. {2}/{3}", package.name, package.version, clonePath, package.path); needToCheck = false; continue; } var newPackage = PackageMeta.FromPackageDir(pkgPath); if (newPackage == null) { Error("Failed to install a package '{0}@{1}': package.json is not found. {2}/{3}", package.name, package.version, clonePath, package.path); needToCheck = false; continue; } if (newPackage.name != package.name) { Error("Failed to install a package '{0}@{1}': Different package name. {2} != {3}", package.name, package.version, newPackage.name, package.name); needToCheck = false; continue; } // Install as an embed package var installPath = "Packages/." + newPackage.GetDirectoryName(); DirUtils.Delete(installPath); DirUtils.Create(installPath); DirUtils.Move(pkgPath, installPath, p => p != ".git"); Log("A package '{0}@{1}' has been installed.", package.name, package.version); needToRefresh = true; AssetDatabase.ImportAsset(installPath, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ImportRecursive); PackageMeta.GitLock(package); } EditorUtility.ClearProgressBar(); } AssetDatabase.StopAssetEditing(); PackageMeta.SaveGitLock(); Log("Dependency resolution complete. refresh = {0}", needToRefresh); if (needToRefresh) { // Recompile the packages AssetDatabase.Refresh(); } }