/// <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; } }
/// <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); }
/// <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); }