diff --git a/build/Microsoft.Windows.Toolkit.Notifications.JavaScript.nuspec b/build/Microsoft.Windows.Toolkit.Notifications.JavaScript.nuspec
new file mode 100644
index 000000000..1ed8f8cf3
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.Notifications.JavaScript.nuspec
@@ -0,0 +1,36 @@
+
+
+
+ Microsoft.Windows.Toolkit.Notifications.JavaScript
+ 0.0.0
+ Microsoft
+ microsoft, andrewbares
+ https://github.com/anbare/NotificationsExtensions/wiki
+ false
+ Generate tile, toast, and badge notifications for Windows 10 via code, with the help of IntelliSense, instead of directly using XML.
+ The official NotificationsExtensions library from Microsoft. Supports JavaScript UWP projects (see NotificationsExtensions.Win10 for the C#/C++ version).
+
+Generate tile, toast, and badge notifications for Windows 10 via code, with the help of IntelliSense, instead of directly using XML.
+
+Supports adaptive tiles and adaptive/interactive toasts for Windows 10!
+ © Microsoft Corporation. All rights reserved.
+ notifications, win10, windows 10, tile, tiles, toast, toasts, badge, xml, uwp, javascript
+ https://raw.githubusercontent.com/anbare/NotificationsExtensions/master/LICENSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/Microsoft.Windows.Toolkit.Notifications.JavaScript.targets b/build/Microsoft.Windows.Toolkit.Notifications.JavaScript.targets
new file mode 100644
index 000000000..d6795fcaa
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.Notifications.JavaScript.targets
@@ -0,0 +1,11 @@
+
+
+
+
+
+ $(MSBuildThisFileDirectory)..\..\lib\Windows\Microsoft.Windows.Toolkit.Notifications.winmd
+ true
+
+
+
+
diff --git a/build/Microsoft.Windows.Toolkit.Notifications.native.targets b/build/Microsoft.Windows.Toolkit.Notifications.native.targets
new file mode 100644
index 000000000..909226547
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.Notifications.native.targets
@@ -0,0 +1,11 @@
+
+
+
+
+
+ $(MSBuildThisFileDirectory)..\..\lib\native\Microsoft.Windows.Toolkit.Notifications.winmd
+ true
+
+
+
+
diff --git a/build/Microsoft.Windows.Toolkit.Notifications.nuspec b/build/Microsoft.Windows.Toolkit.Notifications.nuspec
new file mode 100644
index 000000000..6fa0ecbc5
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.Notifications.nuspec
@@ -0,0 +1,51 @@
+
+
+
+ Microsoft.Windows.Toolkit.Notifications
+ 0.0.0
+ Microsoft
+ microsoft, andrewbares
+ https://github.com/anbare/NotificationsExtensions/wiki
+ false
+ Generate tile, toast, and badge notifications for Windows 10 via code, with the help of IntelliSense, instead of directly using XML.
+ The official NotificationsExtensions library from Microsoft. C# and C++ UWP project types (see NotificationsExtensions.Win10.JavaScript for the JS version). Also works with C# portable class libraries and non-UWP C# projects like server projects.
+
+Generate tile, toast, and badge notifications for Windows 10 via code, with the help of IntelliSense, instead of directly using XML.
+
+Supports adaptive tiles and adaptive/interactive toasts for Windows 10!
+ © Microsoft Corporation. All rights reserved.
+ notifications, win10, windows 10, tile, tiles, toast, toasts, badge, xml, uwp, c#, csharp, c++
+ https://raw.githubusercontent.com/anbare/NotificationsExtensions/master/LICENSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/Microsoft.Windows.Toolkit.Services.nuspec b/build/Microsoft.Windows.Toolkit.Services.nuspec
new file mode 100644
index 000000000..c23197f8d
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.Services.nuspec
@@ -0,0 +1,26 @@
+
+
+
+ Microsoft.Windows.Toolkit.Services
+ 0.5.0
+ UWP Toolkit Services
+ Microsoft Corp
+ Microsoft Corp
+ https://github.com/deltakosh/UWPToolkit
+ https://github.com/deltakosh/UWPToolkit
+ false
+ This library enable access to diferent data source like Bing, Facebook, and Twitter.
+ Initial internal release of core data services.
+ Copyright 2016
+ UWP Toolkit Windows AppStudio Net Portable Twitter OAuth RSS Facebook Bing
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/Microsoft.Windows.Toolkit.UI.Animations.nuspec b/build/Microsoft.Windows.Toolkit.UI.Animations.nuspec
new file mode 100644
index 000000000..a9537bf15
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.UI.Animations.nuspec
@@ -0,0 +1,24 @@
+
+
+
+ Microsoft.Windows.Toolkit.UI.Animations
+ 0.0.0
+ UWP Toolkit Services
+ Microsoft Corp
+ Microsoft Corp
+ https://github.com/deltakosh/UWPToolkit
+ https://github.com/deltakosh/UWPToolkit
+ false
+ This library enable access to diferent data source like Bing, Facebook, and Twitter.
+ Initial internal release of core data services.
+ Copyright 2016
+ UWP Toolkit Windows AppStudio Net Portable Twitter OAuth RSS Facebook Bing
+
+
+
+
+
+
+
+
+
diff --git a/build/Microsoft.Windows.Toolkit.UI.Controls.nuspec b/build/Microsoft.Windows.Toolkit.UI.Controls.nuspec
new file mode 100644
index 000000000..fc2c6017d
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.UI.Controls.nuspec
@@ -0,0 +1,25 @@
+
+
+
+ Microsoft.Windows.Toolkit.UI.Controls
+ 0.0.0
+ UWP Toolkit Services
+ Microsoft Corp
+ Microsoft Corp
+ https://github.com/deltakosh/UWPToolkit
+ https://github.com/deltakosh/UWPToolkit
+ false
+ This library enable access to diferent data source like Bing, Facebook, and Twitter.
+ Initial internal release of core data services.
+ Copyright 2016
+ UWP Toolkit Windows AppStudio Net Portable Twitter OAuth RSS Facebook Bing
+
+
+
+
+
+
+
+
+
+
diff --git a/build/Microsoft.Windows.Toolkit.UI.nuspec b/build/Microsoft.Windows.Toolkit.UI.nuspec
new file mode 100644
index 000000000..7f2f6e3e4
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.UI.nuspec
@@ -0,0 +1,23 @@
+
+
+
+ Microsoft.Windows.Toolkit.UI
+ 0.0.0
+ UWP Toolkit Services
+ Microsoft Corp
+ Microsoft Corp
+ https://github.com/deltakosh/UWPToolkit
+ https://github.com/deltakosh/UWPToolkit
+ false
+ This library enable access to diferent data source like Bing, Facebook, and Twitter.
+ Initial internal release of core data services.
+ Copyright 2016
+ UWP Toolkit Windows AppStudio Net Portable Twitter OAuth RSS Facebook Bing
+
+
+
+
+
+
+
+
diff --git a/build/Microsoft.Windows.Toolkit.nuspec b/build/Microsoft.Windows.Toolkit.nuspec
new file mode 100644
index 000000000..84529a832
--- /dev/null
+++ b/build/Microsoft.Windows.Toolkit.nuspec
@@ -0,0 +1,20 @@
+
+
+
+ Microsoft.Windows.Toolkit
+ 0.0.0
+ UWP Toolkit Services
+ Microsoft Corp
+ Microsoft Corp
+ https://github.com/deltakosh/UWPToolkit
+ https://github.com/deltakosh/UWPToolkit
+ false
+ This library enable access to diferent data source like Bing, Facebook, and Twitter.
+ Initial internal release of core data services.
+ Copyright 2016
+ UWP Toolkit Windows AppStudio Net Portable Twitter OAuth RSS Facebook Bing
+
+
+
+
+
diff --git a/build/build.ps1 b/build/build.ps1
new file mode 100644
index 000000000..74bd3ff18
--- /dev/null
+++ b/build/build.ps1
@@ -0,0 +1,42 @@
+param(
+ [string]$Task = "default",
+ [hashtable] $Parameters = @{},
+ [hashtable] $Properties = @{},
+ [switch]$Help
+)
+
+$path = Split-Path -Parent $MyInvocation.MyCommand.Definition
+
+Import-Module "$path\tools\psake\psake.psm1"
+
+try
+{
+ if ($Help){
+ try {
+ Get-Help $MyInvocation.MyCommand.Definition -full
+
+ Write-Host "Available build tasks:"
+
+ Invoke-psake -nologo -docs
+ }
+ catch {
+ }
+
+ return
+ }
+
+ Invoke-psake "$path/default.ps1" -task $Task -properties $Properties -parameters $Parameters -nologo
+
+ if ($psake.build_success -eq $false)
+ {
+ exit 1
+ }
+ else
+ {
+ exit 0
+ }
+}
+finally
+{
+ Remove-Module psake
+}
\ No newline at end of file
diff --git a/build/default.ps1 b/build/default.ps1
new file mode 100644
index 000000000..a78d4f7e1
--- /dev/null
+++ b/build/default.ps1
@@ -0,0 +1,68 @@
+$psake.use_exit_on_error = $true
+
+properties {
+ $baseDir = Resolve-Path ..
+ $buildDir = "$baseDir\build"
+ $sourceDir = "$baseDir"
+ $toolsDir = "$baseDir\build\tools"
+ $binDir = "$baseDir\bin"
+
+ $isAppVeyor = Test-Path -Path env:\APPVEYOR
+
+ $version = "2.2.1"
+
+ $tempDir = "$binDir\temp"
+ $binariesDir = "$binDir\binaries"
+ $nupkgDir = "$binDir\nupkg"
+
+ $nuget = "$toolsDir\nuget\nuget.exe"
+}
+
+Framework "4.6x86"
+
+task default -depends ?
+
+task Clean -description "Clean the output folder" {
+ if (Test-Path -path $binDir) {
+ WriteColoredOutput -ForegroundColor Green "Deleting Working Directory...`n"
+
+ Remove-Item $binDir -Recurse -Force
+ }
+
+ New-Item -Path $binDir -ItemType Directory | Out-Null
+}
+
+task Setup -description "Setup environment" {
+ WriteColoredOutput -ForegroundColor Green "Setup environment...`n"
+
+ if ($isAppVeyor) {
+ $script:version = $version -replace '([0-9]+(\.[0-9]+){2}).*', ('$1-dev' + $env:APPVEYOR_BUILD_NUMBER)
+
+ Update-AppveyorBuild -Version $script:version
+ }
+ else {
+ $script:version = $version
+ }
+
+ Exec { .$nuget restore $packagesConfig "$sourceDir\Windows App Toolkit.sln" } "Error pre-installing NuGet packages"
+}
+
+task Build -depends Clean, Setup -description "Build all projects and get the assemblies" {
+ New-Item -Path $binariesDir -ItemType Directory | Out-Null
+
+ Exec { msbuild "/t:Clean;Build" /p:Configuration=Release "/p:OutDir=$binariesDir" /p:GenerateProjectSpecificOutputFolder=true /p:TreatWarningsAsErrors=false /m "$sourceDir\Windows App Toolkit.sln" } "Error building $solutionFile"
+}
+
+task PackNuGet -depends Build -description "Create the NuGet packages" {
+ New-Item -Path $nupkgDir -ItemType Directory | Out-Null
+
+ Get-ChildItem $buildDir\*.nuspec | % {
+ $fullFilename = $_.FullName
+
+ Exec { .$nuget pack "$fullFilename" -Version "$script:version" -Output "$nupkgDir" } "Error packaging $projectName"
+ }
+}
+
+task ? -description "Show the help screen" {
+ WriteDocumentation
+}
\ No newline at end of file
diff --git a/build/tools/nuget/NuGet.exe b/build/tools/nuget/NuGet.exe
new file mode 100644
index 000000000..6bb79fe53
Binary files /dev/null and b/build/tools/nuget/NuGet.exe differ
diff --git a/build/tools/psake/psake.ps1 b/build/tools/psake/psake.ps1
new file mode 100644
index 000000000..ac9ec3a45
--- /dev/null
+++ b/build/tools/psake/psake.ps1
@@ -0,0 +1,53 @@
+# Helper script for those who want to run psake without importing the module.
+# Example run from PowerShell:
+# .\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,
+ [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,
+ [Parameter(Position=10,Mandatory=0)]
+ [switch]$detailedDocs = $false
+)
+
+# setting $scriptPath here, not as default argument, to support calling as "powershell -File psake.ps1"
+if (!$scriptPath) {
+ $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 ($buildFile -and (-not(test-path $buildFile))) {
+ $absoluteBuildFile = (join-path $scriptPath $buildFile)
+ if (test-path $absoluteBuildFile) {
+ $buildFile = $absoluteBuildFile
+ }
+}
+
+Invoke-psake $buildFile $taskList $framework $docs $parameters $properties $initialization $nologo $detailedDocs
\ No newline at end of file
diff --git a/build/tools/psake/psake.psm1 b/build/tools/psake/psake.psm1
new file mode 100644
index 000000000..30fdb6496
--- /dev/null
+++ b/build/tools/psake/psake.psm1
@@ -0,0 +1,865 @@
+# 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,
+ [Parameter(Position = 8, Mandatory = 0)][switch] $detailedDocs = $false
+ )
+ try {
+ if (-not $nologo) {
+ "psake version {0}`nCopyright (c) 2010-2014 James Kovacs & Contributors`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 -or $detailedDocs) {
+ WriteDocumentation($detailedDocs)
+ 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')
+ }
+ {($_ -eq '4.5.1') -or ($_ -eq '4.5.2')} {
+ $versions = @('v4.0.30319')
+ $buildToolsVersions = @('14.0', '12.0')
+ }
+ '4.6' {
+ $versions = @('v4.0.30319')
+ $buildToolsVersions = @('14.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) {
+ foreach($ver in $buildToolsVersions) {
+ if (Test-Path "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\$ver") {
+ $frameworkDirs += (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\$ver" -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($showDetailed) {
+ $currentContext = $psake.context.Peek()
+
+ if ($currentContext.tasks.default) {
+ $defaultTaskDependencies = $currentContext.tasks.default.DependsOn
+ } else {
+ $defaultTaskDependencies = @()
+ }
+
+ $docs = $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 }
+ }
+ }
+ if ($showDetailed) {
+ $docs | sort 'Name' | format-list -property Name,Alias,Description,"Depends On",Default
+ } else {
+ $docs | sort 'Name' | format-table -autoSize -wrap -property Name,Alias,"Depends On",Default,Description
+ }
+
+}
+
+function WriteTaskTimeSummary($invokePsakeDuration) {
+ if ($psake.context.count -gt 0) {
+ "-" * 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.4.1" # 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
\ No newline at end of file