fix: allow optional Preview automation paths
This commit is contained in:
@@ -133,7 +133,12 @@ internal static class PilotCli
|
||||
Console.Error.WriteLine("AUTOMATION_PREPARE_BLOCKED:" + string.Join(',', prepared.SafetyDecision.Violations));
|
||||
return new(false, false, false, false, false);
|
||||
}
|
||||
var execution = await service.ExecuteAsync(new(request, prepared.Plan, PermitService.Issue(prepared.Plan, config.ExecutionPermitLifetimeSeconds)), CancellationToken.None); if (!execution.Started || execution.ProcessId is null) return new(false, false, false, false, false);
|
||||
var execution = await service.ExecuteAsync(new(request, prepared.Plan, PermitService.Issue(prepared.Plan, config.ExecutionPermitLifetimeSeconds)), CancellationToken.None);
|
||||
if (!execution.Started || execution.ProcessId is null)
|
||||
{
|
||||
Console.Error.WriteLine("AUTOMATION_EXECUTION_BLOCKED:" + (execution.BlockCode ?? "PROCESS_START_FAILED"));
|
||||
return new(false, false, false, false, false);
|
||||
}
|
||||
var forcedCleanup = false;
|
||||
var gracefulExit = false;
|
||||
try
|
||||
|
||||
@@ -35,7 +35,12 @@ public sealed class PathResolver(IReadOnlyDictionary<string, string?>? environme
|
||||
public ResolvedLauncherPaths Resolve(LauncherPathVariables variables, IEnumerable<string>? required = null)
|
||||
{
|
||||
var resolved = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var name in variables.Values.Keys) resolved[name] = ResolveVariable(name, variables, resolved, []);
|
||||
// Explicit null values represent optional paths (for example the Apply
|
||||
// permit during Preview). They are retained as null rather than being
|
||||
// treated as an unknown variable; required values are still enforced
|
||||
// below.
|
||||
foreach (var name in variables.Values.Keys)
|
||||
resolved[name] = variables[name] is null ? null : ResolveVariable(name, variables, resolved, []);
|
||||
foreach (var name in resolved.Keys.ToArray())
|
||||
if (resolved[name] is { } value && value.StartsWith("A:\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ public sealed class PathAndLaunchTests
|
||||
[Fact] public void PathResolver_ResolvesEnvironmentVariable() => Assert.Equal("C:\\From Environment", Resolver(new Dictionary<string, string?> { ["ROOT"] = "C:\\From Environment" }).Resolve(new(new Dictionary<string, string?> { ["Value"] = "${ROOT}" })).Require("Value"));
|
||||
[Fact] public void PathResolver_RejectsUnknownVariable() => Assert.Throws<InvalidOperationException>(() => Resolver().Resolve(new(new Dictionary<string, string?> { ["Value"] = "${Missing}" })));
|
||||
[Fact] public void PathResolver_RejectsEmptyRequiredVariable() => Assert.Throws<InvalidOperationException>(() => Resolver().Resolve(new(new Dictionary<string, string?> { ["Value"] = "" }), ["Value"]));
|
||||
[Fact] public void PathResolver_PreservesOptionalNullVariable() => Assert.Null(Resolver().Resolve(new(new Dictionary<string, string?> { ["Optional"] = null })).Get("Optional"));
|
||||
[Fact] public void PathResolver_RejectsCycle() => Assert.Throws<InvalidOperationException>(() => Resolver().Resolve(new(new Dictionary<string, string?> { ["A"] = "${B}", ["B"] = "${A}" })));
|
||||
[Fact] public void PathResolver_PreservesUnicode() => Assert.Contains("Проект", Resolver().Resolve(new(Paths)).Require(LauncherPathVariableNames.ProjectRoot));
|
||||
[Fact] public void PathResolver_NormalizesSeparators() => Assert.DoesNotContain('/', Resolver().Resolve(new(Paths)).Require(LauncherPathVariableNames.DisciplineRoot));
|
||||
|
||||
Reference in New Issue
Block a user