Skip to content

Commit 768ab70

Browse files
authored
Merge pull request #13 from tinuwalther/mwa/test
Mwa/test
2 parents 5f81bdf + 1377e15 commit 768ab70

File tree

8 files changed

+197
-54
lines changed

8 files changed

+197
-54
lines changed

Backup/.gitkeep

Whitespace-only changes.

CHANGELOG.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,5 @@
22

33
Version | Description | Date | Author
44
-|-|-|-
5-
1.1.0 | Add Module.Tests.ps1 and Write-PRELog.ps1, rename Get-PRESomeSettings to Get-PRETemplate | 2021-08-28 | Martin Walther
6-
1.0.5 | Automatically rename Example-Function 'Get-PRESomeSettings.ps1' | 2019-10-19 | Martin Walther
7-
1.0.4 | Allows to set the module version each time the build.ps1 is started | 2019-10-16 | Josh Burkard
8-
1.0.3 | Save prefix in json instead of variable | 2019-09-09 | Martin Walther
9-
1.0.2 | Change return of functions to PsCustomObject | 2019-09-09 | Martin Walther
10-
1.0.1 | Automate some manually steps | 2019-09-07 | Martin Walther
11-
1.0.0 | Release Module to Production | 2019-09-05 | Martin Walther
5+
2.0.1 | Initial upload | 2023-04-26 | Martin Walther
6+
2.0.2 | Implementing Parameter WhatIf in functions | 2023-04-29 | Martin Walther

CI/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.json

CI/Build-Module.ps1

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ Write-Host "[BUILD] [START] Launching Build Process" -ForegroundColor Green
1010
#region prepare folders
1111
$Current = (Split-Path -Path $MyInvocation.MyCommand.Path)
1212
$Root = ((Get-Item $Current).Parent).FullName
13-
$TestsPath = Join-Path -Path $Root -ChildPath "Tests"
14-
$CISourcePath = Join-Path -Path $Root -ChildPath "CI"
15-
$CodeSourcePath = Join-Path -Path $Root -ChildPath "Code"
16-
$TestsScript = Join-Path -Path $TestsPath -ChildPath "Functions.Tests.ps1"
17-
$TestsFailures = Join-Path -Path $TestsPath -ChildPath "Functions.Tests.json"
18-
$Settings = Join-Path -Path $CISourcePath -ChildPath "Module-Settings.json"
13+
$BackupPath = Join-Path -Path $Root -ChildPath 'Backup'
14+
$TestsPath = Join-Path -Path $Root -ChildPath 'Tests'
15+
$CISourcePath = Join-Path -Path $Root -ChildPath 'CI'
16+
$CodeSourcePath = Join-Path -Path $Root -ChildPath 'Code'
17+
$PrivatePath = Join-Path -Path $CodeSourcePath -ChildPath 'Private'
18+
$PublicPath = Join-Path -Path $CodeSourcePath -ChildPath 'Public'
19+
$TestsScript = Join-Path -Path $TestsPath -ChildPath 'Functions.Tests.ps1'
20+
$TestsFailures = Join-Path -Path $TestsPath -ChildPath 'Failed.Tests.json'
21+
$Settings = Join-Path -Path $CISourcePath -ChildPath 'Module-Settings.json'
1922
#endregion
2023

2124
#region Module-Settings
@@ -25,59 +28,84 @@ if(Test-Path -Path $Settings){
2528
$ModuleDescription = $ModuleSettings.ModuleDescription
2629
$ModuleVersion = $ModuleSettings.ModuleVersion
2730
$prompt = Read-Host "Enter the Version number of this module in the Semantic Versioning notation [$( $ModuleVersion )]"
28-
if (!$prompt -eq "") { $ModuleVersion = $prompt }
31+
if (!$prompt -eq "") {
32+
$ModuleVersion = $prompt
33+
}else{
34+
$ModuleVersion = [Version]$ModuleSettings.ModuleVersion
35+
$ModuleVersion = "{0}.{1}.{2}" -f $ModuleVersion.Major, $ModuleVersion.Minor, ($ModuleVersion.Build + 1)
36+
}
2937
$ModuleAuthor = $ModuleSettings.ModuleAuthor
3038
$ModuleCompany = $ModuleSettings.ModuleCompany
3139
$ModulePrefix = $ModuleSettings.ModulePrefix
40+
$LastChange = Read-Host 'Describe what did you change'
3241
}
3342
else{
3443
$ModuleName = Read-Host 'Enter the name of the module without the extension'
35-
$ModuleVersion = Read-Host 'Enter the Version number of this module in the Semantic Versioning notation [1.0.0]'
44+
$ModuleVersion = Read-Host 'Enter the Version number of this module in the Semantic Versioning notation [0.0.1]'
45+
if ([String]::IsNullOrEmpty($ModuleVersion)){$ModuleVersion = '0.0.1'}
3646
$ModuleDescription = Read-Host 'Enter the Description of the functionality provided by this module'
3747
$ModuleAuthor = Read-Host 'Enter the Author of this module'
3848
$ModuleCompany = Read-Host 'Enter the Company or vendor of this module'
3949
$ModulePrefix = Read-Host 'Enter the Prefix for all functions of this module'
50+
$LastChange = Read-Host 'Describe what did you change'
4051
}
52+
53+
$ModuleName = $ModuleName -replace '\-', '.' # Lower-case is better for linux
54+
$ModuleFolderRootPath = Join-Path -Path $Root -ChildPath $ModuleName
55+
$ModuleFolderPath = Join-Path -Path $ModuleFolderRootPath -ChildPath $ModuleVersion
56+
4157
[PSCustomObject] @{
4258
ModuleName = $ModuleName
4359
ModuleVersion = $ModuleVersion
4460
ModuleDescription = $ModuleDescription
4561
ModuleAuthor = $ModuleAuthor
4662
ModuleCompany = $ModuleCompany
4763
ModulePrefix = $ModulePrefix
64+
LastChange = $LastChange
4865
} | ConvertTo-Json | Out-File -FilePath $Settings -Encoding utf8
66+
#endregion
67+
68+
#region PRE-functions
69+
Copy-Item -Path $CodeSourcePath -Destination $BackupPath -Filter '*-PRE*.ps1' -Recurse -Force -Confirm:$false
4970

50-
Get-ChildItem -Path $CodeSourcePath -Filter '*-*.ps1' | ForEach-Object {
71+
# Rename private and public PRE-functions
72+
Get-ChildItem -Path $PrivatePath -Filter '*-*.ps1' | ForEach-Object {
5173
$newname = $($_.Name -replace '-PRE',"-$($ModulePrefix)")
5274
(Get-Content -Path $_.FullName) -replace '-PRE',"-$($ModulePrefix)" | Set-Content -Path $_.FullName
53-
Rename-Item -Path $_.FullName -NewName $newname -PassThru
75+
Rename-Item -Path $_.FullName -NewName $newname #-PassThru
76+
}
77+
Get-ChildItem -Path $PublicPath -Filter '*-*.ps1' | ForEach-Object {
78+
$newname = $($_.Name -replace '-PRE',"-$($ModulePrefix)")
79+
(Get-Content -Path $_.FullName) -replace '-PRE',"-$($ModulePrefix)" | Set-Content -Path $_.FullName
80+
Rename-Item -Path $_.FullName -NewName $newname #-PassThru
5481
}
5582
#endregion
5683

57-
#Running Pester Tests
84+
#region Pester Tests
5885
if(Test-Path -Path $TestsFailures){
5986
$file = Get-Item -Path $TestsFailures
6087
$timestamp = Get-Date ($file.LastWriteTime) -f 'yyyyMMdd_HHmmss'
6188
$newname = $($file.Name -replace '.json',"-$($timestamp).json")
6289
Rename-Item -Path $TestsFailures -NewName $newname
6390
}
91+
6492
Write-Host "[BUILD] [TEST] Running Function-Tests" -ForegroundColor Green
6593
#$TestsResult = Invoke-Pester -Script $TestsScript -PassThru -Show None -> for Pester before 5.2.2
6694
$TestsResult = Invoke-Pester -Script $TestsScript -Output Normal -PassThru
6795
if($TestsResult.FailedCount -eq 0){
68-
$ModuleFolderPath = Join-Path -Path $Root -ChildPath $ModuleName
69-
#$ModuleFolderPath = $Root
96+
97+
#$ModuleFolderPath = Join-Path -Path $Root -ChildPath $ModuleName
98+
7099
if(-not(Test-Path -Path $ModuleFolderPath)){
71-
$null = New-Item -Path $ModuleFolderPath -ItemType Directory
100+
$null = New-Item -Path $ModuleFolderPath -ItemType Directory -Force
72101
}
73-
#endregion
74102

75103
#region Update the Module-File
76-
# Remove existent PSM1-File
104+
# Move existent PSM1-File to the backup-folder
77105
$ExportPath = Join-Path -Path $ModuleFolderPath -ChildPath "$($ModuleName).psm1"
78106
if(Test-Path $ExportPath){
79107
Write-Host "[BUILD] [PSM1 ] PSM1 file detected. Deleting..." -ForegroundColor Green
80-
Remove-Item -Path $ExportPath -Force
108+
Move-Item -Path $ExportPath -Destination $BackupPath -Force -Confirm:$false
81109
}
82110

83111
# Prepare new PSM1-File
@@ -87,9 +115,11 @@ if($TestsResult.FailedCount -eq 0){
87115
"#>" | out-File -FilePath $ExportPath -Encoding utf8 -Append
88116

89117
Write-Host "[BUILD] [Code ] Loading Class, public and private functions" -ForegroundColor Green
90-
$PublicFunctions = Get-ChildItem -Path $CodeSourcePath -Filter '*-*.ps1' | sort-object Name
91-
$MainPSM1Contents = @()
92-
$MainPSM1Contents += $PublicFunctions
118+
$PrivateFunctions = Get-ChildItem -Path (Join-Path $CodeSourcePath -ChildPath 'Private') -Filter '*-*.ps1' | sort-object Name
119+
$PublicFunctions = Get-ChildItem -Path (Join-Path $CodeSourcePath -ChildPath 'Public') -Filter '*-*.ps1' | sort-object Name
120+
$MainPSM1Contents = @()
121+
$MainPSM1Contents += $PrivateFunctions
122+
$MainPSM1Contents += $PublicFunctions
93123

94124
#Creating PSM1
95125
Write-Host "[BUILD] [START] [PSM1] Building Module PSM1" -ForegroundColor Green
@@ -105,16 +135,31 @@ if($TestsResult.FailedCount -eq 0){
105135
#region Update the Manifest-File
106136
Write-Host "[BUILD] [START] [PSD1] Manifest PSD1" -ForegroundColor Green
107137
$FullModuleName = Join-Path -Path $ModuleFolderPath -ChildPath "$($ModuleName).psd1"
108-
if(-not(Test-Path $FullModuleName)){
109-
New-ModuleManifest -Path $FullModuleName -ModuleVersion $ModuleVersion -Description $ModuleDescription -Author $ModuleAuthor -CompanyName $ModuleCompany -RootModule "$($ModuleName).psm1" -PowerShellVersion 5.1
138+
if(Test-Path $FullModuleName){
139+
Move-Item -Path $FullModuleName -Destination $BackupPath -Force -Confirm:$false
140+
}
141+
142+
$ModuleManifestSplat = @{
143+
Path = $FullModuleName
144+
ModuleVersion = $ModuleVersion
145+
Description = $ModuleDescription
146+
Author = $ModuleAuthor
147+
CompanyName = $ModuleCompany
148+
RootModule = "$($ModuleName).psm1"
149+
PowerShellVersion = '5.1'
110150
}
151+
New-ModuleManifest @ModuleManifestSplat
111152

112153
Write-Host "[BUILD] [PSD1 ] Adding functions to export" -ForegroundColor Green
113154
$FunctionsToExport = $PublicFunctions.BaseName
114155
$Manifest = Join-Path -Path $ModuleFolderPath -ChildPath "$($ModuleName).psd1"
115156
Update-ModuleManifest -Path $Manifest -FunctionsToExport $FunctionsToExport -ModuleVersion $ModuleVersion
116157

117158
Write-Host "[BUILD] [END ] [PSD1] building Manifest" -ForegroundColor Green
159+
#endregion
160+
161+
$ChangeLog = "$($ModuleVersion) | $($LastChange) | $(Get-Date -f 'yyyy-MM-dd') | $($ModuleAuthor)"
162+
Add-Content -Value $ChangeLog -Path (Join-Path $Root -ChildPath 'CHANGELOG.md')
118163

119164
Write-Host "[BUILD] [END] Launching Build Process" -ForegroundColor Green
120165
}
@@ -127,4 +172,17 @@ else{
127172
Write-Warning "There is something wrong in paradise $($TestArray.Get()))"
128173
}
129174
Write-Host "[BUILD] [END] Launching Build Process with $($TestsResult.FailedCount) Errors" -ForegroundColor Red
130-
}
175+
}
176+
#endregion
177+
178+
#region Module.Tests.ps1
179+
Write-Host "`n"
180+
Invoke-Pester -Script (Join-Path -Path $TestsPath -ChildPath "Module.Tests.ps1") -Output Detailed
181+
#endregion
182+
183+
#region manually
184+
Write-Host "`nIf you have dependencies to other modules, please fill in to the module manifest (psd1) as RequiredModules. See at " -ForegroundColor Cyan
185+
Write-Host "https://learn.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-7.3" -ForegroundColor Cyan
186+
Write-Host "`nModule Manifest:"
187+
Import-LocalizedData -BaseDirectory $ModuleFolderPath -FileName "$($ModuleName).psd1"
188+
#endregion
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function Write-PRELog{
2828
2929
#>
3030

31-
[CmdletBinding()]
31+
[CmdletBinding(SupportsShouldProcess=$True)]
3232
param(
3333
[Parameter(Mandatory=$false)]
3434
[string] $LogFile,
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function Get-PRETemplate{
2020
2121
#>
2222

23-
[CmdletBinding()]
23+
[CmdletBinding(SupportsShouldProcess=$True)]
2424
param(
2525
[Parameter(Mandatory = $true)]
2626
[String]$Name
@@ -31,7 +31,7 @@ function Get-PRETemplate{
3131
foreach($item in $PSBoundParameters.keys){
3232
$params = "$($params) -$($item) $($PSBoundParameters[$item])"
3333
}
34-
Write-PRELog -Status INFO -Message "Running $($function)$($params)" -Source $function
34+
Write-MWALog -Status INFO -Message "Running $($function)$($params)" -Source $function
3535
$ret = $null
3636
}
3737

@@ -59,7 +59,7 @@ function Get-PRETemplate{
5959
}
6060
#don't forget to clear the error-object
6161
$error.Clear()
62-
Write-PRELog -Status ERROR -Message $ret -Source $function
62+
Write-MWALog -Status ERROR -Message $ret -Source $function
6363
}
6464
}
6565

README.md

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [CHANGELOG](#changelog)
77
- [CI](#ci)
88
- [Build-Module.ps1](#build-moduleps1)
9+
- [Usage](#usage)
910
- [Module-Settings.json](#module-settingsjson)
1011
- [Code](#code)
1112
- [Get-PRETemplate.ps1](#get-pretemplateps1)
@@ -15,7 +16,8 @@
1516
- [Module-File](#module-file)
1617
- [Tests](#tests)
1718
- [Functions.Tests.ps1](#functionstestsps1)
18-
- [Functions.Tests.json](#functionstestsjson)
19+
- [Failed.Tests.json](#failedtestsjson)
20+
- [Module.Tests.ps1](#moduletestsps1)
1921

2022
# PowerShell Module Template
2123

@@ -24,7 +26,7 @@ How to create a new PowerShell-Module with PSModuleTemplate?
2426
1. Create a new project in Git and clone it to your computer
2527
2. git clone <https://github.com/tinuwalther/PSModuleTemplate.git>
2628
3. Copy the content from PSModuleTemplate into your new project
27-
4. Update the README.md and CHANGELOG.md with your information
29+
4. Update the README.md with your information
2830
5. Save your function-files in the folder Code
2931
6. Build your Module with Build-Module.ps1
3032

@@ -34,7 +36,7 @@ Information about your project.
3436

3537
## CHANGELOG
3638

37-
Update this file whenever you make changes on your module!
39+
The Build-Module.ps1 update this file with your last change description.
3840

3941
## CI
4042

@@ -49,6 +51,51 @@ The script also updates the Manifest-File (PSD1) with the functions to export. I
4951

5052
Finally Build-Module.ps1 tests if your Module can be imported and removed without any errors. It tests also if the Module contains all of your exported functions.
5153

54+
#### Usage
55+
56+
Open the Terminal and navigate to the Git-Project. Start the Build-Module.ps1 and enter the answers:
57+
58+
````PowerShell
59+
./CI/Build-Module.ps1
60+
`````
61+
62+
`````text
63+
[BUILD] [START] Launching Build Process
64+
Enter the name of the module without the extension: Test-PSModuleTemplate
65+
Enter the Version number of this module in the Semantic Versioning notation [1.0.0]: 0.0.1
66+
Enter the Description of the functionality provided by this module: This is a PowerShell-Module to create simple PowerShell-Modules
67+
Enter the Author of this module: Martin Walther
68+
Enter the Company or vendor of this module: Martin Walther Foto & IT
69+
Enter the Prefix for all functions of this module: MWA
70+
Describe what did you change: Initial upload
71+
[BUILD] [TEST] Running Function-Tests
72+
73+
Starting discovery in 1 files.
74+
Discovery found 0 tests in 13ms.
75+
Running tests.
76+
Tests completed in 13ms
77+
Tests Passed: 0, Failed: 0, Skipped: 0 NotRun: 0
78+
79+
[BUILD] [Code ] Loading Class, public and private functions
80+
[BUILD] [START] [PSM1] Building Module PSM1
81+
[BUILD] [END ] [PSM1] building Module PSM1
82+
[BUILD] [START] [PSD1] Manifest PSD1
83+
[BUILD] [PSD1 ] Adding functions to export
84+
[BUILD] [END ] [PSD1] building Manifest
85+
[BUILD] [END] Launching Build Process
86+
`````
87+
88+
````PowerShell
89+
Import-Module ./test.psmoduletemplate/
90+
Get-Command -Module test.psmoduletemplate
91+
`````
92+
93+
`````text
94+
CommandType Name Version Source
95+
----------- ---- ------- ------
96+
Function Get-PRETemplate 0.0.1 test.psmoduletemplate
97+
`````
98+
5299
### Module-Settings.json
53100
54101
The settings-file will be created, if you build the module at the first time and contains the following properties:
@@ -58,6 +105,8 @@ The settings-file will be created, if you build the module at the first time and
58105
ModuleDescription
59106
ModuleAuthor
60107
ModuleCompany
108+
ModulePrefix
109+
LastChange
61110
62111
## Code
63112
@@ -91,6 +140,30 @@ This folder contains all the Pester-Test-scripts.
91140
92141
Functions.Tests.ps1 tests all of your scripts/functions in the folder Code.
93142
94-
### Functions.Tests.json
143+
### Failed.Tests.json
95144
96145
This file will be created, if there were some errors in the Build-Module.
146+
147+
### Module.Tests.ps1
148+
149+
This is the file for your Function-Tests. Here you should write a test for each function to ensure, that your code is not damaged and is valid.
150+
You can call this Tests in a GitHub-Action or CI/CD-Pipeline or simple manually.
151+
152+
````PowerShell
153+
$TestsResult = Invoke-Pester -Script ./Tests/Module.Tests.ps1 -Output Detailed -PassThru
154+
`````
155+
156+
`````text
157+
Describing Module Tests
158+
Context Import Module
159+
[+] Import test.psmoduletemplate should not throw 8ms (5ms|3ms)
160+
[+] Get-Command -Module test.psmoduletemplate should not throw 11ms (3ms|8ms)
161+
[+] Get-Command -Module test.psmoduletemplate should return commands 10ms (8ms|1ms)
162+
Context Functions
163+
[+] Get-PRETemplate should not throw 53ms (51ms|2ms)
164+
Context Remove Module
165+
[+] Removes test.psmoduletemplate should not throw 8ms (6ms|2ms)
166+
[+] Get-Module -Name test.psmoduletemplate should be NullOrEmpty 4ms (3ms|1ms)
167+
Tests completed in 238ms
168+
Tests Passed: 6, Failed: 0, Skipped: 0 NotRun: 0
169+
`````

0 commit comments

Comments
 (0)