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
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,9 @@ private string BuildScript(string command, string sentinel)
return
"& {" +
" $__af_rc = 0;" +
// $LASTEXITCODE persists across commands and cmdlets do not update it.
// Clear it so any value after invocation belongs to this command.
" $global:LASTEXITCODE = $null;" +
" try {" +
$" $__af_cmd = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('{encoded}'));" +
// Force the user command's success output through the same
Expand All @@ -588,9 +591,11 @@ private string BuildScript(string command, string sentinel)
" [Console]::WriteLine(($_ | Out-String).TrimEnd());" +
" }" +
" };" +
// Capture the pipeline status before flushing overwrites it.
" $__af_ok = $?;" +
" [Console]::Out.Flush();" +
" if ($LASTEXITCODE -ne $null) { $__af_rc = $LASTEXITCODE }" +
" elseif (-not $?) { $__af_rc = 1 }" +
" elseif (-not $__af_ok) { $__af_rc = 1 }" +
" } catch {" +
" [Console]::Error.WriteLine($_.ToString());" +
" $__af_rc = 1" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,37 @@ public async Task Persistent_CarriesEnvironment_AcrossCallsAsync()
Assert.Contains("persisted-value", read.Stdout, StringComparison.Ordinal);
}

[Fact]
public async Task Persistent_PowerShell_DoesNotInheritPreviousExitCodeAsync()
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return;
}

// Arrange
await using var shell = new LocalShellExecutor(new()
{
Mode = ShellMode.Persistent,
Shell = "powershell.exe",
Timeout = TimeSpan.FromSeconds(20),
});

// Act
var firstFailure = await shell.RunAsync("cmd /c exit 3");
var succeeding = await shell.RunAsync("Write-Output ok");
var repeatedFailure = await shell.RunAsync("cmd /c exit 3");
var readback = await shell.RunAsync("Write-Output $LASTEXITCODE");

// Assert
Assert.Equal(3, firstFailure.ExitCode);
Assert.Equal(0, succeeding.ExitCode);
Assert.Contains("ok", succeeding.Stdout, StringComparison.Ordinal);
Assert.Equal(3, repeatedFailure.ExitCode);
Assert.Equal(0, readback.ExitCode);
Assert.Empty(readback.Stdout.Trim());
}

[Fact]
public async Task Persistent_Timeout_ReturnsExitCode124Async()
{
Expand Down
Loading