diff --git a/src/Lively.Console.Tests/EnvConfigurationTests.cs b/src/Lively.Console.Tests/EnvConfigurationTests.cs index e48ea17..3aece3c 100644 --- a/src/Lively.Console.Tests/EnvConfigurationTests.cs +++ b/src/Lively.Console.Tests/EnvConfigurationTests.cs @@ -13,6 +13,7 @@ public void CanBuildApplicationConfigFromEnvironmentVariables() var provider = new TestEnvironmentVariableProvider { { "ASSEMBLY_LOCATION", "assembly-location" }, + { "ASSEMBLY_PATTERN_MATCH", "Lively." }, { "ROOT_TYPES", "type" } }; @@ -22,6 +23,7 @@ public void CanBuildApplicationConfigFromEnvironmentVariables() var type = Assert.Single(config.Generate); Assert.Equal("type", type); Assert.Equal("assembly-location", config.AssemblyLocation); + Assert.Equal("Lively.", config.AssemblyPatternMatch); } [Fact] diff --git a/src/Lively.Console/Configuration/ApplicationConfiguration.cs b/src/Lively.Console/Configuration/ApplicationConfiguration.cs index 2f66b35..ac3b245 100644 --- a/src/Lively.Console/Configuration/ApplicationConfiguration.cs +++ b/src/Lively.Console/Configuration/ApplicationConfiguration.cs @@ -17,6 +17,7 @@ private ApplicationConfiguration() { } public IConfiguration AssemblyConfiguration { get; private set; } public string AssemblyLocation { get; private set; } + public string AssemblyPatternMatch { get; private set; } public HashSet Skip { get; private set; } = new HashSet(); public List Generate { get; private set; } = new List(); public List Errors { get; private set; } = new List(); @@ -43,7 +44,8 @@ public static (ApplicationConfiguration, bool) Build(IEnvironmentVariableProvide private void Validate() { - if (string.IsNullOrEmpty(AssemblyLocation) || !File.Exists(AssemblyLocation)) + if (string.IsNullOrEmpty(AssemblyLocation) + || (!File.Exists(AssemblyLocation) && !Directory.Exists(AssemblyLocation))) { Errors.Add($"Assembly Location '{AssemblyLocation}' is missing or invalid"); } @@ -52,6 +54,7 @@ private void Validate() private void ReadEnvironmentVariables(IEnvironmentVariableProvider environmentVariableProvider) { AssemblyLocation = environmentVariableProvider.GetEnvironmentVariable("ASSEMBLY_LOCATION"); + AssemblyPatternMatch = environmentVariableProvider.GetEnvironmentVariable("ASSEMBLY_PATTERN_MATCH"); _assemblyConfigLocation = environmentVariableProvider.GetEnvironmentVariable("ASSEMBLY_CONFIG_LOCATION"); _configLocation = environmentVariableProvider.GetEnvironmentVariable("APPLICATION_CONFIG_LOCATION"); TrySetInterfaceResolver(environmentVariableProvider.GetEnvironmentVariable("INTERFACE_RESOLVER")); @@ -82,6 +85,9 @@ private void TryReadArgs(string[] args) if (!string.IsNullOrWhiteSpace(inputs.AssemblyLocation)) AssemblyLocation = inputs.AssemblyLocation; + if (!string.IsNullOrWhiteSpace(inputs.AssemblyPatternMatch)) + AssemblyPatternMatch = inputs.AssemblyPatternMatch; + if (!string.IsNullOrWhiteSpace(inputs.InterfaceResolver)) TrySetInterfaceResolver(inputs.InterfaceResolver); diff --git a/src/Lively.Console/Configuration/CommandLineInputs.cs b/src/Lively.Console/Configuration/CommandLineInputs.cs index 5a19a66..bde9b6c 100644 --- a/src/Lively.Console/Configuration/CommandLineInputs.cs +++ b/src/Lively.Console/Configuration/CommandLineInputs.cs @@ -6,9 +6,14 @@ public class CommandLineInputs { [Option('a', "assembly", Required = false, - HelpText = "The location of the assembly to read")] + HelpText = "The assembly file location or directory containing assemblies to load")] public string AssemblyLocation { get; set; } = null!; + [Option("pattern-match", + Required = false, + HelpText = "Regex pattern of assemblies to load in directory")] + public string AssemblyPatternMatch { get; set; } = null!; + [Option("assembly-config", Required = false, HelpText = "The location of the configuration file required to build IConfiguration for Startup")] diff --git a/src/Lively.Console/Program.cs b/src/Lively.Console/Program.cs index 73fa8c5..34f54e7 100644 --- a/src/Lively.Console/Program.cs +++ b/src/Lively.Console/Program.cs @@ -2,6 +2,9 @@ using System.Reflection; using Lively.Diagrams; using Lively.Console.Configuration; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; namespace Lively.Console { @@ -9,7 +12,6 @@ class Program { static int Main(string[] args) { - // System.Console.WriteLine(string.Join(", ", args)); var envProvider = new EnvironmentVariableProvider(); var (applicationConfig, ok) = ApplicationConfiguration.Build(envProvider, args); if (!ok) @@ -18,10 +20,14 @@ static int Main(string[] args) return -1; } - // System.Console.WriteLine(JsonSerializer.Serialize(applicationConfig)); + var (assembliesOk, assemblies) = TryBuildAssemblies(applicationConfig); + if (!assembliesOk) + { + System.Console.WriteLine($"Could not load assemblies from {applicationConfig.AssemblyLocation}"); + return -1; + } - var assembly = Assembly.LoadFrom(applicationConfig.AssemblyLocation); - var config = new DependencyTreeConfig(assembly, applicationConfig.AssemblyConfiguration) + var config = new DependencyTreeConfig(assemblies, applicationConfig.AssemblyConfiguration) { CreateInterfaceResolver = applicationConfig.CreateInterfaceResolver, SkipTypes = applicationConfig.Skip, @@ -77,6 +83,35 @@ static int Main(string[] args) return 0; } + private static (bool, Assembly[]) TryBuildAssemblies(ApplicationConfiguration config) + { + if (string.IsNullOrEmpty(config.AssemblyLocation)) + return (false, null); + + if (File.Exists(config.AssemblyLocation)) + { + var assembly = Assembly.LoadFrom(config.AssemblyLocation); + return (true, new[] { assembly }); + } + else if (Directory.Exists(config.AssemblyLocation)) + { + var assemblies = DependencyTreeConfigExtensions.GetAllAssembliesInDirectory( + config.AssemblyLocation, + filename => + { + if (string.IsNullOrWhiteSpace(config.AssemblyPatternMatch)) + return true; + + var split = filename.Split('/'); + var assemblyName = split[split.Length - 1]; + return Regex.IsMatch(assemblyName, config.AssemblyPatternMatch); + }).ToArray(); + return (true, assemblies); + } + + return (false, null); + } + private static void Print(DependencyTreeNode node, string indent = "") { System.Console.WriteLine($"{indent}{node.Name}");