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.