Skip to content

Commit

Permalink
Merge pull request #97 from PlagueHO/Issue-79-C
Browse files Browse the repository at this point in the history
Complete Support for Composite Resources in Wiki pages
  • Loading branch information
PlagueHO authored Jul 13, 2021
2 parents 5b663a8 + fdc2b99 commit 5be73af
Show file tree
Hide file tree
Showing 8 changed files with 1,217 additions and 6 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Added private functions:
- `Get-CompositeResourceSchemaPropertyContent` - Returns markdown for
composite resource properties returned by `Get-CompositeSchemaObject`.
- `New-DscCompositeResourceWikiPage` - Returns the markdown content for a
wiki page for a DSC composite resource.

### Changed

- `New-DscResourceWikiPage`
- Added support for creating wiki pages for composite resources.

## [0.9.0] - 2021-07-08

### Added
Expand Down
84 changes: 84 additions & 0 deletions source/Private/Get-CompositeResourceSchemaPropertyContent.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<#
.SYNOPSIS
Get-CompositeResourceSchemaPropertyContent is used to generate the parameter content
for the wiki page.
.DESCRIPTION
Get-CompositeResourceSchemaPropertyContent is used to generate the parameter content
for the wiki page.
.PARAMETER Property
A hash table with properties that is returned by Get-CompositeSchemaObject in
the property 'property'.
.PARAMETER UseMarkdown
If certain text should be output as markdown, for example values of the
hashtable property ValueMap.
.EXAMPLE
$content = Get-CompositeResourceSchemaPropertyContent -Property @(
@{
Name = 'StringProperty'
State = 'Required'
Type = 'String'
ValidateSet = @('Value1','Value2')
Description = 'Any description'
}
)
Returns the parameter content based on the passed array of parameter metadata.
#>
function Get-CompositeResourceSchemaPropertyContent
{
[CmdletBinding()]
[OutputType([System.String[]])]
param
(
[Parameter(Mandatory = $true)]
[System.Collections.Hashtable[]]
$Property,

[Parameter()]
[System.Management.Automation.SwitchParameter]
$UseMarkdown
)

$stringArray = [System.String[]] @()

$stringArray += '| Parameter | Attribute | DataType | Description | Allowed Values |'
$stringArray += '| --- | --- | --- | --- | --- |'

foreach ($currentProperty in $Property)
{
$propertyLine = "| **$($currentProperty.Name)** " + `
"| $($currentProperty.State) " + `
"| $($currentProperty.Type) |"

if (-not [System.String]::IsNullOrEmpty($currentProperty.Description))
{
$propertyLine += ' ' + $currentProperty.Description
}

$propertyLine += ' |'

if (-not [System.String]::IsNullOrEmpty($currentProperty.ValidateSet))
{
$valueMap = $currentProperty.ValidateSet

if ($UseMarkdown.IsPresent)
{
$valueMap = $valueMap | ForEach-Object -Process {
'`{0}`' -f $_
}
}

$propertyLine += ' ' + ($valueMap -join ', ')
}

$propertyLine += ' |'

$stringArray += $propertyLine
}

return (, $stringArray)
}
127 changes: 127 additions & 0 deletions source/Private/New-DscCompositeResourceWikiPage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<#
.SYNOPSIS
New-DscCompositeResourceWikiPage generates wiki pages for composite resources
that can be uploaded to GitHub to use as public documentation for a module.
.DESCRIPTION
The New-DscCompositeResourceWikiPage cmdlet will review all of the composite and
in a specified module directory and will output the Markdown files to the
specified directory. These help files include details on the property types
for each resource, as well as a text description and examples where they exist.
.PARAMETER OutputPath
Where should the files be saved to.
.PARAMETER SourcePath
The path to the root of the DSC resource module (where the PSD1 file is found,
not the folder for and individual DSC resource).
.PARAMETER BuiltModulePath
The path to the root of the built DSC resource module, e.g.
'output/MyResource/1.0.0'.
.PARAMETER Force
Overwrites any existing file when outputting the generated content.
.EXAMPLE
New-DscCompositeResourceWikiPage `
-SourcePath C:\repos\MyResource\source `
-BuiltModulePath C:\repos\MyResource\output\MyResource\1.0.0 `
-OutputPath C:\repos\MyResource\output\WikiContent
This example shows how to generate wiki documentation for a specific module.
#>
function New-DscCompositeResourceWikiPage
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.String]
$OutputPath,

[Parameter(Mandatory = $true)]
[System.String]
$SourcePath,

[Parameter(Mandatory = $true)]
[System.String]
$BuiltModulePath,

[Parameter()]
[System.Management.Automation.SwitchParameter]
$Force
)

$compositeSearchPath = Join-Path -Path $SourcePath -ChildPath '\**\*.schema.psm1'
$compositeSchemaFiles = @(Get-ChildItem -Path $compositeSearchPath -Recurse)

Write-Verbose -Message ($script:localizedData.FoundCompositeFilesMessage -f $compositeSchemaFiles.Count, $SourcePath)

# Loop through all the Schema files found in the modules folder
foreach ($compositeSchemaFile in $compositeSchemaFiles)
{
$compositeSchemaObject = Get-CompositeSchemaObject -FileName $compositeSchemaFile.FullName

[System.Array] $readmeFile = Get-ChildItem -Path $compositeSchemaFile.DirectoryName |
Where-Object -FilterScript {
$_.Name -like 'readme.md'
}

if ($readmeFile.Count -eq 1)
{
Write-Verbose -Message ($script:localizedData.GenerateWikiPageMessage -f $compositeSchemaObject.Name)

$output = New-Object -TypeName System.Text.StringBuilder

$null = $output.AppendLine("# $($compositeSchemaObject.Name)")
$null = $output.AppendLine('')
$null = $output.AppendLine('## Parameters')
$null = $output.AppendLine('')

$propertyContent = Get-CompositeResourceSchemaPropertyContent -Property $compositeSchemaObject.Parameters -UseMarkdown

foreach ($line in $propertyContent)
{
$null = $output.AppendLine($line)
}

$descriptionContent = Get-Content -Path $readmeFile.FullName -Raw

# Change the description H1 header to an H2
$descriptionContent = $descriptionContent -replace '# Description', '## Description'
$null = $output.AppendLine()
$null = $output.AppendLine($descriptionContent)

$examplesPath = Join-Path -Path $SourcePath -ChildPath ('Examples\Resources\{0}' -f $compositeSchemaObject.Name)

$examplesOutput = Get-ResourceExampleAsMarkdown -Path $examplesPath

if ($examplesOutput.Length -gt 0)
{
$null = $output.Append($examplesOutput)
}

$outputFileName = "$($compositeSchemaObject.Name).md"
$savePath = Join-Path -Path $OutputPath -ChildPath $outputFileName

Write-Verbose -Message ($script:localizedData.OutputWikiPageMessage -f $savePath)

$null = Out-File `
-InputObject ($output.ToString() -replace '\r?\n', "`r`n") `
-FilePath $savePath `
-Encoding utf8 `
-Force:$Force
}
elseif ($readmeFile.Count -gt 1)
{
Write-Warning -Message ($script:localizedData.MultipleDescriptionFileFoundWarning -f $compositeSchemaObject.Name, $readmeFile.Count)
}
else
{
Write-Warning -Message ($script:localizedData.NoDescriptionFileFoundWarning -f $compositeSchemaObject.Name)
}
}
}
12 changes: 7 additions & 5 deletions source/Public/New-DscResourceWikiPage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
to use as public documentation for a module.
.DESCRIPTION
The New-DscResourceWikiPage cmdlet will review all of the MOF-based and
class-based resources in a specified module directory and will output the
Markdown files to the specified directory. These help files include details
on the property types for each resource, as well as a text description and
examples where they exist.
The New-DscResourceWikiPage cmdlet will review all of the MOF-based,
class-based and composite resources in a specified module directory and will
output the Markdown files to the specified directory. These help files include
details on the property types for each resource, as well as a text description
and examples where they exist.
.PARAMETER OutputPath
Where should the files be saved to.
Expand Down Expand Up @@ -58,4 +58,6 @@ function New-DscResourceWikiPage
New-DscMofResourceWikiPage @PSBoundParameters

New-DscClassResourceWikiPage @PSBoundParameters

New-DscCompositeResourceWikiPage @PSBoundParameters
}
2 changes: 1 addition & 1 deletion source/en-US/DscResource.DocGenerator.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ ConvertFrom-StringData @'
InvokeGitStandardOutputMessage = git standard output: '{0}'
InvokeGitStandardErrorMessage = git standard error: '{0}'
InvokeGitExitCodeMessage = git exit code: '{0}'
FoundCompositeFilesMessage = Found {0} composite files in path '{1}'.
FoundCompositeFilesMessage = Found {0} composite schema files in path '{1}'.
CommentBasedHelpBlockNotFound = A comment-based help block in source file '{0}' could not be found.
CommentBasedHelpBlockNotAtTopMessage = A comment-based help block in source file '{0}' was found, but is not at the top of the file.
CompositeResourceMultiConfigError = {1} composite resources were found in the source file '{0}'. This is not currently supported. Please separate these into different scripts.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#region HEADER
$script:projectPath = "$PSScriptRoot\..\..\.." | Convert-Path
$script:projectName = (Get-ChildItem -Path "$script:projectPath\*\*.psd1" | Where-Object -FilterScript {
($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and
$(try
{
Test-ModuleManifest -Path $_.FullName -ErrorAction Stop
}
catch
{
$false
})
}).BaseName

$script:moduleName = Get-Module -Name $script:projectName -ListAvailable | Select-Object -First 1
Remove-Module -Name $script:moduleName -Force -ErrorAction 'SilentlyContinue'

Import-Module $script:moduleName -Force -ErrorAction 'Stop'
#endregion HEADER

InModuleScope $script:moduleName {
Describe 'Get-CompositeResourceSchemaPropertyContent' {
BeforeAll {
$mockClassProperties = @(
@{
Name = 'StringProperty'
State = 'Required'
Type = 'String'
ValidateSet = $null
Description = 'Any description'
}
@{
Name = 'StringValueMapProperty'
State = 'Required'
Type = 'String'
ValidateSet = @(
'Value1'
'Value2'
)
Description = 'Any description'
}
@{
Name = 'StringArrayWriteProperty'
State = 'Write'
Type = 'String[]'
ValidateSet = $null
Description = 'Any description'
}
)
}

It 'Should return the expected content as a string array' {
$result = Get-CompositeResourceSchemaPropertyContent -Property $mockClassProperties

$result[0] | Should -Be '| Parameter | Attribute | DataType | Description | Allowed Values |'
$result[1] | Should -Be '| --- | --- | --- | --- | --- |'
$result[2] | Should -Be '| **StringProperty** | Required | String | Any description | |'
$result[3] | Should -Be '| **StringValueMapProperty** | Required | String | Any description | Value1, Value2 |'
$result[4] | Should -Be '| **StringArrayWriteProperty** | Write | String[] | Any description | |'
}
}
}
Loading

0 comments on commit 5be73af

Please sign in to comment.