DependencyResolver.cs 9.2 KB

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