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 |
|||
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 |
|||
powershell "Import-Module %~dp0\psake.psm1 ; Invoke-Psake %~dp0\build.ps1 ; exit $LASTEXITCODE" |
|||
@ -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