CakeRunner.ExecuteScript has two execution paths, and they don't honour the same set of
CakeSettings (i.e. ToolSettings) members:
- when the resolved tool path is not
Cake.dll (cake, Cake.exe, homebrew), it calls
Tool<CakeSettings>.Run(settings, args), which honours every ToolSettings member;
- when the resolved tool path is
Cake.dll — which is the default whenever the outer build
runs on Cake.Tool, since GetAlternativeToolPaths points at the executing assembly's
Cake.dll — it hand-copies a subset of the settings onto a DotNetExecuteSettings and runs
them through DotNetExecutor.
The hand-copied subset is missing four members, so they are silently dropped:
HandleExitCode
NoWorkingDirectory
PostAction
SetupProcessSettings
src/Cake.Common/Tools/Cake/CakeRunner.cs:
_coreExecutor.Execute(
toolPath,
GetArguments(scriptPath, settings),
new DotNetExecuteSettings
{
ArgumentCustomization = settings.ArgumentCustomization,
EnvironmentVariables = settings.EnvironmentVariables,
ToolTimeout = settings.ToolTimeout,
WorkingDirectory = settings.WorkingDirectory
});
CakeExecuteExpression delegates to ExecuteScript, so it is affected identically.
Repro
var output = new List<string>();
CakeExecuteExpression(
"Information(\"hello from the nested script\");",
new CakeSettings
{
HandleExitCode = exitCode => true,
SetupProcessSettings = process =>
{
process.RedirectStandardOutput = true;
process.RedirectedStandardOutputHandler = line => { output.Add(line); return line; };
}
});
Information("Captured {0} lines", output.Count);
Expected: the nested script's stdout is redirected and captured, and a non-zero exit code is
handled by the delegate.
Actual: when the outer build runs on Cake.Tool, output is empty (the nested output goes
straight to the console) and a non-zero exit code throws, because neither delegate reaches the
process. Running the same script with ToolPath pointing at cake/Cake.exe behaves as
documented, which makes this look like an environment-dependent bug rather than a missing feature.
This blocks any scenario that needs to inspect a nested Cake run — capturing its output, asserting
on its warnings, or tolerating a deliberate non-zero exit — which is exactly what integration tests
around nested script execution need.
CakeRunner.ExecuteScripthas two execution paths, and they don't honour the same set ofCakeSettings(i.e.ToolSettings) members:Cake.dll(cake,Cake.exe, homebrew), it callsTool<CakeSettings>.Run(settings, args), which honours everyToolSettingsmember;Cake.dll— which is the default whenever the outer buildruns on
Cake.Tool, sinceGetAlternativeToolPathspoints at the executing assembly'sCake.dll— it hand-copies a subset of the settings onto aDotNetExecuteSettingsand runsthem through
DotNetExecutor.The hand-copied subset is missing four members, so they are silently dropped:
HandleExitCodeNoWorkingDirectoryPostActionSetupProcessSettingssrc/Cake.Common/Tools/Cake/CakeRunner.cs:CakeExecuteExpressiondelegates toExecuteScript, so it is affected identically.Repro
Expected: the nested script's stdout is redirected and captured, and a non-zero exit code is
handled by the delegate.
Actual: when the outer build runs on
Cake.Tool,outputis empty (the nested output goesstraight to the console) and a non-zero exit code throws, because neither delegate reaches the
process. Running the same script with
ToolPathpointing atcake/Cake.exebehaves asdocumented, which makes this look like an environment-dependent bug rather than a missing feature.
This blocks any scenario that needs to inspect a nested Cake run — capturing its output, asserting
on its warnings, or tolerating a deliberate non-zero exit — which is exactly what integration tests
around nested script execution need.