Skip to content

Commit

Permalink
v2.9.5
Browse files Browse the repository at this point in the history
  • Loading branch information
nightroman committed May 22, 2014
1 parent 8d98406 commit 074a2ae
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 47 deletions.
6 changes: 3 additions & 3 deletions .build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# Build script parameters are standard parameters
param(
[switch]$SkipTestDiff
[switch]$NoTestDiff
)

# Ensure Invoke-Build works in the most strict mode.
Expand Down Expand Up @@ -141,8 +141,8 @@ task Loop {
# Requires PowerShelf/Assert-SameFile.ps1
task Test {
# invoke tests, get output and result
$output = Invoke-Build . Tests\.build.ps1 -Result result | Out-String -Width:200
if ($SkipTestDiff) {return}
$output = Invoke-Build . Tests\.build.ps1 -Result result -Summary | Out-String -Width:200
if ($NoTestDiff) {return}

assert (194 -eq $result.Tasks.Count) $result.Tasks.Count
assert (39 -eq $result.Errors.Count) $result.Errors.Count
Expand Down
12 changes: 10 additions & 2 deletions Invoke-Build-Help.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,13 @@
All - all defined tasks
Error - a terminating build error
Tasks - invoked tasks including nested
Errors - error messages including nested
Errors - error records including nested (*)
Warnings - warning messages including nested
(*) This list will continue to exist but objects may change in the
future. For better analysis iterate through Tasks and check their
Error.
Task object properties:
Name - task name
Expand Down Expand Up @@ -809,10 +813,14 @@ engine (version 2+).
Result properties:
Tasks - tasks (see: help Invoke-Build -Parameter Result)
Errors - error messages
Errors - error records (*)
Warnings - warning messages
Started - start time
Elapsed - build duration
(*) This list will continue to exist but objects may change in the
future. For better analysis iterate through Tasks and check their
Error.
'@
Timeout = @'
Maximum overall build time in milliseconds.
Expand Down
15 changes: 7 additions & 8 deletions Invoke-Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ function Write-Build([ConsoleColor]$Color, [string]$Text) {
}

#.ExternalHelp Invoke-Build-Help.xml
function Get-BuildVersion {[Version]'2.9.4'}
function Get-BuildVersion {[Version]'2.9.5'}

if ($MyInvocation.InvocationName -eq '.') {
return @'
Invoke-Build 2.9.4
Invoke-Build 2.9.5
Copyright (c) 2011-2014 Roman Kuzmin
Add-BuildTask (task)
Expand Down Expand Up @@ -344,7 +344,7 @@ function *IO {
${private:*p} = [System.Collections.ArrayList]@()
${*i} = foreach($_ in ${*i}) {
if ($_ -isnot [System.IO.FileInfo]) {$_ = [System.IO.FileInfo](*FP $_)}
if (!$_.Exists) {throw "Missing input file '$_'."}
if (!$_.Exists) {throw "Missing Inputs item: '$_'."}
$_
$null = ${*p}.Add($_.FullName)
}
Expand All @@ -361,7 +361,7 @@ function *IO {
${*o}
}
)
if (${*p}.Count -ne ${*o}.Count) {throw "Different input/output: $(${*p}.Count)/$(${*o}.Count)."}
if (${*p}.Count -ne ${*o}.Count) {throw "Different Inputs/Outputs counts: $(${*p}.Count)/$(${*o}.Count)."}

$k = -1
$Task.Inputs = $i = [System.Collections.ArrayList]@()
Expand All @@ -378,7 +378,7 @@ function *IO {
$Task.Outputs = ${*o} = & ${*o}
*SL
}
if (!${*o}) {throw 'Empty output.'}
if (!${*o}) {throw 'Outputs must not be empty.'}

$Task.Inputs = ${*p}
$m = (${*i} | .{process{$_.LastWriteTime.Ticks}} | Measure-Object -Maximum).Maximum
Expand Down Expand Up @@ -523,8 +523,7 @@ function *Task {

function *WE {
Write-Build 14 (*II $Task)
${*x} = "ERROR: Task ${*p}: $_"
$null = ${*}.Errors.Add($(if (*My) {${*x}} else {*EI ${*x} $_}))
$null = ${*}.Errors.Add($_)
}

function *TS($I, $M) {
Expand Down Expand Up @@ -690,7 +689,7 @@ finally {
foreach($_ in ${*}.Tasks) {
'{0,-16} {1} - {2}:{3}' -f $_.Elapsed, $_.Name, $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber
if ($_ = $_.Error) {
Write-Build 12 (*EI "ERROR: $_" $_)
Write-Build 12 $(if (*My) {"ERROR: $_"} else {*EI "ERROR: $_" $_})
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ The above command shows function names and makes their help available:
- [Examples](https://github.com/nightroman/Invoke-Build/wiki/Build-Scripts-in-Projects)
: Build scripts used in various projects.

Suggestions, questions, and issues are welcome [here](https://github.com/nightroman/Invoke-Build/issues).
Or just hit me up on Twitter [@romkuzmin](https://twitter.com/romkuzmin)

## Credits

The project is inspired by
Expand Down
13 changes: 13 additions & 0 deletions Release-Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
Invoke-Build Release Notes
==========================

## v2.9.5

Revised errors

- Removed irrelevant data from error messages in build summary.
- Amended error messages about issues in task Inputs and Outputs.
- Build result property `Errors` contains error objects, not messages.

Custom tasks

- Redesigned the custom task `retry` so that the function `Invoke-RetryAction`
may be used on its own, see an example in *Retry.build.ps1*.

## v2.9.4

Custom tasks `retry` and `test`
Expand Down
29 changes: 25 additions & 4 deletions Tasks/Retry/Retry.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
Invoke-Build * Retry.build.ps1
#>

# Import retry-task definitions.
# Import retry-task tools.
. .\Retry.tasks.ps1

$RetryWorks = 0
$RetryWorks = $false

# Synopsis: A task referenced by a retry-task.
task JustTask {
Expand All @@ -27,15 +27,36 @@ retry RetryWorks -RetryTimeout 10 -RetryInterval 2 JustTask, {
"It works."
}
else {
$script:RetryWorks = 1
$script:RetryWorks = $true
throw "It fails."
}
}

# Synopsis: Retry-task always fails. It is referenced by another task.
# Synopsis: This retry-task always fails. It is referenced by another task.
retry RetryFails -RetryTimeout 4 -RetryInterval 2 {
throw "It fails."
}

# Synopsis: A task with a safe reference to a retry-task.
task CallRetryFails (job RetryFails -Safe)

# Synopsis: A task uses Invoke-RetryAction directly.
task InvokeRetryAction {
# before the action started
"Before the action"

# invoke the action
$script:RetryWorks = $false
Invoke-RetryAction 10 2 {
if ($RetryWorks) {
"It works."
}
else {
$script:RetryWorks = $true
throw "It fails."
}
}

# after the action succeeded
"After the action"
}
85 changes: 60 additions & 25 deletions Tasks/Retry/Retry.tasks.ps1
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

<#
.Synopsis
Defines the custom task "retry".
Defines the custom task "retry" and the function "Invoke-RetryAction".
.Description
Build scripts dot-source this script in order to use the task "retry".
Build scripts dot-source this script in order to use the task "retry" or
the function "Invoke-RetryAction".
A retry-task has a single action. This action is repeated for the specified
time until it succeeds. When the time is out the last error is re-thrown.
Expand All @@ -21,18 +22,67 @@
.Example
>
# Dot-source "retry" definitions
. [<path>]Retry.tasks.ps1
# Dot-source "retry" tools
. <path>\Retry.tasks.ps1
# Add "retry" tasks
retry RetrySomething -RetryTimeout 10 -RetryInterval 2 {
# Use "retry" tasks
retry Task1 -RetryTimeout 10 -RetryInterval 2 {
...
}
# Or use Invoke-RetryAction directly
task Task2 {
...
Invoke-RetryAction 10 2 { ... }
...
}
#>

# New DSL word.
Set-Alias retry Add-RetryTask

<#
.Synopsis
Invokes the action until it succeeds or the time is out.
.Description
The action is repeated for the specified time until it succeeds.
When the time is out the last error is re-thrown.
.Parameter RetryTimeout
Total time for retrying, in seconds.
.Parameter RetryInterval
Time to wait before trying again, in seconds.
.Parameter Action
Specifies the action, a script block or a command name.
#>
function Invoke-RetryAction(
[Parameter()][int]$RetryTimeout,
[int]$RetryInterval,
$Action
)
{
${private:*RetryTimeout} = $RetryTimeout
${private:*RetryInterval} = $RetryInterval
${private:*Action} = $Action
Remove-Variable RetryTimeout, RetryInterval, Action

${private:*time} = [System.Diagnostics.Stopwatch]::StartNew()
for() {
try {
. ${*Action}
return
}
catch {
if (${*time}.Elapsed.TotalSeconds -gt ${*RetryTimeout}) {throw}
Write-Build Yellow "$($Task.Name) error: $_"
"Waiting for ${*RetryInterval} seconds..."
Start-Sleep -Seconds ${*RetryInterval}
"Retrying..."
}
}
}

# Wrapper of "task" which adds a customized task used as "retry".
# Mind setting "Source" for error messages and help comments.
function Add-RetryTask(
Expand All @@ -57,7 +107,10 @@ function Add-RetryTask(
}
else {
$action = $j
{. Invoke-RetryAction}
{
$_ = $Task.Data
. Invoke-RetryAction @_
}
}
}

Expand All @@ -72,21 +125,3 @@ function Add-RetryTask(
$PSCmdlet.ThrowTerminatingError($_)
}
}

# Invokes the current retry action.
function Invoke-RetryAction {
${private:**time} = [System.Diagnostics.Stopwatch]::StartNew()
for() {
try {
. $Task.Data.Action
break
}
catch {
if (${**time}.Elapsed.TotalSeconds -gt $Task.Data.RetryTimeout) {throw}
Write-Build Yellow "$($Task.Name) error: $_"
"Waiting for $($Task.Data.RetryInterval) seconds..."
Start-Sleep -Seconds $Task.Data.RetryInterval
"Retrying..."
}
}
}
2 changes: 1 addition & 1 deletion Tests/.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ task TestVariables {
$MyKnown += @(
# exposed by the project script
'Result'
'SkipTestDiff'
'NoTestDiff'
# system variables
'_'
'foreach'
Expand Down
8 changes: 4 additions & 4 deletions Tests/Incremental.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ PartIncrementalTwoOutOfDate,
Test-Error PartialOutputsFails "Throw in output.*At *\Incremental.build.ps1:*task PartialOutputsFails*"

# thrown from the engine
Test-Issue IncrementalOutputsIsEmpty Incremental.build.ps1 "Empty output.*try { Invoke-Build *OperationStopped*"
Test-Issue InputsOutputsMismatch Incremental.build.ps1 "Different input/output: 1/0.*try { Invoke-Build *OperationStopped*"
Test-Issue IncrementalMissingInputs Incremental.build.ps1 "Missing input file '*\missing'.*try { Invoke-Build *OperationStopped*"
Test-Issue PartialMissingInputs Incremental.build.ps1 "Missing input file '*\missing'.*try { Invoke-Build *OperationStopped*"
Test-Issue IncrementalOutputsIsEmpty Incremental.build.ps1 "Outputs must not be empty.*try { Invoke-Build *OperationStopped*"
Test-Issue InputsOutputsMismatch Incremental.build.ps1 "Different Inputs/Outputs counts: 1/0.*try { Invoke-Build *OperationStopped*"
Test-Issue IncrementalMissingInputs Incremental.build.ps1 "Missing Inputs item: '*\missing'.*try { Invoke-Build *OperationStopped*"
Test-Issue PartialMissingInputs Incremental.build.ps1 "Missing Inputs item: '*\missing'.*try { Invoke-Build *OperationStopped*"

#! LiteralPath does not work in [ ] test.
Remove-Item z.new1.tmp, z.new2.tmp, z.old1.tmp, z.old2.tmp
Expand Down

0 comments on commit 074a2ae

Please sign in to comment.