public static int Run(IHost host, Options options) { var services = new ServiceCollection(); services.AddLogging(x => x.SetupLogging(options.Verbose, options.Silent)); services.AddSingleton(s => ActivatorUtilities.CreateInstance <OutputGeneratorRepository>(s, options.Renderer)); if (options.Components != null) { var xmlLoader = new TypeDescriptionIO.Xml.XmlLoader(); xmlLoader.UseDefinitions(); services.AddSingleton <IComponentDescriptionLookup>(s => new DirectoryComponentDescriptionLookup(s.GetRequiredService <ILoggerFactory>(), options.Components, options.Recursive, xmlLoader)); } else { services.AddSingleton <IComponentDescriptionLookup, DictionaryComponentDescriptionLookup>(); } services.AddSingleton(s => ResourceProviderFactory.Create(s.GetRequiredService <ILogger <ResourceProviderFactory> >(), options.Resources)); services.AddSingleton <OutputRunner>(); services.AddSingleton <ComponentDescriptionRunner>(); services.AddSingleton <ConfigurationDefinitionRunner>(); var serviceProvider = services.BuildServiceProvider(); var app = ActivatorUtilities.CreateInstance <ComponentApp>(serviceProvider); return(app.Run(options)); }
public static void Run(string[] args) { IReadOnlyList <string> input = Array.Empty <string>(); IReadOnlyList <string> resources = null; IReadOnlyList <string> additionalFormats = null; string output = null; string manifest = null; bool allConfigurations = false; // Preview options bool autosize = false; double imgWidth = 640; double imgHeight = 480; string configuration = null; bool recursive = false; bool silent = false; bool verbose = false; var cliOptions = ArgumentSyntax.Parse(args, options => { options.ApplicationName = "cdcli component"; options.DefineOption("o|output", ref output, "Output file (the format will be inferred from the extension). Cannot be used for directory inputs or in combination with specific output format options."); var manifestOption = options.DefineOption("manifest", ref manifest, false, "Writes a manifest file listing the compiled components."); if (manifestOption.IsSpecified && manifest == null) { manifest = "manifest.xml"; } options.DefineOption("autosize", ref autosize, "Automatically sizes the output image to fit the rendered preview."); options.DefineOption("w|width", ref imgWidth, double.Parse, "Width of output images to generate (default=640)."); options.DefineOption("h|height", ref imgHeight, double.Parse, "Height of output images to generate (default=480)."); options.DefineOption("r|recursive", ref recursive, "Recursively searches sub-directories of the input directory."); options.DefineOption("s|silent", ref silent, "Does not output anything to the console on successful operation."); options.DefineOption("v|verbose", ref verbose, "Outputs extra information to the console."); options.DefineOption("c|configuration", ref configuration, "Name of component configuration to use."); options.DefineOption("all-configurations", ref allConfigurations, "Produce an output for every component configuration (supported output formats only)."); options.DefineOptionList("resources", ref resources, "Resources to use in generating the output. Either a directory, or a space-separated list of [key] [filename] pairs."); options.DefineOptionList("format", ref additionalFormats, "Output formats to write."); options.DefineParameterList("input", ref input, "Components to compile."); }); var loggerFactory = new LoggerFactory(); if (!silent) { loggerFactory.AddProvider(new BasicConsoleLogger(LogLevel.Information)); } var logger = loggerFactory.CreateLogger(typeof(ComponentApp)); if (!input.Any()) { logger.LogError("At least one input file must be specified."); Environment.Exit(1); } var generators = new Dictionary <IOutputGenerator, string>(); var outputGenerators = new OutputGeneratorRepository(); bool outputIsDirectory = Directory.Exists(output); if (output != null && !outputIsDirectory) { if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(output), out var generator)) { // Use the generator implied by the file extension generators.Add(generator, output); } else if (additionalFormats?.Any() != true) { logger.LogError("Unable to infer format from output file extension." + Environment.NewLine + "Specify a known file extension or specify explicitly using --format"); Environment.Exit(1); } else { logger.LogInformation("Unable to infer format from output file extension. Using formats only."); } } if (additionalFormats?.Any() == true) { foreach (var format in additionalFormats) { if (outputGenerators.TryGetGeneratorByFormat(format, out var generator)) { generators.Add(generator, outputIsDirectory ? output : null); } else { logger.LogError($"Unknown format: {format}"); Environment.Exit(1); } } } var previewOptions = new PreviewGenerationOptions { Center = true, Crop = autosize, Width = imgWidth, Height = imgHeight, Configuration = configuration, Properties = new Dictionary <string, string>(), }; DirectoryComponentDescriptionLookup componentDescriptionLookup; if (input.Count == 1 && Directory.Exists(input.Single())) { componentDescriptionLookup = new DirectoryComponentDescriptionLookup(input.Single(), true); } else { componentDescriptionLookup = new DirectoryComponentDescriptionLookup(input.ToArray()); } var resourceProvider = ResourceProviderFactory.Create(loggerFactory.CreateLogger(typeof(ResourceProviderFactory)), resources); var outputRunner = new OutputRunner(loggerFactory.CreateLogger <OutputRunner>(), resourceProvider); var compileRunner = new ComponentDescriptionRunner(loggerFactory.CreateLogger <ComponentDescriptionRunner>(), outputRunner); var configurationDefinitionRunner = new ConfigurationDefinitionRunner(loggerFactory.CreateLogger <ConfigurationDefinitionRunner>(), componentDescriptionLookup, outputRunner); var results = new List <IManifestEntry>(); var inputs = new List <string>(); foreach (var i in input) { if (File.Exists(i)) { inputs.Add(i); } else if (Directory.Exists(i)) { foreach (var generator in generators) { if (generator.Value != null && !Directory.Exists(generator.Value)) { logger.LogError("Outputs must be directories when the input is a directory."); Environment.Exit(1); } } foreach (var file in Directory.GetFiles(i, "*.xml", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } foreach (var file in Directory.GetFiles(i, "*.yaml", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } } else { logger.LogError($"Input is not a valid file or directory: {i}"); Environment.Exit(1); } } foreach (var file in inputs.OrderBy(x => x)) { IManifestEntry result; switch (Path.GetExtension(file)) { case ".xml": result = compileRunner.CompileOne(file, previewOptions, allConfigurations, generators); break; case ".yaml": result = configurationDefinitionRunner.CompileOne(file, previewOptions, generators); break; default: throw new NotSupportedException($"File type '{Path.GetExtension(file)}' not supported."); } results.Add(result); } if (manifest != null) { using (var manifestFs = File.Open(manifest, FileMode.Create)) { logger.LogInformation($"Writing manifest to {manifest}"); ManifestWriter.WriteManifest(results, manifestFs); } } }
public static int Run(Options options) { var loggerFactory = new LoggerFactory(); if (!options.Silent) { loggerFactory.AddProvider(new BasicConsoleLogger(options.Verbose ? LogLevel.Debug : LogLevel.Information)); } var logger = loggerFactory.CreateLogger(typeof(ComponentApp)); if (!options.Input.Any()) { logger.LogError("At least one input file must be specified."); return(1); } var generators = new Dictionary <IOutputGenerator, string>(); var outputGenerators = new OutputGeneratorRepository(options.Renderer); bool outputIsDirectory = Directory.Exists(options.Output); if (options.Output != null && !outputIsDirectory) { if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(options.Output), out var generator)) { // Use the generator implied by the file extension generators.Add(generator, options.Output); } else if (options.Formats?.Any() != true) { logger.LogError("Unable to infer format from output file extension." + Environment.NewLine + "Specify a known file extension or specify explicitly using --format"); return(1); } else { logger.LogInformation("Unable to infer format from output file extension. Using formats only."); } } if (options.Formats?.Any() == true) { foreach (var format in options.Formats) { if (outputGenerators.TryGetGeneratorByFormat(format, out var generator)) { generators.Add(generator, outputIsDirectory ? options.Output : null); } else { logger.LogError($"Unknown format: {format}"); return(1); } } } var previewOptions = new PreviewGenerationOptions { Center = true, Crop = options.Autosize, Width = options.Width, Height = options.Height, Configuration = options.Configuration, DebugLayout = options.DebugLayout, Grid = options.Grid, Scale = options.Scale, Properties = new Dictionary <string, string>(), }; if (options.RenderPropertiesPath != null && File.Exists(options.RenderPropertiesPath)) { logger.LogDebug($"Applying render properties from '{options.RenderPropertiesPath}'"); PreviewGenerationOptionsReader.Read(options.RenderPropertiesPath, previewOptions); } IComponentDescriptionLookup componentDescriptionLookup; var descriptionLookupLoggerFactory = options.Verbose ? loggerFactory : (ILoggerFactory)NullLoggerFactory.Instance; if (options.ComponentsDirectory != null) { componentDescriptionLookup = new DirectoryComponentDescriptionLookup(descriptionLookupLoggerFactory, options.ComponentsDirectory, true); } else { componentDescriptionLookup = new DictionaryComponentDescriptionLookup(); } var resourceProvider = ResourceProviderFactory.Create(loggerFactory.CreateLogger(typeof(ResourceProviderFactory)), options.Resources?.ToArray() ?? new string[0]); var outputRunner = new OutputRunner(loggerFactory.CreateLogger <OutputRunner>(), resourceProvider); var compileRunner = new ComponentDescriptionRunner(loggerFactory.CreateLogger <ComponentDescriptionRunner>(), outputRunner); var configurationDefinitionRunner = new ConfigurationDefinitionRunner(loggerFactory.CreateLogger <ConfigurationDefinitionRunner>(), componentDescriptionLookup, outputRunner); var results = new List <IManifestEntry>(); var inputs = new List <string>(); if (File.Exists(options.Input)) { logger.LogDebug("Input is a file."); inputs.Add(options.Input); } else if (Directory.Exists(options.Input)) { logger.LogDebug("Input is a directory."); foreach (var generator in generators) { if (generator.Value != null && !Directory.Exists(generator.Value)) { logger.LogError("Outputs must be directories when the input is a directory."); return(1); } } foreach (var file in Directory.GetFiles(options.Input, "*.xml", options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } foreach (var file in Directory.GetFiles(options.Input, "*.yaml", options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { inputs.Add(file); } } else { logger.LogError($"Input is not a valid file or directory: {options.Input}"); return(1); } foreach (var file in inputs.OrderBy(x => x)) { logger.LogDebug($"Starting '{file}'"); IManifestEntry result; switch (Path.GetExtension(file)) { case ".xml": result = compileRunner.CompileOne(file, previewOptions, options.AllConfigurations, generators); break; case ".yaml": result = configurationDefinitionRunner.CompileOne(file, previewOptions, generators); break; default: throw new NotSupportedException($"File type '{Path.GetExtension(file)}' not supported."); } if (result == null) { return(2); } results.Add(result); logger.LogDebug($"Finshed '{file}'"); } if (options.Manifest != null) { using (var manifestFs = File.Open(options.Manifest, FileMode.Create)) { logger.LogInformation($"Writing manifest to {options.Manifest}"); ManifestWriter.WriteManifest(results, manifestFs); } } return(0); }