using System; using System.Collections.Generic; using System.IO.Compression; using NugetForUnity.Configuration; using NugetForUnity.Helper; using NugetForUnity.PluginAPI; using NugetForUnity.PluginAPI.ExtensionPoints; using NugetForUnity.PluginAPI.Models; using UnityEditor; using UnityEngine; namespace NugetForUnity.PluginSupport { /// /// Plugin Registry loads the plugins and provides methods for calling them. /// internal class PluginRegistry : INugetPluginRegistry, IPackageButtonsHandler, IPackageInstallFileHandler, IPackageUninstallHandler, IFoundInstalledPackageHandler { private readonly List foundInstalledPackageHandlers = new List(); private readonly List packageButtonsHandlers = new List(); private readonly List packageInstallFileHandlers = new List(); private readonly List packageUninstallHandlers = new List(); /// /// Gets the static instance of PluginRegistry. /// public static PluginRegistry Instance { get; private set; } /// /// Gets a value indicating whether we are running from Unity or from CLI version. /// public bool IsRunningInUnity { get; } = SessionState.GetString(nameof(IsRunningInUnity), "true") == "true"; /// public INugetPluginService PluginService { get; } = new NugetPluginService(); /// /// Reloads appropriate plugins after some are enabled or disabled. /// public static void Reinitialize() { if (Instance?.PluginService is IDisposable disposable) { disposable.Dispose(); } Instance = null; InitPlugins(); } /// /// Loads the plug-ins that are enabled in preferences and initialized Instance. /// public static void InitPlugins() { if (Instance != null) { return; } Instance = new PluginRegistry(); var loadedPlugins = new List(); var failedPlugins = new List(); foreach (var plugin in ConfigurationManager.NugetConfigFile.EnabledPlugins) { try { var assembly = AssemblyLoader.Load(plugin); var pluginLoaded = false; foreach (var type in assembly.GetTypes()) { if (typeof(INugetPlugin).IsAssignableFrom(type)) { var pluginInstance = (INugetPlugin)Activator.CreateInstance(type); pluginInstance.Register(Instance); loadedPlugins.Add(plugin.Name); pluginLoaded = true; break; } } if (!pluginLoaded) { failedPlugins.Add($"{plugin.Name}: No class implementing INugetPlugin found"); } } catch (Exception e) { failedPlugins.Add($"{plugin.Name}: {e.GetType().Name} {e.Message}"); } } if (loadedPlugins.Count > 0) { Debug.Log($"Loaded plugins: {string.Join(", ", loadedPlugins)}"); } if (failedPlugins.Count > 0) { Debug.LogError($"Failed to load plugins: {string.Join("\n", failedPlugins)}"); } } /// public void RegisterPackageButtonDrawer(IPackageButtonsHandler packageButtonsHandler) { packageButtonsHandlers.Add(packageButtonsHandler); } /// public void RegisterPackageInstallFileHandler(IPackageInstallFileHandler packageInstallFileHandler) { packageInstallFileHandlers.Add(packageInstallFileHandler); } /// public void RegisterPackageUninstallHandler(IPackageUninstallHandler packageUninstallHandler) { packageUninstallHandlers.Add(packageUninstallHandler); } /// public void RegisterFoundInstalledPackageHandler(IFoundInstalledPackageHandler foundInstalledPackageHandler) { foundInstalledPackageHandlers.Add(foundInstalledPackageHandler); } /// public void DrawButtons(INugetPackage package, INugetPackage installedPackage, bool existsInUnity) { foreach (var packageButtonsHandler in packageButtonsHandlers) { try { packageButtonsHandler.DrawButtons(package, installedPackage, existsInUnity); } catch (Exception e) { Debug.LogError($"Exception while executing DrawButtons plugin handler {e}"); } } } /// public bool HandleFileExtraction(INugetPackage package, ZipArchiveEntry entry, string extractDirectory) { foreach (var packageInstallFileHandler in packageInstallFileHandlers) { try { if (packageInstallFileHandler.HandleFileExtraction(package, entry, extractDirectory)) { return true; } } catch (Exception e) { Debug.LogError($"Exception while executing file extraction plugin handler {e}"); } } return false; } /// public void HandleUninstall(INugetPackage package, PackageUninstallReason uninstallReason) { foreach (var uninstallHandler in packageUninstallHandlers) { try { uninstallHandler.HandleUninstall(package, uninstallReason); } catch (Exception e) { Debug.LogError($"Exception while executing Uninstall plugin handler {e}"); } } } /// public void HandleUninstalledAll() { foreach (var uninstallHandler in packageUninstallHandlers) { try { uninstallHandler.HandleUninstalledAll(); } catch (Exception e) { Debug.LogError($"Exception while executing UninstallAll plugin handler {e}"); } } } /// public void ProcessInstalledPackage(INugetPackage installedPackage) { foreach (var foundInstalledPackageHandler in foundInstalledPackageHandlers) { try { foundInstalledPackageHandler.ProcessInstalledPackage(installedPackage); } catch (Exception e) { Debug.LogError($"Exception while executing ProcessInstalledPackage plugin handler {e}"); } } } } }