public/Test-PsakeTask.ps1
|
function Test-PsakeTask { <# .SYNOPSIS Runs a single task's Action in isolation, without triggering dependencies. .DESCRIPTION Compiles the build file, finds the specified task, and executes only its Action scriptblock with the provided variables. Dependencies are NOT executed.This enables unit-testing individual tasks. .PARAMETER BuildFile The path to the psake build script. Defaults to 'psakefile.ps1'. .PARAMETER TaskName The name of the task to execute. .PARAMETER Variables A hashtable of variables to inject into the task's execution scope. .EXAMPLE $result = Test-PsakeTask -BuildFile './psakefile.ps1' -TaskName 'Build' -Variables @{ Configuration = 'Debug' OutputDir = './test-output' } $result.Success | Should -BeTrue This example runs the 'Build' task from 'psakefile.ps1' with two variables injected into the task's scope. The result object contains details about the execution, including success status, duration, and any error messages. .NOTES This function is intended for testing purposes and does not execute task dependencies or pre/post actions. It directly invokes the specified task's Action scriptblock in isolation. #> [CmdletBinding()] param( [Parameter(Position = 0)] [string]$BuildFile, [Parameter(Mandatory = $true, Position = 1)] [string]$TaskName, [Parameter(Position = 2)] [hashtable]$Variables = @{} ) if (-not $BuildFile) { $BuildFile = $psake.ConfigDefault.BuildFileName } Write-Debug "Test-PsakeTask: BuildFile='$BuildFile' TaskName='$TaskName' Variables=$($Variables.Count)" $result = [PsakeTaskResult]::new() $result.Name = $TaskName try { Invoke-InBuildFileScope -BuildFile $BuildFile -Module $MyInvocation.MyCommand.Module -ScriptBlock { param($CurrentContext, $Module) $taskKey = $TaskName.ToLower() # Resolve alias if ($CurrentContext.aliases.ContainsKey($taskKey)) { $taskKey = $CurrentContext.aliases[$taskKey].Name.ToLower() } Assert ($CurrentContext.tasks.ContainsKey($taskKey)) ($msgs.error_task_name_does_not_exist -f $TaskName) $task = $CurrentContext.tasks[$taskKey] # Inject variables foreach ($key in $Variables.Keys) { Set-Variable -Name $key -Value $Variables[$key] -WhatIf:$false -Confirm:$false } # Execute property blocks for context while ($CurrentContext.properties.Count -gt 0) { $propertyBlock = $CurrentContext.properties.Pop() . $propertyBlock } if ($task.Action) { $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() try { & $task.Action $result.Status = 'Executed' } catch { $result.Status = 'Failed' $result.ErrorMessage = $_.ToString() throw $_ } finally { $stopwatch.Stop() $result.Duration = $stopwatch.Elapsed } } else { $result.Status = 'Skipped' } } $psake.build_success = $true } catch { $psake.build_success = $false $result.Status = 'Failed' if (-not $result.ErrorMessage) { $result.ErrorMessage = $_.ToString() } } finally { Restore-Environment } return $result } |