Skip to content

Commit 27669fb

Browse files
committed
PS5 Compatibility
1 parent 24e19bf commit 27669fb

File tree

10 files changed

+306
-258
lines changed

10 files changed

+306
-258
lines changed

.vscode/tasks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"presentation": {
1818
"echo": true,
19-
"reveal": "silent",
19+
"reveal": "always",
2020
"focus": false,
2121
"panel": "shared",
2222
"showReuseMessage": true,

PotentialContribution/GitHub.psm1

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
Write-Debug "Path: $path"
2727
Push-Location
2828
Set-Location $Path
29-
29+
3030
#not safe!
3131
#populate what info we can from the path
3232
$username, $repo = ((git remote -v | ?{$_ -like "*(push)"}).replace('.git','') -split '\s+')[1].split("/") | select -last 2
@@ -37,7 +37,7 @@
3737
Write-Debug "Username: $username"
3838
Write-Debug "Repository: $repo"
3939
Write-Debug "Branch: $branch"
40-
40+
4141
$status = git status --short|?{$_ -match '(.)(.)\s+(.+)'} | %{[pscustomobject]@{X=$matches[1];Y=$matches[2];File=$matches[3]}}
4242
if($status)
4343
{
@@ -48,13 +48,13 @@
4848
}
4949
}
5050
Write-Verbose "Status: Committed and up to date"
51-
51+
5252
## update version and commit?
5353
## this will be replaced, just a test for commit purposes
5454
$psd1 = gi ((gi $path).name + ".psd1")
5555
Write-Debug "PSD1: $psd1"
5656

57-
57+
5858
$psd1data = (gc $psd1) | %{
5959
if($_ -match 'moduleversion\s*=(.+)')
6060
{
@@ -65,7 +65,7 @@
6565
$versionfull = "$versionshort.$(Get-Date -Format "yyyyMMdd.HHmm")"
6666
"ModuleVersion='$versionfull'"
6767
Write-Verbose "New Versioin: $versionfull"
68-
68+
6969
}
7070
else{$_}
7171
}
@@ -78,49 +78,49 @@
7878
Write-Verbose "Commiting version data"
7979
git commit -a -m "Release Commit - Version Tag $versionfull" | Out-Null
8080
git push origin $branch
81-
81+
8282
Write-Verbose "Creating tag"
8383
$tag = "V$versionshort"
8484
git tag -a $tag -m "Auto Release version $versionfull"
8585
git push --tags
8686

8787
Write-Verbose "Getting Github auth token"
8888
$token = Get-GitToken -Credential $Credential
89-
89+
9090
Write-Verbose "Creating the release"
9191
$GHRelease = New-GitHubRelease -username $username -repo $repo -token $token -tag $tag -branch $branch -Title $title -Description $Description -draft:$draft.IsPresent -Prerelease:$Prerelease.IsPresent
92-
92+
9393
## create a release folder, maybe clear it first?
94-
94+
9595
$releaseFolder = join-path $path Release
9696
Write-Verbose "Creating release folder"
97-
mkdir $releaseFolder -ea 0 | out-null
98-
97+
New-Item -ItemType Directory $releaseFolder -ea 0 | out-null
98+
9999
#create a folder for module files
100100
Write-Verbose "Creating copy of module"
101101
$modtemp = join-path $releaseFolder $moduleName
102102
Write-Debug "creating temp folder: $modtemp"
103-
mkdir $modtemp -ea 0 | Out-Null
103+
New-Item -ItemType Directory $modtemp -ea 0 | Out-Null
104104
#get all files
105105
$filenames = git ls-tree -r $branch --name-only | ? {$_ -notlike ".*"}
106106
$files = $filenames | %{join-path . $_} | gi
107107
#copy files to module temp/release location
108108
copy $files $modtemp
109-
110-
Write-Verbose "Signing moved files"
109+
110+
Write-Verbose "Signing moved files"
111111
if($Certificate)
112112
{
113113
gci $modtemp | Set-AuthenticodeSignature -Certificate $Certificate | Out-Null
114114
}
115115

116-
116+
117117
## create packages
118118
#poshcode/nuget/chocolatey
119119
ipmo $modtemp -Global
120120
sleep 1
121121
Write-Verbose "Creating nuget package"
122122
$nugetfiles = Compress-Module -Module $moduleName -OutputPath $releaseFolder -Force
123-
123+
124124
#exclude xml
125125
#todo: move packageinfo/nuspec to repo add/overwite etc
126126
#todo: rename nuget file to remove extend version info
@@ -191,7 +191,7 @@ function New-GitHubRepo {
191191
# The name of the Repository to create
192192
[Parameter(Mandatory=$true)]
193193
[String]$Name,
194-
# A short description of the repository
194+
# A short description of the repository
195195
[String]$Description,
196196
# A URL with more information about the repository
197197
[String]$Homepage,
@@ -298,4 +298,4 @@ function Get-GitToken {
298298
Write-Error "An unexpected error occurred (bad user/password?) $($Error[0])"
299299
}
300300
}
301-
}
301+
}

PotentialContribution/ModuleCreation.ps1

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ $helpPath = Join-Path $modulePath en-US
88

99
$HelpFile = Join-Path $helpPath "$moduleName.psm1-help.xml"
1010

11-
mkdir $helpPath -Force #create both module folder and help folder
11+
New-Item -ItemType Directory $helpPath -Force #create both module folder and help folder
1212

1313
New-ModuleManifest $modulePath -RootModule "$moduleName.psm1" -ModuleVersion 0.0.0.1
1414

15-
16-
1715
New-Item -Path $modulePath -Name "${moduleName}_${guid}_HelpInfo.xml" -ItemType File -Value "" ## templated, get guid from psd1
1816
New-Item -Path $helpPath -Name "$moduleName.psm1-help.xml" -ItemType File -Value "" #pull value from template some place
1917

@@ -23,4 +21,4 @@ New-Item -Path $helpPath -Name "$moduleName.psm1-help.xml" -ItemType File -Value
2321
## assumed variables based on Replace: $moduleName, $ShortDescription
2422

2523
iex ("@`"`n{0}`n`"@" -f (gc .\ReadMe.md -Raw)) | Out-File ReadMe.md
26-
cp .\module.psm1 $moduleName.psm1
24+
cp .\module.psm1 $moduleName.psm1

Source/Private/GetRelativePath.ps1

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
function GetRelativePath {
2+
<#
3+
.SYNOPSIS
4+
Returns the relative path, or $Path if the paths don't share the same root.
5+
For backward compatibility, this is [System.IO.Path]::GetRelativePath for .NET 4.x
6+
#>
7+
[CmdletBinding()]
8+
param(
9+
# The source path the result should be relative to. This path is always considered to be a directory.
10+
[Parameter(Mandatory)]
11+
[string]$RelativeTo,
12+
13+
# The destination path.
14+
[Parameter(Mandatory)]
15+
[string]$Path
16+
)
17+
18+
# This giant mess is because PowerShell drives aren't valid filesystem drives
19+
$Drive = $Path -replace "^([^\\/]+:[\\/])?.*", '$1'
20+
if ($Drive -ne ($RelativeTo -replace "^([^\\/]+:[\\/])?.*", '$1')) {
21+
Write-Verbose "Paths on different drives"
22+
return $Path # no commonality, different drive letters on windows
23+
}
24+
$RelativeTo = $RelativeTo -replace "^[^\\/]+:[\\/]", [IO.Path]::DirectorySeparatorChar
25+
$Path = $Path -replace "^[^\\/]+:[\\/]", [IO.Path]::DirectorySeparatorChar
26+
$RelativeTo = [IO.Path]::GetFullPath($RelativeTo).TrimEnd('\/') -replace "^[^\\/]+:[\\/]", [IO.Path]::DirectorySeparatorChar
27+
$Path = [IO.Path]::GetFullPath($Path) -replace "^[^\\/]+:[\\/]", [IO.Path]::DirectorySeparatorChar
28+
29+
$commonLength = 0
30+
while ($Path[$commonLength] -eq $RelativeTo[$commonLength]) {
31+
$commonLength++
32+
}
33+
if ($commonLength -eq $RelativeTo.Length -and $RelativeTo.Length -eq $Path.Length) {
34+
Write-Verbose "Equal Paths"
35+
return "." # The same paths
36+
}
37+
if ($commonLength -eq 0) {
38+
Write-Verbose "Paths on different drives?"
39+
return $Drive + $Path # no commonality, different drive letters on windows
40+
}
41+
42+
Write-Verbose "Common base: $commonLength $($RelativeTo.Substring(0,$commonLength))"
43+
# In case we matched PART of a name, like C:\Users\Joel and C:\Users\Joe
44+
while ($commonLength -gt $RelativeTo.Length -and ($RelativeTo[$commonLength] -ne [IO.Path]::DirectorySeparatorChar)) {
45+
$commonLength--
46+
}
47+
48+
Write-Verbose "Common base: $commonLength $($RelativeTo.Substring(0,$commonLength))"
49+
# create '..' segments for segments past the common on the "$RelativeTo" path
50+
if ($commonLength -lt $RelativeTo.Length) {
51+
$result = @('..') * @($RelativeTo.Substring($commonLength).Split([IO.Path]::DirectorySeparatorChar).Where{ $_ }).Length -join ([IO.Path]::DirectorySeparatorChar)
52+
}
53+
(@($result, $Path.Substring($commonLength).TrimStart([IO.Path]::DirectorySeparatorChar)).Where{ $_ } -join ([IO.Path]::DirectorySeparatorChar))
54+
}

Source/Private/ResolveOutputFolder.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function ResolveOutputFolder {
5151
$OutputDirectory = Join-Path $OutputDirectory $ModuleName
5252
}
5353
# Ensure the OutputDirectory is not a parent of the SourceDirectory
54-
if (-not [io.path]::GetRelativePath($OutputDirectory, $Source).StartsWith("..")) {
54+
if (-not (GetRelativePath $OutputDirectory $Source).StartsWith("..")) {
5555
Write-Verbose "Added Version to OutputDirectory path: $OutputDirectory"
5656
$OutputDirectory = Join-Path $OutputDirectory $Version
5757
}

Tests/Convert-FolderSeparator.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
function global:Convert-FolderSeparator {
1+
filter global:Convert-FolderSeparator {
22
[CmdletBinding()]
33
param(
4-
[Parameter(Mandatory)]
4+
[Parameter(Mandatory, ValueFromPipeline)]
55
[string]$Path,
66
[switch]$Relative,
77
[switch]$Validate
@@ -34,6 +34,8 @@ function global:Convert-FolderSeparator {
3434
Write-Verbose "Result: $Result"
3535
$Path = $Path -replace ([regex]::escape($ConvertedPath)), $Result
3636
}
37+
# if it's a testdrive path, it should be a testdrive path
38+
$Path = $Path.Replace($TestDrive,"TestDrive:")
3739
if ($Drive) {
3840
$Path -replace "\w*:", "$($Drive):"
3941
} else {

Tests/Integration/Source1.Tests.ps1

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#requires -Module ModuleBuilder
2+
. $PSScriptRoot\..\Convert-FolderSeparator.ps1
23

34
Describe "When we call Build-Module" -Tag Integration {
45
$Output = Build-Module $PSScriptRoot\Source1\build.psd1 -Passthru
@@ -193,11 +194,54 @@ Describe "Regression test for #40.2 not copying suffix if prefix" -Tag Integrati
193194
$Module = [IO.Path]::ChangeExtension($Output.Path, "psm1")
194195
$Code = Get-Content $Module
195196
$Code[0] | Should -be "using module ModuleBuilder" # because we moved it, from GetFinale
196-
$Code[1] | Should -be "#Region './_GlobalScope.ps1' 0"
197+
$Code[1] | Should -be "#Region '$('./_GlobalScope.ps1' -replace '/', ([IO.Path]::DirectorySeparatorChar))' 0"
197198
$Code[2] | Should -be '$Global:Module = "Testing"'
198199

199200
$Code[-3] | Should -be '$Global:Module = "Testing"'
200-
$Code[-2] | Should -be "#EndRegion './_GlobalScope.ps1' 2"
201+
$Code[-2] | Should -be "#EndRegion '$('./_GlobalScope.ps1' -replace '/', ([IO.Path]::DirectorySeparatorChar))' 2"
201202
$Code[-1] | Should -be ""
202203
}
203204
}
205+
206+
# There's no such thing as a drive root on unix
207+
if ($PSVersionTable.Platform -eq "Win32NT") {
208+
Describe "Able to build from the drive root" {
209+
$null = New-ModuleManifest "TestDrive:/MyModule.psd1" -ModuleVersion "1.0.0" -Author "Tester"
210+
$null = New-Item "TestDrive:/Public/Test.ps1" -Type File -Value 'MATCHING TEST CONTENT' -Force
211+
212+
$Result = Build-Module -SourcePath 'TestDrive:/MyModule.psd1' -Version "1.0.0" -OutputDirectory './output' -Encoding UTF8 -SourceDirectories @('Public') -Target Build -Passthru
213+
214+
It "Builds the Module in the designated output folder" {
215+
$Result.ModuleBase | Convert-FolderSeparator | Should -Be (Convert-FolderSeparator "TestDrive:/Output/MyModule")
216+
'TestDrive:/Output/MyModule/MyModule.psm1' | Convert-FolderSeparator | Should -FileContentMatch 'MATCHING TEST CONTENT'
217+
}
218+
}
219+
}
220+
221+
Describe "Copies additional items specified in CopyPaths" {
222+
223+
$null = New-Item "TestDrive:/build.psd1" -Type File -Force -Value "@{
224+
SourcePath = 'TestDrive:/MyModule.psd1'
225+
SourceDirectories = @('Public')
226+
OutputDirectory = './output'
227+
CopyPaths = './lib', './MyModule.format.ps1xml'
228+
}"
229+
$null = New-ModuleManifest "TestDrive:/MyModule.psd1" -ModuleVersion "1.0.0" -Author "Tester"
230+
$null = New-Item "TestDrive:/Public/Test.ps1" -Type File -Value 'MATCHING TEST CONTENT' -Force
231+
$null = New-Item "TestDrive:/MyModule.format.ps1xml" -Type File -Value '<Configuration />' -Force
232+
$null = New-Item "TestDrive:/lib/imaginary1.dll" -Type File -Value '1' -Force
233+
$null = New-Item "TestDrive:/lib/subdir/imaginary2.dll" -Type File -Value '2' -Force
234+
235+
$Result = Build-Module -SourcePath 'TestDrive:/build.psd1' -OutputDirectory './output' -Version '1.0.0' -Passthru -Target Build
236+
237+
It "Copies single files that are in CopyPaths" {
238+
(Convert-FolderSeparator $Result.ModuleBase) | Should -Be (Convert-FolderSeparator "$TestDrive/output/MyModule")
239+
'TestDrive:/output/MyModule/MyModule.format.ps1xml' | Should -Exist
240+
'TestDrive:/output/MyModule/MyModule.format.ps1xml' | Should -FileContentMatch '<Configuration />'
241+
}
242+
243+
It "Recursively copies all the files in folders that are in CopyPaths" {
244+
'TestDrive:/output/MyModule/lib/imaginary1.dll' | Should -FileContentMatch '1'
245+
'TestDrive:/output/MyModule/lib/subdir/imaginary2.dll' | Should -FileContentMatch '2'
246+
}
247+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#requires -Module ModuleBuilder
2+
Describe "GetRelativePath" {
3+
. $PSScriptRoot\..\Convert-FolderSeparator.ps1
4+
$CommandInfo = InModuleScope ModuleBuilder { Get-Command GetRelativePath }
5+
6+
Context "All Parameters are mandatory" {
7+
8+
It "has a mandatory string RelativeTo parameter" {
9+
$RelativeTo = $CommandInfo.Parameters['RelativeTo']
10+
$RelativeTo | Should -Not -BeNullOrEmpty
11+
$RelativeTo.ParameterType | Should -Be ([String])
12+
$RelativeTo.Attributes.Where{ $_ -is [Parameter] }.Mandatory | Should -Be $True
13+
}
14+
15+
It "has a mandatory string Path parameter" {
16+
$Path = $CommandInfo.Parameters['Path']
17+
$Path | Should -Not -BeNullOrEmpty
18+
$Path.ParameterType | Should -Be ([string])
19+
$Path.Attributes.Where{ $_ -is [Parameter] }.Mandatory | Should -Be $True
20+
}
21+
}
22+
23+
# I'm not going to bother writing tests for this other than "it's the same as .NET's"
24+
if ([System.IO.Path]::GetRelativePath) {
25+
Context "The output always matches [System.IO.Path]::GetRelativePath" {
26+
$TestCases = @(
27+
@{ RelativeTo = "G:\Module"; Path = "G:\Module\Source" }
28+
@{ RelativeTo = "G:\Module"; Path = "G:\Module\Source\Public" }
29+
@{ RelativeTo = "G:\Module\Source"; Path = "G:\Module\Output" }
30+
@{ RelativeTo = "G:\Module\Source"; Path = "G:\Module\Output\" }
31+
@{ RelativeTo = "G:\Module\Source\"; Path = "G:\Module\Output\" }
32+
@{ RelativeTo = "G:\Module\Source\"; Path = "G:\Module\Output" }
33+
@{ RelativeTo = "G:\Projects\Modules\MyModule\Source\Public"; Path = "G:\Modules\MyModule" }
34+
@{ RelativeTo = "G:\Projects\Modules\MyModule\Source\Public"; Path = "G:\Projects\Modules\MyModule" }
35+
# These ones are backwards, but they still work
36+
@{ RelativeTo = "G:\Module\Source" ; Path = "G:\Module" }
37+
@{ RelativeTo = "G:\Module\Source\Public"; Path = "G:\Module" }
38+
# These are linux-like:
39+
@{ RelativeTo = "/mnt/c/Users/Jaykul/Projects/Modules/ModuleBuilder"; Path = "/mnt/c/Users/Jaykul/Projects/Modules/ModuleBuilder/Source"; }
40+
@{ RelativeTo = "/mnt/c/Users/Jaykul/Projects/Modules/ModuleBuilder"; Path = "/mnt/c/Users/Jaykul/Projects/Output"; }
41+
@{ RelativeTo = "/mnt/c/Users/Jaykul/Projects/Modules/ModuleBuilder"; Path = "/mnt/c/Users/Jaykul/Projects/"; }
42+
# Weird PowerShell Paths
43+
@{ RelativeTo = "TestDrive:/Projects/Modules/ModuleBuilder"; Path = "TestDrive:\Projects" }
44+
@{ RelativeTo = "TestDrive:/Projects/Modules/ModuleBuilder"; Path = "TestDrive:/Projects" }
45+
@{ RelativeTo = "TestDrive:/Projects"; Path = "TestDrive:/Projects/Modules/ModuleBuilder" }
46+
)
47+
48+
# On Windows, there's a shortcut when the path points to totally different drive letters:
49+
if ($PSVersionTable.Platform -eq "Win32NT") {
50+
$TestCases += @(
51+
@{ RelativeTo = "G:\Projects\Modules\MyModule\Source\Public"; Path = "C:\Modules\MyModule" }
52+
@{ RelativeTo = "G:\Projects\Modules\MyModule\Source\Public"; Path = "F:\Projects\Modules\MyModule" }
53+
)
54+
}
55+
56+
It "Returns the same result as Path.GetRelativePath for <Path>" -TestCases $TestCases {
57+
param($RelativeTo, $Path)
58+
$RelativeTo = Convert-FolderSeparator $RelativeTo
59+
$Path = Convert-FolderSeparator $Path
60+
# Write-Verbose $Path -Verbose
61+
$Expected = [System.IO.Path]::GetRelativePath($RelativeTo, $Path)
62+
& $CommandInfo $RelativeTo $Path | Should -Be $Expected
63+
}
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)