using Newtonsoft.Json; namespace AlicizaX.PackageManager.Editor { using System; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEditor; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; using Newtonsoft.Json.Linq; public static class PackageManagerCheckTool { private static Dictionary cachedManifestDependencies; private static ListRequest listRequest; [Serializable] public class ManifestDependencies { public Dictionary dependencies = new Dictionary(); } public static void ValidatePackageStates(List packages) { var manifest = ReadManifestFile(); var installedPackages = GetInstalledPackagesFromPM(); foreach (var package in packages) { // 检查是否在manifest中存在 if (manifest.dependencies.TryGetValue(package.name, out var gitUrl)) { // 检查PackageCache目录 var cachePath = FindInPackageCache(package.name); if (!string.IsNullOrEmpty(cachePath)) { var localTime = Directory.GetLastWriteTimeUtc(cachePath); if (DateTime.TryParse(package.updatedAt, out var remoteTime)) { package.PackageState = remoteTime > localTime ? PackageState.Update : PackageState.Install; } else { package.PackageState = PackageState.Install; } } else { package.PackageState = PackageState.Install; } } else { // 检查Packages目录 var packagePath = Path.GetFullPath($"Packages/{package.name}"); package.PackageState = Directory.Exists(packagePath) ? PackageState.InstallLocal : PackageState.UnInstall; } } } private static string FindInPackageCache(string packageName) { var cacheRoot = Path.GetFullPath("Library/PackageCache"); if (!Directory.Exists(cacheRoot)) return null; foreach (var dir in Directory.GetDirectories(cacheRoot)) { if (dir.Contains(packageName + "@")) { return dir; } } return null; } private static ManifestDependencies ReadManifestFile() { var manifestPath = Path.GetFullPath("Packages/manifest.json"); var json = File.ReadAllText(manifestPath); return JsonConvert.DeserializeObject(json); } public static void InstallPackage(string gitUrl) { Client.Add(gitUrl); } public static void UpdatePackage(string packageName) { Client.Add($"git:{packageName}"); } public static void UninstallPackage(string packageName) { Client.Remove(packageName); } private static List GetInstalledPackagesFromPM() { var packages = new List(); listRequest = Client.List(); EditorApplication.CallbackFunction checkProgress = null; checkProgress = () => { if (listRequest.IsCompleted) { if (listRequest.Status == StatusCode.Success) { foreach (var package in listRequest.Result) { packages.Add(package.name); } } EditorApplication.update -= checkProgress; } }; EditorApplication.update += checkProgress; return packages; } // 辅助方法:从Git URL提取包名 public static string ExtractPackageNameFromUrl(string gitUrl) { try { Uri uri = new Uri(gitUrl); string path = uri.AbsolutePath; int startIndex = path.LastIndexOf('/') + 1; string name = path.Substring(startIndex); return name.Replace(".git", "").Replace("_", ".").ToLower(); } catch { return Path.GetFileNameWithoutExtension(gitUrl); } } } }