Skip to content

Commit

Permalink
Resolve and make constant $BuildRoot after loading tasks, close #95
Browse files Browse the repository at this point in the history
  • Loading branch information
nightroman committed Nov 4, 2017
1 parent 909b9a0 commit 254fc1e
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 9 deletions.
26 changes: 20 additions & 6 deletions Invoke-Build-Help.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
script. The process is called build and the script is called build script.
A build script defines parameters, variables, tasks, and blocks. Any code
is invoked with the current location set to $BuildRoot, the build script
directory. $ErrorActionPreference is set to 'Stop'.
is invoked with the current location set to $BuildRoot, normally the build
script directory. $ErrorActionPreference is set to 'Stop'.
To get help for commands dot-source Invoke-Build:
Expand Down Expand Up @@ -79,11 +79,14 @@
Exposed variables designed for build scripts and tasks:
$WhatIf - WhatIf mode, Invoke-Build parameter
$BuildRoot - build script location
$BuildRoot - build script location, by default
$BuildFile - build script path
$BuildTask - initial tasks
$Task - current task
$BuildRoot may be changed by scripts on loading in order to set a custom
build root directory. Other variables should not be changed.
$Task is available for script blocks defined by task parameters If, Inputs,
Outputs, and Jobs and by blocks Enter|Exit-BuildTask, Enter|Exit-BuildJob,
Set-BuildHeader.
Expand Down Expand Up @@ -208,9 +211,20 @@
INLINE SCRIPT
`File` is a script block as a build script. It is used in order to
assemble a build on the fly without creating an extra build script.
Dynamic parameters and persistent builds are not used in this case.
`File` is a script block which is normally used in order to assemble a
build on the fly without creating and using an extra build script file.
Script parameters are not supported. Use the parent scope variables
instead, either directly or with the helpers `property` and `requires`.
$BuildRoot is the calling script root (or the current location). If it
is not what the build needs as its root directory, then change this
variable in the beginning of the inline script block.
$BuildFile is the calling script (it may be null, e.g. in jobs).
This variable is rarely used, just keep in mind the difference.
Persistent and parallel builds are not supported.
'@
Checkpoint = @'
Specifies the checkpoint file and makes the build persistent. It is
Expand Down
5 changes: 4 additions & 1 deletion Invoke-Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ function *IO {
${private:*p} = [System.Collections.Generic.List[object]]@()
${*i} = foreach($_ in ${*i}) {
if ($_ -isnot [System.IO.FileInfo]) {$_ = [System.IO.FileInfo](*Path $_)}
if (!$_.Exists) {throw "Missing Inputs item: '$_'."}
if (!$_.Exists) {throw "Missing Inputs item '$_'."}
$_
${*p}.Add($_.FullName)
}
Expand Down Expand Up @@ -678,6 +678,9 @@ try {
*Check $BuildTask
}

New-Variable BuildRoot (*Path $BuildRoot) -Option Constant -Force
if (![System.IO.Directory]::Exists($BuildRoot)) {throw "Missing build root '$BuildRoot'."}

Write-Build 11 "Build $($BuildTask -join ', ') $BuildFile"
foreach($_ in ${*}.Redefined) {
Write-Build 8 "Redefined task '$($_.Name)'."
Expand Down
4 changes: 4 additions & 0 deletions Release-Notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

# Invoke-Build Release Notes

## v3.7.2

Normalize, test, and make `$BuildRoot` constant after loading tasks (#95).

## v3.7.1

*Invoke-Builds* (parallel builds)
Expand Down
87 changes: 87 additions & 0 deletions Tests/BuildRoot.test.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

<#
.Synopsis
Tests the custom $BuildRoot, see https://github.com/nightroman/Invoke-Build/issues/95
.Description
All tests except Parameter define builds as script blocks. Unlike build
scripts, blocks do not have own natural build roots because they are not
files in some directories. Their conventional build roots come from the
calling scripts. This is not always what the builds require, so use of
custom build roots is especially important for script block builds.
.Example
Invoke-Build * BuildRoot.test.ps1
#>

<#
Features:
- Specify the custom $BuildRoot as the parameter.
- Provide the default value based on the original $BuildRoot.
- Run with the default custom root and passed as the parameter.
- Custom paths are normalized, i.e. // and .. are not in the result.
#>
task Parameter {
Set-Content z.ps1 {
param(
$BuildRoot = "$BuildRoot//.."
)
task root {
($ref.Value = $BuildRoot)
}
}

$ref = @{}
Invoke-Build root z.ps1
equals $ref.Value (Split-Path $BuildRoot)

$ref = @{}
Invoke-Build root z.ps1 -BuildRoot ..//..
equals $ref.Value (Split-Path (Split-Path $BuildRoot))

Remove-Item z.ps1
}

task Relative {
$file = {
# change to another location
Set-Location ..
# tell to use it just as '.'
$BuildRoot = '.'
# tasks use it as the full path
task root {
($ref.Value = $BuildRoot)
}
}
$ref = @{}
Invoke-Build root $file
equals $ref.Value (Split-Path $BuildRoot)
}

task Invalid {
$file = {
$BuildRoot = ":"
task root
}
($r = try {Invoke-Build root $file} catch {$_})
assert ($r[-1].FullyQualifiedErrorId -clike 'Missing build root ''*\:''.,Invoke-Build.ps1')
}

task Constant1 {
$file = {
task root {
$script:BuildRoot = 'z'
}
}
($r = try {Invoke-Build root $file} catch {$_})
equals $r[-1].FullyQualifiedErrorId VariableNotWritable
}

task Constant2 {
$file = {
Enter-Build {$BuildRoot = 'z'}
task root
}
($r = try {Invoke-Build root $file} catch {$_})
equals $r[-1].FullyQualifiedErrorId VariableNotWritable
}
4 changes: 2 additions & 2 deletions Tests/Incremental.test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ task TestInputsOutputsMismatch (job InputsOutputsMismatch -Safe), {
task IncrementalMissingInputs -Inputs {'missing'} -Outputs {} {throw}
task PartialMissingInputs -Partial -Inputs {'missing'} -Outputs {} {throw}
task TestMissingInputs (job IncrementalMissingInputs -Safe), (job PartialMissingInputs -Safe), {
Test-Error IncrementalMissingInputs "Missing Inputs item: '*\missing'.*"
Test-Error PartialMissingInputs "Missing Inputs item: '*\missing'.*"
Test-Error IncrementalMissingInputs "Missing Inputs item '*\missing'.*"
Test-Error PartialMissingInputs "Missing Inputs item '*\missing'.*"
}

### #49
Expand Down

0 comments on commit 254fc1e

Please sign in to comment.