diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c091839 --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so +*.pyc + +# Numerous always-ignore extensions +################### +*.diff +*.err +*.orig +*.log +*.rej +*.swo +*.swp +*.vi +*~ + +*.sass-cache +# Folders to ignore +################### +.hg +.svn +.CVS +# OS or Editor folders +################### +.DS_Store +Icon? +Thumbs.db +ehthumbs.db +nbproject +.cache +.project +.settings +.tmproj +*.esproj +*.sublime-project +*.sublime-workspace +# Dreamweaver added files +################### +_notes +dwsync.xml +# Komodo +################### +*.komodoproject +.komodotools diff --git a/README.markdown b/README.markdown index 025ae8e..5f981ff 100644 --- a/README.markdown +++ b/README.markdown @@ -6,16 +6,16 @@ psake-contrib is a repository for scripts, modules and functions that are useful ## How to get started: -**Step 1:** Download the project zip file +**Step 1:** Download the project zip file -**Step 2:** CD into the directory where you downloaded the zip +**Step 2:** CD into the directory where you downloaded the zip You will need to "unblock" the zip file before extracting - PowerShell by default does not run files downloaded from the internet. Just right-click the zip and click on "properties" and click on the "unblock" button. **Step 3:** Extract the files in the zip -**Step 4:** Use the scripts and modules in your build +**Step 4:** Use the scripts and modules in your build The following is an excellent technet article on how to ["dot source"](http://technet.microsoft.com/en-us/library/ee176949.aspx) a script diff --git a/database.psm1 b/database.psm1 index 93ab883..dea9253 100644 --- a/database.psm1 +++ b/database.psm1 @@ -2,31 +2,31 @@ function Invoke-SqlCommand { [cmdletbinding(DefaultParameterSetName='customauth')] param( [Parameter(Mandatory=$false)] - [string] + [string] $sqlServer = ".\SQLEXPRESS", - + [Parameter(Mandatory=$false)] - [string] + [string] $database = "Northwind", - - [Parameter(Mandatory=$true)] - [string] + + [Parameter(Mandatory=$true)] + [string] $sqlCommand, - + [Parameter(Mandatory=$false, ParameterSetName='credauth')] - [System.Management.Automation.PsCredential] + [System.Management.Automation.PsCredential] $credential, - + [Parameter(Mandatory=$false, ParameterSetName='customauth')] - [string] + [string] $authentication ="Integrated Security=SSPI;", - + [Parameter(ParameterSetName='devauth')] [switch] $developmentAuthentication ) - switch ($PsCmdlet.ParameterSetName) { + switch ($PsCmdlet.ParameterSetName) { 'devauth' { $authentication = 'User ID=sa;Password=pass' Write-Debug "Using development authentication: $authentication" diff --git a/debugging.psm1 b/debugging.psm1 index 95cd04a..8c9c4f8 100644 --- a/debugging.psm1 +++ b/debugging.psm1 @@ -39,12 +39,12 @@ Shows what tasks are called when Full task is specified during Invoke-Psake buil Add-Type -path "$PSScriptRoot\lib\NodeXl\Microsoft.NodeXL.Layouts.dll" Add-Type -path "$PSScriptRoot\lib\NodeXl\Microsoft.NodeXL.Util.dll" Add-Type -path "$PSScriptRoot\lib\NodeXl\Microsoft.NodeXL.Visualization.Wpf.dll" - + $c = New-Object Microsoft.NodeXL.Visualization.Wpf.NodeXlControl $c.Layout = New-Object Microsoft.NodeXL.Layouts.SugiyamaLayout #$c.Layout = New-Object Microsoft.NodeXL.Layouts.HarelKorenFastMultiscaleLayout $c.BackColor = [System.Windows.Media.Color]::FromRgb(0xff, 0xff, 0xff) - + function New-Vertex { param($vertices, $name) $v = $vertices.Add() @@ -54,8 +54,8 @@ Shows what tasks are called when Full task is specified during Invoke-Psake buil $v.SetValue([Microsoft.NodeXL.Core.ReservedMetadataKeys]::PerVertexLabelFillColor, [System.Drawing.Color]::White) $v } - - + + function New-Edge { param($edges, $vert1, $vert2) $e = $edges.Add($vert1, $vert2, $true) @@ -63,15 +63,15 @@ Shows what tasks are called when Full task is specified during Invoke-Psake buil $e.SetValue([Microsoft.NodeXL.Core.ReservedMetadataKeys]::PerEdgeWidth, [single]3) $e } - + function Get-TaskGraph { $m = Import-Module $psakeModuleFile -pass - & $m { + & $m { $script:dependencies = New-Object Collections.ArrayList - + ${function:Write-TaskTimeSummary} = {} ${function:Invoke-Task} = { - param($taskName) + param($taskName) write-host Task $taskname $taskKey = $taskName.ToLower() $currentContext = $psake.context.Peek() @@ -93,16 +93,16 @@ Shows what tasks are called when Full task is specified during Invoke-Psake buil @($dependencies | Select-Object -ExpandProperty Parent) + @($dependencies | Select-Object -ExpandProperty DependsOn) | Select-Object -unique | % -begin { $vertices=@{}}` - -process { + -process { Write-Debug "Adding vertex for $_" $vertices[$_] = New-Vertex $c.Graph.Vertices $_ } - + $dependencies | % { Write-Debug "Adding edge for $_" New-Edge $c.Graph.Edges $vertices[$_.Parent] $vertices[$_.DependsOn] > $null } - + $window = New-Object Windows.Window $window.Title = "Invoke-Psake build visualizer" $window.Content = $c diff --git a/io.psm1 b/io.psm1 index 93c6bcb..a12bfdb 100644 --- a/io.psm1 +++ b/io.psm1 @@ -3,14 +3,14 @@ function Set-WorkingDirectory { .Synopsis Allows to execute given scriptblock in different directory. .Description - Allows to execute given scriptblock in different directory. It wraps - cmdlets that work with location. It changes the location to $Directory nad + Allows to execute given scriptblock in different directory. It wraps + cmdlets that work with location. It changes the location to $Directory nad after the $code is executed, it changes the directory to original one. .Example Set-location c:\temp Set-WorkingDirectory -dir c:\ -code { gci } write-host Current directory: get-location - + It performs gci in directory c:\ #> param( @@ -25,7 +25,7 @@ function Set-WorkingDirectory { Push-Location Set-Location $directory try { - . $code + . $code } finally { Pop-Location diff --git a/nunit.psm1 b/nunit.psm1 index 9371ffe..b07d0d7 100644 --- a/nunit.psm1 +++ b/nunit.psm1 @@ -7,7 +7,7 @@ param( $script:nunit = $nunitPath Write-Host "Nunit path set to $nunitPath" -function nunit +function nunit { param( [Parameter(Position=0,Mandatory=$true)] @@ -28,12 +28,12 @@ function nunit ) $tempFile = "$env:TEMP\psake-nunit.xml" if (test-path $tempFile) { Get-Item $tempFile | Remove-Item } #Remove-Item $tempFile doesn't work because my temp is C:\Users\J34EF~1.STE\AppData\Local\Temp - + $param = @() if ($Include.Count -gt 0) { $param += '/include:'+($Include -join ',') } if ($Exclude.Count -gt 0) { $param += '/exclude:'+($Exclude -join ',') } if ($NoShadow) { $param += '/noshadow' } - + Write-Debug "output xml file: $tempFile" $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $output = & $nunit $assembly /nologo /xml:$tempFile @param @@ -41,7 +41,7 @@ function nunit $output | Out-Host } $stopwatch.stop() - + $ret = new-Object PsObject -prop @{ Assembly = $assembly Failed = $false @@ -60,11 +60,11 @@ function nunit $ret.Error = 'No output file was created' return $ret } - # when silent, normal output is not written, but then it is not clear what caused the error + # when silent, normal output is not written, but then it is not clear what caused the error # so we will parse the xml and show the failing test $res = [xml](gc $tempFile) - $failed = $res | - Select-Xml -XPath '//test-case' | + $failed = $res | + Select-Xml -XPath '//test-case' | Select-Object -ExpandProperty Node | ? { $_.success -eq "false" } | % { $ret.FailedTestCases += new-Object PsObject -prop @{ @@ -81,7 +81,7 @@ function nunit $ret.Total = $res.Total $ret.Failures = $res.Failures # should be 0 $ret.Errors = $res.Errors # should be 0 - $ret.NotRun = $res.'Not-Run' + $ret.NotRun = $res.'Not-Run' } $ret } @@ -89,18 +89,18 @@ function nunit function Write-NunitRes { param([Parameter(Mandatory=$true)][PsObject]$res) - + if ($res.Failed) { Write-ScriptError "Some Nunit tests failed:" - $res.FailedTestCases | + $res.FailedTestCases | % { Write-Host "------------------------------------" - Write-Host Name:`n $_.Name + Write-Host Name:`n $_.Name Write-Host Statk trace:`n $_.StackTrace Write-Host Message:`n $_.Messsage Write-Host } } - Write-Host "Total: " $res.Total + Write-Host "Total: " $res.Total Write-Host "Errors " $res.Errors Write-Host "Failures " $res.Failures Write-Host "NotRun: " $res.NotRun diff --git a/svn.psm1 b/svn.psm1 index c575304..f6b8603 100644 --- a/svn.psm1 +++ b/svn.psm1 @@ -1,9 +1,9 @@ -# takes one parameter and somehow notifies user; It could be email, growl message, output to file... +# takes one parameter and somehow notifies user; It could be email, growl message, output to file... [scriptblock]$script:Notifier = {} # todo: read output from xml function Set-SvnNotifier { - param( + param( [Parameter(Mandatory=$true)][scriptblock]$notifier ) $script:Notifier = $notifier @@ -16,7 +16,7 @@ function Get-SvnInfo ) $info = svn info $dir $ret = new-object PSObject - $info | % { + $info | % { if ($_ -match '^Revision') { $ret | Add-Member NoteProperty Revision ($_ -replace 'Revision[\s:]*','') } if ($_ -match '^Last Changed Author') { $ret | Add-Member NoteProperty Author ($_ -replace 'Last Changed Author[\s:]*','') } if ($_ -match '^Last Changed Date') { $ret | Add-Member NoteProperty Date ($_ -replace 'Last Changed Date[\s:]*','') } @@ -28,15 +28,15 @@ function Update-Svn { param( [Parameter(Mandatory=$true)][string]$dir, - [switch]$gui, + [switch]$gui, [switch]$Wait ) $info = Get-SvnInfo $dir if ($gui) { Start-Process TortoiseProc.exe -Argument "/command:update", "/path:`"$dir`"" -wait:$wait } else { - svn update $dir | - % { + svn update $dir | + % { $m = $_ switch -regex ($m) { '^(Updated to|At revision)' { write-host $m } @@ -58,7 +58,7 @@ function Update-Svn $_.Info | % { write-host " $_" } } } - # more colors: + # more colors: #"Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White" -split ', '|% { write-host $_ -fore $_ } } @@ -82,12 +82,12 @@ function Get-SvnLogInfos $line = $_ switch -regex ($_) { '^(-*|\s*)$' { return } - '^r\d+\s*\|\s*[\w\.]+\s\|' { + '^r\d+\s*\|\s*[\w\.]+\s\|' { if ($header -ne $null) { $ret += $header } - $header = new-object PSObject -property @{Header = $line; Info = @() } + $header = new-object PSObject -property @{Header = $line; Info = @() } } - default { - $header.Info += $line + default { + $header.Info += $line } } } diff --git a/teamcity.psm1 b/teamcity.psm1 index 5e5cd40..01744b0 100644 --- a/teamcity.psm1 +++ b/teamcity.psm1 @@ -40,16 +40,16 @@ function TeamCity-TestFailed([string]$name, [string]$message, [string]$details=' if (![string]::IsNullOrEmpty($type)) { $output += " type='$type'" } - + $output += " name='$name' message='$message' details='$details'" - + if (![string]::IsNullOrEmpty($expected)) { $output += " expected='$expected'" } if (![string]::IsNullOrEmpty($actual)) { $output += " actual='$actual'" } - + $output += ']' Write-Output $output } @@ -99,20 +99,20 @@ function TeamCity-SetBuildStatistic([string]$key, [string]$value) { function TeamCity-CreateInfoDocument([string]$buildNumber='', [boolean]$status=$true, [string[]]$statusText=$null, [System.Collections.IDictionary]$statistics=$null) { $doc=New-Object xml; $buildEl=$doc.CreateElement('build'); - + if (![string]::IsNullOrEmpty($buildNumber)) { $buildEl.SetAttribute('number', $buildNumber); } - + $buildEl=$doc.AppendChild($buildEl); - + $statusEl=$doc.CreateElement('statusInfo'); if ($status) { $statusEl.SetAttribute('status', 'SUCCESS'); } else { $statusEl.SetAttribute('status', 'FAILURE'); } - + if ($statusText -ne $null) { foreach ($text in $statusText) { $textEl=$doc.CreateElement('text'); @@ -120,30 +120,30 @@ function TeamCity-CreateInfoDocument([string]$buildNumber='', [boolean]$status=$ $textEl.set_InnerText($text); $textEl=$statusEl.AppendChild($textEl); } - } - + } + $statusEl=$buildEl.AppendChild($statusEl); - + if ($statistics -ne $null) { foreach ($key in $statistics.Keys) { $val=$statistics.$key if ($val -eq $null) { $val='' } - + $statEl=$doc.CreateElement('statisticsValue'); $statEl.SetAttribute('key', $key); $statEl.SetAttribute('value', $val.ToString()); $statEl=$buildEl.AppendChild($statEl); } } - + return $doc; } function TeamCity-WriteInfoDocument([xml]$doc) { $dir=(Split-Path $buildFile) $path=(Join-Path $dir 'teamcity-info.xml') - + $doc.Save($path); } \ No newline at end of file diff --git a/visualstudio.psm1 b/visualstudio.psm1 index e03afb6..82b88df 100644 --- a/visualstudio.psm1 +++ b/visualstudio.psm1 @@ -18,12 +18,12 @@ function Get-CsprojDependencies { Returns list of C# projects and its dependencies. .Description Returns list of C# projects and its dependencies. The dependencies include also dependencies on binaries. - If a solution contains project A and project B and both copy its output to directory \bin and + If a solution contains project A and project B and both copy its output to directory \bin and project B depends on \bin\A.dll then there is dependency of B on A, that is not explicit. This function is able to find this dependencies and list them as well. The example is very simple but in real world, with very projects with more solutions, it is likely - that there will be some projects that depend on each other through this dependencies. - + that there will be some projects that depend on each other through this dependencies. + This function helps you determine correct order how the projects should be built. #> param( @@ -38,59 +38,59 @@ function Get-CsprojDependencies { } process { Write-Debug "Reading csproj $Csprojs.." - $Csprojs | % { + $Csprojs | % { $content = [xml](gc $_.FullName) if (!($content.Project)) { Write-Warning "Project $($_.FullName) skipped. Does not contain root tag with name Project." return } - + Write-Debug "Reading $($_.FullName)" $ret = New-Object PSObject -prop @{FullName=$_.fullname; References=''; AssemblyName='' } - + $ns = @{'e'="http://schemas.microsoft.com/developer/msbuild/2003" } $ret.References = @( @(Select-Xml -Xml $content -XPath '//e:ProjectReference' -Namespace $ns) | - select -ExpandProperty Node | - select -ExpandProperty Include | + select -ExpandProperty Node | + select -ExpandProperty Include | % { Resolve-Path (Join-Path (Split-Path $ret.FullName -Parent) $_ ) }) $ret.AssemblyName = Select-Xml -Xml $content -XPath '//e:AssemblyName' -Namespace $ns | - select -ExpandProperty Node -First 1 | + select -ExpandProperty Node -First 1 | select -ExpandProperty '#text' - + # processing references to bin @(Select-Xml -Xml $content -XPath '//e:Reference' -Namespace $ns) | - select -ExpandProperty Node | + select -ExpandProperty Node | ? { $_.HintPath} | - select -ExpandProperty HintPath | + select -ExpandProperty HintPath | % { $assemblyName = [IO.Path]::GetFileNameWithoutExtension($_) # e.g. Gmc.System - if (!$binReference.ContainsKey($assemblyName)) { + if (!$binReference.ContainsKey($assemblyName)) { $binReference[$assemblyName] = @() } $binReference[$assemblyName] += $ret } - + $infos += $ret - + Write-Debug "Count of referencies: $($ret.References.Count)" } } - + end { write-Debug "End" #resolve dependencies by assembly - $binReference.Keys | + $binReference.Keys | % { $assemblyName = $_ $assemblyCsproj = $infos | ? { $_.AssemblyName -eq $assemblyName } - if (!$assemblyCsproj) { + if (!$assemblyCsproj) { $assemblyName } else { $binReference[$assemblyName] | % { $_.References += $assemblyCsproj.FullName } } - } | - sort | + } | + sort | % -Begin { Write-Verbose "These assemblies are referenced but don't have related projects" } ` -Process { Write-Verbose " $_" } $infos @@ -112,10 +112,10 @@ function Get-CsprojIncludedFiles { ) process { $nm = @{n='http://schemas.microsoft.com/developer/msbuild/2003' } - $Csproj | % { - [xml](gc $_.FullName) | + $Csproj | % { + [xml](gc $_.FullName) | Select-Xml -xpath '//n:ItemGroup/n:Compile' -Namespace $nm | - Select-Object -exp Node | + Select-Object -exp Node | Select-Object -exp Include | % { Join-Path (Split-Path $Csproj) $_ } } @@ -143,8 +143,8 @@ function Get-CsprojInfo { [IO.FileInfo[]] $Csproj ) - process { - $Csproj | % { + process { + $Csproj | % { $xml = [xml](gc $_.FullName) new-object PSObject -property @{ Path = $_.FullName @@ -174,8 +174,8 @@ function Get-CsprojsFromSln # parses Remote.Api\Gtr.Remote.Api.csproj $r = New-Object text.regularexpressions.regex '^Project\([^)]+\)\s*=\s*"[^"]+",\s*"(?[^"]+)"', 'multiline' $content = (Get-Content $SlnPath) -join "`r`n" - $r.Matches($content) | - % { $_.Groups["csprojPath"].Value} | + $r.Matches($content) | + % { $_.Groups["csprojPath"].Value} | ? { $_.EndsWith(".csproj") } | % { if ($FullPaths) { join-path (split-path $SlnPath) $_