in src/Microsoft.Atlas.CommandLine/Commands/WorkflowCommands.cs [96:233]
public async Task<int> ExecuteCore(bool generateOnly)
{
if (!OutputDirectory.HasValue())
{
OutputDirectory.TryParse($"_output");
}
var logsPath = Path.Combine(OutputDirectory.Required(), "logs");
if (Directory.Exists(logsPath))
{
foreach (var file in Directory.EnumerateFiles(logsPath))
{
File.Delete(file);
}
}
var generatedPath = Path.Combine(OutputDirectory.Required(), "generated");
if (Directory.Exists(generatedPath))
{
foreach (var file in Directory.EnumerateFiles(generatedPath, "*.*", new EnumerationOptions { RecurseSubdirectories = true }))
{
File.Delete(file);
}
foreach (var folder in Directory.EnumerateDirectories(generatedPath))
{
Directory.Delete(folder, recursive: true);
}
}
var blueprint = await _blueprintManager.GetBlueprintPackage(Blueprint.Required());
if (blueprint == null)
{
throw new ApplicationException($"Unable to locate blueprint {Blueprint.Required()}");
}
var eachValues = new List<object>();
var defaultValuesFiles =
File.Exists("values.yaml") ? new[] { "values.yaml" } :
new string[0];
foreach (var valuesFile in Values.OptionalMany(defaultValuesFiles))
{
using (var reader = File.OpenText(valuesFile))
{
eachValues.Add(_serializers.YamlDeserializer.Deserialize(reader));
}
}
if (Set.HasValue())
{
var setValues = new Dictionary<object, object>();
foreach (var set in Set.Values)
{
var parts = set.Split('=', 2);
if (parts.Length == 1)
{
throw new ApplicationException("Equal sign required when using the option --set name=value");
}
var name = parts[0];
var value = parts[1];
var segments = name.Split('.');
if (segments.Any(segment => string.IsNullOrEmpty(segment)))
{
throw new ApplicationException("Name must not have empty segments when using the option --set name=value");
}
var cursor = (IDictionary<object, object>)setValues;
foreach (var segment in segments.Reverse().Skip(1).Reverse())
{
if (cursor.TryGetValue(segment, out var child) && child is IDictionary<object, object>)
{
cursor = (IDictionary<object, object>)child;
}
else
{
child = new Dictionary<object, object>();
cursor[segment] = child;
cursor = (IDictionary<object, object>)child;
}
}
cursor[segments.Last()] = value;
}
eachValues.Add(setValues);
}
IDictionary<object, object> values = new Dictionary<object, object>();
foreach (var addValues in eachValues)
{
values = (IDictionary<object, object>)MergeUtils.Merge(addValues, values) ?? values;
}
var(templateEngine, workflow, effectiveValues) = _workflowLoader.Load(blueprint, values, GenerateOutput);
if (generateOnly == false)
{
var patternMatcher = _patternMatcherFactory.Create(Target.Values.Any() ? Target.Values : new List<string>() { "/**" });
var context = new ExecutionContext.Builder()
.UseBlueprintPackage(blueprint)
.UseTemplateEngine(templateEngine)
.UsePatternMatcher(patternMatcher)
.SetOutputDirectory(OutputDirectory.Required())
.SetNonInteractive(NonInteractive?.HasValue() ?? false)
.SetDryRun(DryRun?.HasValue() ?? false)
.SetValues(effectiveValues)
.Build();
context.AddValuesIn(_valuesEngine.ProcessValues(workflow.values, context.Values) ?? context.Values);
var resultOut = await _workflowEngine.ExecuteOperations(context, workflow.operations);
if (workflow.output != null)
{
context.AddValuesOut(_valuesEngine.ProcessValues(workflow.output, MergeUtils.Merge(resultOut, context.Values) ?? context.Values));
}
else
{
context.AddValuesOut(resultOut);
}
if (context.ValuesOut != null)
{
GenerateOutput("output.yaml", writer => _serializers.YamlSerializer.Serialize(writer, context.ValuesOut));
using (var writer = _secretTracker.FilterTextWriter(_console.Out))
{
_serializers.YamlSerializer.Serialize(writer, context.ValuesOut);
}
}
}
return 0;
}