/// <summary> /// Executes the selected code generation. /// </summary> protected override async Task OnRunAsync(ExecutorRunArgs args) { 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")) { // As this can be long running, check and see if a stop has been initiated. if (State != ExecutionState.Running) { return; } 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; Logger.Default.Info(" 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. Logger.Default.Info(" [Files: Unchanged = {0}, Updated = {1}, Created = {2}]", NotChangedCount, UpdatedCount, CreatedCount); } }