How to create dynamic build tasks with Invoke-Build in PowerShell

三世轮回 提交于 2019-12-11 00:08:45

问题


Using Invoke-Build I am trying to create dynamic build tasks, an example of the approach is below. Where, in a similar fashion to the classic UNIX make facility an output file will be generated for each input file iff the input file is newer than the output file.

It accomplishes this by dynamically generating a set of incremental tasks and then calling the tasks.

The generation of the incremental tasks is outlined below:

    $Jobs = Foreach($_ in $Conf ) {
        $SourceFile = Get-Item $_
        $FileName = $SourceFile.Name
        $ObjectName = $FileName -replace '^Thing-(.*)\.conf\.ps1$','$1'
        $TaskName = "Task-$ObjectName"
        $OutFile = "Thing-$ObjectName.ps1"
        # Import the script, overwriting the "$MetaData" variable    
        $MetaData = . $SourceFile

    $TaskCode = @'
.\BuildThing.ps1
BuildThing -MetaData $MetaData
'@
        Write-Verbose "$SourceFile $OutFile"
        $SBInputs = [scriptblock]::Create(  { $SourceFile } ).GetNewClosure()
        $SBOutputs = [scriptblock]::Create( { $OutFile } ).GetNewClosure()
        $SBMain = [scriptblock]::Create($TaskCode).GetNewClosure()
        Task "$TaskName" -Inputs $SBInputs -Outputs $SBOutputs ($SBMain)

        Write-Output $TaskName
    }

This does appear to work well apart from the scoping of required other functions. No matter where I try to source the BuildThing.ps1 script when the task Task-Thing- is executed Invoke-Build complains that BuildThing is not recognized as:

"the name of a cmdlet, function, script file or operable program."

If I dot source the relevant files before running Invoke-Build everything works as desired.

This seems like a scoping problem - but it's not clear how to resolve it in a straightforward manner.

If I try to include BuildThing.ps1 outside of the loop in a static way, it does seem to be called, as confirmed by debugging, but does not appear to be in scope to be executed by the dynamic task.


回答1:


With regard to the above, the appropriate approach appears to be to modify the definition of $TaskCode to dot source the file.

If we assume .\BuildThing.ps1 contains a function - e.g.

function BuildThing {
param(...)
...
}

Then the dynamic task code needs to dot source this code. This seems inefficient for a large set of similar build tasks, however it does resolve the issue.

$TaskCode = @'
. .\BuildThing.ps1
BuildThing -MetaData $MetaData
'@


来源:https://stackoverflow.com/questions/28568879/how-to-create-dynamic-build-tasks-with-invoke-build-in-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!