Esempio n. 1
0
        /// <summary>
        /// Executes the selected code generation.
        /// </summary>
        public async Task RunAsync()
        {
            var overallCreatedCount = 0;
            var overallUpdatedCount = 0;

            try
            {
                XElement?xmlScript;
                if (_args.ScriptFile !.Exists)
                {
                    using var fs = File.OpenText(_args.ScriptFile.FullName);
                    xmlScript    = await XElement.LoadAsync(fs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false);
                }
                else
                {
                    xmlScript = await ResourceManager.GetScriptContentXmlAsync(_args.ScriptFile.Name, _args.Assemblies.ToArray()).ConfigureAwait(false);
                }

                if (xmlScript?.Name != "Script")
                {
                    throw new CodeGenException("The Script XML file must have a root element named 'Script'.");
                }

                if (!xmlScript.Elements("Generate").Any())
                {
                    throw new CodeGenException("The Script XML file must have at least a single 'Generate' element.");
                }

                // Create the code generator instance.
                string?outputDir = null;

                using var cfs = File.OpenText(_args.ConfigFile !.FullName);
                var gen = CodeGenerator.Create(await XElement.LoadAsync(cfs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false), GetLoaders(xmlScript));
                gen.CodeGenerated += (sender, e) => { CodeGenerated(outputDir !, e); };

                // Execute each of the script instructions.
                foreach (var scriptEle in xmlScript.Elements("Generate"))
                {
                    string?template        = null;
                    string?outDir          = null;
                    string?helpText        = null;
                    var    otherParameters = new Dictionary <string, string>();
                    foreach (var att in scriptEle.Attributes())
                    {
                        switch (att.Name.LocalName)
                        {
                        case "Template": template = att.Value; break;

                        case "OutDir": outDir = att.Value; break;

                        case "HelpText": helpText = att.Value; break;

                        default: otherParameters.Add(att.Name.LocalName, att.Value); break;
                        }
                    }

                    // Manage the parameters.
                    gen.ClearParameters();
                    gen.CopyParameters(_args.Parameters);
                    gen.CopyParameters(otherParameters);

                    // Log progress.
                    CreatedCount    = 0;
                    UpdatedCount    = 0;
                    NotChangedCount = 0;
                    _args.Logger.LogInformation("  Template: {0} {1}", template !, helpText == null ? string.Empty : $"({helpText})");

                    XElement xmlTemplate;
                    if (_args.TemplatePath != null)
                    {
                        var fi = new FileInfo(Path.Combine(_args.TemplatePath.FullName, template !));
                        if (!fi.Exists)
                        {
                            throw new CodeGenException($"The Template XML file '{fi.FullName}' does not exist.");
                        }

                        using var fs = File.OpenText(fi.FullName);
                        xmlTemplate  = await XElement.LoadAsync(fs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false);
                    }
                    else
                    {
                        xmlTemplate = await ResourceManager.GetTemplateContentXmlAsync(template !, _args.Assemblies.ToArray()).ConfigureAwait(false) ??
                                      throw new CodeGenException($"The Template XML resource '{template}' does not exist.");
                    }

                    // Execute the code generation itself.
                    outputDir = Path.Combine(_args.OutputPath !.FullName, SubstituteOutputDir(outDir !));
                    await gen.GenerateAsync(xmlTemplate).ConfigureAwait(false);

                    // Provide statistics.
                    _args.Logger.LogInformation("   [Files: Unchanged = {0}, Updated = {1}, Created = {2}]", NotChangedCount, UpdatedCount, CreatedCount);

                    // Keep track of overall counts.
                    overallCreatedCount += CreatedCount;
                    overallUpdatedCount += UpdatedCount;
                }
            }
Esempio n. 2
0
        /// <summary>
        /// Executes the selected code generation.
        /// </summary>
        protected override Task OnRunAsync(ExecutorRunArgs args)
        {
            try
            {
                // Load the script file instructions.
                XElement xmlScript = (_args.ScriptFile.Exists) ? XElement.Load(_args.ScriptFile.FullName) : ResourceManager.GetScriptContentXml(_args.ScriptFile.Name, _args.Assemblies.ToArray());
                if (xmlScript.Name != "Script")
                {
                    throw new CodeGenException("The Script XML file must have a root element named 'Script'.");
                }

                if (xmlScript.Elements("Generate").Count() == 0)
                {
                    throw new CodeGenException("The Script XML file must have at least a single 'Generate' element.");
                }

                // Create the code generator instance.
                string outputDir = null;

                var gen = CodeGenerator.Create(XElement.Load(_args.ConfigFile.FullName), GetLoaders(xmlScript));
                gen.CodeGenerated += (sender, e) => { CodeGenerated(outputDir, e); };

                // Execute each of the script instructions.
                foreach (var scriptEle in xmlScript.Elements("Generate"))
                {
                    // As this can be long running, check and see if a stop has been initiated.
                    if (this.State != ExecutionState.Running)
                    {
                        return(Task.CompletedTask);
                    }

                    string template        = null;
                    string outDir          = null;
                    var    otherParameters = new Dictionary <string, string>();
                    foreach (var att in scriptEle.Attributes())
                    {
                        switch (att.Name.LocalName)
                        {
                        case "Template": template = att.Value; break;

                        case "OutDir": outDir = att.Value; break;

                        default: otherParameters.Add(att.Name.LocalName, att.Value); break;
                        }
                    }

                    // Manage the parameters.
                    gen.ClearParameters();
                    gen.CopyParameters(_args.Parameters);
                    gen.CopyParameters(otherParameters);

                    // Log progress.
                    CreatedCount    = 0;
                    UpdatedCount    = 0;
                    NotChangedCount = 0;
                    Logger.Default.Info("  Template: {0}", template);

                    XElement xmlTemplate;
                    if (_args.TemplatePath != null)
                    {
                        var fi = new FileInfo(Path.Combine(_args.TemplatePath.FullName, template));
                        if (!fi.Exists)
                        {
                            throw new CodeGenException(string.Format("The Template XML file '{0}' does not exist.", fi.FullName));
                        }

                        xmlTemplate = XElement.Load(fi.FullName);
                    }
                    else
                    {
                        xmlTemplate = ResourceManager.GetTemplateContentXml(template, _args.Assemblies.ToArray()) ??
                                      throw new CodeGenException(string.Format("The Template XML resource '{0}' does not exist.", template));
                    }

                    // Execute the code generation itself.
                    outputDir = Path.Combine(_args.OutputPath.FullName, SubstituteOutputDir(outDir));
                    gen.Generate(xmlTemplate);

                    // Provide statistics.
                    Logger.Default.Info("   [Files: Unchanged = {0}, Updated = {1}, Created = {2}]", NotChangedCount, UpdatedCount, CreatedCount);
                }
            }
            catch (CodeGenException gcex)
            {
                Logger.Default.Error(gcex.Message);
                Logger.Default.Info(string.Empty);
            }

            return(Task.CompletedTask);
        }
Esempio n. 3
0
        /// <summary>
        /// Executes the selected code generation.
        /// </summary>
        public async Task <bool> RunAsync()
        {
            var overallCreatedCount = 0;
            var overallUpdatedCount = 0;

            try
            {
                // Load the script configuration.
                var(scripts, loaders, configType) = await LoadScriptConfigAsync().ConfigureAwait(false);

                ConfigBase? cfg  = null;
                IRootConfig?rcfg = null;
                if (configType == ConfigType.Entity)
                {
                    cfg = await LoadConfigFileAsync(configType).ConfigureAwait(false);

                    rcfg = (IRootConfig)cfg;
                    rcfg.ReplaceRuntimeParameters(_args.Parameters);
                    cfg.Prepare(cfg, cfg);
                }

                // Create the "legacy" code generator instance.
                string?outputDir = null;

                using var cfs = File.OpenText(_args.ConfigFile !.FullName);
                var gen = CodeGenerator.Create(await XElement.LoadAsync(cfs, LoadOptions.None, CancellationToken.None).ConfigureAwait(false), loaders);
                gen.CodeGenerated += (sender, e) => { CodeGenerated(outputDir !, e); };

                // Execute each of the script instructions.
                foreach (var script in scripts)
                {
                    NotChangedCount = 0;
                    UpdatedCount    = 0;
                    CreatedCount    = 0;

                    // Log progress.
                    _args.Logger.LogInformation("  Template: {0} {1}", script.Template !, script.HelpText == null ? string.Empty : $"({script.HelpText})");

                    // Get the template contents.
                    var template = await GetTemplateContentsAsync(script).ConfigureAwait(false);

                    if (script.GenType != null)
                    {
                        // Execute the new+improved handlebars-based code-gen.
                        rcfg !.ResetRuntimeParameters();
                        rcfg !.ReplaceRuntimeParameters(_args.Parameters);
                        rcfg !.ReplaceRuntimeParameters(script.OtherParameters);

                        var gt = Type.GetType(script.GenType) ?? throw new CodeGenException($"GenType '{script.GenType}' was unable to be loaded.");
                        var cg = (CodeGeneratorBase)(Activator.CreateInstance(gt) ?? throw new CodeGenException($"GenType '{script.GenType}' was unable to be instantiated."));
                        cg.OutputFileName = script.FileName;
                        cg.OutputDirName  = script.OutDir;
                        cg.Generate(template, cfg !, e => CodeGenerated(_args.OutputPath !.FullName, e));
                    }
                    else
                    {
                        // Execute the legacy custom code-gen (being slowly deprecated).
                        gen.ClearParameters();
                        gen.CopyParameters(_args.Parameters);
                        gen.CopyParameters(script.OtherParameters);

                        outputDir = Path.Combine(_args.OutputPath !.FullName, SubstituteOutputDir(script.OutDir !));

                        using var sr = new StringReader(template);
                        await gen.GenerateAsync(XElement.Load(sr, LoadOptions.None)).ConfigureAwait(false);
                    }

                    // Provide statistics.
                    _args.Logger.LogInformation("   [Files: Unchanged = {0}, Updated = {1}, Created = {2}]", NotChangedCount, UpdatedCount, CreatedCount);

                    // Keep track of overall counts.
                    overallCreatedCount += CreatedCount;
                    overallUpdatedCount += UpdatedCount;
                }
            }
            catch (CodeGenException gcex)
            {
                _args.Logger.LogError(gcex.Message);
                _args.Logger.LogInformation(string.Empty);
                return(false);
            }

            if (_args.ExpectNoChange && (overallCreatedCount != 0 || overallUpdatedCount != 0))
            {
                _args.Logger.LogError("Unexpected changes detected; one or more files were created and/or updated.");
                return(false);
            }

            return(true);
        }