如何使用PowerShell中的Invoke-Build创建动态构建任务

时间:2015-02-17 18:48:49

标签: powershell build build-process psake invoke-build

使用Invoke-Build我正在尝试创建动态构建任务,下面是该方法的一个示例。其中,与传统的UNIX make工具类似,如果输入文件比输出文件新,则将为每个输入文件生成输出文件。

它通过动态生成一组增量任务然后调用任务来实现此目的。

增量任务的生成概述如下:

    $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
    }

除了确定所需的其他功能外,这似乎也很有效。无论我在执行Task-Thing-任务时尝试获取BuildThing.ps1脚本,Invoke-Build都会抱怨BuildThing不被识别为:

  

" cmdlet,函数,脚本文件或可操作程序的名称。"

如果我在运行Invoke-Build之前点源相关文件,一切都按预期工作。

这似乎是一个范围问题 - 但它并不清楚如何以直接的方式解决它。

如果我尝试以静态方式在循环外部包含BuildThing.ps1,它似乎被调用,正如调试所证实的那样,但似乎不在动态任务的执行范围内。

1 个答案:

答案 0 :(得分:1)

关于上述内容,适当的方法似乎是将$ TaskCode的定义修改为dot source该文件。

如果我们假设。\ BuildThing.ps1包含一个函数 - 例如

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

然后动态任务代码需要点源此代码。对于大量类似的构建任务而言,这似乎效率低下,但它确实解决了这个问题。

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