aboutsummaryrefslogtreecommitdiff
path: root/Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs')
-rw-r--r--Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs197
1 files changed, 197 insertions, 0 deletions
diff --git a/Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs b/Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs
new file mode 100644
index 0000000..e3a23f9
--- /dev/null
+++ b/Packages/com.vrchat.core.vpm-resolver/Editor/Resolver/Resolver.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Serilog;
+using Serilog.Sinks.Unity3D;
+using UnityEditor;
+using UnityEngine;
+using VRC.PackageManagement.Core;
+using VRC.PackageManagement.Core.Types;
+using VRC.PackageManagement.Core.Types.Packages;
+using Version = VRC.PackageManagement.Core.Types.VPMVersion.Version;
+
+namespace VRC.PackageManagement.Resolver
+{
+
+ [InitializeOnLoad]
+ public class Resolver
+ {
+ private const string _projectLoadedKey = "PROJECT_LOADED";
+
+ private static string _projectDir;
+ public static string ProjectDir
+ {
+ get
+ {
+ if (_projectDir != null)
+ {
+ return _projectDir;
+ }
+
+ try
+ {
+ _projectDir = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent.Parent.Parent
+ .FullName;
+ return _projectDir;
+ }
+ catch (Exception)
+ {
+ return "";
+ }
+ }
+ }
+
+ static Resolver()
+ {
+ SetupLogging();
+ if (!SessionState.GetBool(_projectLoadedKey, false))
+ {
+#pragma warning disable 4014
+ CheckResolveNeeded();
+#pragma warning restore 4014
+ }
+ }
+
+ private static void SetupLogging()
+ {
+ VRCLibLogger.SetLoggerDirectly(
+ new LoggerConfiguration()
+ .MinimumLevel.Information()
+ .WriteTo.Unity3D()
+ .CreateLogger()
+ );
+ }
+
+ private static async Task CheckResolveNeeded()
+ {
+ SessionState.SetBool(_projectLoadedKey, true);
+
+ //Wait for project to finish compiling
+ while (EditorApplication.isCompiling || EditorApplication.isUpdating)
+ {
+ await Task.Delay(250);
+ }
+
+ try
+ {
+
+ if (string.IsNullOrWhiteSpace(ProjectDir))
+ {
+ return;
+ }
+
+ if (VPMProjectManifest.ResolveIsNeeded(ProjectDir))
+ {
+ Debug.Log($"Resolve needed.");
+ var result = EditorUtility.DisplayDialog("VRChat Package Management",
+ $"This project requires some VRChat Packages which are not in the project yet.\n\nPress OK to download and install them.",
+ "OK", "Show Me What's Missing");
+ if (result)
+ {
+ ResolveStatic(ProjectDir);
+ }
+ else
+ {
+ ResolverWindow.ShowWindow();
+ }
+ }
+ }
+ catch (Exception)
+ {
+ // Unity says we can't open windows from this function so it throws an exception but also works fine.
+ }
+ }
+
+ public static bool VPMManifestExists()
+ {
+ return VPMProjectManifest.Exists(ProjectDir, out _);
+ }
+
+ public static void CreateManifest()
+ {
+ VPMProjectManifest.Load(ProjectDir);
+ ResolverWindow.Refresh().ConfigureAwait(false);
+ }
+
+ public static void ResolveManifest()
+ {
+ ResolveStatic(ProjectDir);
+ }
+
+ public static void ResolveStatic(string dir)
+ {
+ // Todo: calculate and show actual progress
+ EditorUtility.DisplayProgressBar($"Getting all VRChat Packages", "Downloading and Installing...", 0.5f);
+ VPMProjectManifest.Resolve(ProjectDir);
+ EditorUtility.ClearProgressBar();
+ ForceRefresh();
+ }
+
+ public static List<string> GetAllVersionsOf(string id)
+ {
+ var project = new UnityProject(ProjectDir);
+
+ var versions = new List<string>();
+ foreach (var provider in Repos.GetAll)
+ {
+ var packagesWithVersions = provider.GetAllWithVersions();
+
+ foreach (var packageVersionList in packagesWithVersions)
+ {
+ foreach (var package in packageVersionList.Value.VersionsDescending)
+ {
+ if (package.Id != id)
+ continue;
+ if (Version.TryParse(package.Version, out var result))
+ {
+ if (!versions.Contains(package.Version))
+ versions.Add(package.Version);
+ }
+ }
+ }
+ }
+
+ // Sort packages in project to the top
+ var sorted = from entry in versions orderby project.VPMProvider.HasPackage(entry) descending select entry;
+
+ return sorted.ToList<string>();
+ }
+
+ public static List<string> GetAffectedPackageList(IVRCPackage package)
+ {
+ List<string> list = new List<string>();
+
+ var project = new UnityProject(ProjectDir);
+
+ if (Repos.GetAllDependencies(package, out Dictionary<string, string> dependencies, null))
+ {
+ foreach (KeyValuePair<string, string> item in dependencies)
+ {
+ project.VPMProvider.Refresh();
+ if (project.VPMProvider.GetPackage(item.Key, item.Value) == null)
+ {
+ IVRCPackage d = Repos.GetPackageWithVersionMatch(item.Key, item.Value);
+ if (d != null)
+ {
+ list.Add(d.Id + " " + d.Version + "\n");
+ }
+ }
+ }
+
+ return list;
+ }
+
+ return null;
+ }
+
+ public static void ForceRefresh ()
+ {
+ UnityEditor.PackageManager.Client.Resolve();
+ AssetDatabase.Refresh();
+ }
+
+ }
+} \ No newline at end of file