1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
namespace marlin.core.functional;
using models.meta;
using models.meta.dto;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
public class WorkflowBuilder
{
private static readonly IDeserializer Deserializer = new DeserializerBuilder()
.WithNamingConvention(HyphenatedNamingConvention.Instance)
.WithEnumNamingConvention(HyphenatedNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build();
private readonly Workflow _workflow = new();
public Workflow Build() => this._workflow;
public void LoadFromDirectory(string path)
{
var files = Directory.EnumerateFiles(path, "*.yml", SearchOption.AllDirectories);
foreach (var file in files)
this.LoadFromString(File.ReadAllText(file));
}
public void LoadFromString(string content)
{
var file = Deserializer.Deserialize<WorkflowFileDto>(content);
if (file == null)
return;
this.ApplyRequirements(file.Requirements);
this.ApplyRecipes(file.Recipes);
this.ApplySteps(file.Steps);
}
private void ApplyRequirements(Dictionary<string, RequirementSetDto>? requirements)
{
if (requirements == null)
return;
foreach (var (id, dto) in requirements)
{
var requirementSet = new RequirementSet(id)
{
Base = dto.Base,
Has = dto.Has != null ? new Dictionary<string, string>(dto.Has) : new()
};
this._workflow.Requirements[id] = requirementSet;
}
}
private void ApplyRecipes(Dictionary<string, RecipeDto>? recipes)
{
if (recipes == null)
return;
foreach (var (id, dto) in recipes)
{
var recipe = new Recipe(id)
{
Name = dto.Name ?? id,
RunsOnId = dto.RunsOn,
RequireIds = dto.Requires ?? [],
Parameters = dto.Parameters != null ? new Dictionary<string, string>(dto.Parameters) : new(),
Environment = dto.Environment != null ? new Dictionary<string, string>(dto.Environment) : new()
};
if (dto.Steps != null)
{
foreach (var (stepId, stepDto) in dto.Steps)
recipe.Steps[stepId] = this.BuildRecipeStep(stepId, stepDto);
}
this._workflow.Recipes[id] = recipe;
}
}
private void ApplySteps(Dictionary<string, StepDto>? steps)
{
if (steps == null)
return;
foreach (var (id, dto) in steps)
this._workflow.Steps[id] = this.BuildRecipeStep(id, dto);
}
private RecipeStep BuildRecipeStep(string id, StepDto dto)
{
var step = new RecipeStep(id);
ApplyAbstractStep(step, dto);
step.BaseId = dto.Base;
if (dto.Artifacts != null)
{
foreach (var item in dto.Artifacts)
step.Artifacts[item.Key] = item.Value;
}
if (dto.Cleanup != null)
step.Cleanup = BuildCleanupStep(id + "/cleanup", dto.Cleanup);
return step;
}
private static CleanupStep BuildCleanupStep(string id, CleanupStepDto dto)
{
var step = new CleanupStep(id) { After = dto.After ?? CleanupAfter.Step };
ApplyAbstractStep(step, dto);
return step;
}
private static void ApplyAbstractStep(AbstractStep step, StepDtoBase dto)
{
step.Name = dto.Name;
step.Run = dto.Run;
step.With = dto.With != null ? new Dictionary<string, string>(dto.With) : new();
step.Fail = dto.Fail;
}
}
|