mirror of https://github.com/SixLabors/ImageSharp
3 changed files with 904 additions and 33 deletions
@ -1,34 +1,3 @@ |
|||||
@ECHO OFF |
@echo off |
||||
|
|
||||
SET version=2.0.1.0 |
powershell "Import-Module %~dp0\psake.psm1 ; Invoke-Psake %~dp0\build.ps1 ; exit $LASTEXITCODE" |
||||
SET webversion=4.0.0.0 |
|
||||
SET webconfigversion=2.0.0.0 |
|
||||
SET webppluginversion=1.0.1.0 |
|
||||
SET cairpluginversion=1.0.0.0 |
|
||||
|
|
||||
ECHO Building ImageProcessor %version%, ImageProcessor.Web %webversion%, ImageProcessor.Web.Config %webconfigversion% |
|
||||
|
|
||||
ECHO Building ImageProcessor.Plugins.WebP %webppluginversion%, ImageProcessor.Plugins.Cair %cairpluginversion% |
|
||||
|
|
||||
ECHO Removing _BuildOutput directory so everything is nice and clean |
|
||||
RD _BuildOutput /q /s |
|
||||
|
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.ImageProcessor.proj" /p:BUILD_RELEASE=%version% /p:BUILD_COMMENT=%comment% |
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.ImageProcessor.Web.proj" /p:BUILD_RELEASE=%webversion% /p:BUILD_COMMENT=%comment% |
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.ImageProcessor.Plugins.WebP.proj" /p:BUILD_RELEASE=%webppluginversion% /p:BUILD_COMMENT=%comment% |
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.ImageProcessor.Plugins.Cair.proj" /p:BUILD_RELEASE=%cairpluginversion% /p:BUILD_COMMENT=%comment% |
|
||||
|
|
||||
ECHO Packing the NuGet release files |
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\ImageProcessor.nuspec -Version %version% |
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\ImageProcessor.Web.nuspec -Version %webversion% |
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\ImageProcessor.Web.Config.nuspec -Version %webconfigversion% |
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\ImageProcessor.Plugins.WebP.nuspec -Version %webppluginversion% |
|
||||
..\src\.nuget\NuGet.exe pack NuSpecs\ImageProcessor.Plugins.Cair.nuspec -Version %cairpluginversion% |
|
||||
PAUSE |
|
||||
|
|
||||
IF ERRORLEVEL 1 GOTO :showerror |
|
||||
|
|
||||
GOTO :EOF |
|
||||
|
|
||||
:showerror |
|
||||
PAUSE |
|
||||
@ -0,0 +1,55 @@ |
|||||
|
Properties { |
||||
|
$version = "2.0.1.0" |
||||
|
$webversion = "4.0.0.0" |
||||
|
$webconfigversion = "2.0.0.0" |
||||
|
$webppluginversion = "1.0.1.0" |
||||
|
$cairpluginversion = "1.0.0.0" |
||||
|
|
||||
|
$PROJ_PATH = "." |
||||
|
$BIN_PATH = (Join-Path $PROJ_PATH "_BuildOutput") |
||||
|
$NUGET_EXE = "..\src\.nuget\NuGet.exe" |
||||
|
$NUSPECS_PATH = (Join-Path $PROJ_PATH "NuSpecs") |
||||
|
$NUGET_OUTPUT = (Join-Path $BIN_PATH "NuGets") |
||||
|
# TODO: add opencover and nunit runner binaries |
||||
|
} |
||||
|
|
||||
|
Framework "4.0x86" |
||||
|
FormatTaskName "-------- {0} --------" |
||||
|
|
||||
|
task default -depends Cleanup-Binaries, Build-Solution, Generate-Package |
||||
|
|
||||
|
# cleans up the binaries output folder |
||||
|
task Cleanup-Binaries { |
||||
|
Write-Host "Removing $BIN_PATH directory so everything is nice and clean" |
||||
|
if (Test-Path $BIN_PATH) { |
||||
|
Remove-Item $BIN_PATH -Force -Recurse |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# builds the solutions |
||||
|
task Build-Solution -depends Cleanup-Binaries { |
||||
|
Write-Host "Building projects" |
||||
|
Exec { |
||||
|
msbuild (Join-Path $PROJ_PATH "Build.ImageProcessor.proj") /p:BUILD_RELEASE="$version" |
||||
|
msbuild (Join-Path $PROJ_PATH "Build.ImageProcessor.Web.proj") /p:BUILD_RELEASE="$version" |
||||
|
msbuild (Join-Path $PROJ_PATH "Build.ImageProcessor.Plugins.WebP.proj") /p:BUILD_RELEASE="$version" |
||||
|
msbuild (Join-Path $PROJ_PATH "Build.ImageProcessor.Plugins.Cair.proj") /p:BUILD_RELEASE="$version" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# generates a Nuget package |
||||
|
task Generate-Package -depends Build-Solution { |
||||
|
Write-Host "Generating Nuget packages for each project" |
||||
|
|
||||
|
# Nuget doesn't create the output dir automatically... |
||||
|
if (-not (Test-Path $NUGET_OUTPUT)) { |
||||
|
mkdir $NUGET_OUTPUT | Out-Null |
||||
|
} |
||||
|
|
||||
|
# Package the nuget |
||||
|
& $NUGET_EXE Pack (Join-Path $NUSPECS_PATH "ImageProcessor.nuspec") -OutputDirectory $NUGET_OUTPUT |
||||
|
& $NUGET_EXE Pack (Join-Path $NUSPECS_PATH "ImageProcessor.Web.nuspec") -OutputDirectory $NUGET_OUTPUT |
||||
|
& $NUGET_EXE Pack (Join-Path $NUSPECS_PATH "ImageProcessor.Web.Config.nuspec") -OutputDirectory $NUGET_OUTPUT |
||||
|
& $NUGET_EXE Pack (Join-Path $NUSPECS_PATH "ImageProcessor.Plugins.WebP.nuspec") -OutputDirectory $NUGET_OUTPUT |
||||
|
& $NUGET_EXE Pack (Join-Path $NUSPECS_PATH "ImageProcessor.Plugins.Cair.nuspec") -OutputDirectory $NUGET_OUTPUT |
||||
|
} |
||||
@ -0,0 +1,847 @@ |
|||||
|
# psake |
||||
|
# Copyright (c) 2012 James Kovacs |
||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
# of this software and associated documentation files (the "Software"), to deal |
||||
|
# in the Software without restriction, including without limitation the rights |
||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
# copies of the Software, and to permit persons to whom the Software is |
||||
|
# furnished to do so, subject to the following conditions: |
||||
|
# |
||||
|
# The above copyright notice and this permission notice shall be included in |
||||
|
# all copies or substantial portions of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
# THE SOFTWARE. |
||||
|
|
||||
|
#Requires -Version 2.0 |
||||
|
|
||||
|
#-- Public Module Functions --# |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Invoke-Task |
||||
|
{ |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)] [string]$taskName |
||||
|
) |
||||
|
|
||||
|
Assert $taskName ($msgs.error_invalid_task_name) |
||||
|
|
||||
|
$taskKey = $taskName.ToLower() |
||||
|
|
||||
|
if ($currentContext.aliases.Contains($taskKey)) { |
||||
|
$taskName = $currentContext.aliases.$taskKey.Name |
||||
|
$taskKey = $taskName.ToLower() |
||||
|
} |
||||
|
|
||||
|
$currentContext = $psake.context.Peek() |
||||
|
|
||||
|
Assert ($currentContext.tasks.Contains($taskKey)) ($msgs.error_task_name_does_not_exist -f $taskName) |
||||
|
|
||||
|
if ($currentContext.executedTasks.Contains($taskKey)) { return } |
||||
|
|
||||
|
Assert (!$currentContext.callStack.Contains($taskKey)) ($msgs.error_circular_reference -f $taskName) |
||||
|
|
||||
|
$currentContext.callStack.Push($taskKey) |
||||
|
|
||||
|
$task = $currentContext.tasks.$taskKey |
||||
|
|
||||
|
$precondition_is_valid = & $task.Precondition |
||||
|
|
||||
|
if (!$precondition_is_valid) { |
||||
|
WriteColoredOutput ($msgs.precondition_was_false -f $taskName) -foregroundcolor Cyan |
||||
|
} else { |
||||
|
if ($taskKey -ne 'default') { |
||||
|
|
||||
|
if ($task.PreAction -or $task.PostAction) { |
||||
|
Assert ($task.Action -ne $null) ($msgs.error_missing_action_parameter -f $taskName) |
||||
|
} |
||||
|
|
||||
|
if ($task.Action) { |
||||
|
try { |
||||
|
foreach($childTask in $task.DependsOn) { |
||||
|
Invoke-Task $childTask |
||||
|
} |
||||
|
|
||||
|
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew() |
||||
|
$currentContext.currentTaskName = $taskName |
||||
|
|
||||
|
& $currentContext.taskSetupScriptBlock |
||||
|
|
||||
|
if ($task.PreAction) { |
||||
|
& $task.PreAction |
||||
|
} |
||||
|
|
||||
|
if ($currentContext.config.taskNameFormat -is [ScriptBlock]) { |
||||
|
& $currentContext.config.taskNameFormat $taskName |
||||
|
} else { |
||||
|
WriteColoredOutput ($currentContext.config.taskNameFormat -f $taskName) -foregroundcolor Cyan |
||||
|
} |
||||
|
|
||||
|
foreach ($variable in $task.requiredVariables) { |
||||
|
Assert ((test-path "variable:$variable") -and ((get-variable $variable).Value -ne $null)) ($msgs.required_variable_not_set -f $variable, $taskName) |
||||
|
} |
||||
|
|
||||
|
& $task.Action |
||||
|
|
||||
|
if ($task.PostAction) { |
||||
|
& $task.PostAction |
||||
|
} |
||||
|
|
||||
|
& $currentContext.taskTearDownScriptBlock |
||||
|
$task.Duration = $stopwatch.Elapsed |
||||
|
} catch { |
||||
|
if ($task.ContinueOnError) { |
||||
|
"-"*70 |
||||
|
WriteColoredOutput ($msgs.continue_on_error -f $taskName,$_) -foregroundcolor Yellow |
||||
|
"-"*70 |
||||
|
$task.Duration = $stopwatch.Elapsed |
||||
|
} else { |
||||
|
throw $_ |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
# no action was specified but we still execute all the dependencies |
||||
|
foreach($childTask in $task.DependsOn) { |
||||
|
Invoke-Task $childTask |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
foreach($childTask in $task.DependsOn) { |
||||
|
Invoke-Task $childTask |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Assert (& $task.Postcondition) ($msgs.postcondition_failed -f $taskName) |
||||
|
} |
||||
|
|
||||
|
$poppedTaskKey = $currentContext.callStack.Pop() |
||||
|
Assert ($poppedTaskKey -eq $taskKey) ($msgs.error_corrupt_callstack -f $taskKey,$poppedTaskKey) |
||||
|
|
||||
|
$currentContext.executedTasks.Push($taskKey) |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Exec |
||||
|
{ |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][scriptblock]$cmd, |
||||
|
[Parameter(Position=1,Mandatory=0)][string]$errorMessage = ($msgs.error_bad_command -f $cmd), |
||||
|
[Parameter(Position=2,Mandatory=0)][int]$maxRetries = 0, |
||||
|
[Parameter(Position=3,Mandatory=0)][string]$retryTriggerErrorPattern = $null |
||||
|
) |
||||
|
|
||||
|
$tryCount = 1 |
||||
|
|
||||
|
do { |
||||
|
try { |
||||
|
$global:lastexitcode = 0 |
||||
|
& $cmd |
||||
|
if ($lastexitcode -ne 0) { |
||||
|
throw ("Exec: " + $errorMessage) |
||||
|
} |
||||
|
break |
||||
|
} |
||||
|
catch [Exception] |
||||
|
{ |
||||
|
if ($tryCount -gt $maxRetries) { |
||||
|
throw $_ |
||||
|
} |
||||
|
|
||||
|
if ($retryTriggerErrorPattern -ne $null) { |
||||
|
$isMatch = [regex]::IsMatch($_.Exception.Message, $retryTriggerErrorPattern) |
||||
|
|
||||
|
if ($isMatch -eq $false) { |
||||
|
throw $_ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Write-Host "Try $tryCount failed, retrying again in 1 second..." |
||||
|
|
||||
|
$tryCount++ |
||||
|
|
||||
|
[System.Threading.Thread]::Sleep([System.TimeSpan]::FromSeconds(1)) |
||||
|
} |
||||
|
} |
||||
|
while ($true) |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Assert |
||||
|
{ |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)]$conditionToCheck, |
||||
|
[Parameter(Position=1,Mandatory=1)]$failureMessage |
||||
|
) |
||||
|
if (!$conditionToCheck) { |
||||
|
throw ("Assert: " + $failureMessage) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Task |
||||
|
{ |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][string]$name = $null, |
||||
|
[Parameter(Position=1,Mandatory=0)][scriptblock]$action = $null, |
||||
|
[Parameter(Position=2,Mandatory=0)][scriptblock]$preaction = $null, |
||||
|
[Parameter(Position=3,Mandatory=0)][scriptblock]$postaction = $null, |
||||
|
[Parameter(Position=4,Mandatory=0)][scriptblock]$precondition = {$true}, |
||||
|
[Parameter(Position=5,Mandatory=0)][scriptblock]$postcondition = {$true}, |
||||
|
[Parameter(Position=6,Mandatory=0)][switch]$continueOnError = $false, |
||||
|
[Parameter(Position=7,Mandatory=0)][string[]]$depends = @(), |
||||
|
[Parameter(Position=8,Mandatory=0)][string[]]$requiredVariables = @(), |
||||
|
[Parameter(Position=9,Mandatory=0)][string]$description = $null, |
||||
|
[Parameter(Position=10,Mandatory=0)][string]$alias = $null, |
||||
|
[Parameter(Position=11,Mandatory=0)][string]$maxRetries = 0, |
||||
|
[Parameter(Position=12,Mandatory=0)][string]$retryTriggerErrorPattern = $null |
||||
|
) |
||||
|
if ($name -eq 'default') { |
||||
|
Assert (!$action) ($msgs.error_default_task_cannot_have_action) |
||||
|
} |
||||
|
|
||||
|
$newTask = @{ |
||||
|
Name = $name |
||||
|
DependsOn = $depends |
||||
|
PreAction = $preaction |
||||
|
Action = $action |
||||
|
PostAction = $postaction |
||||
|
Precondition = $precondition |
||||
|
Postcondition = $postcondition |
||||
|
ContinueOnError = $continueOnError |
||||
|
Description = $description |
||||
|
Duration = [System.TimeSpan]::Zero |
||||
|
RequiredVariables = $requiredVariables |
||||
|
Alias = $alias |
||||
|
MaxRetries = $maxRetries |
||||
|
RetryTriggerErrorPattern = $retryTriggerErrorPattern |
||||
|
} |
||||
|
|
||||
|
$taskKey = $name.ToLower() |
||||
|
|
||||
|
$currentContext = $psake.context.Peek() |
||||
|
|
||||
|
Assert (!$currentContext.tasks.ContainsKey($taskKey)) ($msgs.error_duplicate_task_name -f $name) |
||||
|
|
||||
|
$currentContext.tasks.$taskKey = $newTask |
||||
|
|
||||
|
if($alias) |
||||
|
{ |
||||
|
$aliasKey = $alias.ToLower() |
||||
|
|
||||
|
Assert (!$currentContext.aliases.ContainsKey($aliasKey)) ($msgs.error_duplicate_alias_name -f $alias) |
||||
|
|
||||
|
$currentContext.aliases.$aliasKey = $newTask |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Properties { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][scriptblock]$properties |
||||
|
) |
||||
|
$psake.context.Peek().properties += $properties |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Include { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][string]$fileNamePathToInclude |
||||
|
) |
||||
|
Assert (test-path $fileNamePathToInclude -pathType Leaf) ($msgs.error_invalid_include_path -f $fileNamePathToInclude) |
||||
|
$psake.context.Peek().includes.Enqueue((Resolve-Path $fileNamePathToInclude)); |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function FormatTaskName { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)]$format |
||||
|
) |
||||
|
$psake.context.Peek().config.taskNameFormat = $format |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function TaskSetup { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][scriptblock]$setup |
||||
|
) |
||||
|
$psake.context.Peek().taskSetupScriptBlock = $setup |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function TaskTearDown { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][scriptblock]$teardown |
||||
|
) |
||||
|
$psake.context.Peek().taskTearDownScriptBlock = $teardown |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Framework { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position=0,Mandatory=1)][string]$framework |
||||
|
) |
||||
|
$psake.context.Peek().config.framework = $framework |
||||
|
ConfigureBuildEnvironment |
||||
|
} |
||||
|
|
||||
|
# .ExternalHelp psake.psm1-help.xml |
||||
|
function Invoke-psake { |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(Position = 0, Mandatory = 0)][string] $buildFile, |
||||
|
[Parameter(Position = 1, Mandatory = 0)][string[]] $taskList = @(), |
||||
|
[Parameter(Position = 2, Mandatory = 0)][string] $framework, |
||||
|
[Parameter(Position = 3, Mandatory = 0)][switch] $docs = $false, |
||||
|
[Parameter(Position = 4, Mandatory = 0)][hashtable] $parameters = @{}, |
||||
|
[Parameter(Position = 5, Mandatory = 0)][hashtable] $properties = @{}, |
||||
|
[Parameter(Position = 6, Mandatory = 0)][alias("init")][scriptblock] $initialization = {}, |
||||
|
[Parameter(Position = 7, Mandatory = 0)][switch] $nologo = $false |
||||
|
) |
||||
|
try { |
||||
|
if (-not $nologo) { |
||||
|
"psake version {0}`nCopyright (c) 2010 James Kovacs`n" -f $psake.version |
||||
|
} |
||||
|
|
||||
|
if (!$buildFile) { |
||||
|
$buildFile = $psake.config_default.buildFileName |
||||
|
} |
||||
|
elseif (!(test-path $buildFile -pathType Leaf) -and (test-path $psake.config_default.buildFileName -pathType Leaf)) { |
||||
|
# If the $config.buildFileName file exists and the given "buildfile" isn 't found assume that the given |
||||
|
# $buildFile is actually the target Tasks to execute in the $config.buildFileName script. |
||||
|
$taskList = $buildFile.Split(', ') |
||||
|
$buildFile = $psake.config_default.buildFileName |
||||
|
} |
||||
|
|
||||
|
# Execute the build file to set up the tasks and defaults |
||||
|
Assert (test-path $buildFile -pathType Leaf) ($msgs.error_build_file_not_found -f $buildFile) |
||||
|
|
||||
|
$psake.build_script_file = get-item $buildFile |
||||
|
$psake.build_script_dir = $psake.build_script_file.DirectoryName |
||||
|
$psake.build_success = $false |
||||
|
|
||||
|
$psake.context.push(@{ |
||||
|
"taskSetupScriptBlock" = {}; |
||||
|
"taskTearDownScriptBlock" = {}; |
||||
|
"executedTasks" = new-object System.Collections.Stack; |
||||
|
"callStack" = new-object System.Collections.Stack; |
||||
|
"originalEnvPath" = $env:path; |
||||
|
"originalDirectory" = get-location; |
||||
|
"originalErrorActionPreference" = $global:ErrorActionPreference; |
||||
|
"tasks" = @{}; |
||||
|
"aliases" = @{}; |
||||
|
"properties" = @(); |
||||
|
"includes" = new-object System.Collections.Queue; |
||||
|
"config" = CreateConfigurationForNewContext $buildFile $framework |
||||
|
}) |
||||
|
|
||||
|
LoadConfiguration $psake.build_script_dir |
||||
|
|
||||
|
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew() |
||||
|
|
||||
|
set-location $psake.build_script_dir |
||||
|
|
||||
|
LoadModules |
||||
|
|
||||
|
$frameworkOldValue = $framework |
||||
|
. $psake.build_script_file.FullName |
||||
|
|
||||
|
$currentContext = $psake.context.Peek() |
||||
|
|
||||
|
if ($framework -ne $frameworkOldValue) { |
||||
|
writecoloredoutput $msgs.warning_deprecated_framework_variable -foregroundcolor Yellow |
||||
|
$currentContext.config.framework = $framework |
||||
|
} |
||||
|
|
||||
|
ConfigureBuildEnvironment |
||||
|
|
||||
|
while ($currentContext.includes.Count -gt 0) { |
||||
|
$includeFilename = $currentContext.includes.Dequeue() |
||||
|
. $includeFilename |
||||
|
} |
||||
|
|
||||
|
if ($docs) { |
||||
|
WriteDocumentation |
||||
|
CleanupEnvironment |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
foreach ($key in $parameters.keys) { |
||||
|
if (test-path "variable:\$key") { |
||||
|
set-item -path "variable:\$key" -value $parameters.$key -WhatIf:$false -Confirm:$false | out-null |
||||
|
} else { |
||||
|
new-item -path "variable:\$key" -value $parameters.$key -WhatIf:$false -Confirm:$false | out-null |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# The initial dot (.) indicates that variables initialized/modified in the propertyBlock are available in the parent scope. |
||||
|
foreach ($propertyBlock in $currentContext.properties) { |
||||
|
. $propertyBlock |
||||
|
} |
||||
|
|
||||
|
foreach ($key in $properties.keys) { |
||||
|
if (test-path "variable:\$key") { |
||||
|
set-item -path "variable:\$key" -value $properties.$key -WhatIf:$false -Confirm:$false | out-null |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# Simple dot sourcing will not work. We have to force the script block into our |
||||
|
# module's scope in order to initialize variables properly. |
||||
|
. $MyInvocation.MyCommand.Module $initialization |
||||
|
|
||||
|
# Execute the list of tasks or the default task |
||||
|
if ($taskList) { |
||||
|
foreach ($task in $taskList) { |
||||
|
invoke-task $task |
||||
|
} |
||||
|
} elseif ($currentContext.tasks.default) { |
||||
|
invoke-task default |
||||
|
} else { |
||||
|
throw $msgs.error_no_default_task |
||||
|
} |
||||
|
|
||||
|
WriteColoredOutput ("`n" + $msgs.build_success + "`n") -foregroundcolor Green |
||||
|
|
||||
|
WriteTaskTimeSummary $stopwatch.Elapsed |
||||
|
|
||||
|
$psake.build_success = $true |
||||
|
} catch { |
||||
|
$currentConfig = GetCurrentConfigurationOrDefault |
||||
|
if ($currentConfig.verboseError) { |
||||
|
$error_message = "{0}: An Error Occurred. See Error Details Below: `n" -f (Get-Date) |
||||
|
$error_message += ("-" * 70) + "`n" |
||||
|
$error_message += "Error: {0}`n" -f (ResolveError $_ -Short) |
||||
|
$error_message += ("-" * 70) + "`n" |
||||
|
$error_message += ResolveError $_ |
||||
|
$error_message += ("-" * 70) + "`n" |
||||
|
$error_message += "Script Variables" + "`n" |
||||
|
$error_message += ("-" * 70) + "`n" |
||||
|
$error_message += get-variable -scope script | format-table | out-string |
||||
|
} else { |
||||
|
# ($_ | Out-String) gets error messages with source information included. |
||||
|
$error_message = "Error: {0}: `n{1}" -f (Get-Date), (ResolveError $_ -Short) |
||||
|
} |
||||
|
|
||||
|
$psake.build_success = $false |
||||
|
|
||||
|
# if we are running in a nested scope (i.e. running a psake script from a psake script) then we need to re-throw the exception |
||||
|
# so that the parent script will fail otherwise the parent script will report a successful build |
||||
|
$inNestedScope = ($psake.context.count -gt 1) |
||||
|
if ( $inNestedScope ) { |
||||
|
throw $_ |
||||
|
} else { |
||||
|
if (!$psake.run_by_psake_build_tester) { |
||||
|
WriteColoredOutput $error_message -foregroundcolor Red |
||||
|
} |
||||
|
} |
||||
|
} finally { |
||||
|
CleanupEnvironment |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#-- Private Module Functions --# |
||||
|
function WriteColoredOutput { |
||||
|
param( |
||||
|
[string] $message, |
||||
|
[System.ConsoleColor] $foregroundcolor |
||||
|
) |
||||
|
|
||||
|
$currentConfig = GetCurrentConfigurationOrDefault |
||||
|
if ($currentConfig.coloredOutput -eq $true) { |
||||
|
if (($Host.UI -ne $null) -and ($Host.UI.RawUI -ne $null) -and ($Host.UI.RawUI.ForegroundColor -ne $null)) { |
||||
|
$previousColor = $Host.UI.RawUI.ForegroundColor |
||||
|
$Host.UI.RawUI.ForegroundColor = $foregroundcolor |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$message |
||||
|
|
||||
|
if ($previousColor -ne $null) { |
||||
|
$Host.UI.RawUI.ForegroundColor = $previousColor |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function LoadModules { |
||||
|
$currentConfig = $psake.context.peek().config |
||||
|
if ($currentConfig.modules) { |
||||
|
|
||||
|
$scope = $currentConfig.moduleScope |
||||
|
|
||||
|
$global = [string]::Equals($scope, "global", [StringComparison]::CurrentCultureIgnoreCase) |
||||
|
|
||||
|
$currentConfig.modules | foreach { |
||||
|
resolve-path $_ | foreach { |
||||
|
"Loading module: $_" |
||||
|
$module = import-module $_ -passthru -DisableNameChecking -global:$global |
||||
|
if (!$module) { |
||||
|
throw ($msgs.error_loading_module -f $_.Name) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
"" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function LoadConfiguration { |
||||
|
param( |
||||
|
[string] $configdir = $PSScriptRoot |
||||
|
) |
||||
|
|
||||
|
$psakeConfigFilePath = (join-path $configdir "psake-config.ps1") |
||||
|
|
||||
|
if (test-path $psakeConfigFilePath -pathType Leaf) { |
||||
|
try { |
||||
|
$config = GetCurrentConfigurationOrDefault |
||||
|
. $psakeConfigFilePath |
||||
|
} catch { |
||||
|
throw "Error Loading Configuration from psake-config.ps1: " + $_ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function GetCurrentConfigurationOrDefault() { |
||||
|
if ($psake.context.count -gt 0) { |
||||
|
return $psake.context.peek().config |
||||
|
} else { |
||||
|
return $psake.config_default |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function CreateConfigurationForNewContext { |
||||
|
param( |
||||
|
[string] $buildFile, |
||||
|
[string] $framework |
||||
|
) |
||||
|
|
||||
|
$previousConfig = GetCurrentConfigurationOrDefault |
||||
|
|
||||
|
$config = new-object psobject -property @{ |
||||
|
buildFileName = $previousConfig.buildFileName; |
||||
|
framework = $previousConfig.framework; |
||||
|
taskNameFormat = $previousConfig.taskNameFormat; |
||||
|
verboseError = $previousConfig.verboseError; |
||||
|
coloredOutput = $previousConfig.coloredOutput; |
||||
|
modules = $previousConfig.modules; |
||||
|
moduleScope = $previousConfig.moduleScope; |
||||
|
} |
||||
|
|
||||
|
if ($framework) { |
||||
|
$config.framework = $framework; |
||||
|
} |
||||
|
|
||||
|
if ($buildFile) { |
||||
|
$config.buildFileName = $buildFile; |
||||
|
} |
||||
|
|
||||
|
return $config |
||||
|
} |
||||
|
|
||||
|
function ConfigureBuildEnvironment { |
||||
|
$framework = $psake.context.peek().config.framework |
||||
|
if ($framework -cmatch '^((?:\d+\.\d+)(?:\.\d+){0,1})(x86|x64){0,1}$') { |
||||
|
$versionPart = $matches[1] |
||||
|
$bitnessPart = $matches[2] |
||||
|
} else { |
||||
|
throw ($msgs.error_invalid_framework -f $framework) |
||||
|
} |
||||
|
$versions = $null |
||||
|
$buildToolsVersions = $null |
||||
|
switch ($versionPart) { |
||||
|
'1.0' { |
||||
|
$versions = @('v1.0.3705') |
||||
|
} |
||||
|
'1.1' { |
||||
|
$versions = @('v1.1.4322') |
||||
|
} |
||||
|
'2.0' { |
||||
|
$versions = @('v2.0.50727') |
||||
|
} |
||||
|
'3.0' { |
||||
|
$versions = @('v2.0.50727') |
||||
|
} |
||||
|
'3.5' { |
||||
|
$versions = @('v3.5', 'v2.0.50727') |
||||
|
} |
||||
|
'4.0' { |
||||
|
$versions = @('v4.0.30319') |
||||
|
} |
||||
|
'4.5.1' { |
||||
|
$versions = @('v4.0.30319') |
||||
|
$buildToolsVersions = @('12.0') |
||||
|
} |
||||
|
default { |
||||
|
throw ($msgs.error_unknown_framework -f $versionPart, $framework) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$bitness = 'Framework' |
||||
|
if ($versionPart -ne '1.0' -and $versionPart -ne '1.1') { |
||||
|
switch ($bitnessPart) { |
||||
|
'x86' { |
||||
|
$bitness = 'Framework' |
||||
|
$buildToolsKey = 'MSBuildToolsPath32' |
||||
|
} |
||||
|
'x64' { |
||||
|
$bitness = 'Framework64' |
||||
|
$buildToolsKey = 'MSBuildToolsPath' |
||||
|
} |
||||
|
{ [string]::IsNullOrEmpty($_) } { |
||||
|
$ptrSize = [System.IntPtr]::Size |
||||
|
switch ($ptrSize) { |
||||
|
4 { |
||||
|
$bitness = 'Framework' |
||||
|
$buildToolsKey = 'MSBuildToolsPath32' |
||||
|
} |
||||
|
8 { |
||||
|
$bitness = 'Framework64' |
||||
|
$buildToolsKey = 'MSBuildToolsPath' |
||||
|
} |
||||
|
default { |
||||
|
throw ($msgs.error_unknown_pointersize -f $ptrSize) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
default { |
||||
|
throw ($msgs.error_unknown_bitnesspart -f $bitnessPart, $framework) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$frameworkDirs = @() |
||||
|
if ($buildToolsVersions -ne $null) { |
||||
|
$frameworkDirs = @($buildToolsVersions | foreach { (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\$_" -Name $buildToolsKey).$buildToolsKey }) |
||||
|
} |
||||
|
$frameworkDirs = $frameworkDirs + @($versions | foreach { "$env:windir\Microsoft.NET\$bitness\$_\" }) |
||||
|
|
||||
|
for ($i = 0; $i -lt $frameworkDirs.Count; $i++) { |
||||
|
$dir = $frameworkDirs[$i] |
||||
|
if ($dir -Match "\$\(Registry:HKEY_LOCAL_MACHINE(.*?)@(.*)\)") { |
||||
|
$key = "HKLM:" + $matches[1] |
||||
|
$name = $matches[2] |
||||
|
$dir = (Get-ItemProperty -Path $key -Name $name).$name |
||||
|
$frameworkDirs[$i] = $dir |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$frameworkDirs | foreach { Assert (test-path $_ -pathType Container) ($msgs.error_no_framework_install_dir_found -f $_)} |
||||
|
|
||||
|
$env:path = ($frameworkDirs -join ";") + ";$env:path" |
||||
|
# if any error occurs in a PS function then "stop" processing immediately |
||||
|
# this does not effect any external programs that return a non-zero exit code |
||||
|
$global:ErrorActionPreference = "Stop" |
||||
|
} |
||||
|
|
||||
|
function CleanupEnvironment { |
||||
|
if ($psake.context.Count -gt 0) { |
||||
|
$currentContext = $psake.context.Peek() |
||||
|
$env:path = $currentContext.originalEnvPath |
||||
|
Set-Location $currentContext.originalDirectory |
||||
|
$global:ErrorActionPreference = $currentContext.originalErrorActionPreference |
||||
|
[void] $psake.context.Pop() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function SelectObjectWithDefault |
||||
|
{ |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(ValueFromPipeline=$true)] |
||||
|
[PSObject] |
||||
|
$InputObject, |
||||
|
[string] |
||||
|
$Name, |
||||
|
$Value |
||||
|
) |
||||
|
|
||||
|
process { |
||||
|
if ($_ -eq $null) { $Value } |
||||
|
elseif ($_ | Get-Member -Name $Name) { |
||||
|
$_.$Name |
||||
|
} |
||||
|
elseif (($_ -is [Hashtable]) -and ($_.Keys -contains $Name)) { |
||||
|
$_.$Name |
||||
|
} |
||||
|
else { $Value } |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx |
||||
|
# modified to better handle SQL errors |
||||
|
function ResolveError |
||||
|
{ |
||||
|
[CmdletBinding()] |
||||
|
param( |
||||
|
[Parameter(ValueFromPipeline=$true)] |
||||
|
$ErrorRecord=$Error[0], |
||||
|
[Switch] |
||||
|
$Short |
||||
|
) |
||||
|
|
||||
|
process { |
||||
|
if ($_ -eq $null) { $_ = $ErrorRecord } |
||||
|
$ex = $_.Exception |
||||
|
|
||||
|
if (-not $Short) { |
||||
|
$error_message = "`nErrorRecord:{0}ErrorRecord.InvocationInfo:{1}Exception:`n{2}" |
||||
|
$formatted_errorRecord = $_ | format-list * -force | out-string |
||||
|
$formatted_invocationInfo = $_.InvocationInfo | format-list * -force | out-string |
||||
|
$formatted_exception = '' |
||||
|
|
||||
|
$i = 0 |
||||
|
while ($ex -ne $null) { |
||||
|
$i++ |
||||
|
$formatted_exception += ("$i" * 70) + "`n" + |
||||
|
($ex | format-list * -force | out-string) + "`n" |
||||
|
$ex = $ex | SelectObjectWithDefault -Name 'InnerException' -Value $null |
||||
|
} |
||||
|
|
||||
|
return $error_message -f $formatted_errorRecord, $formatted_invocationInfo, $formatted_exception |
||||
|
} |
||||
|
|
||||
|
$lastException = @() |
||||
|
while ($ex -ne $null) { |
||||
|
$lastMessage = $ex | SelectObjectWithDefault -Name 'Message' -Value '' |
||||
|
$lastException += ($lastMessage -replace "`n", '') |
||||
|
if ($ex -is [Data.SqlClient.SqlException]) { |
||||
|
$lastException += "(Line [$($ex.LineNumber)] " + |
||||
|
"Procedure [$($ex.Procedure)] Class [$($ex.Class)] " + |
||||
|
" Number [$($ex.Number)] State [$($ex.State)] )" |
||||
|
} |
||||
|
$ex = $ex | SelectObjectWithDefault -Name 'InnerException' -Value $null |
||||
|
} |
||||
|
$shortException = $lastException -join ' --> ' |
||||
|
|
||||
|
$header = $null |
||||
|
$current = $_ |
||||
|
$header = (($_.InvocationInfo | |
||||
|
SelectObjectWithDefault -Name 'PositionMessage' -Value '') -replace "`n", ' '), |
||||
|
($_ | SelectObjectWithDefault -Name 'Message' -Value ''), |
||||
|
($_ | SelectObjectWithDefault -Name 'Exception' -Value '') | |
||||
|
? { -not [String]::IsNullOrEmpty($_) } | |
||||
|
Select -First 1 |
||||
|
|
||||
|
$delimiter = '' |
||||
|
if ((-not [String]::IsNullOrEmpty($header)) -and |
||||
|
(-not [String]::IsNullOrEmpty($shortException))) |
||||
|
{ $delimiter = ' [<<==>>] ' } |
||||
|
|
||||
|
return "$($header)$($delimiter)Exception: $($shortException)" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function WriteDocumentation { |
||||
|
$currentContext = $psake.context.Peek() |
||||
|
|
||||
|
if ($currentContext.tasks.default) { |
||||
|
$defaultTaskDependencies = $currentContext.tasks.default.DependsOn |
||||
|
} else { |
||||
|
$defaultTaskDependencies = @() |
||||
|
} |
||||
|
|
||||
|
$currentContext.tasks.Keys | foreach-object { |
||||
|
if ($_ -eq "default") { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
$task = $currentContext.tasks.$_ |
||||
|
new-object PSObject -property @{ |
||||
|
Name = $task.Name; |
||||
|
Alias = $task.Alias; |
||||
|
Description = $task.Description; |
||||
|
"Depends On" = $task.DependsOn -join ", " |
||||
|
Default = if ($defaultTaskDependencies -contains $task.Name) { $true } |
||||
|
} |
||||
|
} | sort 'Name' | format-table -autoSize -wrap -property Name,Alias,"Depends On",Default,Description |
||||
|
} |
||||
|
|
||||
|
function WriteTaskTimeSummary($invokePsakeDuration) { |
||||
|
"-" * 70 |
||||
|
"Build Time Report" |
||||
|
"-" * 70 |
||||
|
$list = @() |
||||
|
$currentContext = $psake.context.Peek() |
||||
|
while ($currentContext.executedTasks.Count -gt 0) { |
||||
|
$taskKey = $currentContext.executedTasks.Pop() |
||||
|
$task = $currentContext.tasks.$taskKey |
||||
|
if ($taskKey -eq "default") { |
||||
|
continue |
||||
|
} |
||||
|
$list += new-object PSObject -property @{ |
||||
|
Name = $task.Name; |
||||
|
Duration = $task.Duration |
||||
|
} |
||||
|
} |
||||
|
[Array]::Reverse($list) |
||||
|
$list += new-object PSObject -property @{ |
||||
|
Name = "Total:"; |
||||
|
Duration = $invokePsakeDuration |
||||
|
} |
||||
|
# using "out-string | where-object" to filter out the blank line that format-table prepends |
||||
|
$list | format-table -autoSize -property Name,Duration | out-string -stream | where-object { $_ } |
||||
|
} |
||||
|
|
||||
|
DATA msgs { |
||||
|
convertfrom-stringdata @' |
||||
|
error_invalid_task_name = Task name should not be null or empty string. |
||||
|
error_task_name_does_not_exist = Task {0} does not exist. |
||||
|
error_circular_reference = Circular reference found for task {0}. |
||||
|
error_missing_action_parameter = Action parameter must be specified when using PreAction or PostAction parameters for task {0}. |
||||
|
error_corrupt_callstack = Call stack was corrupt. Expected {0}, but got {1}. |
||||
|
error_invalid_framework = Invalid .NET Framework version, {0} specified. |
||||
|
error_unknown_framework = Unknown .NET Framework version, {0} specified in {1}. |
||||
|
error_unknown_pointersize = Unknown pointer size ({0}) returned from System.IntPtr. |
||||
|
error_unknown_bitnesspart = Unknown .NET Framework bitness, {0}, specified in {1}. |
||||
|
error_no_framework_install_dir_found = No .NET Framework installation directory found at {0}. |
||||
|
error_bad_command = Error executing command {0}. |
||||
|
error_default_task_cannot_have_action = 'default' task cannot specify an action. |
||||
|
error_duplicate_task_name = Task {0} has already been defined. |
||||
|
error_duplicate_alias_name = Alias {0} has already been defined. |
||||
|
error_invalid_include_path = Unable to include {0}. File not found. |
||||
|
error_build_file_not_found = Could not find the build file {0}. |
||||
|
error_no_default_task = 'default' task required. |
||||
|
error_loading_module = Error loading module {0}. |
||||
|
warning_deprecated_framework_variable = Warning: Using global variable $framework to set .NET framework version used is deprecated. Instead use Framework function or configuration file psake-config.ps1. |
||||
|
required_variable_not_set = Variable {0} must be set to run task {1}. |
||||
|
postcondition_failed = Postcondition failed for task {0}. |
||||
|
precondition_was_false = Precondition was false, not executing task {0}. |
||||
|
continue_on_error = Error in task {0}. {1} |
||||
|
build_success = Build Succeeded! |
||||
|
'@ |
||||
|
} |
||||
|
|
||||
|
import-localizeddata -bindingvariable msgs -erroraction silentlycontinue |
||||
|
|
||||
|
$script:psake = @{} |
||||
|
$psake.version = "4.3.2" # contains the current version of psake |
||||
|
$psake.context = new-object system.collections.stack # holds onto the current state of all variables |
||||
|
$psake.run_by_psake_build_tester = $false # indicates that build is being run by psake-BuildTester |
||||
|
$psake.config_default = new-object psobject -property @{ |
||||
|
buildFileName = "default.ps1"; |
||||
|
framework = "4.0"; |
||||
|
taskNameFormat = "Executing {0}"; |
||||
|
verboseError = $false; |
||||
|
coloredOutput = $true; |
||||
|
modules = $null; |
||||
|
moduleScope = ""; |
||||
|
} # contains default configuration, can be overriden in psake-config.ps1 in directory with psake.psm1 or in directory with current build script |
||||
|
|
||||
|
$psake.build_success = $false # indicates that the current build was successful |
||||
|
$psake.build_script_file = $null # contains a System.IO.FileInfo for the current build script |
||||
|
$psake.build_script_dir = "" # contains a string with fully-qualified path to current build script |
||||
|
|
||||
|
LoadConfiguration |
||||
|
|
||||
|
export-modulemember -function Invoke-psake, Invoke-Task, Task, Properties, Include, FormatTaskName, TaskSetup, TaskTearDown, Framework, Assert, Exec -variable psake |
||||
Loading…
Reference in new issue