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

Feature splathash & build refactor #63

Merged
merged 6 commits into from
Sep 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions InvokeBuild.ps1 → Build/InvokeBuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ task Test Init, {
task Build Test, {
$lines

Set-Location $ProjectRoot
# Load the module, read the exported functions, update the psd1 FunctionsToExport
Set-ModuleFunctions

Expand Down
16 changes: 16 additions & 0 deletions Build/Start-Build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
param(
$Task = 'Build' # build is the default task, add support to deploy later
)

# dependencies
Get-PackageProvider -Name NuGet -ForceBootstrap | Out-Null
if(-not (Get-Module -ListAvailable PSDepend))
{
& (Resolve-Path "$PSScriptRoot\helpers\Install-PSDepend.ps1")
}
Import-Module PSDepend
$null = Invoke-PSDepend -Path "$PSScriptRoot\build.requirements.psd1" -Install -Import -Force

Set-BuildEnvironment -Force

Invoke-Build -File $PSScriptRoot\InvokeBuild.ps1 -Task $Task
14 changes: 14 additions & 0 deletions Build/build.requirements.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@{
# Some defaults for all dependencies
PSDependOptions = @{
Target = '$ENV:USERPROFILE\Documents\WindowsPowerShell\Modules'
AddToPath = $True
}

# Grab some modules without depending on PowerShellGet
'InvokeBuild' = @{ DependencyType = 'PSGalleryNuget' }
'PSDeploy' = @{ DependencyType = 'PSGalleryNuget' }
'BuildHelpers' = @{ DependencyType = 'PSGalleryNuget' }
'Pester' = @{ DependencyType = 'PSGalleryNuget' }
'PSScriptAnalyzer' = @{ DependencyType = 'PSGalleryNuget' }
}
50 changes: 50 additions & 0 deletions Build/helpers/Install-PSDepend.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<#
.SYNOPSIS
Bootstrap PSDepend

.DESCRIPTION
Bootstrap PSDepend

Why? No reliance on PowerShellGallery

* Downloads nuget to your ~\ home directory
* Creates $Path (and full path to it)
* Downloads module to $Path\PSDepend
* Moves nuget.exe to $Path\PSDepend (skips nuget bootstrap on initial PSDepend import)

.PARAMETER Path
Module path to install PSDepend

Defaults to Profile\Documents\WindowsPowerShell\Modules

.EXAMPLE
.\Install-PSDepend.ps1 -Path C:\Modules

# Installs to C:\Modules\PSDepend
#>
[cmdletbinding()]
param(
[string]$Path = $( Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'WindowsPowerShell\Modules')
)
$ExistingProgressPreference = "$ProgressPreference"
$ProgressPreference = 'SilentlyContinue'
try {
# Bootstrap nuget if we don't have it
if(-not ($NugetPath = (Get-Command 'nuget.exe' -ErrorAction SilentlyContinue).Path)) {
$NugetPath = Join-Path $ENV:USERPROFILE nuget.exe
if(-not (Test-Path $NugetPath)) {
Invoke-WebRequest -uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -OutFile $NugetPath
}
}

# Bootstrap PSDepend, re-use nuget.exe for the module
if($path) { $null = mkdir $path -Force }
$NugetParams = 'install', 'PSDepend', '-Source', 'https://www.powershellgallery.com/api/v2/',
'-ExcludeVersion', '-NonInteractive', '-OutputDirectory', $Path
& $NugetPath @NugetParams
Move-Item -Path $NugetPath -Destination "$(Join-Path $Path PSDepend)\nuget.exe" -Force
}
finally {
$ProgressPreference = $ExistingProgressPreference
}

File renamed without changes.
24 changes: 24 additions & 0 deletions PSRemotely/private/ConfigurationData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,27 @@ function ConvertPSObjectToHashtable
}
}
}


Function Sanitize-PesterSplatHash {
[CmdletBinding()]
param(
# Pass the Pester splat hash to be modified
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[HashTable]$SplatHash
)

# Filter our the conflicting keys from the PesterSplathash
# Keys to remove - Script, PassThru, Quiet, OutputFormat, OutPutFile
$ExcludeKeys = @('Script','PassThru','Quiet','OutputFormat','OutputFile')
$CloneHash = $SplatHash.Clone()
Foreach ($Key in $CloneHash.Keys) {
# process each key present in the splat hash
if ($ExcludeKeys -contains $Key) {
# remove this key and value
Write-Warning -Message "Key $Key found in the SplatHash. Removing it"
$SplatHash.Remove($Key)
}
}
}
48 changes: 41 additions & 7 deletions PSRemotely/public/Invoke-PSRemotely.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,19 @@ Function Invoke-PSRemotely {
]
}


.PARAMETER PesterSplatHash
Pass a hash table which is splatted to Invoke-Pester's execution on the PSRemotely node.
This let's you pass arguments to Invoke-Pester such as -Tag, -ExcludeTag, -Strict etc.
Note - PSRemotely automatically supplies the below arguments to Invoke-Pester. So if these are
specified then it will be ignored.

Script = <Based on the input this gets passed to Pester>
PassThru = $True;
Quiet = $True;
OutputFormat = 'NunitXML';
OutputFile = <NodeName>.xml;


.EXAMPLE
PS> Invoke-PSRemotely

Expand Down Expand Up @@ -101,7 +113,7 @@ Function Invoke-PSRemotely {
#>
[CmdletBinding(DefaultParameterSetName='BootStrap',SupportsShouldProcess=$True)]
param(
[Parameter(Position=-0,
[Parameter(Position=0,
Mandatory=$False,
ParameterSetName='BootStrap',
ValueFromPipeline=$true)]
Expand All @@ -110,7 +122,12 @@ Function Invoke-PSRemotely {
[Parameter(Position=0,
Mandatory=$true,
ParameterSetName='JSON')]
[String]$JSONInput
[String]$JSONInput,

[Parameter(Position=1,
Mandatory=$False)]
[Alias('SplatHash')]
[HashTable]$PesterSplatHash

)
BEGIN {
Expand All @@ -137,14 +154,19 @@ Function Invoke-PSRemotely {
Select-Object -ExpandProperty Value |
Select-Object -ExpandProperty Session

# Check if the Pester splat hash was passed
if ($PesterSplatHash) {
Sanitize-PesterSplatHash -SplatHash $PesterSplatHash
}
# build the splat hashtable
$invokeTestParams = @{
Session = $session;
ArgumentList = $JSONInput, $Object.NodeName #@(,$Object.Tests.Name);
ArgumentList = $JSONInput, $Object.NodeName, $PesterSplatHash #@(,$Object.Tests.Name);
ScriptBlock = {
param(
[String]$JSONString,
[String]$NodeName
[String]$NodeName,
[HashTable]$PesterSplatHash
)
$Object = ConvertFrom-Json -InputObject $JSONString
foreach ($test in @($Object.Tests.Name)) {
Expand All @@ -166,11 +188,22 @@ Function Invoke-PSRemotely {

$testFile = "$($Global:PSRemotely.PSRemotelyNodePath)\$testFileName"
$outPutFile = "{0}\{1}.{2}.xml" -f $PSRemotely.PSRemotelyNodePath, $nodeName, $test
$invokePesterParams = @{
PassThru = $True;
Quiet = $True;
OutputFormat = 'NunitXML';
OutputFile = $OutputFile
}

if ($PesterSplatHash) {
$invokePesterParams += $PesterSplatHash
}

if ($Node) {
Invoke-Pester -Script @{Path=$($TestFile); Parameters=@{Node=$Node}} -PassThru -Quiet -OutputFormat NUnitXML -OutputFile $outPutFile
Invoke-Pester -Script @{Path=$($TestFile); Parameters=@{Node=$Node}} @invokePesterParams
}
else {
Invoke-Pester -Script $testFile -PassThru -Quiet -OutputFormat NUnitXML -OutputFile $outPutFile
Invoke-Pester -Script $testFile @invokePesterParams
}
}
}; # end scriptBlock
Expand Down Expand Up @@ -209,6 +242,7 @@ Function Invoke-PSRemotely {
try {
do{
Write-VerboseLog -Message "Invoking test script -> $($testscript.path)"
# TODO pass the PesterSplatHash if specified in the command line
& $invokeTestScript -Path $testScript.Path -Arguments $testScript.Arguments -Parameters $testScript.Parameters
} until ($true)
}
Expand Down
43 changes: 43 additions & 0 deletions Tests/Unit/ConfigurationData.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,47 @@ InModuleScope -ModuleName $ENV:BHProjectName {
}
}
}

Describe "Sanitize-PesterSplatHash" -Tag UnitTest {

Context "Sanitizing the Splat hash" {
# Arrange
$SplatHash = @{
Script=".\test.ps1";
Tag = @('Dev','WebServers');
PassThru=$False;
Quiet=$True;
OutputFormat="XML";
OutputFile="dummy.xml";
TestName='Dummy test';
}
$OrigSplatHash = $SplatHash.Clone()
$ExcludedKeys = @('Script','PassThru','Quiet','OutputFormat','OutputFile')

# Act
$Result = Sanitize-PesterSplatHash -SplatHash $SplatHash

# Assert

foreach ($key in $OrigSplatHash.keys) {

if ($ExcludedKeys -contains $key) {
It "Should NOT have the reserved key -> $key in the Splat hash" {
$SplatHash.ContainsKey($key) | Should Be $False
}
}
else {
It "Should retain the non-reserved key -> $key in the Splat hash" {
$SplatHash.ContainsKey($key) | Should Be $True
}
}

}

It "Should not return anything" {
$Result | Should Be $Null
}

}
}
}
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ build: false

#Kick off the CI/CD pipeline
test_script:
- ps: . .\build.ps1
- ps: . .\build\Start-Build.ps1 -Task Build


# Block the RDP for debugging
#on_finish:
Expand Down
54 changes: 0 additions & 54 deletions build.ps1

This file was deleted.