Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update, simplify, and consolidate build scripts #1082

Merged
merged 17 commits into from
Oct 23, 2018
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,10 @@ FakesAssemblies/
*.opt

##Our project binplace location
PSScriptAnalyzer/
PSScriptAnalyzer/

# Vim swap files
*.swp

# Test result file
TestResults.xml
43 changes: 32 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,33 @@ Note: the PSScriptAnalyzer Chocolatey package is provided and supported by the c
* Building

You can either build using the `Visual Studio` solution `PSScriptAnalyzer.sln` or build using `PowerShell` specifically for your platform as follows:
* Windows PowerShell version 5.0 and greater
* The default build is for PowerShell Core
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the sake of argument, should the default build be for the current platform the script is being run on? That's possibly an order of magnitude harder to accomplish, but thought I would bring it up.

Copy link
Collaborator

@bergmeister bergmeister Oct 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for that but I see it as an optional nice to have that could come after this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) why would anyone be using anything other than core? :)

```powershell
.\buildCoreClr.ps1 -Framework net451 -Configuration Release -Build
.\build.ps1
```
* Windows PowerShell version 5.0
```powershell
.\build.ps1 -Framework full -PSVersion 5 -Configuration Release
```
* Windows PowerShell version 4.0
```powershell
.\buildCoreClr.ps1 -Framework net451 -Configuration PSV4Release -Build
.\build.ps1 -Framework full -PSVersion 4 -Configuration Release
```
* Windows PowerShell version 3.0
```powershell
.\buildCoreClr.ps1 -Framework net451 -Configuration PSV3Release -Build
.\build.ps1 -Framework full -PSVersion 3 -Configuration Release
```
* PowerShell Core
```powershell
.\buildCoreClr.ps1 -Framework netstandard2.0 -Configuration Release -Build
.\buildCoreClr.ps1 -Framework core -Configuration Release -Build
```
* Build documentation
```powershell
.\build.ps1 -Documentation
```
* Build documenatation
* Build all versions (PowerShell v3, v4, v5, and Core) and documentation
```powershell
.\build.ps1 -BuildDocs
.\build.ps1 -All
```
* Import the module
```powershell
Expand All @@ -157,12 +165,25 @@ For adding/removing resource strings in the `*.resx` files, it is recommended to
#### Tests
Pester-based ScriptAnalyzer Tests are located in `path/to/PSScriptAnalyzer/Tests` folder.

* Ensure [Pester 4.3.1](https://www.powershellgallery.com/packages/Pester/4.3.1) is installed
* Copy `path/to/PSScriptAnalyzer/out/PSScriptAnalyzer` to a folder in `PSModulePath`
* Ensure [Pester 4.3.1](https://www.powershellgallery.com/packages/Pester/4.3.1) or higher is installed
* Ensure that the documentation has been built (`./build.ps1 -Documentation`)
* In the root folder of your local repository, run:
``` PowerShell
$testScripts = ".\Tests\Engine",".\Tests\Rules",".\Tests\Documentation"
Invoke-Pester -Script $testScripts
./build -Test
```

To retrieve the results of the run, you can use the tools which are part of the build module (`build.psm1`)

```powershell
Import-Module ./build.psm1
Get-TestResults
```

To retrieve only the errors, you can use the following:

```powershell
Import-Module ./build.psm1
Get-TestFailures
```

[Back to ToC](#table-of-contents)
Expand Down
4 changes: 2 additions & 2 deletions Tests/Engine/CustomizedRule.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Describe "Test importing correct customized rules" {
It "will show the custom rules when given a glob" {
# needs fixing for Linux
$expectedNumRules = 4
if ($IsLinux -or $IsMacOS)
if ($IsLinux)
{
$expectedNumRules = 3
}
Expand All @@ -113,7 +113,7 @@ Describe "Test importing correct customized rules" {
It "will show the custom rules when given glob with recurse switch" {
# needs fixing for Linux
$expectedNumRules = 5
if ($IsLinux -or $IsMacOS)
if ($IsLinux)
{
$expectedNumRules = 4
}
Expand Down
215 changes: 52 additions & 163 deletions build.ps1
Original file line number Diff line number Diff line change
@@ -1,183 +1,72 @@
# This function might be a partially out of date and only the -BuildDoc switch is guaranteed to work since it is used and needed for the build process.
[CmdletBinding()]
param(
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

[Parameter(ParameterSetName='Build')]
[ValidateSet('PSV3 Debug','PSV3 Release','Debug','Release')]
[string] $Configuration = 'Debug',
[CmdletBinding(DefaultParameterSetName="BuildOne")]
param(
[Parameter(ParameterSetName="BuildAll")]
[switch]$All,

[Parameter(ParameterSetName='Build')]
[switch] $BuildDocs = $false,
[Parameter(ParameterSetName="BuildOne")]
[ValidateSet("full", "core")]
[string]$Framework = "core",

[Parameter(ParameterSetName='Build')]
[switch] $CleanOutput = $false,
[Parameter(ParameterSetName="BuildOne")]
[ValidateSet("3","4","5")]
[string]$PSVersion = "5",

[Parameter(ParameterSetName='Build')]
[switch] $Install = $false,
[Parameter(ParameterSetName="BuildOne")]
[Parameter(ParameterSetName="BuildAll")]
[ValidateSet("Debug", "Release")]
[string]$Configuration = "Debug",

[Parameter(ParameterSetName='Build')]
[switch] $Uninstall = $false,
[Parameter(ParameterSetName="BuildDoc")]
[switch]$Documentation,

[Parameter(ParameterSetName='Test')]
[switch] $Test = $false,
[Parameter(ParameterSetName='BuildAll')]
[Parameter(ParameterSetName='BuildOne')]
[switch]$Clobber,

[Parameter(ParameterSetName='Test')]
[switch] $Engine = $false,
[Parameter(Mandatory=$true,ParameterSetName='Clean')]
[switch] $Clean,

[Parameter(ParameterSetName='Test')]
[switch] $Rules = $false,
[Parameter(Mandatory=$true,ParameterSetName='Test')]
[switch] $Test,

[Parameter(ParameterSetName='Test')]
[switch] $RunInDifferentProcess = $false
[switch] $InProcess
)

# Some cmdlets like copy-item do not respond to the $verbosepreference variable
# hence we set it explicitly
$verbosity = $false
if ($VerbosePreference.Equals([System.Management.Automation.ActionPreference]'Continue'))
{
$verbosity = $true
}

Function CreateIfNotExists([string] $folderPath)
{
if (-not (Test-Path $folderPath))
{
New-Item -Path $folderPath -ItemType Directory -Verbose:$verbosity
}
}

$projectRoot = Resolve-path (Split-Path $MyInvocation.InvocationName)
$solutionPath = Join-Path $projectRoot 'PSScriptAnalyzer.sln'
$outPath = Join-Path $projectRoot 'out'
$destinationPath = Join-Path $outPath PSScriptAnalyzer

if (-not (Test-Path $solutionPath))
{
$errMsg = "{0} not the right directory" -f $solutionPath
throw $errMsg
}

if ($CleanOutput)
{
Remove-Item -Recurse $outPath\* -Force -Verbose:$verbosity
}

if ($BuildDocs)
{
$docsPath = Join-Path $projectRoot 'docs'
$markdownDocsPath = Join-Path $docsPath 'markdown'
$outputDocsPath = Join-Path $destinationPath en-US

CreateIfNotExists($outputDocsPath)

# Build documentation using platyPS
$requiredVersionOfplatyPS = 0.9
if ($null -eq (Get-Module platyPS -ListAvailable -Verbose:$verbosity | Where-Object { $_.Version -ge $requiredVersionOfplatyPS }))
{
"Cannot find required minimum version $requiredVersionOfplatyPS of platyPS. Please install it from https://www.powershellgallery.com/packages/platyPS/ using e.g. the following command: Install-Module platyPS"
}
if ($null -eq (Get-Module platyPS -Verbose:$verbosity))
{
Import-Module platyPS -Verbose:$verbosity
}
if (-not (Test-Path $markdownDocsPath -Verbose:$verbosity))
{
throw "Cannot find markdown documentation folder."
}
New-ExternalHelp -Path $markdownDocsPath -OutputPath $outputDocsPath -Force -Verbose:$verbosity
}

# Appveyor errors out due to $profile being null. Hence...
$moduleRootPath = "$HOME/Documents/WindowsPowerShell/Modules"
if ($null -ne $profile)
{
$moduleRootPath = Join-Path (Split-Path $profile) 'Modules'
}
$modulePSSAPath = Join-Path $moduleRootPath 'PSScriptAnalyzer'
if ($Install)
{
if (-not (Test-Path $moduleRootPath))
{
New-Item -Path $moduleRootPath -ItemType Directory -Force -Verbose:$verbosity
}
if (-not (Test-Path -Path $destinationPath))
{
throw "Please build the module first."
}
Copy-Item -Path $destinationPath -Destination $modulePSSAPath -Recurse -Verbose:$verbosity
}

if ($Test)
{
Import-Module -Name Pester -MinimumVersion 4.3.1 -ErrorAction Stop
Function GetTestRunnerScriptContent($testPath)
{
$x = @"
cd $testPath
Invoke-Pester
"@
return $x
}

Function CreateTestRunnerScript($testPath)
{
$tmptmpFilePath = [System.IO.Path]::GetTempFileName()
$tmpFilePath = $tmptmpFilePath + '.ps1'
Move-Item $tmptmpFilePath $tmpFilePath -Verbose:$verbosity
$content = GetTestRunnerScriptContent $testPath
Set-Content -Path $tmpFilePath -Value $content -Verbose:$verbosity
return $tmpFilePath
}

Function GetTestPath($TestType)
{
if ($TestType -eq "engine")
{
$testPath = Join-Path $projectRoot "Tests/Engine"
}
else
{
$testPath = Join-Path $projectRoot "Tests/Rules"
END {
Import-Module -Force (Join-Path $PSScriptRoot build.psm1)
if ( $Clean -or $Clobber ) {
Remove-Build
if ( $PSCmdlet.ParameterSetName -eq "Clean" ) {
return
}
return $testPath
}

Function RunTest($TestType, [Boolean] $DifferentProcess)
{
$testPath = GetTestPath($TestType)
if ($DifferentProcess)
{
$testScriptFilePath = CreateTestRunnerScript $testPath
Start-Process powershell -ArgumentList "-NoExit","-File $testScriptFilePath" -Verb runas
# clean up the test file
$setName = $PSCmdlet.ParameterSetName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is used above, maybe it's worth assigning above, below the Import-Module line?

switch ( $setName ) {
"BuildAll" {
Build-ScriptAnalyzer -All -Configuration $Configuration
}
else
{
try
{
Push-Location .
([scriptblock]::Create((GetTestRunnerScriptContent $testPath))).Invoke()
}
finally
{
Pop-Location

"BuildDoc" {
Build-ScriptAnalyzer -Documentation
}
"BuildOne" {
$buildArgs = @{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: I find I do this a lot in PowerShell as well (pass arguments down through commands). Perhaps it's an antipattern (Law of Demeter violation type of thing), but it would be nice to introduce a simpler way for commands to "inherit" all the common parameters between it and its caller (which haven't been overridden).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i often create a hash earlier in the script and then modify it based on conditions.

Framework = $Framework
PSVersion = $PSVersion
Configuration = $Configuration
}
Build-ScriptAnalyzer @buildArgs
}
"Test" {
Test-ScriptAnalyzer -InProcess:$InProcess
return
}
default {
throw "Unexpected parameter set '$setName'"
}
}

if ($Engine -or (-not ($Engine -or $Rules)))
{
RunTest 'engine' $RunInDifferentProcess
}
if ($Rules -or (-not ($Engine -or $Rules)))
{
RunTest 'rules' $RunInDifferentProcess
}
}

if ($Uninstall)
{
Remove-Item -Path $modulePSSAPath -Force -Verbose:$verbosity -Recurse
}
Loading