DependencyResolver.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using ET;
  7. using MongoDB.Bson.Serialization;
  8. using MongoDB.Bson.Serialization.Attributes;
  9. using UnityEditor;
  10. using UnityEditor.PackageManager;
  11. using PackageInfo = UnityEditor.PackageManager.PackageInfo;
  12. using UnityEditor.PackageManager.Requests;
  13. using Debug = UnityEngine.Debug;
  14. namespace Hibzz.DependencyResolver
  15. {
  16. [InitializeOnLoad]
  17. public class DependencyResolver
  18. {
  19. //[MenuItem("ET/MoveToPackage")]
  20. static void MoveToPackage()
  21. {
  22. Process process = ProcessHelper.PowerShell($"-NoExit -ExecutionPolicy Bypass -File .\\Scripts/MoveToPackages.ps1", waitExit: true);
  23. Debug.Log(process.StandardOutput.ReadToEnd());
  24. AssetDatabase.Refresh();
  25. }
  26. static AddAndRemoveRequest packageInstallationRequest;
  27. static DependencyResolver()
  28. {
  29. Events.registeredPackages += OnPackagesRegistered;
  30. }
  31. // Invoked when the package manager completes registering new packages
  32. static void OnPackagesRegistered(PackageRegistrationEventArgs packageRegistrationInfo)
  33. {
  34. if (packageRegistrationInfo.added.Count == 0)
  35. {
  36. return;
  37. }
  38. Debug.Log($"Packages Registered: {string.Join(" ", packageRegistrationInfo.added.Select(x=>x.name))}");
  39. // loop through all of the added packages and get their git
  40. // dependencies and add it to the list that contains all the
  41. // dependencies that need to be installed
  42. Dictionary<string, string> dependencies = new();
  43. List<PackageInfo> installedPackages = PackageInfo.GetAllRegisteredPackages().ToList();
  44. foreach (var package in packageRegistrationInfo.added)
  45. {
  46. if (!package.name.StartsWith("cn.etetet."))
  47. {
  48. continue;
  49. }
  50. // get the dependencies of the added package
  51. if (!GetDependencies(package, out PackageGit packageDependencies))
  52. {
  53. continue;
  54. }
  55. foreach (var gitDependency in packageDependencies.GitDependencies)
  56. {
  57. if (IsInCollection(gitDependency.Key, installedPackages))
  58. {
  59. continue;
  60. }
  61. dependencies[gitDependency.Key] = gitDependency.Value;
  62. }
  63. }
  64. // Install the dependencies
  65. InstallDependencies(dependencies);
  66. }
  67. /// <summary>
  68. /// Request a list of git dependencies in the package
  69. /// </summary>
  70. /// <param name="packageInfo">The package to get the git dependencies from</param>
  71. /// <param name="dependencies">The retrieved list of git dependencies </param>
  72. /// <returns>Was the request successful?</returns>
  73. static bool GetDependencies(PackageInfo packageInfo, out PackageGit dependencies)
  74. {
  75. string packageJsonPath = $"{packageInfo.resolvedPath}/packagegit.json";
  76. if (!File.Exists(packageJsonPath))
  77. {
  78. throw new Exception($"package already move to packages dir, please refresh your unity project! RepairDependencies retry please! {packageInfo.name} {packageJsonPath}");
  79. }
  80. dependencies = PackageGitHelper.Load(packageJsonPath);
  81. if (dependencies.GitDependencies is null || dependencies.GitDependencies.Count == 0)
  82. {
  83. return false;
  84. }
  85. return true;
  86. }
  87. /// <summary>
  88. /// Is the given dependency url found in the given collection
  89. /// </summary>
  90. /// <param name="dependency">The url the dependency to check for</param>
  91. /// <param name="collection">The collection to look through</param>
  92. /// <returns></returns>
  93. static bool IsInCollection(string dependency, List<PackageInfo> collection)
  94. {
  95. // when package collection given is null, it's inferred that the dependency is not in the collection
  96. if (collection == null)
  97. {
  98. return false;
  99. }
  100. // check if any of the installed package has the dependency
  101. foreach (var package in collection)
  102. {
  103. // the package id for a package installed with git is `package_name@package_giturl`
  104. // get the repo url by performing some string manipulation on the package id
  105. //string repourl = package.packageId.Substring(package.packageId.IndexOf('@') + 1);
  106. // Found!
  107. if (package.name == dependency)
  108. {
  109. return true;
  110. }
  111. }
  112. // the dependency wasn't found in the package collection
  113. return false;
  114. }
  115. /// <summary>
  116. /// Install all the given dependencies
  117. /// </summary>
  118. static void InstallDependencies(Dictionary<string, string> dependencies)
  119. {
  120. if (dependencies.Count == 0)
  121. {
  122. MoveToPackage();
  123. Debug.Log($"git Dependencies are all installed");
  124. return;
  125. }
  126. // before installing the packages, make sure that user knows what
  127. // the dependencies to install are... additionally, check if the
  128. // application is being run on batch mode so that we can skip the
  129. // installation dialog
  130. Debug.Log($"The following dependencies are required:\n{string.Join("\n", dependencies.Keys)}");
  131. // the user pressed install, perform the actual installation
  132. // (or the application was in batch mode)
  133. packageInstallationRequest = Client.AddAndRemove(dependencies.Values.ToArray());
  134. // show the progress bar till the installation is complete
  135. EditorUtility.DisplayProgressBar("Dependency Resolver", "Preparing installation of dependencies...", 0);
  136. EditorApplication.update += DisplayProgress;
  137. }
  138. /// <summary>
  139. /// Shows a progress bar till the AddAndRemoveRequest is completed
  140. /// </summary>
  141. static void DisplayProgress()
  142. {
  143. if (!packageInstallationRequest.IsCompleted)
  144. {
  145. return;
  146. }
  147. EditorUtility.ClearProgressBar();
  148. EditorApplication.update -= DisplayProgress;
  149. }
  150. [MenuItem("ET/Init/RepairDependencies")]
  151. static void RepairDependencies()
  152. {
  153. MoveToPackage();
  154. Dictionary<string, string> dependencies = new();
  155. List<PackageInfo> installedPackages = PackageInfo.GetAllRegisteredPackages().ToList();
  156. foreach (var package in installedPackages)
  157. {
  158. if (!package.name.StartsWith("cn.etetet."))
  159. {
  160. continue;
  161. }
  162. if (!GetDependencies(package, out PackageGit packageDependencies))
  163. {
  164. continue;
  165. }
  166. foreach (var gitDependency in packageDependencies.GitDependencies)
  167. {
  168. if (IsInCollection(gitDependency.Key, installedPackages))
  169. {
  170. continue;
  171. }
  172. if (dependencies.TryGetValue(gitDependency.Key, out string findV))
  173. {
  174. if (findV != gitDependency.Value)
  175. {
  176. Debug.Log($"package dup {gitDependency.Key} but git url diff: {findV} {gitDependency.Value}");
  177. }
  178. continue;
  179. }
  180. Debug.Log($"Dependency not found: {gitDependency.Key}");
  181. dependencies.Add(gitDependency.Key, gitDependency.Value);
  182. }
  183. }
  184. if (dependencies.Count == 0)
  185. {
  186. Debug.Log($"git Dependencies are all installed");
  187. return;
  188. }
  189. InstallDependencies(dependencies);
  190. }
  191. }
  192. }