main
1# psake v0.11
2# Copyright � 2008 James Kovacs
3# Permission is hereby granted, free of charge, to any person obtaining a copy
4# of this software and associated documentation files (the "Software"), to deal
5# in the Software without restriction, including without limitation the rights
6# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7# copies of the Software, and to permit persons to whom the Software is
8# furnished to do so, subject to the following conditions:
9#
10# The above copyright notice and this permission notice shall be included in
11# all copies or substantial portions of the Software.
12#
13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19# THE SOFTWARE.
20
21param(
22 [string]$buildFile = 'default.ps1',
23 [string[]]$taskList = @(),
24 [string]$framework = '3.5',
25 [switch]$debug = $false,
26 [switch]$help = $false
27)
28
29
30
31if($help) {
32@"
33psake [buildFile] [tasks] [-framework ver] [-debug]
34 where buildFile is the name of the build file, (default: default.ps1)
35 tasks is a list of tasks to execute from the build file,
36 ver is the .NET Framework version to target - 1.0, 1.1, 2.0, 3.0, or 3.5
37 3.5 is the default
38 debug dumps information the tasks.
39psake -help
40 Displays this message.
41"@
42 return
43}
44
45$global:tasks = @{}
46$global:properties = @()
47$script:executedTasks = New-Object System.Collections.Stack
48$script:callStack = New-Object System.Collections.Stack
49$originalEnvPath = $env:path
50$originalDirectory = Get-Location
51
52function task([string]$name, [scriptblock]$action = $null, [string[]]$depends = @()) {
53 if($name -eq 'default' -and $action -ne $null) {
54 throw "Error: default task cannot specify an action"
55 }
56 $newTask = @{
57 Name = $name
58 DependsOn = $depends
59 Action = $action
60 }
61 if($global:tasks.$name -ne $null) { throw "Error: Task, $name, has already been defined." }
62 $global:tasks.$name = $newTask
63}
64
65function properties([scriptblock]$propertyBlock) {
66 $global:properties += $propertyBlock
67}
68
69
70function AssertNotCircular([string]$name) {
71 if($script:callStack.Contains($name)) {
72 throw "Circular reference found for task, $name"
73 }
74}
75
76function ExecuteTask([string]$name) {
77 if($script:executedTasks.Contains($name)) { return }
78 AssertNotCircular $name
79 $script:callStack.Push($name)
80
81 $task = $global:tasks.$name
82 foreach($childTask in $task.DependsOn) {
83 ExecuteTask $childTask
84 }
85 if($name -ne 'default') {
86 Write-Host "Executing task, $name..."
87 if($task.Action -ne $null) {
88 & $task.Action
89 }
90 Write-Host "`n"
91 }
92
93 $poppedTask = $script:callStack.Pop()
94 if($poppedTask -ne $name) {
95 throw "CallStack was corrupt. Expected $name, but got $poppedTask."
96 }
97 $script:executedTasks.Push($name)
98}
99
100function DumpTasks {
101 Write-Host 'Dumping tasks:'
102 foreach($key in $global:tasks.Keys) {
103 $task = $global:tasks.$key;
104 $task.Name + " depends on " + $task.DependsOn.Length + " other tasks: " + $task.DependsOn;
105 }
106 Write-Host "`n"
107}
108
109function DumpProperties {
110 Write-Host 'Dumping properties:'
111 $global:properties
112}
113
114function ConfigureEnvForBuild {
115 $version = $null
116 switch ($framework) {
117 '1.0' { $version = 'v1.0.3705' }
118 '1.1' { $version = 'v1.1.4322' }
119 '2.0' { $version = 'v2.0.50727' }
120 '3.0' { $version = 'v2.0.50727' } # .NET 3.0 uses the .NET 2.0 compilers
121 '3.5' { $version = 'v3.5' }
122 default { throw "Error: Unknown .NET Framework version, $framework" }
123 }
124 $frameworkDir = "$env:windir\Microsoft.NET\Framework\$version\"
125 if(!(test-path $frameworkDir)) {
126 throw "Error: No .NET Framework installation directory found at $frameworkDir"
127 }
128 $env:path = "$frameworkDir;$env:path"
129}
130
131function Cleanup {
132 $env:path = $originalEnvPath
133 $global:tasks = $null
134 Set-Location $originalDirectory
135}
136
137function RunBuild {
138 # Faking a finally block
139 trap {
140 Write-Host -foregroundcolor Red $_
141 Cleanup
142 break
143 }
144
145 # Execute the build file to set up the tasks and defaults
146 if(test-path $buildFile) {
147 $buildFile = resolve-path $buildFile
148 set-location (split-path $buildFile)
149 & $buildFile
150 } else {
151 throw "Error: Could not find the build file, $buildFile."
152 }
153
154 if($debug) {
155 DumpProperties
156 DumpTasks
157 }
158
159 ConfigureEnvForBuild
160
161
162 foreach($propertyBlock in $global:properties) {
163 . $propertyBlock
164 }
165
166
167 # Execute the list of tasks or the default task
168 if($taskList.Length -ne 0) {
169 foreach($task in $taskList) {
170 ExecuteTask $task
171 }
172 } elseif ($global:tasks.default -ne $null) {
173 EXecuteTask default
174 }
175
176 # Clear out any global variables
177 Cleanup
178}
179
180# Avoids printing of error dump with line numbers
181trap {
182 # continue
183}
184
185RunBuild
186