From ff0926be56fc6eafdce36411847d73bf4ce9f183 Mon Sep 17 00:00:00 2001 From: vnugent Date: Sun, 16 Jun 2024 13:08:31 -0400 Subject: feat: Allow multiple plugin loading directories --- lib/Plugins.Runtime/src/LoaderExtensions.cs | 49 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'lib/Plugins.Runtime/src') diff --git a/lib/Plugins.Runtime/src/LoaderExtensions.cs b/lib/Plugins.Runtime/src/LoaderExtensions.cs index 5ffbecb..53715a6 100644 --- a/lib/Plugins.Runtime/src/LoaderExtensions.cs +++ b/lib/Plugins.Runtime/src/LoaderExtensions.cs @@ -445,28 +445,29 @@ namespace VNLib.Plugins.Runtime /// /// Specifies the directory that the plugin loader will search for plugins in /// - /// The search directory path + /// An array of search directories /// /// The current builder instance for chaining /// - public static PluginStackBuilder WithSearchDirectory(this PluginStackBuilder builder, string path) => WithSearchDirectory(builder, new DirectoryInfo(path)); + public static PluginStackBuilder WithSearchDirectories(this PluginStackBuilder builder, string[] paths) + => WithSearchDirectories(builder, paths.Select(static p => new DirectoryInfo(p)).ToArray()); /// /// Specifies the directory that the plugin loader will search for plugins in /// - /// The search directory instance + /// The search directory instance /// /// The current builder instance for chaining /// - public static PluginStackBuilder WithSearchDirectory(this PluginStackBuilder builder, DirectoryInfo dir) + public static PluginStackBuilder WithSearchDirectories(this PluginStackBuilder builder, DirectoryInfo[] dirs) { - ArgumentNullException.ThrowIfNull(builder, nameof(builder)); - ArgumentNullException.ThrowIfNull(dir, nameof(dir)); - - PluginDirectorySearcher dirSearcher = new (dir); - builder.WithDiscoveryManager(dirSearcher); + ArgumentNullException.ThrowIfNull(builder); + ArgumentNullException.ThrowIfNull(dirs); + + builder.WithDiscoveryManager(discoveryManager: new PluginDirectorySearcher(dirs)); return builder; } + /// /// Registers a new for the current plugin stack @@ -493,15 +494,19 @@ namespace VNLib.Plugins.Runtime /// An enumeration of all wrappers public static IEnumerable GetAllPlugins(this IPluginStack stack) => stack.Plugins.SelectMany(static p => p.Controller.Plugins); - private sealed record class PluginDirectorySearcher(DirectoryInfo Dir) : IPluginDiscoveryManager + private sealed record class PluginDirectorySearcher(DirectoryInfo[] SearchDirs) : IPluginDiscoveryManager { private const string PLUGIN_FILE_EXTENSION = ".dll"; /// public string[] DiscoverPluginFiles() { - //Enumerate all dll files within the seach directory - IEnumerable dirs = Dir.EnumerateDirectories("*", SearchOption.TopDirectoryOnly); + /* + * Accumulate all plugin child directores + * from the search directories + */ + + IEnumerable dirs = SearchDirs.SelectMany(static p => p.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)); //Search all directories for plugins and return the paths return GetPluginPaths(dirs).ToArray(); @@ -547,19 +552,16 @@ namespace VNLib.Plugins.Runtime //Get the plugin config file name string pluginConfigFile = GetConfigFilePathCallback(asmConfig); - using JsonDocument hConfig = JsonDocument.Parse(HostJson, jdo); - - //Read the plugin config file + using JsonDocument hostConfig = JsonDocument.Parse(HostJson, jdo); + if (FileOperations.FileExists(pluginConfigFile)) { //Open file stream to read data - using FileStream confStream = File.OpenRead(pluginConfigFile); - - //Parse the config file - using JsonDocument pConfig = JsonDocument.Parse(confStream, jdo); + using FileStream pluginConfFileData = File.OpenRead(pluginConfigFile); - //Merge the configs - using JsonDocument merged = hConfig.Merge(pConfig,"host", "plugin"); + using JsonDocument pluginConf = JsonDocument.Parse(pluginConfFileData, jdo); + + using JsonDocument merged = hostConfig.Merge(pluginConf,"host", "plugin"); //Write the merged config to the output stream using Utf8JsonWriter writer = new(configData); @@ -569,10 +571,9 @@ namespace VNLib.Plugins.Runtime { byte[] pluginConfig = Encoding.UTF8.GetBytes("{}"); - using JsonDocument pConfig = JsonDocument.Parse(pluginConfig, jdo); + using JsonDocument pluginConf = JsonDocument.Parse(pluginConfig, jdo); - //Merge the configs - using JsonDocument merged = hConfig.Merge(pConfig,"host", "plugin"); + using JsonDocument merged = hostConfig.Merge(pluginConf, "host", "plugin"); //Write the merged config to the output stream using Utf8JsonWriter writer = new(configData); -- cgit