-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #106 from NoxOrg/feature/jobs-foreach
- foreach working
- Loading branch information
Showing
14 changed files
with
357 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System.Collections.ObjectModel; | ||
|
||
namespace Nox.Cli.Abstractions; | ||
|
||
public class NoxJobDictionary: KeyedCollection<string, INoxJob> | ||
{ | ||
public NoxJobDictionary(): base(StringComparer.OrdinalIgnoreCase) | ||
{ | ||
|
||
} | ||
|
||
protected override string GetKeyForItem(INoxJob item) | ||
{ | ||
return item.Id; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
using System.Text.RegularExpressions; | ||
using Nox.Cli.Abstractions; | ||
using YamlDotNet.Serialization; | ||
using YamlDotNet.Serialization.NamingConventions; | ||
|
||
namespace Nox.Cli.Variables; | ||
|
||
public class ForEachVariableProvider | ||
{ | ||
private readonly Regex _variableRegex = new(@"\$\{\{\s*(?<variable>\b(foreach)\b[\w\.\-_:]+)\s*\}\}", RegexOptions.Compiled | RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1)); | ||
|
||
private readonly Dictionary<string, object?> _variables; | ||
|
||
|
||
public ForEachVariableProvider(INoxJob job) | ||
{ | ||
_variables = new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase); | ||
Initialize(job); | ||
} | ||
|
||
public void ResolveAll(INoxJob job, object forEachObject) | ||
{ | ||
_variables.ResolveForEachVariables(forEachObject); | ||
foreach (var step in job.Steps) | ||
{ | ||
foreach (var (_, input) in step.Value.Inputs) | ||
{ | ||
if (input.Default is string inputValueString) | ||
{ | ||
input.Default = ReplaceVariable(inputValueString); | ||
} | ||
else if (input.Default is List<object> inputValueList) | ||
{ | ||
for (var i = 0; i < inputValueList.Count; i++) | ||
{ | ||
if (inputValueList[i] is string) | ||
{ | ||
var index = inputValueList.FindIndex(n => n.Equals(inputValueList[i])); | ||
inputValueList[index] = ReplaceVariable((string)inputValueList[i]); | ||
} | ||
} | ||
} | ||
else if (input.Default is Dictionary<object, object> inputValueDictionary) | ||
{ | ||
for (var i = 0; i < inputValueDictionary.Count; i++) | ||
{ | ||
var item = inputValueDictionary.ElementAt(i); | ||
|
||
if (item.Value is string itemValueString) | ||
{ | ||
inputValueDictionary[item.Key] = ReplaceVariable(itemValueString); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
job.Name = ReplaceVariable(job.Name).ToString()!; | ||
if (!string.IsNullOrWhiteSpace(job.Display?.Success)) | ||
{ | ||
job.Display.Success = ReplaceVariable(job.Display.Success).ToString()!; | ||
} | ||
} | ||
|
||
private void Initialize(INoxJob job) | ||
{ | ||
var serializer = new SerializerBuilder() | ||
.WithNamingConvention(CamelCaseNamingConvention.Instance) | ||
.Build(); | ||
|
||
var serialized = serializer.Serialize(job); | ||
|
||
var matches = _variableRegex.Matches(serialized); | ||
|
||
var variablesTemp = matches.Select(m => m.Groups[2].Value) | ||
.Distinct(StringComparer.OrdinalIgnoreCase) | ||
.OrderBy(e => e); | ||
|
||
foreach (var v in variablesTemp) | ||
{ | ||
_variables.Add(v, null); | ||
} | ||
} | ||
|
||
private object ReplaceVariable(string value) | ||
{ | ||
object result = value; | ||
|
||
var match = _variableRegex.Match(result.ToString()!); | ||
|
||
while (match.Success) | ||
{ | ||
var fullPhrase = match.Groups[0].Value; | ||
|
||
var variable = match.Groups["variable"].Value; | ||
|
||
var resolvedValue = LookupValue(variable); | ||
|
||
if (resolvedValue == null || resolvedValue.GetType() == typeof(object)) | ||
{ | ||
break; | ||
} | ||
else if (resolvedValue.GetType().IsSimpleType()) | ||
{ | ||
result = result.ToString()!.Replace(fullPhrase, resolvedValue.ToString()); | ||
} | ||
else | ||
{ | ||
result = resolvedValue; | ||
break; | ||
} | ||
|
||
match = _variableRegex.Match(result.ToString()!); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private object? LookupValue(string variable) | ||
{ | ||
if (_variables.ContainsKey(variable)) | ||
{ | ||
var lookupVar = _variables[variable]; | ||
if (lookupVar == null) return null; | ||
return _variables[variable]; | ||
} | ||
return null; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using Nox.Cli.Abstractions; | ||
|
||
namespace Nox.Cli.Variables; | ||
|
||
public static class ForEachVariableResolver | ||
{ | ||
public static void ResolveForEachVariables(this IDictionary<string, object?> variables, object forEachObject) | ||
{ | ||
var forEachKeys = variables | ||
.Select(pk => pk.Key) | ||
.Where(pk => pk.StartsWith("forEach.", StringComparison.OrdinalIgnoreCase)) | ||
.Select(pk => pk[8..]) | ||
.ToArray(); | ||
|
||
forEachObject.WalkProperties( (name, value) => { if (forEachKeys.Contains(name, StringComparer.OrdinalIgnoreCase)) { variables[$"forEach.{name}"] = value; } }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.