Skip to content

Commit cab2708

Browse files
committed
consolidate build of script analyzer into module
Require any 2.1 sdk for building, this way we can build with the same sdk as PowerShell core
1 parent 789151c commit cab2708

File tree

2 files changed

+258
-1
lines changed

2 files changed

+258
-1
lines changed

build.psm1

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
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+
}

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"sdk": {
3-
"version": "2.1.101"
3+
"version": "2.1.400"
44
}
55
}

0 commit comments

Comments
 (0)