public CompileResult CompileOne(string inputFile, PreviewGenerationOptions previewOptions, IDictionary <IOutputGenerator, string> formats) { logger.LogInformation(inputFile); var loader = new XmlLoader(); using (var fs = File.OpenRead(inputFile)) { if (!loader.Load(fs, logger, out var description)) { Environment.Exit(1); } var outputs = Generate(fs, description, Path.GetFileNameWithoutExtension(inputFile), formats, previewOptions); return(new CompileResult(description.Metadata.Author, description.ComponentName, description.Metadata.GUID, true, description.Metadata.AdditionalInformation, inputFile, description.Metadata.Entries.ToImmutableDictionary(), outputs.ToImmutableDictionary())); } }
public IManifestEntry CompileOne(string inputFile, PreviewGenerationOptions previewOptions, bool allConfigurations, IDictionary <IOutputGenerator, string> formats) { logger.LogInformation(inputFile); var loader = new XmlLoader(); using (var fs = File.OpenRead(inputFile)) { if (!loader.Load(fs, logger, out var description)) { Environment.Exit(1); } var baseName = Path.GetFileNameWithoutExtension(inputFile); var outputs = outputRunner.Generate(fs, description, null, baseName, formats, previewOptions, SourceFileType.ComponentDescription).ToList(); Dictionary <string, IReadOnlyDictionary <string, string> > configurationOutputs = new Dictionary <string, IReadOnlyDictionary <string, string> >(); if (allConfigurations) { foreach (var configuration in description.Metadata.Configurations) { var renderOptions = new PreviewGenerationOptions { Center = previewOptions.Center, Crop = previewOptions.Crop, DebugLayout = previewOptions.DebugLayout, Width = previewOptions.Width, Height = previewOptions.Height, Horizontal = previewOptions.Horizontal, Size = previewOptions.Size, Configuration = configuration.Name, }; var configurationOutput = outputRunner.Generate(fs, description, configuration, baseName, formats, renderOptions, SourceFileType.ComponentDescriptionConfiguration); configurationOutputs[configuration.Name] = configurationOutput.ToImmutableDictionary(); } } var metadata = description.Metadata.Entries.ToDictionary(x => x.Key, x => x.Value); var svgIcon = GetSvgIconPath(Path.GetDirectoryName(inputFile), description); if (svgIcon != null) { metadata["org.circuit-diagram.icon-svg"] = svgIcon; } return(new ComponentDescriptionManifestEntry { Author = description.Metadata.Author, ComponentName = description.ComponentName, ComponentGuid = description.Metadata.GUID, Success = true, Description = description.Metadata.AdditionalInformation, Version = description.Metadata.Version.ToString(), InputFile = CleanPath(inputFile), Metadata = metadata, OutputFiles = outputs.ToImmutableDictionary(), ConfigurationOutputFiles = configurationOutputs, }); } }
public IManifestEntry CompileOne(string inputFile, PreviewGenerationOptions previewOptions, IDictionary <IOutputGenerator, string> formats) { logger.LogInformation(inputFile); var reader = new ConfigurationDefinitionReader(componentDescriptionLookup); using (var fs = File.OpenRead(inputFile)) { var configurationDefinition = reader.ReadDefinition(fs); var renderOptions = new PreviewGenerationOptions { Center = previewOptions.Center, Crop = previewOptions.Crop, DebugLayout = previewOptions.DebugLayout, Width = previewOptions.Width, Height = previewOptions.Height, Horizontal = previewOptions.Horizontal, Size = previewOptions.Size, RawProperties = configurationDefinition.Configuration.Setters, }; var outputs = outputRunner.Generate(fs, configurationDefinition.ComponentDescription, configurationDefinition.Configuration, Path.GetFileNameWithoutExtension(inputFile), formats, renderOptions, SourceFileType.ConfigurationDefinition); return(new ComponentConfigurationManifestEntry { Metadata = configurationDefinition.Metadata, InputFile = ComponentDescriptionRunner.CleanPath(inputFile), ComponentGuid = configurationDefinition.ComponentDescription.Metadata.GUID, ConfigurationName = configurationDefinition.Configuration.Name, OutputFiles = outputs.ToImmutableDictionary(), }); } }
internal static IEnumerable <KeyValuePair <string, string> > Generate(FileStream input, ComponentDescription description, string inputBaseName, IResourceProvider resourceProvider, IDictionary <IOutputGenerator, string> formats, PreviewGenerationOptions previewOptions) { foreach (var f in formats) { string format = f.Key.FileExtension.Substring(1); string autoGeneratedName = $"{inputBaseName}{f.Key.FileExtension}"; string outputPath = f.Value != null && Directory.Exists(f.Value) ? Path.Combine(f.Value, autoGeneratedName) : f.Value ?? autoGeneratedName; using (var output = File.Open(outputPath, FileMode.Create)) { Log.LogDebug($"Starting {format} generation."); input.Seek(0, SeekOrigin.Begin); f.Key.Generate(description, resourceProvider, previewOptions, input, output); Log.LogInformation($" {format,-4} -> {outputPath}"); } yield return(new KeyValuePair <string, string>(format, outputPath)); } }
public static void Run(string[] args) { string input = null; string propertiesPath = "render.properties"; string output = "render.png"; bool watch = false; bool silent = false; ArgumentSyntax.Parse(args, options => { options.ApplicationName = "cdcli render"; options.DefineOption("o|output", ref output, "Path to output file (default: render.png)."); options.DefineOption("s|silent", ref silent, "Does not output anything to the console on successful operation."); options.DefineOption("w|watch", ref watch, "Re-render output whenever the input file changes."); options.DefineOption("p|properties", ref propertiesPath, "Path to render properties file."); options.DefineParameter("input", ref input, "Path to input XML component file."); }); var loggerFactory = new LoggerFactory(); if (!silent) { loggerFactory.AddProvider(new BasicConsoleLogger(LogLevel.Information)); } var logger = loggerFactory.CreateLogger(typeof(RenderApp)); var renderOptions = new PreviewGenerationOptions { Size = 80.0, Center = true, Crop = false, Width = 640, Height = 480, Horizontal = false, }; renderOptions = PreviewGenerationOptionsReader.Read(propertiesPath); Render(logger, input, output, renderOptions); if (watch) { var fullPath = Path.GetFullPath(input); var watcher = new FileSystemWatcher(Path.GetDirectoryName(fullPath)); while (true) { var changes = watcher.WaitForChanged(WatcherChangeTypes.Changed); if (changes.Name == input || changes.Name == "render.properties") { renderOptions = PreviewGenerationOptionsReader.Read(propertiesPath); Render(logger, input, output, renderOptions); } } } }
public static PreviewGenerationOptions Read(string path) { var options = new PreviewGenerationOptions { Horizontal = true, Size = 80, Center = true, Width = 640.0, Height = 480.0, Properties = new Dictionary <string, string>(), }; if (!File.Exists(path)) { return(options); } using (var fs = File.Open(path, FileMode.Open, FileAccess.Read)) { var reader = new StreamReader(fs); while (!reader.EndOfStream) { var tokens = reader.ReadLine().Split('='); if (tokens.Length < 2) { continue; } switch (tokens[0].Trim()) { case "horizontal": options.Horizontal = bool.Parse(tokens[1]); break; case "configuration": options.Configuration = tokens[1]; break; default: if (tokens[0].StartsWith("$")) { options.Properties[tokens[0].Substring(1)] = tokens[1]; } break; } } } return(options); }
static CompileResult Run(string inputFile, IResourceProvider resourceProvider, PreviewGenerationOptions previewOptions, IDictionary <IOutputGenerator, string> formats) { Log.LogInformation(inputFile); var loader = new XmlLoader(); using (var fs = File.OpenRead(inputFile)) { loader.Load(fs); if (loader.LoadErrors.Any()) { foreach (var error in loader.LoadErrors) { switch (error.Category) { case LoadErrorCategory.Error: Log.LogError(error.Message); break; } } if (loader.LoadErrors.Any(x => x.Category == LoadErrorCategory.Error)) { Environment.Exit(1); } } var description = loader.GetDescriptions()[0]; var outputs = Generate(fs, description, Path.GetFileNameWithoutExtension(inputFile), resourceProvider, formats, previewOptions); return(new CompileResult(description.Metadata.Author, description.ComponentName, description.Metadata.GUID, true, description.Metadata.AdditionalInformation, inputFile, description.Metadata.Entries.ToImmutableDictionary(), outputs.ToImmutableDictionary())); } }
public static void Read(string path, PreviewGenerationOptions options) { using (var fs = File.Open(path, FileMode.Open, FileAccess.Read)) { var reader = new StreamReader(fs); while (!reader.EndOfStream) { var tokens = reader.ReadLine().Split('=').Select(x => x.Trim()).ToArray(); if (tokens.Length < 2) { continue; } switch (tokens[0]) { case "horizontal": options.Horizontal = bool.Parse(tokens[1]); break; case "size": options.Size = double.Parse(tokens[1]); break; case "configuration": options.Configuration = tokens[1]; break; case "flip": options.Flip = Enum.Parse <FlipState>(tokens[1], ignoreCase: true); break; default: if (tokens[0].StartsWith("$")) { options.Properties[tokens[0].Substring(1)] = tokens[1]; } break; } } } }
public IEnumerable <KeyValuePair <string, string> > Generate(FileStream input, ComponentDescription description, ComponentConfiguration configuration, string inputBaseName, IDictionary <IOutputGenerator, string> formats, PreviewGenerationOptions previewOptions, SourceFileType sourceType) { foreach (var f in formats) { if (!f.Key.AcceptsSourceFileType(sourceType)) { continue; } string format = f.Key.Format; if (sourceType == SourceFileType.ComponentDescriptionConfiguration) { inputBaseName += $"--{Regex.Replace(configuration.Name.ToLowerInvariant().Replace(" ", "_"), "[^a-z0-9_]", "")}"; } string autoGeneratedName = $"{inputBaseName}{f.Key.FileExtension}"; string outputPath = f.Value != null && Directory.Exists(f.Value) ? Path.Combine(f.Value, autoGeneratedName) : f.Value ?? autoGeneratedName; using (var output = File.Open(outputPath, FileMode.Create)) { logger.LogDebug($"Starting {format} generation."); input.Seek(0, SeekOrigin.Begin); f.Key.Generate(description, configuration, resourceProvider, previewOptions, input, output, sourceType); logger.LogInformation($" {format,-4} -> {outputPath}"); } yield return(new KeyValuePair <string, string>(format, outputPath)); } }
public int Run(Options options) { if (!options.Input.Any()) { _logger.LogError("At least one input file must be specified."); return(1); } var generators = new Dictionary <IOutputGenerator, string>(); bool outputIsDirectory = Directory.Exists(options.Output); if (options.Output != null && !outputIsDirectory) { if (_outputGeneratorRepository.TryGetGeneratorByFileExtension(Path.GetExtension(options.Output), out var generator)) { // Use the generator implied by the file extension generators.Add(generator, options.Output); } else if (options.Format?.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.Format?.Any() == true) { foreach (var format in options.Format) { if (_outputGeneratorRepository.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); } 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); }
public void Generate(ComponentDescription description, IResourceProvider resourceProvider, PreviewGenerationOptions options, Stream input, Stream output) { ComponentCompileResult result = compiler.Compile(input, output, resourceProvider, new CompileOptions()); if (!result.Success) { throw new Exception(); } }
public void Generate(ComponentDescription description, ComponentConfiguration configuration, IResourceProvider resourceProvider, PreviewGenerationOptions options, Stream input, Stream output, SourceFileType sourceType) { switch (Renderer) { case PngRenderer.Skia: { var drawingContext = PreviewRenderer.RenderPreview(size => new SkiaDrawingContext((int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height), SKColors.White, (float)options.Scale), description, options); drawingContext.WriteAsPng(output); break; } case PngRenderer.ImageSharp: { var drawingContext = PreviewRenderer.RenderPreview(size => new ImageSharpDrawingContext((int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height), SixLabors.ImageSharp.Color.White), description, options); drawingContext.WriteAsPng(output); break; } default: throw new InvalidOperationException($"Unknown renderer: {Renderer}"); } }
public void Generate(ComponentDescription description, ComponentConfiguration configuration, IResourceProvider resourceProvider, PreviewGenerationOptions options, Stream input, Stream output, SourceFileType sourceType) { var drawingContext = PreviewRenderer.RenderPreview(size => new SvgDrawingContext(Math.Ceiling(size.Width), Math.Ceiling(size.Height), output), description, options); drawingContext.Dispose(); }
public void Generate(ComponentDescription description, IResourceProvider resourceProvider, PreviewGenerationOptions options, Stream input, Stream output) { var drawingContext = PreviewRenderer.RenderPreview(size => new SkiaDrawingContext((int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height), SKColors.White), description, options); drawingContext.WriteAsPng(output); }
static void Main(string[] args) { IReadOnlyList <string> input = Array.Empty <string>(); IReadOnlyList <string> resources = null; string output = null; string cdcom = null; string svg = null; string png = null; string manifest = null; // Preview options bool autosize = false; double imgWidth = 640; double imgHeight = 480; bool recursive = false; bool silent = false; bool verbose = false; bool version = false; var cliOptions = ArgumentSyntax.Parse(args, options => { options.ApplicationName = "cdcompile"; 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 cdcomOption = options.DefineOption("cdcom", ref cdcom, false, "Output a compiled binary component."); if (cdcomOption.IsSpecified && cdcom == null) { cdcom = string.Empty; } var svgOption = options.DefineOption("svg", ref svg, false, "Render preview in SVG format."); if (svgOption.IsSpecified && svg == null) { svg = string.Empty; } var pngOption = options.DefineOption("png", ref png, false, "Render preview in PNG format (experimental)."); if (pngOption.IsSpecified && png == null) { png = string.Empty; } 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("version", ref version, "Prints the version of this application."); 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.DefineParameterList("input", ref input, "Components to compile."); }); if (version) { var assemblyName = typeof(Program).GetTypeInfo().Assembly.GetName(); Console.WriteLine($"cdcompile {assemblyName.Version} ({assemblyName.ProcessorArchitecture})"); return; } if (!silent) { LogManager.LoggerFactory.AddProvider(new BasicConsoleLogger(verbose ? LogLevel.Debug : LogLevel.Information)); } if (!input.Any()) { cliOptions.ReportError("At least one input file must be specified."); } if (output != null && (svg != null || png != null)) { cliOptions.ReportError("Supplying both --output and a specific format is not supported."); } IResourceProvider resourceProvider = null; if (resources != null && resources.Count == 1) { string directory = resources.Single(); if (!Directory.Exists(directory)) { cliOptions.ReportError($"Directory '{directory}' used for --resources does not exist."); } Log.LogDebug($"Using directory '{directory}' as resource provider."); resourceProvider = new DirectoryResourceProvider(resources.Single()); } else if (resources != null && resources.Count % 2 == 0) { Log.LogDebug("Mapping resources as key-file pairs."); resourceProvider = new FileMapResourceProvider(); for (int i = 0; i + 1 < resources.Count; i += 2) { ((FileMapResourceProvider)resourceProvider).Mappings.Add(resources[i], resources[i + 1]); } } else if (resources != null) { cliOptions.ReportError("--resources must either be a directory or a space-separated list of [key] [filename] pairs."); } else { Log.LogDebug("Not supplying resources."); resourceProvider = new FileMapResourceProvider(); } var formats = new Dictionary <IOutputGenerator, string>(); if (output != null) { IOutputGenerator generator; if (Generators.TryGetValue(Path.GetExtension(output), out generator)) { // Use the generator implied by the file extension formats.Add(generator, output); } else { Log.LogError("Unable to infer format from output file extension."); Environment.Exit(1); } } if (cdcom != null) { formats.Add(new BinaryComponentGenerator(), NullIfEmpty(cdcom)); } if (svg != null) { formats.Add(new SvgPreviewRenderer(), NullIfEmpty(svg)); } if (png != null) { formats.Add(new PngPreviewRenderer(), NullIfEmpty(png)); } var previewOptions = new PreviewGenerationOptions { Center = true, Crop = autosize, Width = imgWidth, Height = imgHeight }; var results = new List <CompileResult>(); foreach (var i in input) { if (File.Exists(i)) { var result = Run(i, resourceProvider, previewOptions, formats); results.Add(result); } else if (Directory.Exists(i)) { foreach (var generator in formats) { if (!Directory.Exists(generator.Value)) { cliOptions.ReportError("Outputs must be directories when the input is a directory."); } } foreach (var file in Directory.GetFiles(i, "*.xml", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { var result = Run(file, resourceProvider, previewOptions, formats); results.Add(result); } } else { Log.LogError($"Input is not a valid file or directory: {i}"); Environment.Exit(1); } } if (manifest != null) { using (var manifestFs = File.Open(manifest, FileMode.Create)) { Log.LogInformation($"Writing manifest to {manifest}"); ManifestGenerator.WriteManifest(results, manifestFs); } } }
private static void Render(ILogger logger, string inputPath, string outputPath, PreviewGenerationOptions renderOptions) { var loader = new XmlLoader(); loader.UseDefinitions(); using (var fs = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { if (!loader.Load(fs, logger, out var description)) { logger.LogError("Unable to render due to errors."); return; } var drawingContext = PreviewRenderer.RenderPreview((size) => new SkiaDrawingContext((int)size.Width, (int)size.Height, SKColors.White), description, renderOptions); using (var outputFs = File.OpenWrite(outputPath)) { drawingContext.WriteAsPng(outputFs); } } logger.LogInformation($"{inputPath} -> {outputPath}"); }
public void Generate(ComponentDescription description, ComponentConfiguration configuration, IResourceProvider resourceProvider, PreviewGenerationOptions options, Stream input, Stream output, SourceFileType sourceType) { ComponentCompileResult result = compiler.Compile(input, output, resourceProvider, new CompileOptions() { WriteExtendedMetadata = true }); if (!result.Success) { throw new Exception(); } }
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); } } }