diff --git a/CHANGELOG.md b/CHANGELOG.md index bda71bc..b8f4aba 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,18 @@ # Changelog +## [1.1.0](https://github.com/mob-sakai/GitDependencyResolverForUnity/tree/1.1.0) (2019-06-11) + +[Full Changelog](https://github.com/mob-sakai/GitDependencyResolverForUnity/compare/1.0.0...1.1.0) + +**Implemented enhancements:** + +- Add notes on using this package [\#13](https://github.com/mob-sakai/GitDependencyResolverForUnity/issues/13) +- Refer to no files from the Library folder [\#12](https://github.com/mob-sakai/GitDependencyResolverForUnity/issues/12) +- Deterministic package installation [\#10](https://github.com/mob-sakai/GitDependencyResolverForUnity/issues/10) + ## [1.0.0](https://github.com/mob-sakai/GitDependencyResolverForUnity/tree/1.0.0) (2019-05-16) -[Full Changelog](https://github.com/mob-sakai/GitDependencyResolverForUnity/compare/a3e62a69d2a251711e8044936af8e56431b4b0f2...1.0.0) +[Full Changelog](https://github.com/mob-sakai/GitDependencyResolverForUnity/compare/96d11551ce2e670f5c991a254ac3dd4fb4b67c02...1.0.0) This plugin resolves git url dependencies in the package for Unity Package Manager. diff --git a/Editor/GitDependencyResolver.cs b/Editor/GitDependencyResolver.cs index 16b87ff..99a5c4a 100644 --- a/Editor/GitDependencyResolver.cs +++ b/Editor/GitDependencyResolver.cs @@ -9,60 +9,72 @@ namespace Coffee.PackageManager [InitializeOnLoad] public static class GitDependencyResolver { + const System.StringComparison Ordinal = System.StringComparison.Ordinal; + static GitDependencyResolver () { EditorApplication.projectChanged += StartResolve; StartResolve (); } + + static PackageMeta[] GetInstalledPackages() + { + //return Directory.GetDirectories ("./Library/PackageCache") + // .Concat (Directory.GetDirectories ("./Packages")) + // .Select (PackageMeta.FromPackageDir) // Convert to PackageMeta + // .Where (x => x != null) // Skip null + // .ToArray (); + return AssetDatabase.GetAllAssetPaths() + .Where(x => x.StartsWith("Packages/", Ordinal) && x.EndsWith("/package.json", Ordinal)) + .Select(PackageMeta.FromPackageJson) // Convert to PackageMeta + .Where (x => x != null) // Skip null + .ToArray(); + } /// /// Uninstall unused packages (for auto-installed packages) /// static void UninstallUnusedPackages () { - bool check = true; - while (check) + bool needToCheck = true; + while (needToCheck) { - check = false; - + needToCheck = false; + // Collect all dependencies. - var allDependencies = Directory.GetDirectories ("./Library/PackageCache") - .Concat (Directory.GetDirectories ("./Packages")) - .Select (PackageMeta.FromPackageDir) // Convert to PackageMeta - .Where (x => x != null) // Skip null + var allDependencies = GetInstalledPackages() .SelectMany (x => x.dependencies) // Get all dependencies .ToArray (); - - // Collect unused pakages. - var unusedPackages = Directory.GetDirectories ("./Packages") - .Where (x => Path.GetFileName (x).StartsWith (".")) // Directory name starts with '.'. This is 'auto-installed package' - .Select (PackageMeta.FromPackageDir) // Convert to PackageMeta - .Where (x => x != null) // Skip null - .Where (x => allDependencies.All (y => y.name != x.name)) // No depended from other packages + + PackageMeta[] autoInstalledPackages = Directory.GetDirectories ("./Packages") + .Where (x => Path.GetFileName(x).StartsWith (".", Ordinal)) // Directory name starts with '.'. This is 'auto-installed package' + .Select (PackageMeta.FromPackageDir) // Convert to PackageMeta + .Where (x => x != null) // Skip null .ToArray (); + + // Collect unused pakages. + var unusedPackages = autoInstalledPackages + .Where (x => Path.GetFileName(x.path).StartsWith (".", Ordinal)) // Directory name starts with '.'. This is 'auto-installed package' + .Where (x => !allDependencies.Any (y => y.name == x.name && y.version == x.version)) // No depended from other packages + ; // Uninstall unused packages and re-check. foreach (var p in unusedPackages) { - check = true; - Debug.LogFormat ("[Resolver] Uninstall unused package: {0} from {1}", p.name, p.path); + needToCheck = true; + Debug.LogFormat ("[Resolver] Uninstall unused package {0}:{1} from {2}", p.name, p.version,p.path); FileUtil.DeleteFileOrDirectory (p.path); } } } - static void StartResolve () { // Uninstall unused packages (for auto-installed packages) UninstallUnusedPackages (); // Collect all installed pakages. - var installedPackages = Directory.GetDirectories ("./Library/PackageCache") - .Concat (Directory.GetDirectories ("./Packages")) - .Select (PackageMeta.FromPackageDir) // Convert to PackageMeta - .Where (x => x != null) // Skip null - .ToArray (); + PackageMeta[] installedPackages = GetInstalledPackages(); // Collect all dependencies. var dependencies = installedPackages @@ -82,7 +94,6 @@ static void StartResolve () // Install the depended package later. if (!isInstalled) { - Debug.LogFormat ("[Resolver] A dependency package is requested: {0}", dependency.name); requestedPackages.RemoveAll (x => dependency.name == x.name); requestedPackages.Add (dependency); } @@ -96,12 +107,12 @@ static void StartResolve () for (int i = 0; i < requestedPackages.Count; i++) { PackageMeta meta = requestedPackages [i]; - EditorUtility.DisplayProgressBar ("Add Package", "Cloning: " + meta.name, i / (float)requestedPackages.Count); - Debug.LogFormat ("[Resolver] A package is cloning: {0}", meta.name); + EditorUtility.DisplayProgressBar ("Clone Package", string.Format ("Cloning {0}:{1}", meta.name, meta.version), i / (float)requestedPackages.Count); + Debug.LogFormat ("[Resolver] Cloning {0}: {1}", meta.name, meta.version); bool success = GitUtils.ClonePackage (meta); if (!success) { - Debug.LogFormat ("[Resolver] Failed to clone: {0}", meta.name); + Debug.LogFormat ("[Resolver] Failed to clone {0}:{1}", meta.name, meta.version); break; } } diff --git a/Editor/PackageMeta.cs b/Editor/PackageMeta.cs index d9fd7bf..1c27a5d 100644 --- a/Editor/PackageMeta.cs +++ b/Editor/PackageMeta.cs @@ -15,12 +15,17 @@ public class PackageMeta public string path { get; private set; } public PackageMeta [] dependencies { get; private set; } - public static PackageMeta FromPackageDir (string dir) + public static PackageMeta FromPackageJson (string filePath) { try { - Dictionary dict = Json.Deserialize (File.ReadAllText (dir + "/package.json")) as Dictionary; - PackageMeta meta = new PackageMeta () { path = dir, }; + if(!File.Exists(filePath)) + { + return null; + } + + Dictionary dict = Json.Deserialize (File.ReadAllText (filePath)) as Dictionary; + PackageMeta meta = new PackageMeta () { path = Path.GetDirectoryName(filePath), }; object obj; if (dict.TryGetValue ("name", out obj)) @@ -51,6 +56,11 @@ public static PackageMeta FromPackageDir (string dir) } } + public static PackageMeta FromPackageDir (string dir) + { + return FromPackageJson(dir + "/package.json"); + } + public static PackageMeta FromNameAndUrl (string name, string url) { PackageMeta meta = new PackageMeta () { name = name, dependencies = new PackageMeta [0] }; diff --git a/README.md b/README.md index b6c4101..bedd08b 100755 --- a/README.md +++ b/README.md @@ -60,6 +60,39 @@ You can use a git url as a package dependency! * Support Unity 2019.1+ * Support .Net 3.5 & 4.x * Update package with a specific tag/branch +* Deterministic package installation +* Refer to no files from the Library folder + + +#### Notes + +From: https://forum.unity.com/threads/git-support-on-package-manager.573673/page-3#post-4552084 + +> There is no conflict detection and/or resolution algorithm. +> The lastest package found with the same name is used. +> This is not how the package manager resolve dependency (See https://docs.unity3d.com/Manual/upm-conflicts-auto.html). + +In Unity's algorithm, package conflicts are resolved by "dependency-level from root". +The all packages resolved by this plugin are "dependency-level=1". +Therefore, in some cases, the package of the intended version may not be installed. + +For example, in the case of a project with a dependency graph like this: + +``` +project (root) + ├ package A: 1.0.0 + │ └ package X: 2.0.0 + └ package B: 1.0.0 + └ package C: 2.0.0 + └ package X: 2.0.1 +``` + +**This plugin's algorithm** + +Install -> A: 1.0.0, B: 1.0.0, C: 2.0.0, X: 2.0.1 + +**Unity's algorithm** +Install -> A: 1.0.0, B: 1.0.0, C: 2.0.0, X: **2.0.0** @@ -70,13 +103,13 @@ Find `Packages/manifest.json` in your project and edit it to look like this: ```js { "dependencies": { - "com.coffee.git-dependency-resolver": "https://github.com/mob-sakai/GitDependencyResolverForUnity.git#1.0.0", + "com.coffee.git-dependency-resolver": "https://github.com/mob-sakai/GitDependencyResolverForUnity.git#1.1.0", ... } } ``` -To update the package, change `#{version}` to the target version. -Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension.git). +To update the package, change `#{version}` to the target version. +Or, use [UpmGitExtension](https://github.com/mob-sakai/UpmGitExtension.git) to install or update the package. ##### Requirement @@ -102,7 +135,7 @@ eg. `1.0.0`, `0.5.0-preview10`, `0.1.0-alpha+daily5`



## Demo -https://github.com/mob-sakai/GitPackageTest/tree/git-dependency-resolver-test +https://github.com/mob-sakai/UnityGitDependencyTest diff --git a/package.json b/package.json index 7b7ed3d..e895719 100755 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "com.coffee.git-dependency-resolver", "displayName": "Git Dependency Resolver", "description": "This plugin resolves git dependencies in the package for Unity Package Manager.\nYou can use a git url as a package dependency!", - "version": "1.0.0", + "version": "1.1.0", "unity": "2018.3", "license": "MIT", "repository": {