Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/Invex.Atom.Build/BuildResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public BuildModel Resolve()
var usedParams = new List<UsedParam>();

foreach (var param in x.Params)
AddParamAndChildren(param.Param, param.Required, usedParams, paramModels, []);
AddParamAndChildren(x.Name, param.Param, param.Required, usedParams, paramModels, []);

return new TargetModel(x.Name, x.Description, x.Hidden)
{
Expand Down Expand Up @@ -261,12 +261,14 @@ void Visit(TargetModel target)
/// <summary>
/// Recursively adds a parameter and its chained dependencies to the list of used parameters for a target.
/// </summary>
/// <param name="target">The name of the target that references the parameter.</param>
/// <param name="param">The name of the parameter to add.</param>
/// <param name="required">A value indicating whether the parameter is required.</param>
/// <param name="usedParams">The list of used parameters to add to.</param>
/// <param name="paramModels">A dictionary of all available parameter models.</param>
/// <param name="visited">A set of already-visited parameter names to detect and prevent circular chains.</param>
private static void AddParamAndChildren(
string target,
string param,
bool required,
List<UsedParam> usedParams,
Expand All @@ -276,10 +278,13 @@ private static void AddParamAndChildren(
if (!visited.Add(param))
return;

var model = paramModels[param];
if (!paramModels.TryGetValue(param, out var model))
throw new BuildConfigurationException(
$"Target '{target}' references parameter '{param}' which is not defined in the build.");

usedParams.Add(new(model, required));

foreach (var chainedParam in model.ChainedParams)
AddParamAndChildren(chainedParam, required, usedParams, paramModels, visited);
AddParamAndChildren(target, chainedParam, required, usedParams, paramModels, visited);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ public void Resolve_WithMissingDependency_ThrowsException()
ex.Message.ShouldContain("depends on target 'Target2' which does not exist");
}

[Test]
public void Resolve_WithMissingParam_ThrowsException()
{
// Arrange
var buildDefinition = new TestBuildDefinition(_services)
{
ManualTargetDefinitions = new Dictionary<string, Target>
{
["Target1"] = t => t.RequiresParam("MissingParam"),
},
};

var commandLineArgs = new CommandLineArgs(true, [new CommandArg("Target1")]);
var paramService = A.Fake<IParamService>();
var logger = A.Fake<ILogger<BuildResolver>>();
var buildResolver = new BuildResolver(buildDefinition, paramService, commandLineArgs, logger);

// Act & Assert
var ex = Should.Throw<BuildConfigurationException>(buildResolver.Resolve);
ex.Message.ShouldBe("Target 'Target1' references parameter 'MissingParam' which is not defined in the build.");
}

[Test]
public void Resolve_WithComplexCircularDependency_ThrowsException()
{
Expand Down
Loading