Skip to content
Open
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@

### Changed

- [**#105**](https://github.com/psake/PowerShellBuild/issues/105)
**Breaking:** help generation moved from `platyPS` 0.14.x to
[`Microsoft.PowerShell.PlatyPS`](https://www.powershellgallery.com/packages/Microsoft.PowerShell.PlatyPS)
1.x. PlatyPS is also no longer a `RequiredModules` entry, so
`Install-Module PowerShellBuild` no longer installs it — the two PlatyPS
modules cannot be loaded into one process, so forcing the new one into every
session would break any consumer still holding the old one. Install it
yourself if you build help. `$PSBPreference.Docs.AlphabeticParamsOrder` is
removed, because PlatyPS 1.x always sorts parameters alphabetically and
offers no way back. Generated markdown carries the 1.x schema, though its
on-disk layout is unchanged. `Build-PSBuildUpdatableHelp` warns and returns
until the cabinet pipeline migrates in
[#152](https://github.com/psake/PowerShellBuild/issues/152); it could never
succeed in 0.8.x either, see
[#169](https://github.com/psake/PowerShellBuild/issues/169). See the
[v0.8 → v1.0 migration guide](docs/migration-v0.8-to-v1.0.md).

- [**#144**](https://github.com/psake/PowerShellBuild/issues/144)
**Breaking:** `Test-PSBuildScriptAnalysis` now counts PSScriptAnalyzer
`ParseError` records alongside `Error`. A file that does not parse at all
Expand Down Expand Up @@ -62,7 +79,7 @@
that passed before may now correctly fail.
- [**#96**](https://github.com/psake/PowerShellBuild/issues/96)
`Test-PSBuildScriptAnalysis` no longer fails with a path-resolution error
when `SettingsPath` is not supplied. An unsupplied path was forwarded to

Check warning on line 82 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (unsupplied) Suggestions: (unapplied, unsullied, unspoiled, unstapled, unsupported)
PSScriptAnalyzer as `-Settings ''`, which resolved against the current
directory and threw before any analysis ran, so the function's own
documented example could not run as written.
Expand Down
13 changes: 6 additions & 7 deletions PowerShellBuild/IB.tasks.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@



$analyzePreReqs = {

Check warning on line 48 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$result = $true
if (-not $PSBPreference.Test.ScriptAnalysis.Enabled) {
Write-Warning 'Script analysis is not enabled.'
Expand All @@ -59,7 +59,7 @@
}

# Synopsis: Execute PSScriptAnalyzer tests
Task Analyze -If (. $analyzePreReqs) Build, {

Check warning on line 62 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$analyzeParams = @{
Path = $PSBPreference.Build.ModuleOutDir
SeverityThreshold = $PSBPreference.Test.ScriptAnalysis.FailBuildOnSeverityLevel
Expand All @@ -68,7 +68,7 @@
Test-PSBuildScriptAnalysis @analyzeParams
}

$pesterPreReqs = {

Check warning on line 71 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$result = $true
if (-not $PSBPreference.Test.Enabled) {
Write-Warning 'Pester testing is not enabled.'
Expand All @@ -86,7 +86,7 @@
}

# Synopsis: Execute Pester tests
Task Pester -If (. $pesterPreReqs) Build, {

Check warning on line 89 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$pesterParams = @{
Path = $PSBPreference.Test.RootDir
ModuleName = $PSBPreference.General.ModuleName
Expand All @@ -107,10 +107,10 @@



$genMarkdownPreReqs = {

Check warning on line 110 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$result = $true
if (-not (Get-Module platyPS -ListAvailable)) {
Write-Warning "platyPS module is not installed. Skipping [$($task.name)] task."
if (-not (Get-Module Microsoft.PowerShell.PlatyPS -ListAvailable)) {
Write-Warning "Microsoft.PowerShell.PlatyPS module is not installed. Skipping [$($task.name)] task."
$result = $false
}
$result
Expand All @@ -124,7 +124,6 @@
DocsPath = $PSBPreference.Docs.RootDir
Locale = $PSBPreference.Help.DefaultLocale
Overwrite = $PSBPreference.Docs.Overwrite
AlphabeticParamsOrder = $PSBPreference.Docs.AlphabeticParamsOrder
ExcludeDontShow = $PSBPreference.Docs.ExcludeDontShow
UseFullTypeName = $PSBPreference.Docs.UseFullTypeName
}
Expand All @@ -133,8 +132,8 @@

$genHelpFilesPreReqs = {
$result = $true
if (-not (Get-Module platyPS -ListAvailable)) {
Write-Warning "platyPS module is not installed. Skipping [$($task.name)] task."
if (-not (Get-Module Microsoft.PowerShell.PlatyPS -ListAvailable)) {
Write-Warning "Microsoft.PowerShell.PlatyPS module is not installed. Skipping [$($task.name)] task."
$result = $false
}
$result
Expand All @@ -147,8 +146,8 @@

$genUpdatableHelpPreReqs = {
$result = $true
if (-not (Get-Module platyPS -ListAvailable)) {
Write-Warning "platyPS module is not installed. Skipping [$($task.name)] task."
if (-not (Get-Module Microsoft.PowerShell.PlatyPS -ListAvailable)) {
Write-Warning "Microsoft.PowerShell.PlatyPS module is not installed. Skipping [$($task.name)] task."
$result = $false
}
$result
Expand Down
1 change: 0 additions & 1 deletion PowerShellBuild/PowerShellBuild.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
RequiredModules = @(
@{ModuleName = 'BuildHelpers'; ModuleVersion = '2.0.16' }
@{ModuleName = 'Pester'; ModuleVersion = '5.6.1' }
@{ModuleName = 'platyPS'; ModuleVersion = '0.14.1' }
@{ModuleName = 'psake'; ModuleVersion = '4.9.0' }
)
FunctionsToExport = @(
Expand Down
50 changes: 43 additions & 7 deletions PowerShellBuild/Public/Build-PSBuildMAMLHelp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,49 @@ function Build-PSBuildMAMLHelp {

# Generate the module's primary MAML help file
foreach ($locale in $helpLocales) {
$externalHelpParams = @{
Path = [IO.Path]::Combine($Path, $locale)
OutputPath = [IO.Path]::Combine($DestinationPath, $locale)
Force = $true
ErrorAction = 'SilentlyContinue'
Verbose = $VerbosePreference
$localePath = [IO.Path]::Combine($Path, $locale)

# Only command documents can be exported. A module landing page imports without
# complaint but fails on export, and that failure aborts the whole batch and writes
# nothing, so it has to be filtered out rather than caught.
$commandMarkdownPath = @(
Measure-PlatyPSMarkdown -Path ([IO.Path]::Combine($localePath, '*.md')) |
Where-Object { $_.Filetype -match 'CommandHelp' } |
Select-Object -ExpandProperty 'FilePath'
)
if ($commandMarkdownPath.Count -eq 0) {
continue
}

# Export-MamlCommandHelp writes to <OutputFolder>/<ModuleName>/<external help file>,
# a level deeper than PowerShell looks and with the file name taken from the
# document's front matter. Export to a staging directory and move the results so the
# published layout stays <DestinationPath>/<locale>/<ModuleName>-help.xml, which is
# where every consumer's existing .ExternalHelp directive already points.
$stagingPath = [IO.Path]::Combine(
[IO.Path]::GetTempPath(),
[IO.Path]::GetRandomFileName()
)
try {
$mamlFile = @(
Import-MarkdownCommandHelp -Path $commandMarkdownPath |
Export-MamlCommandHelp -OutputFolder $stagingPath -Force -Verbose:($VerbosePreference -eq 'Continue')
)

$localeDestinationPath = [IO.Path]::Combine($DestinationPath, $locale)
if (-not (Test-Path -LiteralPath $localeDestinationPath)) {
New-Item -Path $localeDestinationPath -ItemType Directory -Force > $null
}

foreach ($file in $mamlFile) {
# The file name is whatever the document's "external help file" front matter
# says, which Build-PSBuildMarkdown pins to the 0.14.x casing. Renaming here
# instead would leave the markdown and the MAML disagreeing about the name.
$destinationFilePath = Join-Path -Path $localeDestinationPath -ChildPath $file.Name
Move-Item -LiteralPath $file.FullName -Destination $destinationFilePath -Force
}
} finally {
Remove-Item -LiteralPath $stagingPath -Recurse -Force -ErrorAction SilentlyContinue
}
New-ExternalHelp @externalHelpParams > $null
}
}
105 changes: 73 additions & 32 deletions PowerShellBuild/Public/Build-PSBuildMarkdown.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
Creates PlatyPS markdown documents based on comment-based help of module.
.DESCRIPTION
Creates PlatyPS markdown documents based on comment-based help of module.

Existing command markdown is refreshed in place with Update-MarkdownCommandHelp so
hand-written prose survives, and markdown for commands that have no document yet is
generated with New-MarkdownCommandHelp.
.PARAMETER ModulePath
The path to the module
.PARAMETER ModuleName
Expand All @@ -14,10 +18,8 @@
The locale to save the markdown docs.
.PARAMETER Overwrite
Overwrite existing markdown files and use comment based help as the source of truth.
.PARAMETER AlphabeticParamsOrder
Order parameters alphabetically by name in PARAMETERS section. There are 5 exceptions: -Confirm, -WhatIf, -IncludeTotalCount, -Skip, and -First parameters will be the last.
.PARAMETER ExcludeDontShow
Exclude the parameters marked with `DontShow` in the parameter attribute from the help content.

Check warning on line 22 in PowerShellBuild/Public/Build-PSBuildMarkdown.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Dont) Suggestions: (dent, dint, doit, dolt, dona)
.PARAMETER UseFullTypeName
Indicates that the target document will use a full type name instead of a short name for parameters.
.EXAMPLE
Expand All @@ -42,9 +44,6 @@
[parameter(Mandatory)]
[bool]$Overwrite,

[parameter(Mandatory)]
[bool]$AlphabeticParamsOrder,

[parameter(Mandatory)]
[bool]$ExcludeDontShow,

Expand All @@ -60,41 +59,83 @@
return
}

if (-not (Test-Path -LiteralPath $DocsPath)) {
New-Item -Path $DocsPath -ItemType Directory > $null
$localePath = [IO.Path]::Combine($DocsPath, $Locale)
if (-not (Test-Path -LiteralPath $localePath)) {
New-Item -Path $localePath -ItemType Directory -Force > $null
}

if (Get-ChildItem -LiteralPath $DocsPath -Filter *.md -Recurse) {
$updateMDParams = @{
AlphabeticParamsOrder = $AlphabeticParamsOrder
ExcludeDontShow = $ExcludeDontShow
UseFullTypeName = $UseFullTypeName
Verbose = $VerbosePreference
}
Get-ChildItem -LiteralPath $DocsPath -Directory | ForEach-Object {
Update-MarkdownHelp -Path $_.FullName @updateMDParams > $null
# Refresh first. Update-MarkdownCommandHelp merges the module's current surface into
# existing documents and preserves hand-written prose, where regenerating would
# discard it. -NoBackup keeps it from littering the docs tree with .md.bak files.
# Module landing pages are a different document type and are left alone.
$existingMarkdown = @(
Get-ChildItem -LiteralPath $localePath -Filter '*.md' -File -ErrorAction SilentlyContinue
)
if ($existingMarkdown.Count -gt 0) {
$existingCommandMarkdown = @(
$existingMarkdown.Where({
(Measure-PlatyPSMarkdown -LiteralPath $_.FullName).Filetype -match 'CommandHelp'
})
)
if ($existingCommandMarkdown.Count -gt 0) {
Update-MarkdownCommandHelp -LiteralPath $existingCommandMarkdown.FullName -NoBackup > $null
}
}

# ErrorAction set to SilentlyContinue so this command will not overwrite an existing MD file.
$newMDParams = @{
Module = $ModuleName
Locale = $Locale
OutputFolder = [IO.Path]::Combine($DocsPath, $Locale)
AlphabeticParamsOrder = $AlphabeticParamsOrder
ExcludeDontShow = $ExcludeDontShow
UseFullTypeName = $UseFullTypeName
ErrorAction = 'SilentlyContinue'
Verbose = $VerbosePreference
}
if ($Overwrite) {
$newMDParams.Add('Force', $true)
$newMDParams.Remove('ErrorAction')
# New-MarkdownCommandHelp always writes to <OutputFolder>/<ModuleName>, and without
# -Force it skips existing files with a warning rather than an error. Generating into
# an empty staging directory and moving the results keeps the documented
# <DocsPath>/<Locale> layout and keeps Overwrite meaning what it did before.
$stagingPath = [IO.Path]::Combine(
[IO.Path]::GetTempPath(),
[IO.Path]::GetRandomFileName()
)
try {
$newMarkdownParams = @{
ModuleInfo = $moduleInfo
OutputFolder = $stagingPath
Locale = $Locale
# PlatyPS 1.x defaults this front matter key to "<Module>-Help.xml", where
# 0.14.x wrote "<Module>-help.xml". The key is what Export-MamlCommandHelp
# names the MAML file after, so pinning it here keeps the markdown, the MAML
# file name, and any existing .ExternalHelp directive in agreement -- and
# keeps help resolving on case-sensitive file systems. Renaming after export
# would fix the file name while leaving the front matter disagreeing with it.
Metadata = @{ 'external help file' = "$ModuleName-help.xml" }
# Compared explicitly rather than passing $VerbosePreference through. The
# preference is an ActionPreference, and converting it to a switch uses the
# underlying number, so Stop and Inquire turn verbose output on even though
# neither asked for it.
Verbose = ($VerbosePreference -eq 'Continue')
}
if ($ExcludeDontShow) {
$newMarkdownParams.ExcludeDontShow = $true
}
# The sense of this option inverted in PlatyPS 1.x: full type names are now the
# default and abbreviation is the switch, so the old setting maps to its absence.
if (-not $UseFullTypeName) {
$newMarkdownParams.AbbreviateParameterTypeName = $true
}
New-MarkdownCommandHelp @newMarkdownParams > $null

$generatedPath = [IO.Path]::Combine($stagingPath, $ModuleName)
$generatedMarkdown = @(
Get-ChildItem -LiteralPath $generatedPath -Filter '*.md' -File -ErrorAction SilentlyContinue
)
foreach ($markdownFile in $generatedMarkdown) {
$destinationPath = Join-Path -Path $localePath -ChildPath $markdownFile.Name
if ((Test-Path -LiteralPath $destinationPath) -and -not $Overwrite) {
# Already refreshed above; regenerating would discard hand-written prose.
continue
}
Move-Item -LiteralPath $markdownFile.FullName -Destination $destinationPath -Force
}
} finally {
Remove-Item -LiteralPath $stagingPath -Recurse -Force -ErrorAction SilentlyContinue
}
New-MarkdownHelp @newMDParams > $null
} catch {
Write-Error ($LocalizedData.FailedToGenerateMarkdownHelp -f $_)
} finally {
Remove-Module $moduleName
Remove-Module $ModuleName
}
}
57 changes: 16 additions & 41 deletions PowerShellBuild/Public/Build-PSBuildUpdatableHelp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ function Build-PSBuildUpdatableHelp {
Create updatable help .cab file based on PlatyPS markdown help.
.DESCRIPTION
Create updatable help .cab file based on PlatyPS markdown help.

Not implemented against PlatyPS 1.x yet. The cabinet pipeline is migrated in
psake/PowerShellBuild#152 along with the three defects in #169 that prevented this
function from ever succeeding. Until then it reports that updatable help was skipped
and returns without writing anything.
.PARAMETER DocsPath
Path to PlatyPS markdown help files.
.PARAMETER OutputPath
Expand All @@ -14,8 +19,11 @@ function Build-PSBuildUpdatableHelp {
.EXAMPLE
PS> Build-PSBuildUpdatableHelp -DocsPath ./docs -OutputPath ./Output/UpdatableHelp

Create help .cab file based on PlatyPS markdown help.
Reports that updatable help is not available and returns.
#>
# The parameters are unused only because the body is stubbed. They stay so the public
# signature does not change twice -- once here and again when #152 restores the body.
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
[CmdletBinding()]
param(
[parameter(Mandatory)]
Expand All @@ -27,44 +35,11 @@ function Build-PSBuildUpdatableHelp {
[string]$Module = $ModuleName
)

if ($null -ne $IsWindows -and -not $IsWindows) {
Write-Warning $LocalizedData.MakeCabNotAvailable
return
}

$helpLocales = (Get-ChildItem -Path $DocsPath -Directory).Name

# Create updatable help output directory
if (-not (Test-Path -LiteralPath $OutputPath)) {
$newItemSplat = @{
ItemType = 'Directory'
Verbose = $VerbosePreference
Path = $OutputPath
}
New-Item @newItemSplat > $null
} else {
Write-Verbose ($LocalizedData.DirectoryAlreadyExists -f $OutputPath)
$removeItemSplat = @{
Recurse = $true
Force = $true
Verbose = $VerbosePreference
}
Get-ChildItem $OutputPath | Remove-Item @removeItemSplat
}

# Generate updatable help files. Note: this will currently update the
# version number in the module's MD file in the metadata.
foreach ($locale in $helpLocales) {
$cabParams = @{
CabFilesFolder = [IO.Path]::Combine($moduleOutDir, $locale)
LandingPagePath = [IO.Path]::Combine(
$DocsPath,
$locale,
"$Module.md"
)
OutputFolder = $OutputPath
Verbose = $VerbosePreference
}
New-ExternalHelpCab @cabParams > $null
}
# Deliberately references no PlatyPS command. Naming New-ExternalHelpCab here is enough to
# make PowerShell autoload platyPS 0.14.2 on any session that resolves it, and once that
# module is loaded, Microsoft.PowerShell.PlatyPS can no longer be imported in the same
# process -- both ship their own YamlDotNet with different assembly identities. Leaving the
# old call in place would poison every session that still has 0.14.2 installed, which is
# every consumer part-way through the upgrade.
Write-Warning $LocalizedData.UpdatableHelpNotMigrated
}
9 changes: 3 additions & 6 deletions PowerShellBuild/build.properties.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,13 @@
# Whether to overwrite existing markdown files and use comment based help as the source of truth
Overwrite = $false

# Whether to order parameters alphabetically by name in PARAMETERS section.
# Value passed to New-MarkdownHelp and Update-MarkdownHelp.
AlphabeticParamsOrder = $false

# Exclude the parameters marked with `DontShow` in the parameter attribute from the help content.

Check warning on line 129 in PowerShellBuild/build.properties.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Dont) Suggestions: (dent, dint, doit, dolt, dona)
# Value passed to New-MarkdownHelp and Update-MarkdownHelp.
# Value passed to New-MarkdownCommandHelp.
ExcludeDontShow = $false

# Indicates that the target document will use a full type name instead of a short name for parameters.
# Value passed to New-MarkdownHelp and Update-MarkdownHelp.
# PlatyPS 1.x writes full type names by default, so $false is passed through as
# New-MarkdownCommandHelp's -AbbreviateParameterTypeName switch.
UseFullTypeName = $false
}
Publish = @{
Expand Down Expand Up @@ -173,10 +170,10 @@

# Name of the environment variable that holds the Base64-encoded PFX certificate.
# Used by the EnvVar source and as the presence-detection key for Auto.
CertificateEnvVar = 'SIGNCERTIFICATE'

Check warning on line 173 in PowerShellBuild/build.properties.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (SIGNCERTIFICATE)

# Name of the environment variable that holds the PFX password (EnvVar source).
CertificatePasswordEnvVar = 'CERTIFICATEPASSWORD'

Check warning on line 176 in PowerShellBuild/build.properties.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (CERTIFICATEPASSWORD)

# File system path to a PFX/P12 certificate file (PfxFile source).
PfxFilePath = $null
Expand Down
1 change: 1 addition & 0 deletions PowerShellBuild/en-US/Messages.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ NoCommandsExported=No commands have been exported. Skipping markdown generation.
FailedToGenerateMarkdownHelp=Failed to generate markdown help. : {0}
AddingFileToPsm1=Adding [{0}] to PSM1
MakeCabNotAvailable=MakeCab.exe is not available. Cannot create help cab.
UpdatableHelpNotMigrated=Updatable help was skipped. The cabinet pipeline has not been migrated to Microsoft.PowerShell.PlatyPS 1.x yet; see psake/PowerShellBuild#152.
DirectoryAlreadyExists=Directory already exists [{0}].
PathLongerThan3Chars=Path [{0}] must be longer than 3 characters.
BuildSystemDetails=Build System Details:
Expand Down
Loading
Loading