Skip to content

Commit eb64c10

Browse files
committed
Add full module scaffolding functions with documentation, strict parameter ordering, and consistent template generation
This commit updates and standardizes all scaffolding functions in the module template system. Each function now includes full comment‑based help, mandatory parameter ordering, UTF‑8 output, and consistent single‑quoted template here‑strings with placeholder replacement. The module generator now produces a complete, professional PowerShell module structure including manifest, loader, tests, analyzer settings, documentation scripts, build/publish scripts, and README generation.
1 parent aa1732b commit eb64c10

21 files changed

Lines changed: 509 additions & 121 deletions

‎NewModuleTemplate.psd1‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
'New-DocumentationScripts',
2121
'New-ModuleChangelog',
2222
'New-ModuleFolders',
23+
'New-ModuleLoader',
2324
'New-ModuleManifestFile',
2425
'New-ModuleReadme',
2526
'New-ModuleTemplate',

‎NewModuleTemplate.psm1‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Export-ModuleMember -Function @(
1717
'New-DocumentationScripts',
1818
'New-ModuleChangelog',
1919
'New-ModuleFolders',
20+
'New-ModuleLoader',
2021
'New-ModuleManifestFile',
2122
'New-ModuleReadme',
2223
'New-ModuleTemplate',

‎Public/Initialize-GitRepository.ps1‎

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
1+
<#
2+
.SYNOPSIS
3+
Initializes a new Git repository inside a module folder.
4+
5+
.DESCRIPTION
6+
Creates a .gitignore file, initializes a Git repository, stages all files,
7+
and performs an initial commit. This function is used by New-ModuleTemplate
8+
when the -InitGit switch is provided.
9+
10+
.PARAMETER BasePath
11+
The root directory of the module where the Git repository should be created.
12+
This must be the module's top-level folder (e.g., C:\Projects\MyModule).
13+
14+
.EXAMPLE
15+
Initialize-GitRepository -BasePath "C:\Projects\MyModule"
16+
17+
.EXAMPLE
18+
$root = "C:\Modules\Tools"
19+
Initialize-GitRepository -BasePath $root
20+
21+
.NOTES
22+
- Requires Git to be installed and available in PATH.
23+
- This function performs a commit with the message "Initial commit".
24+
#>
125
function Initialize-GitRepository {
2-
param([string]$BasePath)
26+
[CmdletBinding()]
27+
param(
28+
[Parameter(Mandatory)]
29+
[string]$BasePath
30+
)
331

32+
# Create a standard .gitignore file for PowerShell modules
433
$gitignore = @'
534
## Build artifacts
635
bin/
@@ -17,15 +46,17 @@ Docs/*.xml
1746
1847
# Logs
1948
*.log
20-
2149
'@
2250

23-
Set-Content -Path "$BasePath\.gitignore" -Value $gitignore
51+
# Write .gitignore to the module root
52+
Set-Content -Path "$BasePath\.gitignore" -Value $gitignore -Encoding UTF8
2453

54+
# Initialize the Git repository inside the module folder
2555
Push-Location $BasePath
2656
git init | Out-Null
2757
Pop-Location
2858

59+
# Stage all files and create the initial commit
2960
git -C $BasePath add . | Out-Null
3061
git -C $BasePath commit -m "Initial commit" | Out-Null
3162
}

‎Public/New-AnalyzerSettings.ps1‎

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,53 @@
1+
<#
2+
.SYNOPSIS
3+
Generates a PSScriptAnalyzer settings file for the module.
4+
5+
.DESCRIPTION
6+
Creates a PSScriptAnalyzer settings file inside the module's AnalyzerSettings
7+
directory. The file defines rule severities and allows the module to enforce
8+
consistent linting behavior across development environments and CI pipelines.
9+
10+
.PARAMETER BasePath
11+
The root directory of the module where the AnalyzerSettings folder exists.
12+
This is typically the path returned by New-ModuleFolders.
13+
14+
.EXAMPLE
15+
New-AnalyzerSettings -BasePath "C:\Projects\MyModule"
16+
17+
.EXAMPLE
18+
$root = Join-Path $env:TEMP "TestModule"
19+
New-AnalyzerSettings -BasePath $root
20+
21+
.NOTES
22+
This function is automatically invoked by New-ModuleTemplate.
23+
The settings file created is named PSScriptAnalyzerSettings.psd1.
24+
#>
125
function New-AnalyzerSettings {
2-
param([string]$BasePath)
26+
[CmdletBinding()]
27+
param(
28+
[Parameter(Mandatory)]
29+
[string]$BasePath
30+
)
31+
32+
# Path to the AnalyzerSettings directory
33+
$settingsDir = Join-Path $BasePath 'Analyzer'
34+
35+
# Ensure the directory exists (New-ModuleFolders normally creates it)
36+
if (-not (Test-Path $settingsDir)) {
37+
New-Item -ItemType Directory -Path $settingsDir -Force | Out-Null
38+
}
339

40+
# Default analyzer configuration
441
$content = @'
542
@{
643
Severity = @{
744
PSAvoidUsingWriteHost = 'Warning'
8-
PSProvideCommentHelp = 'Information'
45+
PSProvideCommentHelp = 'Information'
946
}
1047
}
1148
'@
1249

13-
Set-Content -Path "$BasePath\Analyzer\PSScriptAnalyzerSettings.psd1" -Value $content
50+
# Write the settings file
51+
$settingsPath = Join-Path $settingsDir 'PSScriptAnalyzerSettings.psd1'
52+
Set-Content -Path $settingsPath -Value $content -Encoding UTF8
1453
}

‎Public/New-BuildScript.ps1‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,29 @@
33
Creates a build.ps1 script inside the generated module.
44
55
.DESCRIPTION
6-
The build script runs PSScriptAnalyzer, Pester tests, and updates PlatyPS documentation.
6+
Generates a build script that performs common module maintenance tasks:
7+
- Runs PSScriptAnalyzer using the module's analyzer settings
8+
- Executes Pester tests
9+
- Regenerates PlatyPS documentation
10+
The script supports switches to skip individual steps.
11+
12+
.PARAMETER BasePath
13+
The root directory of the module where the Scripts folder will be created.
14+
15+
.PARAMETER Name
16+
The name of the module. Used to reference the module manifest and display
17+
status messages inside the generated build script.
18+
19+
.EXAMPLE
20+
New-BuildScript -BasePath "C:\Projects\MyModule" -Name "MyModule"
21+
22+
.EXAMPLE
23+
$root = Join-Path $env:TEMP "TestModule"
24+
New-BuildScript -BasePath $root -Name "TestModule"
25+
26+
.NOTES
27+
- The Analyzer folder is intentionally named "Analyzer".
28+
- This script is automatically invoked by New-ModuleTemplate.
729
#>
830
function New-BuildScript {
931
[CmdletBinding()]
@@ -15,6 +37,13 @@ function New-BuildScript {
1537
[string]$Name
1638
)
1739

40+
# Ensure the Scripts directory exists
41+
$scriptsDir = Join-Path $BasePath 'Scripts'
42+
if (-not (Test-Path $scriptsDir)) {
43+
New-Item -ItemType Directory -Path $scriptsDir -Force | Out-Null
44+
}
45+
46+
# Template for the build script
1847
$content = @'
1948
param(
2049
[switch]$SkipTests,
@@ -43,7 +72,10 @@ if (-not $SkipDocs) {
4372
Write-Host "Build complete."
4473
'@
4574

75+
# Replace placeholder with module name
4676
$content = $content.Replace('__MODULE__', $Name)
4777

48-
Set-Content -Path "$BasePath\Scripts\build.ps1" -Value $content
78+
# Write the build script
79+
$buildScriptPath = Join-Path $scriptsDir 'build.ps1'
80+
Set-Content -Path $buildScriptPath -Value $content -Encoding UTF8 -Force
4981
}
Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,58 @@
1+
<#
2+
.SYNOPSIS
3+
Creates a documentation update script for the module.
4+
5+
.DESCRIPTION
6+
Generates a PowerShell script that updates PlatyPS-based Markdown help
7+
for the module. The script imports PlatyPS and calls Update-MarkdownHelp
8+
using the module's manifest and Docs folder. This allows developers to
9+
regenerate documentation after modifying public functions.
10+
11+
.PARAMETER BasePath
12+
The root directory of the module where the Scripts folder will be created.
13+
14+
.PARAMETER Name
15+
The name of the module. Used to reference the module manifest inside the
16+
generated documentation update script.
17+
18+
.EXAMPLE
19+
New-DocumentationScripts -BasePath "C:\Projects\MyModule" -Name "MyModule"
20+
21+
.EXAMPLE
22+
$root = Join-Path $env:TEMP "TestModule"
23+
New-DocumentationScripts -BasePath $root -Name "TestModule"
24+
25+
.NOTES
26+
- The generated script is named Update-ModuleDocumentation.ps1.
27+
- PlatyPS must be installed for the script to run successfully.
28+
#>
129
function New-DocumentationScripts {
30+
[CmdletBinding()]
231
param(
32+
[Parameter(Mandatory)]
333
[string]$BasePath,
34+
35+
[Parameter(Mandatory)]
436
[string]$Name
537
)
638

39+
# Ensure the Scripts directory exists
40+
$scriptsDir = Join-Path $BasePath 'Scripts'
41+
if (-not (Test-Path $scriptsDir)) {
42+
New-Item -ItemType Directory -Path $scriptsDir -Force | Out-Null
43+
}
44+
45+
# Template for the documentation update script
746
$content = @'
847
Import-Module PlatyPS
948
10-
Update-MarkdownHelp -Module "$PSScriptRoot\..\__MODULE_NAME__.psd1" -OutputFolder "$PSScriptRoot\Docs" -Force
49+
Update-MarkdownHelp -Module "$PSScriptRoot\..\__MODULE_NAME__.psd1" -OutputFolder "$PSScriptRoot\..\Docs" -Force
1150
'@
1251

13-
$content = $content.Replace('__MODULE_NAME__', "$Name")
14-
# $content = $content.Replace('__DOCS_PATH__', "$BasePath\Docs")
52+
# Replace placeholder with module name
53+
$content = $content.Replace('__MODULE_NAME__', $Name)
1554

16-
Set-Content -Path "$BasePath\Scripts\Update-ModuleDocumentation.ps1" -Value $content
55+
# Write the documentation update script
56+
$docScriptPath = Join-Path $scriptsDir 'Update-ModuleDocumentation.ps1'
57+
Set-Content -Path $docScriptPath -Value $content -Encoding UTF8
1758
}

‎Public/New-ModuleChangelog.ps1‎

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,40 @@
1+
<#
2+
.SYNOPSIS
3+
Creates or updates a CHANGELOG.md file for the module.
4+
5+
.DESCRIPTION
6+
Generates a Markdown changelog file following the "Keep a Changelog" format
7+
and Semantic Versioning guidelines. The function writes a new changelog
8+
entry using the provided version and notes. If the file does not exist,
9+
it is created. If it exists, the new entry is appended.
10+
11+
.PARAMETER BasePath
12+
The root directory of the module where CHANGELOG.md will be created.
13+
14+
.PARAMETER Version
15+
The version number associated with the changelog entry.
16+
Defaults to "1.0.0".
17+
18+
.PARAMETER Notes
19+
A description of the changes included in this version.
20+
Defaults to "Initial release."
21+
22+
.EXAMPLE
23+
New-ModuleChangelog -BasePath "C:\Projects\MyModule" -Version "1.2.0" -Notes "Added new API endpoints"
24+
25+
.EXAMPLE
26+
$root = Join-Path $env:TEMP "TestModule"
27+
New-ModuleChangelog -BasePath $root -Version "0.1.0" -Notes "Prototype scaffolding"
28+
29+
.NOTES
30+
- This function is typically invoked by New-ModuleTemplate.
31+
- The changelog format follows https://keepachangelog.com/.
32+
#>
133
function New-ModuleChangelog {
234
[CmdletBinding()]
335
param(
436
[Parameter(Mandatory)]
5-
[string]$Path,
37+
[string]$BasePath,
638

739
[Parameter()]
840
[string]$Version = "1.0.0",
@@ -11,14 +43,15 @@ function New-ModuleChangelog {
1143
[string]$Notes = "Initial release."
1244
)
1345

14-
# Ensure the path exists
15-
if (-not (Test-Path $Path)) {
16-
throw "The path '$Path' does not exist."
46+
# Ensure the module root exists
47+
if (-not (Test-Path $BasePath)) {
48+
throw "The path '$BasePath' does not exist."
1749
}
1850

19-
$changelogPath = Join-Path $Path "CHANGELOG.md"
51+
# Path to the changelog file
52+
$changelogPath = Join-Path $BasePath "CHANGELOG.md"
2053

21-
# Build content
54+
# Build the changelog entry
2255
$date = (Get-Date).ToString("yyyy-MM-dd")
2356

2457
$content = @"
@@ -34,7 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3467
3568
"@
3669

37-
# Write file
70+
# Write the changelog file (overwrite or create)
3871
Set-Content -Path $changelogPath -Value $content -Encoding UTF8
3972

4073
# Return the path for convenience

‎Public/New-ModuleFolders.ps1‎

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,54 @@
1+
<#
2+
.SYNOPSIS
3+
Creates the folder structure for a new PowerShell module.
4+
5+
.DESCRIPTION
6+
Generates the standard directory layout used by your module scaffolding
7+
system. This includes the Public, Private, Tests, Docs, Analyzer, and
8+
Scripts directories. The function returns the full path to the module's
9+
root folder.
10+
11+
.PARAMETER BasePath
12+
The directory where the module folder will be created. The module root
13+
becomes <BasePath>\<Name>.
14+
15+
.PARAMETER Name
16+
The name of the module. This becomes the root folder name and is used
17+
throughout the scaffolding process.
18+
19+
.EXAMPLE
20+
New-ModuleFolders -BasePath "C:\Projects" -Name "MyModule"
21+
22+
.EXAMPLE
23+
$root = Join-Path $env:TEMP "TestModule"
24+
New-ModuleFolders -BasePath $root -Name "Tools"
25+
26+
.NOTES
27+
- This function is invoked internally by New-ModuleTemplate.
28+
- The folder names are intentionally kept as: Public, Private, Tests,
29+
Docs, Analyzer, Scripts.
30+
#>
131
function New-ModuleFolders {
232
[CmdletBinding()]
333
param(
434
[Parameter(Mandatory)]
5-
[string]$Name,
35+
[string]$Path,
636

737
[Parameter(Mandatory)]
8-
[string]$Path
38+
[string]$Name
939
)
1040

11-
# Base module path: <Path>\<Name>
12-
$base = Join-Path $Path $Name
13-
New-Item -ItemType Directory -Path $base -Force | Out-Null
41+
# Build the module root path: <BasePath>\<Name>
42+
$moduleRoot = Join-Path $Path $Name
43+
44+
# Create the root folder
45+
New-Item -ItemType Directory -Path $moduleRoot -Force | Out-Null
1446

15-
# Standard module folder structure
47+
# Create the standard module subfolders
1648
foreach ($folder in 'Public', 'Private', 'Tests', 'Docs', 'Analyzer', 'Scripts') {
17-
New-Item -ItemType Directory -Path (Join-Path $base $folder) -Force | Out-Null
49+
New-Item -ItemType Directory -Path (Join-Path $moduleRoot $folder) -Force | Out-Null
1850
}
1951

20-
return $base
52+
# Return the module root path for chaining
53+
return $moduleRoot
2154
}

0 commit comments

Comments
 (0)