Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate markdown documentation for module help #55

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
7 changes: 5 additions & 2 deletions .build/profiles/docs/runbook.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Use this file to manage the phases and tasks.
#>

Build | jobs @(

'Build' | jobs @(
'convert.codeblocks.pwsh',
'format.common.params',
'add.component.heading',
'invoke.markdownlint'
)
59 changes: 59 additions & 0 deletions .build/profiles/docs/tasks/add.component.heading.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

param(

)

#Synopsis: Add a COMPONENT header to the markdown file
task add.component.heading {
Import-Module 'C:\Users\TAldrich\projects\github\PSMarkdig\source\PSMarkdig' -Force
$componentMap = @{}
$BuildInfo | Foreach-Module {
$config = $_
$config.SourceInfo
| Where-Object Type -Like 'function'
| ForEach-Object {
if (-not ([string]::IsNullorEmpty($_.Component))) {
$componentMap.Add($_.Name, $_.Component)
}
}
}

foreach ($mdDoc in (Get-ChildItem -Path .\docs -Filter '*.md' -Recurse)) {
# Check to see if Component heading already exists first
$componentHeading = "`r`n## COMPONENT`r`n" | PSMarkdig\New-MarkdownElement

logDebug "Markdown file $($mdDoc.BaseName)"

if ($componentMap.ContainsKey( $mdDoc.BaseName )) {
$componentName = $componentMap[$mdDoc.BaseName]
$componentText = "`r`n$componentName`r`n" | PSMarkdig\New-MarkdownElement

$doc = PSMarkdig\Import-Markdown $mdDoc

logDebug "- Adding Component $componentName"

if ($null -ne $doc) {
logDebug "- Imported markdown. $($doc.Count) elements"

$headings = PSMarkdig\Get-MarkdownHeading $doc
if ($null -ne $headings) {
logDebug " - There are $($headings.Count) headings"
$lastHeading = $headings | Select-Object -Last 1
}

try {
logDebug "- Adding $($componentHeading.GetType().FullName) to doc"

PSMarkdig\Add-MarkdownElement -Element $componentHeading -Document $doc -Before $lastHeading
logDebug "- Adding $($componentText.GetType().FullName) to doc"
PSMarkdig\Add-MarkdownElement -Element $componentText -Document $doc -Before $lastHeading

PSMarkdig\Write-MarkdownElement $doc | Set-Content $mdDoc -NoNewline
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}
Remove-Variable componentHeading, componentText, doc
}
}
}
}
88 changes: 88 additions & 0 deletions .build/profiles/docs/tasks/add.task.config.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

#Synopsis: Create task config files from the source
task add.task.config {
logDebug "CopyAdditional: ($($CopyAdditionalItems | ConvertTo-Psd))"
Import-Module '.\tools\BuildProperties.psm1'

$taskConfigDir = '.\.build\profiles\default\config\tasks'
$scriptPropertyMap = Get-BuildScriptProperty

$propertyData = Get-ParameterData
#TODO: To make this task idempotent, the additon should skip if the field and value already exist

foreach ($map in $scriptPropertyMap.GetEnumerator()) {
$name = $map.Name
logDebug "Property: $name"
try {
$currentValue = Get-BuildProperty $name
} catch {
$currentValue = (Get-Variable $name -ValueOnly)
}
logDebug "Value: $($currentValue | ConvertTo-Psd)"
$commentText = (
($propertyData
| Where-Object Name -Like $name
| Select-Object -Expand Help
) -join "`n")

$instances = $map.Value
:file foreach ($instance in $instances) {
$taskConfigFile = $instance.File -replace 'build\.ps1', 'config.psd1'
logDebug "- Task configuration file: $taskConfigFile"
$taskConfigPath = (Join-Path $taskConfigDir $taskConfigFile)

if (Test-Path $taskConfigPath) {
logDebug " - already exists"
$currentContent = Import-Psd $taskConfigPath
if ($currentContent.ContainsKey($name)) {
logDebug " - already has a $name key"
if ($currentContent['$name'] -eq $currentValue) {
logDebug " - and content matches"
continue file
} else {
logDebug " - but content doesn't match"
$xml = Import-PsdXml -Path $taskConfigPath
Set-Psd -Xml $xml -Value $currentValue -XPath (-join ('//Data/Table/Item[@Key="', $name, '"]'))
Export-PsdXml -Path $taskConfigPath -Xml $xml
continue file
}
} else {
logDebug " - does not have a $name key"
$xml = Import-PsdXml -Path $taskConfigPath
$table = $xml.Data.Table
$newLine = $xml.CreateElement('NewLine')
$comment = $xml.CreateElement('Comment')
[void]$table.AppendChild($newLine)
[void]$table.AppendChild($comment)
[void]$table.AppendChild($newLine)
$currentValueData = $currentValue | ConvertTo-Psd | Convert-PsdToXml
$newItem = $xml.CreateElement('Item')
[void]$newItem.SetAttribute('Key', $name)
$newItem.InnerXml = $currentValueData

Export-PsdXml -Path $taskConfigPath -Xml $xml
}
} else {
logDebug " - does not exist"
$data = @{
$name = $currentValue
}

$data | ConvertTo-Psd | Set-Content $taskConfigPath
$xml = Import-PsdXml -Path $taskConfigPath
$newLine = $xml.CreateElement('NewLine')
$comment = $xml.CreateElement('Comment')
$comment.InnerText = (-join (
'<# ',
$commentText,
' #>'))
$table = $xml.Data.Table
[void]$table.PrependChild($newLine)
[void]$table.PrependChild($comment)
[void]$table.PrependChild($newLine)
Export-PsdXml -Path $taskConfigPath -Xml $xml
}
$taskConfigPath | Convert-LineEnding -LF
}
}
}
18 changes: 18 additions & 0 deletions .build/profiles/docs/tasks/convert.codeblocks.pwsh.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

#SYNOPSIS: PlatyPS does not add 'powershell' to the fenced code blocks. This task does.
task convert.codeblocks.pwsh {
foreach ($mdDoc in (Get-ChildItem -Path .\docs -Filter "*.md" -Recurse)) {
$doc = Import-Markdown $mdDoc.FullName
$blocks = $doc | Where-Object {
$_.GetType().FullName -like 'Markdig.Syntax.FencedCodeBlock'
}
foreach ($block in $blocks) {
if ([string]::IsNullOrEmpty($block.UnescapedInfo)) {
$block.Info = 'powershell'
$block.UnescapedInfo = 'powershell'
}
}
logInfo "Setting codeblocks to powershell in $($mdDoc.Name)"
$doc | Write-MarkdownElement | Set-Content $mdDoc.FullName -NoNewline
}
}
11 changes: 11 additions & 0 deletions .build/profiles/docs/tasks/format.common.params.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

# Synopsis: Remove the list of common parameters from the documentation
task format.common.params {
$replacementText = "This cmdlet supports the common parameters.`nFor more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216)."
foreach ($mdDoc in (Get-ChildItem -Path .\docs -Filter '*.md' -Recurse)) {
logInfo "Replacing Common Parameters extra info in $($mdDoc.Name)"
(get-content $mdDoc -Raw ) -replace [regex]::Escape(
'This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).'
) , $replacementText | Set-Content $mdDoc -NoNewline
}
}
35 changes: 35 additions & 0 deletions .build/profiles/docs/tasks/invoke.markdownlint.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

# Synopsis: Format documentation with markdownlint
task invoke.markdownlint {
$tempFile = [System.IO.Path]::GetTempFileName()
$basedir = "$env:APPDATA\npm"
$node = 'node.exe'
$mdLintPath = "$basedir/node_modules/markdownlint-cli/markdownlint.js"

if (Test-Path $mdLintPath) {

[string[]]$argList = @()

$argList += $mdLintPath
$argList += '.\docs\stitch'
$argList += '--fix'
$argList += '--output'
$argList += $tempFile
$argList += '--json'
$argList += '--quiet'
logInfo "Calling markdownlint"
& $node $argList

$lintErrors = Get-Content $tempFile | ConvertFrom-Json
if ($lintErrors.Count -gt 0) {
foreach ($lintError in $lintErrors) {
'{0}:{1} - {2}' -f $lintError.fileName , $lintError.lineNumber, $lineError.ruleDescription
}
}
Remove-Item $tempFile

logInfo "Markdown Errors: $($lintErrors.Count)"
} else {
throw "Markdownlint is not installed. Run npm install -g markdownlint-cli"
}
}
47 changes: 47 additions & 0 deletions .build/profiles/docs/tasks/set.external.help.build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

#SYNOPSIS: Remove the Comment-based help in the given file and replace it with `.EXTERNALHELPFILE
task set.external.help {
$BuildInfo | Foreach-Module {
$config = $_
$externalHelpText = @"
<#
.EXTERNALHELPFILE $($config.Name)-help.xml
#>
"@
$functions = $config.SourceInfo | Where-Object Type -Like 'function'
foreach ($source in $functions) {
if ($null -ne $env:TestExternalHelp) {
if ($source.Name -notlike $env:TestExternalHelp) {
continue
} else {
logInfo "TestExternalHelp is set to $env:TestExternalHelp"
logInfo "processing File"
}
}
if ($source.Tokens.Count -gt 0) {
$commentBasedHelp = $source.Tokens | Where-Object {
($_.Kind -like 'Comment' ) -and
($_.Extent.Text -match '\.SYNOPSIS' )
}
}
if ($null -ne $commentBasedHelp) {
logInfo "$($source.Name) has comment-based help"
#! in Get-SourceItemInfo ToString is overloaded to output the content of the file
$content = $source.ToString()
$start = ($commentBasedHelp.Extent.StartOffSet - 1)
$end = ($commentBasedHelp.Extent.EndOffset + 1)

logInfo "help starts at $start and ends at $end"
logInfo "Help Content:`n$(-join ($content[$start..$end]))"

# Now we "splice" the content
logInfo "Splicing content"
$preComment = (-join ($content[0..$start]))
$postComment = (-join ($content[$end..-1]))

$preComment, $externalHelpText, $postComment | Set-Content $source.Path

}
}
}
}
Loading