Permalink
Browse files

Implemented psake scripts

  • Loading branch information...
1 parent 8c9cbaf commit f438c68ef2a6bceefccdd4cbed65b8f44521cecf @kblooie kblooie committed Aug 12, 2012
Showing with 1,020 additions and 1 deletion.
  1. +2 −1 .gitignore
  2. +2 −0 Build.RunTask.bat
  3. +11 −0 build/Build.RunTask.ps1
  4. +37 −0 build/Modules/ILMerge.psm1
  5. +64 −0 build/Modules/IO.psm1
  6. +135 −0 build/default.ps1
  7. +2 −0 build/psake-config.ps1
  8. +11 −0 build/psake.cmd
  9. +47 −0 build/psake.ps1
  10. +709 −0 build/psake.psm1
View
3 .gitignore
@@ -10,4 +10,5 @@ _ReSharper.*
*.Resharper
*.Cache
*.cache
-~$*
+~$*
+[Pp]ublish
View
2 Build.RunTask.bat
@@ -0,0 +1,2 @@
+@echo off
+powershell -NoProfile -ExecutionPolicy unrestricted -Command "& .\build\Build.RunTask.ps1 %*"
View
11 build/Build.RunTask.ps1
@@ -0,0 +1,11 @@
+Param($task)
+
+if($task -eq $null) {
+ $task = read-host "Enter Task"
+}
+
+$scriptPath = $(Split-Path -parent $MyInvocation.MyCommand.path)
+
+. .\build\psake.ps1 -scriptPath $scriptPath -t $task
+
+read-host "Press enter to exit" | out-null
View
37 build/Modules/ILMerge.psm1
@@ -0,0 +1,37 @@
+$script:ilMergeModule = @{}
+$script:ilMergeModule.ilMergePath = $null
+
+function Merge-Assemblies {
+ Param(
+ $files,
+ $outputFile,
+ $exclude,
+ $keyfile,
+ $targetPlatform="v4,C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319"
+ )
+
+ $exclude | out-file ".\exclude.txt"
+
+ $args = @(
+ "/keyfile:$keyfile",
+ "/internalize:exclude.txt",
+ "/xmldocs",
+ "/wildcards",
+ "/targetplatform:$targetPlatform",
+ "/out:$outputFile") + $files
+
+ if($ilMergeModule.ilMergePath -eq $null)
+ {
+ write-error "IlMerge Path is not defined. Please set variable `$ilMergeModule.ilMergePath"
+ }
+
+ & $ilMergeModule.ilMergePath $args
+
+ if($LastExitCode -ne 0) {
+ write-error "Merge Failed"
+ }
+
+ remove-item ".\exclude.txt"
+}
+
+Export-ModuleMember -Variable "ilMergeModule" -Function "Merge-Assemblies"
View
64 build/Modules/IO.psm1
@@ -0,0 +1,64 @@
+function Clean-Item {
+ Param(
+ [parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
+ [string] $path
+ )
+ Process
+ {
+ if(($path -ne $null) -and (test-path $path))
+ {
+ write-verbose ("Removing {0}" -f $path)
+ remove-item -force -recurse $path | Out-Null
+ }
+ }
+}
+
+function Remove-Directory {
+ Param(
+ [parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
+ [string] $path
+ )
+ rd $path -recurse -force -ErrorAction SilentlyContinue | out-null
+}
+
+function New-Directory
+{
+ Param(
+ [parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
+ [string] $path
+ )
+
+ mkdir $path -ErrorAction SilentlyContinue | out-null
+}
+
+function Copy-Files {
+ Param(
+ [parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
+ [string] $source,
+ [string] $destination,
+ [alias("exclude")]
+ [string[]] $excludeFiles=@(),
+ [string[]] $excludeDirectories=@()
+ )
+
+ New-Directory $destination
+
+ #Get-ChildItem $source -Recurse -Exclude $exclude | Copy-Item -Destination {Join-Path $destination $_.FullName.Substring($source.length)}
+
+
+ $arguments = @($source, $destination, "*.*", "/e")
+
+ if(($excludeFiles -ne $null) -and ($excludeFiles.Length -gt 0)) {
+ $arguments += "/xf"
+ $arguments += $excludeFiles
+ }
+
+ if(($excludeDirectories -ne $null) -and ($excludeFiles.Length -gt 0)) {
+ $arguments += "/xd"
+ $arguments += $excludeDirectories
+ }
+
+ robocopy.exe $arguments | out-null
+
+ Expect-ExitCode -expectedExitCode 0,1 -formatMessage { param($taskName) "Copy was not successful" }
+}
View
135 build/default.ps1
@@ -0,0 +1,135 @@
+properties {
+ $base_directory = Resolve-Path ..
+ $publish_directory = "$base_directory\publish"
+ $build_directory = "$base_directory\build"
+ $src_directory = "$base_directory\Src"
+ $output_directory = "$base_directory\output"
+ $packages_directory = "$src_directory\packages"
+
+ $sln_file = "$base_directory\src\EventStore.sln"
+ $keyfile = "$src_directory/EventStore.snk"
+ $target_config = "Release"
+ $framework_version = "v4.0"
+
+ $mspec_path = "$packages_directory\Machine.Specifications.0.5.7\tools\mspec-x86-clr4.exe"
+ $ilMergeModule.ilMergePath = "$base_directory\bin\ilmerge-bin\ILMerge.exe"
+
+ if($runPersistenceTests -eq $null) {
+ $runPersistenceTests = $false
+ }
+}
+
+task default -depends Build
+
+task Build -depends Clean, Compile, Test
+
+task Compile {
+ exec { msbuild /nologo /verbosity:quiet $sln_file /p:Configuration=$target_config /t:Clean }
+
+ exec { msbuild /nologo /verbosity:quiet $sln_file /p:Configuration=$target_config /p:TargetFrameworkVersion=v4.0 }
+}
+
+task Test -depends RunUnitTests, RunPersistenceTests, RunSerializationTests
+
+task RunUnitTests {
+ write-host "Unit Tests"
+
+ exec { &$mspec_path "$src_directory/tests/EventStore.Core.UnitTests/bin/$target_config/EventStore.Core.UnitTests.dll" }
+}
+
+task RunPersistenceTests -precondition { $runPersistenceTests } {
+ write-host "Acceptance Tests: Persistence Tests"
+
+ exec { &$mspec_path "$src_directory/tests/EventStore.Persistence.AcceptanceTests/bin/$target_config/EventStore.Persistence.AcceptanceTests.dll" }
+}
+
+task RunSerializationTests {
+ exec { &$mspec_path "$src_directory\tests\EventStore.Serialization.AcceptanceTests\bin\$target_config\EventStore.Serialization.AcceptanceTests.dll" }
+}
+
+task Package -depends Build, PackageEventStore, PackageMongoPersistence, PackageRavenPersistence, PackageJsonSerialization, PackageServiceStackSerialization, PackageNLogLogging, PackageLog4NetLogging {
+ move $output_directory $publish_directory
+}
+
+task PackageEventStore -depends Clean, Compile {
+ mkdir "$output_directory\bin" | out-null
+ Merge-Assemblies -outputFile "$output_directory\bin\EventStore.dll" -exclude "EventStore.*" -keyfile $keyFile -files @(
+ "$src_directory\proj\EventStore\bin\$target_config\EventStore.dll",
+ "$src_directory\proj\EventStore.Core\bin\$target_config\EventStore.Core.dll",
+ "$src_directory\proj\EventStore.Serialization\bin\$target_config\EventStore.Serialization.dll",
+ "$src_directory\proj\EventStore.Persistence.SqlPersistence\bin\$target_config\EventStore.Persistence.SqlPersistence.dll",
+ "$src_directory\proj\EventStore.Wireup\bin\$target_config\EventStore.Wireup.dll"
+ )
+
+ write-host Rereferencing Merged Assembly
+ exec { msbuild /nologo /verbosity:quiet $sln_file /p:Configuration=$target_config /t:Clean }
+
+ exec { msbuild /nologo /verbosity:quiet $sln_file /p:Configuration=$target_config /p:ILMerged=true /p:TargetFrameworkVersion=v4.0 }
+}
+
+task PackageMongoPersistence -depends Clean, Compile,PackageEventStore {
+ mkdir $output_directory\plugins\persistence\mongo | out-null
+
+ Merge-Assemblies -outputFile "$output_directory/plugins/persistence/mongo/EventStore.Persistence.MongoPersistence.dll" -exclude "MongoDB.*" -keyfile $keyFile -files @(
+ "$src_directory/proj/EventStore.Persistence.MongoPersistence/bin/$target_config/EventStore.Persistence.MongoPersistence.dll",
+ "$src_directory/proj/EventStore.Persistence.MongoPersistence.Wireup/bin/$target_config/EventStore.Persistence.MongoPersistence.Wireup.dll"
+ )
+
+ copy "$src_directory\proj\EventStore.Persistence.MongoPersistence\bin\$target_config\MongoDB*.dll" "$output_directory\plugins\persistence\mongo"
+}
+
+task PackageRavenPersistence -depends Clean, Compile,PackageEventStore {
+ mkdir $output_directory\plugins\persistence\raven | out-null
+
+ Merge-Assemblies -outputFile "$output_directory/plugins/persistence/raven/EventStore.Persistence.RavenPersistence.dll" -exclude "Raven.*" -keyfile $keyFile -files @(
+ "$src_directory/proj/EventStore.Persistence.RavenPersistence/bin/$target_config/EventStore.Persistence.RavenPersistence.dll",
+ "$src_directory/proj/EventStore.Persistence.RavenPersistence.Wireup/bin/$target_config/EventStore.Persistence.RavenPersistence.Wireup.dll"
+ )
+
+ copy "$src_directory\proj\EventStore.Persistence.RavenPersistence\bin\$target_config\Raven*.dll" "$output_directory\plugins\persistence\raven"
+}
+
+task PackageJsonSerialization -depends Clean, Compile,PackageEventStore {
+ mkdir $output_directory\plugins\serialization\json-net | out-null
+
+ Merge-Assemblies -outputFile "$output_directory/plugins/serialization/json-net/EventStore.Serialization.Json.dll" -exclude "EventStore.*" -keyfile $keyFile -files @(
+ "$src_directory/proj/EventStore.Serialization.Json/bin/$target_config/EventStore.Serialization.Json.dll",
+ "$src_directory/proj/EventStore.Serialization.Json/bin/$target_config/Newtonsoft.Json*.dll",
+ "$src_directory/proj/EventStore.Serialization.Json.Wireup/bin/$target_config/EventStore.Serialization.Json.Wireup.dll"
+ )
+}
+
+task PackageServiceStackSerialization -depends Clean, Compile, PackageEventStore {
+ mkdir $output_directory\plugins\serialization\servicestack | out-null
+
+ Merge-Assemblies -outputFile "$output_directory/plugins/serialization/servicestack/EventStore.Serialization.ServiceStack.dll" -exclude "EventStore.*" -keyfile $keyFile -files @(
+ "$src_directory/proj/EventStore.Serialization.ServiceStack/bin/$target_config/EventStore.Serialization.ServiceStack.dll",
+ "$src_directory/proj/EventStore.Serialization.ServiceStack/bin/$target_config/ServiceStack.Text.dll",
+ "$src_directory/proj/EventStore.Serialization.ServiceStack.Wireup/bin/$target_config/EventStore.Serialization.ServiceStack.Wireup.dll"
+ )
+}
+
+task PackageNLogLogging -depends Clean, Compile,PackageEventStore {
+ mkdir $output_directory\plugins\logging\nlog | out-null
+ copy "$src_directory\proj\EventStore.Logging.NLog\bin\$target_config\EventStore.Logging.NLog.*" "$output_directory\plugins\logging\nlog"
+
+ copy "$src_directory\proj\EventStore.Logging.NLog\bin\$target_config\NLog.dll" "$output_directory\plugins\logging\nlog"
+}
+
+task PackageLog4NetLogging -depends Clean, Compile,PackageEventStore {
+ mkdir $output_directory\plugins\logging\log4net | out-null
+
+ copy "$src_directory\proj\EventStore.Logging.Log4Net\bin\$target_config\EventStore.Logging.Log4Net.*" "$output_directory\plugins\logging\log4net"
+
+ copy "$src_directory\proj\EventStore.Logging.Log4Net\bin\$target_config\log4net.dll" "$output_directory\plugins\logging\log4net"
+}
+
+task PackageDocs {
+ mkdir "$output_directory\doc"
+ copy "$base_directory\doc\*.*" "$output_directory\doc"
+}
+
+task Clean {
+ Clean-Item $publish_directory -ea SilentlyContinue
+ Clean-Item $output_directory -ea SilentlyContinue
+}
View
2 build/psake-config.ps1
@@ -0,0 +1,2 @@
+$config.modules=(".\build\modules\*.psm1")
+$config.moduleScope="global"
View
11 build/psake.cmd
@@ -0,0 +1,11 @@
+@echo off
+
+if '%1'=='/?' goto help
+if '%1'=='-help' goto help
+if '%1'=='-h' goto help
+
+powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0\psake.ps1' %*; if ($psake.build_success -eq $false) { exit 1 } else { exit 0 }"
+goto :eof
+
+:help
+powershell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0\psake.ps1' -help"
View
47 build/psake.ps1
@@ -0,0 +1,47 @@
+# Helper script for those who want to run psake without importing the module.
+# Example:
+# .\psake.ps1 "default.ps1" "BuildHelloWord" "4.0"
+
+# Must match parameter definitions for psake.psm1/invoke-psake
+# otherwise named parameter binding fails
+param(
+ [Parameter(Position=0,Mandatory=0)]
+ [string]$buildFile = 'default.ps1',
+ [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)]
+ [System.Collections.Hashtable]$parameters = @{},
+ [Parameter(Position=5, Mandatory=0)]
+ [System.Collections.Hashtable]$properties = @{},
+ [Parameter(Position=6, Mandatory=0)]
+ [alias("init")]
+ [scriptblock]$initialization = {},
+ [Parameter(Position=7, Mandatory=0)]
+ [switch]$nologo = $false,
+ [Parameter(Position=8, Mandatory=0)]
+ [switch]$help = $false,
+ [Parameter(Position=9, Mandatory=0)]
+ [string]$scriptPath = $(Split-Path -parent $MyInvocation.MyCommand.path)
+)
+
+# '[p]sake' is the same as 'psake' but $Error is not polluted
+remove-module [p]sake
+import-module (join-path $scriptPath psake.psm1)
+if ($help) {
+ Get-Help Invoke-psake -full
+ return
+}
+
+if (-not(test-path $buildFile)) {
+ $absoluteBuildFile = (join-path $scriptPath $buildFile)
+ if (test-path $absoluteBuildFile) {
+ $buildFile = $absoluteBuildFile
+ }
+}
+
+$psake.use_exit_on_error = $true
+invoke-psake $buildFile $taskList $framework $docs $parameters $properties $initialization $nologo
View
709 build/psake.psm1
@@ -0,0 +1,709 @@
+# psake
+# Copyright (c) 2010 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) {
+ Write-ColoredOutput ($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 {
+ Write-ColoredOutput ($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
+ Write-ColoredOutput ($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)
+ )
+ & $cmd
+ if ($lastexitcode -ne 0) {
+ throw ("Exec: " + $errorMessage)
+ }
+}
+
+# .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
+ )
+ 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
+ }
+
+ $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
+}
+
+# .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 the default.ps1 file exists and the given "buildfile" isn 't found assume that the given
+ # $buildFile is actually the target Tasks to execute in the default.ps1 script.
+ if ($buildFile -and !(test-path $buildFile -pathType Leaf) -and (test-path $psake.config_default.buildFileName -pathType Leaf)) {
+ $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" = Create-ConfigurationForNewContext $buildFile $framework
+ })
+
+ Load-Configuration $psake.build_script_dir
+
+ Load-Modules
+
+ $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+
+ set-location $psake.build_script_dir
+
+ $frameworkOldValue = $framework
+ . $psake.build_script_file.FullName
+
+ $currentContext = $psake.context.Peek()
+
+ if ($framework -ne $frameworkOldValue) {
+ write-coloredoutput $msgs.warning_deprecated_framework_variable -foregroundcolor Yellow
+ $currentContext.config.framework = $framework
+ }
+
+ if ($docs) {
+ Write-Documentation
+ Cleanup-Environment
+ return
+ }
+
+ Configure-BuildEnvironment
+
+ while ($currentContext.includes.Count -gt 0) {
+ $includeFilename = $currentContext.includes.Dequeue()
+ . $includeFilename
+ }
+
+ foreach ($key in $parameters.keys) {
+ if (test-path "variable:\$key") {
+ set-item -path "variable:\$key" -value $parameters.$key | out-null
+ } else {
+ new-item -path "variable:\$key" -value $parameters.$key | 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 | 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
+ }
+
+ Write-ColoredOutput ("`n" + $msgs.build_success + "`n") -foregroundcolor Green
+
+ Write-TaskTimeSummary $stopwatch.Elapsed
+
+ $psake.build_success = $true
+ } catch {
+ $currentConfig = Get-CurrentConfigurationOrDefault
+ if ($currentConfig.verboseError) {
+ $error_message = "{0}: An Error Occurred. See Error Details Below: `n" -f (Get-Date)
+ $error_message += ("-" * 70) + "`n"
+ $error_message += Resolve-Error $_
+ $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 = "{0}: An Error Occurred: `n{1}" -f (Get-Date), ($_ | Out-String)
+ }
+
+ $psake.build_success = $false
+
+ if (!$psake.run_by_psake_build_tester) {
+ # 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 {
+ Write-ColoredOutput $error_message -foregroundcolor Red
+ }
+
+ }
+ } finally {
+ Cleanup-Environment
+ }
+}
+
+#-- Private Module Functions --#
+function Write-ColoredOutput {
+ param(
+ [string] $message,
+ [System.ConsoleColor] $foregroundcolor
+ )
+
+ $currentConfig = Get-CurrentConfigurationOrDefault
+ if ($currentConfig.coloredOutput -eq $true) {
+ if (($Host.UI -ne $null) -and ($Host.UI.RawUI -ne $null)) {
+ $previousColor = $Host.UI.RawUI.ForegroundColor
+ $Host.UI.RawUI.ForegroundColor = $foregroundcolor
+ }
+ }
+
+ $message
+
+ if ($previousColor -ne $null) {
+ $Host.UI.RawUI.ForegroundColor = $previousColor
+ }
+}
+
+function Load-Modules {
+ $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 Load-Configuration {
+ param(
+ [string] $configdir = $PSScriptRoot
+ )
+
+ $psakeConfigFilePath = (join-path $configdir "psake-config.ps1")
+
+ if (test-path $psakeConfigFilePath -pathType Leaf) {
+ try {
+ $config = Get-CurrentConfigurationOrDefault
+ . $psakeConfigFilePath
+ } catch {
+ throw "Error Loading Configuration from psake-config.ps1: " + $_
+ }
+ }
+}
+
+function Get-CurrentConfigurationOrDefault() {
+ if ($psake.context.count -gt 0) {
+ return $psake.context.peek().config
+ } else {
+ return $psake.config_default
+ }
+}
+
+function Create-ConfigurationForNewContext {
+ param(
+ [string] $buildFile,
+ [string] $framework
+ )
+
+ $previousConfig = Get-CurrentConfigurationOrDefault
+
+ $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 Configure-BuildEnvironment {
+ $framework = $psake.context.peek().config.framework
+ if ($framework.Length -ne 3 -and $framework.Length -ne 6) {
+ throw ($msgs.error_invalid_framework -f $framework)
+ }
+ $versionPart = $framework.Substring(0, 3)
+ $bitnessPart = $framework.Substring(3)
+ $versions = $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')
+ }
+ 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'
+ }
+ 'x64' {
+ $bitness = 'Framework64'
+ }
+ { [string]::IsNullOrEmpty($_) } {
+ $ptrSize = [System.IntPtr]::Size
+ switch ($ptrSize) {
+ 4 {
+ $bitness = 'Framework'
+ }
+ 8 {
+ $bitness = 'Framework64'
+ }
+ default {
+ throw ($msgs.error_unknown_pointersize -f $ptrSize)
+ }
+ }
+ }
+ default {
+ throw ($msgs.error_unknown_bitnesspart -f $bitnessPart, $framework)
+ }
+ }
+ }
+ $frameworkDirs = $versions | foreach { "$env:windir\Microsoft.NET\$bitness\$_\" }
+
+ $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 Cleanup-Environment {
+ 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()
+ }
+}
+
+# borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx
+function Resolve-Error($ErrorRecord = $Error[0]) {
+ $error_message = "`nErrorRecord:{0}ErrorRecord.InvocationInfo:{1}Exception:{2}"
+ $formatted_errorRecord = $ErrorRecord | format-list * -force | out-string
+ $formatted_invocationInfo = $ErrorRecord.InvocationInfo | format-list * -force | out-string
+ $formatted_exception = ""
+ $Exception = $ErrorRecord.Exception
+ for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException)) {
+ $formatted_exception += ("$i" * 70) + "`n"
+ $formatted_exception += $Exception | format-list * -force | out-string
+ $formatted_exception += "`n"
+ }
+
+ return $error_message -f $formatted_errorRecord, $formatted_invocationInfo, $formatted_exception
+}
+
+function Write-Documentation {
+ $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;
+ Description = $task.Description;
+ "Depends On" = $task.DependsOn -join ", "
+ Default = if ($defaultTaskDependencies -contains $task.Name) { $true }
+ }
+ } | sort 'Name' | format-table -autoSize -property Name,Description,"Depends On",Default
+}
+
+function Write-TaskTimeSummary($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.1.0" # 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 = "local";
+} # 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
+
+Load-Configuration
+
+export-modulemember -function invoke-psake, invoke-task, task, properties, include, formattaskname, tasksetup, taskteardown, framework, assert, exec -variable psake

0 comments on commit f438c68

Please sign in to comment.