예제 #1
0
        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()));
            }
        }
예제 #2
0
        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(),
                });
            }
        }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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);
        }
예제 #7
0
        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;
                    }
                }
            }
        }
예제 #9
0
        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));
            }
        }
예제 #10
0
        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);
        }
예제 #11
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();
            }
        }
예제 #12
0
        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}");
            }
        }
예제 #13
0
        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();
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
                }
            }
        }
예제 #16
0
        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}");
        }
예제 #17
0
        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();
            }
        }
예제 #18
0
        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);
                }
            }
        }