|
| 1 | +# BUILDCORECLR |
| 2 | + |
| 3 | +$projectRoot = $PSScriptRoot |
| 4 | +$destinationDir = Join-Path -Path $projectRoot -ChildPath (Join-Path -Path "out" -ChildPath "PSScriptAnalyzer") |
| 5 | +function Publish-File |
| 6 | +{ |
| 7 | + param ([string[]]$itemsToCopy, [string]$destination) |
| 8 | + if (-not (Test-Path $destination)) |
| 9 | + { |
| 10 | + $null = New-Item -ItemType Directory $destination -Force |
| 11 | + } |
| 12 | + foreach ($file in $itemsToCopy) |
| 13 | + { |
| 14 | + Copy-Item -Path $file -Destination (Join-Path $destination (Split-Path $file -Leaf)) -Force |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +function Uninstall-ScriptAnalyzer |
| 19 | +{ |
| 20 | + |
| 21 | +} |
| 22 | + |
| 23 | +# attempt to get the users module directory |
| 24 | +function Get-UserModulePath |
| 25 | +{ |
| 26 | + if ( $IsCoreCLR -and ! $IsWindows ) |
| 27 | + { |
| 28 | + $platformType = "System.Management.Automation.Platform" -as [Type] |
| 29 | + if ( $platformType ) { |
| 30 | + ${platformType}::SelectProductNameForDirectory("USER_MODULES") |
| 31 | + } |
| 32 | + else { |
| 33 | + throw "Could not determine users module path" |
| 34 | + } |
| 35 | + } |
| 36 | + else { |
| 37 | + "${HOME}/Documents/WindowsPowerShell/Modules" |
| 38 | + } |
| 39 | + |
| 40 | +} |
| 41 | + |
| 42 | +# install script analyzer, by default into the users module path |
| 43 | +function Install-ScriptAnalyzer |
| 44 | +{ |
| 45 | + [CmdletBinding(SupportsShouldProcess)] |
| 46 | + param ( $ModulePath = $(Join-Path -Path (Get-UserModulePath) -ChildPath PSScriptAnalyzer) ) |
| 47 | + |
| 48 | + #Write-Progress "Installing to $modulePath" |
| 49 | + Copy-Item -Recurse -Path "$destinationDir" -Destination "$ModulePath\." -Force |
| 50 | +} |
| 51 | + |
| 52 | +# if script analyzer is installed, remove it |
| 53 | +function Uninstall-ScriptAnalyzer |
| 54 | +{ |
| 55 | + [CmdletBinding(SupportsShouldProcess)] |
| 56 | + param ( $ModulePath = $(Join-Path -Path (Get-UserModulePath) -ChildPath PSScriptAnalyzer) ) |
| 57 | + $ |
| 58 | + if (Test-Path $ModulePath -and (Get-Item $ModulePath).PSIsContainer ) |
| 59 | + { |
| 60 | + Remove-Item -Force -Recurse $ModulePath |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +# Build documentation using platyPS |
| 65 | +function Build-Doc |
| 66 | +{ |
| 67 | + $docsPath = Join-Path $projectRoot docs |
| 68 | + $markdownDocsPath = Join-Path $docsPath markdown |
| 69 | + $outputDocsPath = Join-Path $destinationDir en-US |
| 70 | + $requiredVersionOfplatyPS = 0.9 |
| 71 | + $modInfo = new-object Microsoft.PowerShell.Commands.ModuleSpecification -ArgumentList @{ ModuleName = "platyps"; ModuleVersion = $requiredVersionOfplatyPS} |
| 72 | + if ( $null -eq (Get-Module -ListAvailable -FullyQualifiedName $modInfo)) |
| 73 | + { |
| 74 | + throw "Cannot find required minimum version $requiredVersionOfplatyPS of platyPS. Install via 'Install-Module platyPS'" |
| 75 | + } |
| 76 | + if (-not (Test-Path $markdownDocsPath)) |
| 77 | + { |
| 78 | + throw "Cannot find markdown documentation folder." |
| 79 | + } |
| 80 | + Import-Module platyPS |
| 81 | + if ( ! (Test-Path $outputDocsPath)) { |
| 82 | + $null = New-Item -Type Directory -Path $outputDocsPath -Force |
| 83 | + } |
| 84 | + $null = New-ExternalHelp -Path $markdownDocsPath -OutputPath $outputDocsPath -Force |
| 85 | +} |
| 86 | + |
| 87 | +# Clean up the build location |
| 88 | +function Remove-Build |
| 89 | +{ |
| 90 | + [CmdletBinding(SupportsShouldProcess=$true)] |
| 91 | + param () |
| 92 | + $ |
| 93 | + if ( $PSCmdlet.ShouldProcess("${destinationDir}")) { |
| 94 | + if ( test-path -dir ${destinatationDir} ) { |
| 95 | + Remove-Item -Force -Recurse ${destinationDir} |
| 96 | + } |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +# build script analyzer (and optionally build everything with -All) |
| 101 | +function Build-ScriptAnalyzer |
| 102 | +{ |
| 103 | + [CmdletBinding(DefaultParameterSetName="BuildOne")] |
| 104 | + param ( |
| 105 | + [Parameter(ParameterSetName="BuildAll")] |
| 106 | + [switch]$All, |
| 107 | + |
| 108 | + [Parameter(ParameterSetName="BuildOne")] |
| 109 | + [ValidateSet("full", "core")] |
| 110 | + [string]$Framework = "core", |
| 111 | + |
| 112 | + [Parameter(ParameterSetName="BuildOne")] |
| 113 | + [ValidateSet("PSv3","PSv4","PSv5")] |
| 114 | + [string]$AnalyzerVersion = "PSv5", |
| 115 | + |
| 116 | + [Parameter(ParameterSetName="BuildOne")] |
| 117 | + [ValidateSet("Debug", "Release")] |
| 118 | + [string]$Configuration = "Debug", |
| 119 | + |
| 120 | + [Parameter(ParameterSetName="BuildDoc")] |
| 121 | + [switch]$Documentation |
| 122 | + ) |
| 123 | + |
| 124 | + if ( $All ) |
| 125 | + { |
| 126 | + # Build all the versions of the analyzer |
| 127 | + Build-ScriptAnalyzer -Framework full -Configuration $Configuration -AnalyzerVersion "PSv3" |
| 128 | + Build-ScriptAnalyzer -Framework full -Configuration $Configuration -AnalyzerVersion "PSv4" |
| 129 | + Build-ScriptAnalyzer -Framework full -Configuration $Configuration -AnalyzerVersion "PSv5" |
| 130 | + Build-ScriptAnalyzer -Framework core -Configuration $Configuration -AnalyzerVersion "PSv5" |
| 131 | + Build-ScriptAnalyzer -Documentation |
| 132 | + return |
| 133 | + } |
| 134 | + |
| 135 | + if ( $Documentation ) |
| 136 | + { |
| 137 | + Build-Doc |
| 138 | + return |
| 139 | + } |
| 140 | + |
| 141 | + Push-Location -Path $projectRoot |
| 142 | + |
| 143 | + if ( $framework -eq "core" ) { |
| 144 | + $frameworkName = "netstandard2.0" |
| 145 | + } |
| 146 | + else { |
| 147 | + $frameworkName = "net451" |
| 148 | + } |
| 149 | + |
| 150 | + # build the appropriate assembly |
| 151 | + if ($AnalyzerVersion -match "PSv3|PSv4" -and $Framework -eq "core") |
| 152 | + { |
| 153 | + throw ("ScriptAnalyzer Version '{0}' is not applicable to {1} framework" -f $AnalyzerVersion,$Framework) |
| 154 | + } |
| 155 | + |
| 156 | + #Write-Progress "Building ScriptAnalyzer" |
| 157 | + if (-not (Test-Path "$projectRoot/global.json")) |
| 158 | + { |
| 159 | + throw "Not in solution root" |
| 160 | + } |
| 161 | + |
| 162 | + $itemsToCopyCommon = @( |
| 163 | + "$projectRoot\Engine\PSScriptAnalyzer.psd1", "$projectRoot\Engine\PSScriptAnalyzer.psm1", |
| 164 | + "$projectRoot\Engine\ScriptAnalyzer.format.ps1xml", "$projectRoot\Engine\ScriptAnalyzer.types.ps1xml" |
| 165 | + ) |
| 166 | + |
| 167 | + $settingsFiles = Get-Childitem "$projectRoot\Engine\Settings" | ForEach-Object -MemberName FullName |
| 168 | + |
| 169 | + $destinationDir = "$projectRoot\out\PSScriptAnalyzer" |
| 170 | + # this is normalizing case as well as selecting the proper location |
| 171 | + if ( $Framework -eq "core" ) { |
| 172 | + $destinationDirBinaries = "$destinationDir\coreclr" |
| 173 | + } |
| 174 | + elseif ($AnalyzerVersion -eq 'PSv3') { |
| 175 | + $destinationDirBinaries = "$destinationDir\PSv3" |
| 176 | + } |
| 177 | + elseif ($AnalyzerVersion -eq 'PSv4') { |
| 178 | + $destinationDirBinaries = "$destinationDir\PSv4" |
| 179 | + } |
| 180 | + else { |
| 181 | + $destinationDirBinaries = $destinationDir |
| 182 | + } |
| 183 | + |
| 184 | + # build the analyzer |
| 185 | + #Write-Progress "Building for framework $Framework, configuration $Configuration" |
| 186 | + # The Rules project has a dependency on the Engine therefore just building the Rules project is enough |
| 187 | + try { |
| 188 | + Push-Location $projectRoot/Rules |
| 189 | + Write-Progress "Building ScriptAnalyzer '$framework' version '${AnalyzerVersion}' configuration '${Configuration}'" |
| 190 | + $buildOutput = dotnet build Rules.csproj --framework $frameworkName --configuration "${AnalyzerVersion}${Configuration}" |
| 191 | + if ( $LASTEXITCODE -ne 0 ) { throw "$buildOutput" } |
| 192 | + } |
| 193 | + catch { |
| 194 | + Write-Error "Failure to build $framework ${AnalyzerVersion}${Configuration}" |
| 195 | + return |
| 196 | + } |
| 197 | + finally { |
| 198 | + Pop-Location |
| 199 | + } |
| 200 | + |
| 201 | + #Write-Progress "Copying files to $destinationDir" |
| 202 | + Publish-File $itemsToCopyCommon $destinationDir |
| 203 | + |
| 204 | + $itemsToCopyBinaries = @( |
| 205 | + "$projectRoot\Engine\bin\${AnalyzerVersion}${Configuration}\${frameworkName}\Microsoft.Windows.PowerShell.ScriptAnalyzer.dll", |
| 206 | + "$projectRoot\Rules\bin\${AnalyzerVersion}${Configuration}\${frameworkName}\Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.dll" |
| 207 | + ) |
| 208 | + Publish-File $itemsToCopyBinaries $destinationDirBinaries |
| 209 | + |
| 210 | + Publish-File $settingsFiles (Join-Path -Path $destinationDir -ChildPath Settings) |
| 211 | + |
| 212 | + # copy newtonsoft dll if net451 framework |
| 213 | + if ($Framework -eq "full") { |
| 214 | + Copy-Item -path "$projectRoot\Rules\bin\${AnalyzerVersion}${Configuration}\${frameworkName}\Newtonsoft.Json.dll" -Destination $destinationDirBinaries |
| 215 | + } |
| 216 | + |
| 217 | + Pop-Location |
| 218 | +} |
| 219 | + |
| 220 | +# Run our tests |
| 221 | +function Test-ScriptAnalyzer |
| 222 | +{ |
| 223 | + [CmdletBinding()] |
| 224 | + $testModulePath = Join-Path "${projectRoot}" -ChildPath out |
| 225 | + $testResultsFile = Join-Path ${projectRoot} -childPath TestResults.xml |
| 226 | + $testScripts = "${projectRoot}\Tests\Engine,${projectRoot}\Tests\Rules,${projectRoot}\Tests\Documentation" |
| 227 | + try { |
| 228 | + $savedModulePath = $env:PSModulePath |
| 229 | + $env:PSModulePath = "${testModulePath}{0}${env:PSModulePath}" -f [System.IO.Path]::PathSeparator |
| 230 | + $scriptBlock = [scriptblock]::Create("Invoke-Pester -Path $testScripts -OutputFormat NUnitXml -OutputFile $testResultsFile -Show Describe") |
| 231 | + Write-Verbose -verbose "$scriptBlock" |
| 232 | + $powershell = (Get-Process -id $PID).MainModule.FileName |
| 233 | + & ${powershell} -Command $scriptBlock |
| 234 | + } |
| 235 | + finally { |
| 236 | + $env:PSModulePath = $savedModulePath |
| 237 | + } |
| 238 | +} |
| 239 | + |
| 240 | +# a simple function to make it easier to retrieve the test results |
| 241 | +function Get-TestResults |
| 242 | +{ |
| 243 | + param ( $logfile = (Join-Path -Path ${projectRoot} -ChildPath TestResults.xml) ) |
| 244 | + $logPath = (Resolve-Path $logfile).Path |
| 245 | + $results = [xml](Get-Content $logPath) |
| 246 | + $results.SelectNodes(".//test-case") |
| 247 | +} |
| 248 | + |
| 249 | +# a simple function to make it easier to retrieve the failures |
| 250 | +# it's not a filter of the results of Get-TestResults because this is faster |
| 251 | +function Get-TestFailures |
| 252 | +{ |
| 253 | + param ( $logfile = (Join-Path -Path ${projectRoot} -ChildPath TestResults.xml) ) |
| 254 | + $logPath = (Resolve-Path $logfile).Path |
| 255 | + $results = [xml](Get-Content $logPath) |
| 256 | + $results.SelectNodes(".//test-case[@result='Failure']") |
| 257 | +} |
0 commit comments