Skip to content
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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
# The docs are generated by the build script and should be considered artifacts
docs/en-US/* linguist-generated
20 changes: 20 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/v0.19.1/schema/markdownlint-cli2-config-schema.json",
"config": {
"MD013": {
"tables": false,
"code_blocks": false
},
"MD024": {
"siblings_only": true
}
},
"ignores": [
"AGENTS.md",
// Intentionally narrow: only ignores docs/en-US (platyPS-generated help) so that
// other markdown files in docs/ are still linted. No other language directories
// are expected.
"docs/en-US/**",
"instructions/**"
]
}
29 changes: 24 additions & 5 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
# Changelog

All notable changes to this project will be documented in this file.
All notable changes to this template will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
and this project uses [Calendar Versioning](https://calver.org/) (`YYYY.MM.DD`).

For the changelog of a *module initialized from this template*, see the module's
own `CHANGELOG.md` (generated from `CHANGELOG.template.md` during init).

## [Unreleased]

## [0.1.0] - {{Date}}
## [2026.04.29] - 2026-04-29

### Added

- Initial release
- `Get-{{Prefix}}Example` - Example public function
- SemVer-aware dependency version checks: new `tests/ManifestHelpers.psm1` exporting `Test-VersionConstraint`. `tests/Manifest.tests.ps1` now differentiates `RequiredVersion` / `ModuleVersion` / `MaximumVersion`, accepts both string and hashtable shapes in `requirements.psd1`, and detects duplicate `RequiredModules` entries.
- README split: template-facing `README.md` (what GitHub visitors see) and module-facing `README.template.md` (substituted into `README.md` during init).
- `docs/en-US/about_{{ModuleName}}.help.md` stub for `Get-Help about_<Module>`. `Initialize-Template.ps1` now also renames `{{ModuleName}}` files in `docs/en-US/`.
- `.gitattributes` marking `docs/en-US/*` as `linguist-generated`.
- `.markdownlint-cli2.jsonc` config (relax MD013 in tables/code, allow MD024 siblings, ignore generated docs and `instructions/`).

### Changed

- `PSScriptAnalyzerSettings.psd1`: replaced one-line `@{ IncludeRules = @('*') }` with the structured form (Include/Exclude/Rules + commented compat scaffold).
- Bumped `PSScriptAnalyzer` 1.24.0 → 1.25.0.

### Fixed

- `tests/Help.tests.ps1`: replaced undefined `$parameterNames` with `$commandParameterNames` in the help-vs-code parameter check (was silently asserting against `$null`).
- `{{ModuleName}}/{{ModuleName}}.psm1`: dot-source catch block now preserves the original `ErrorRecord` via bare `throw`. Previously the catch threw a new string (`"Unable to dot source ..."`), which wrapped the original exception in a fresh `ErrorRecord` and lost the underlying stack trace.

[Unreleased]: https://github.com/tablackburn/PowerShellModuleTemplate/compare/v2026.04.29...HEAD
[2026.04.29]: https://github.com/tablackburn/PowerShellModuleTemplate/releases/tag/v2026.04.29
15 changes: 15 additions & 0 deletions CHANGELOG.template.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.0] - {{Date}}

### Added

- Initial release
- `Get-{{Prefix}}Example` - Example public function
41 changes: 38 additions & 3 deletions Initialize-Template.ps1
Original file line numberDiff line numberDiff line change
Expand Up@@ -180,6 +180,7 @@ $filesToProcess = Get-ChildItem -Path $PSScriptRoot -Recurse -File | Where-Objec
$_.FullName -notmatch '[\\/]Output[\\/]' -and
$_.FullName -notmatch '[\\/]out[\\/]' -and
$_.Name -ne 'Initialize-Template.ps1' -and
$_.Name -ne 'CHANGELOG.md' -and
$_.Extension -in @('.ps1', '.psm1', '.psd1', '.md', '.json', '.yml', '.yaml', '.xml', '.txt', '')
}

Expand DownExpand Up@@ -241,8 +242,8 @@ if (Test-Path -Path $templateModuleFolder) {
# Rename example function files
$publicFolder = Join-Path -Path $moduleFolder -ChildPath 'Public'
$privateFolder = Join-Path -Path $moduleFolder -ChildPath 'Private'
$testPublicFolder = Join-Path -Path $PSScriptRoot -ChildPath 'tests\Unit\Public'
$testPrivateFolder = Join-Path -Path $PSScriptRoot -ChildPath 'tests\Unit\Private'
$testPublicFolder = Join-Path -Path $PSScriptRoot -ChildPath 'tests/Unit/Public'
$testPrivateFolder = Join-Path -Path $PSScriptRoot -ChildPath 'tests/Unit/Private'

$foldersToCheck = @($publicFolder, $privateFolder, $testPublicFolder, $testPrivateFolder)

Expand All@@ -262,6 +263,40 @@ if (Test-Path -Path $templateModuleFolder) {
Write-Host ' Renamed example function files' -ForegroundColor Green
}

# Rename files in docs/en-US/ that contain {{ModuleName}} placeholder (e.g., about_{{ModuleName}}.help.md)
$docsFolder = Join-Path -Path $PSScriptRoot -ChildPath 'docs/en-US'
if (Test-Path -Path $docsFolder) {
$docsFiles = Get-ChildItem -Path $docsFolder -File | Where-Object {
$_.Name -match '\{\{ModuleName\}\}'
}
foreach ($file in $docsFiles) {
$newName = $file.Name -replace '\{\{ModuleName\}\}', $ModuleName
Rename-Item -Path $file.FullName -NewName $newName
Write-Verbose "Renamed: $($file.Name) -> $newName"
}
if ($docsFiles) {
Write-Host " Renamed docs/en-US files" -ForegroundColor Green
}
}

# Replace template-facing README.md with the module-facing README.template.md
# (placeholders inside README.template.md were already substituted by the file-processing loop above)
$readmeTemplate = Join-Path -Path $PSScriptRoot -ChildPath 'README.template.md'
$readmePath = Join-Path -Path $PSScriptRoot -ChildPath 'README.md'
if (Test-Path -Path $readmeTemplate) {
Move-Item -Path $readmeTemplate -Destination $readmePath -Force
Write-Host ' Generated module README.md from template' -ForegroundColor Green
}

# Replace template-facing CHANGELOG.md with the module-facing CHANGELOG.template.md
# (placeholders inside CHANGELOG.template.md were already substituted by the file-processing loop above)
$changelogTemplate = Join-Path -Path $PSScriptRoot -ChildPath 'CHANGELOG.template.md'
$changelogPath = Join-Path -Path $PSScriptRoot -ChildPath 'CHANGELOG.md'
if (Test-Path -Path $changelogTemplate) {
Move-Item -Path $changelogTemplate -Destination $changelogPath -Force
Write-Host ' Generated module CHANGELOG.md from template' -ForegroundColor Green
}

# Initialize Git repository if requested
if (-not $NoGitInit) {
$gitFolder = Join-Path -Path $PSScriptRoot -ChildPath '.git'
Expand DownExpand Up@@ -303,7 +338,7 @@ Write-Host '========================================' -ForegroundColor Green
Write-Host ''
Write-Host 'Next steps:' -ForegroundColor Cyan
Write-Host " 1. Review the generated files in the $ModuleName folder"
Write-Host ' 2. Update the README.md with your project details'
Write-Host ' 2. Review README.md and adjust to taste'
Write-Host ' 3. Add your functions to the Public/ and Private/ folders'
Write-Host ' 4. Run ./build.ps1 -Task Test to verify everything works'
Write-Host ' 5. Push to your GitHub repository'
Expand Down
27 changes: 26 additions & 1 deletion PSScriptAnalyzerSettings.psd1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
# https://learn.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/using-scriptanalyzer
@{
IncludeRules = @('*')
IncludeDefaultRules = $true

IncludeRules = @(
# Default rules
'PS*'
)

# If IncludeRules and ExcludeRules are empty, all rules will be applied
ExcludeRules = @()

Rules = @{
# PSUseCompatibleSyntax = @{
# # This turns the rule on (setting it to false will turn it off)
# Enable = $true

# # List the targeted versions of PowerShell here
# TargetVersions = @(
# '5.1',
# '7.2'
# )
# }
# PSUseCompatibleCmdlets = @{
# compatibility = @('core-7.2.0-windows')
# }
}
}
Loading