Skip to content

Commit

Permalink
Updated background invocation & operator to use -WorkingDirectory
Browse files Browse the repository at this point in the history
… when starting a new job (#16180)
  • Loading branch information
ayousuf23 committed Feb 21, 2022
1 parent 5d41c1f commit 31c14f2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
Expand Up @@ -531,12 +531,8 @@ private static string GetParameterText(string parameterName)
var pipelineOffset = pipelineAst.Extent.StartOffset;
var variables = pipelineAst.FindAll(static x => x is VariableExpressionAst, true);

// Used to make sure that the job runs in the current directory
const string cmdPrefix = @"Microsoft.PowerShell.Management\Set-Location -LiteralPath $using:pwd ; ";

// Minimize allocations by initializing the stringbuilder to the size of the source string + prefix + space for ${using:} * 2
System.Text.StringBuilder updatedScriptblock = new System.Text.StringBuilder(cmdPrefix.Length + scriptblockBodyString.Length + 18);
updatedScriptblock.Append(cmdPrefix);
// Minimize allocations by initializing the stringbuilder to the size of the source string + space for ${using:} * 2
System.Text.StringBuilder updatedScriptblock = new System.Text.StringBuilder(scriptblockBodyString.Length + 18);
int position = 0;

// Prefix variables in the scriptblock with $using:
Expand Down Expand Up @@ -568,14 +564,25 @@ private static string GetParameterText(string parameterName)
var sb = ScriptBlock.Create(updatedScriptblock.ToString());
var commandInfo = new CmdletInfo("Start-Job", typeof(StartJobCommand));
commandProcessor = context.CommandDiscovery.LookupCommandProcessor(commandInfo, CommandOrigin.Internal, false, context.EngineSessionState);
var parameter = CommandParameterInternal.CreateParameterWithArgument(

var workingDirectoryParameter = CommandParameterInternal.CreateParameterWithArgument(
parameterAst: pipelineAst,
"ScriptBlock",
null,
parameterName: "WorkingDirectory",
parameterText: null,
argumentAst: pipelineAst,
sb,
false);
commandProcessor.AddParameter(parameter);
value: context.SessionState.Path.CurrentLocation.Path,
spaceAfterParameter: false);

var scriptBlockParameter = CommandParameterInternal.CreateParameterWithArgument(
parameterAst: pipelineAst,
parameterName: "ScriptBlock",
parameterText: null,
argumentAst: pipelineAst,
value: sb,
spaceAfterParameter: false);

commandProcessor.AddParameter(workingDirectoryParameter);
commandProcessor.AddParameter(scriptBlockParameter);
pipelineProcessor.Add(commandProcessor);
pipelineProcessor.LinkPipelineSuccessOutput(outputPipe ?? new Pipe(new List<object>()));

Expand Down
12 changes: 11 additions & 1 deletion test/powershell/Modules/Microsoft.PowerShell.Core/Job.Tests.ps1
Expand Up @@ -178,7 +178,7 @@ Describe "Debug-job test" -Tag "Feature" {
}
}

Describe "Ampersand background test" -Tag "CI","Slow" {
Describe "Ampersand background test" -Tag "CI", "Slow" {
Context "Simple background job" {
AfterEach {
Get-Job | Remove-Job -Force
Expand Down Expand Up @@ -218,6 +218,16 @@ Describe "Ampersand background test" -Tag "CI","Slow" {
$j = Get-Location | ForEach-Object -MemberName Path &
Receive-Job -Wait $j | Should -Be ($PWD.Path)
}
It "Make sure Set-Location is not used in the job's script block to set the working directory" {
$j = (Get-Variable -Value ExecutionContext).SessionState.PSVariable.Get("MyInvocation").Value.MyCommand.ScriptBlock &
(Receive-Job -Wait $j).ToString() | Should -BeExactly "(Get-Variable -Value ExecutionContext).SessionState.PSVariable.Get(`"MyInvocation`").Value.MyCommand.ScriptBlock"
}
It "Test that changing working directory also changes background job's working directory" {
Set-Location ..
$WorkingDirectory = (Get-Location).ToString()
$BackgroundJob = (Get-Location &)
(Receive-Job -Wait $BackgroundJob).ToString() | Should -BeExactly $WorkingDirectory
}
It "Test that output redirection is done in the background job" {
$j = Write-Output hello > $TESTDRIVE/hello.txt &
Receive-Job -Wait $j | Should -BeNullOrEmpty
Expand Down

0 comments on commit 31c14f2

Please sign in to comment.