Browse Source

Replaces the old-school batch file with a shiny new PSake build script

Former-commit-id: 1fa7d934e56afe551654425637151a8f1b19bc5f
af/merge-core
Thomas Broust 12 years ago
parent
commit
fe4a5f8a5b
  1. 35
      build/Build.bat
  2. 55
      build/build.ps1
  3. 847
      build/psake.psm1

35
build/Build.bat

@ -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"

55
build/build.ps1

@ -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
}

847
build/psake.psm1

@ -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…
Cancel
Save