diff --git a/ParallelKit.Harness.ps1 b/ParallelKit.Harness.ps1 index a2b6cf9..7525cf4 100644 --- a/ParallelKit.Harness.ps1 +++ b/ParallelKit.Harness.ps1 @@ -197,6 +197,11 @@ Test-Assert ($seen.Count -eq 6) "-OnComplete fires for each command that ran" Test-Assert (-not $batch.Aborted) "a clean batch is not marked aborted" $wd = Invoke-PkProcessBatch -Commands @(@{ FilePath = $cmdExe; Arguments = '/c cd'; WorkingDirectory = $env:SystemRoot }) -MaxConcurrent 1 Test-Assert ($wd.Results[0].Stdout.Trim() -ieq $env:SystemRoot) "a command's WorkingDirectory is honored" +# A foreach over nothing yields $null, not an empty array - the usual way to build the list when no files match. +$noCommands = foreach ($x in @()) { @{ FilePath = $cmdExe; Arguments = '/c exit 0' } } +$emptyBatch = $null +try { $emptyBatch = Invoke-PkProcessBatch -Commands $noCommands -MaxConcurrent 2 } catch { Write-Host " empty batch threw: $_" } +Test-Assert ($null -ne $emptyBatch -and $emptyBatch.Results.Count -eq 0 -and -not $emptyBatch.Aborted) "a batch given `$null (an empty foreach) returns no results" Write-Host "" # ============================================================================== diff --git a/ParallelKit.ps1 b/ParallelKit.ps1 index d2f9723..c06634b 100644 --- a/ParallelKit.ps1 +++ b/ParallelKit.ps1 @@ -1155,8 +1155,11 @@ function Invoke-PkProcessBatch { # Returns @{ Results; Aborted; ForceKilledCount }; each result is # @{ Command; ExitCode; Stdout; Stderr; StreamTimedOut; StreamError; StartError; Aborted }, # every field always present - keep the three places that build one in sync. + # $Commands may be $null: a foreach that matches nothing yields $null, not + # an empty array, and an empty batch should just return no results. param( [Parameter(Mandatory)] + [AllowNull()] [AllowEmptyCollection()] [hashtable[]]$Commands, [int]$MaxConcurrent = 4, @@ -1176,7 +1179,10 @@ function Invoke-PkProcessBatch { $jobBuilder = { param($group) $jobs = [System.Collections.Generic.List[hashtable]]::new() - foreach ($c in $Commands) { $jobs.Add(@{ FilePath = $c['FilePath']; Arguments = [string]$c['Arguments']; WorkingDirectory = [string]$c['WorkingDirectory']; Command = $c }) } + foreach ($c in $Commands) { + if ($null -eq $c) { continue } + $jobs.Add(@{ FilePath = $c['FilePath']; Arguments = [string]$c['Arguments']; WorkingDirectory = [string]$c['WorkingDirectory']; Command = $c }) + } return $jobs }.GetNewClosure()