Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ScriptAutomate
Last active September 5, 2019 02:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ScriptAutomate/28712f09f5726394e55e5790d8c8ac62 to your computer and use it in GitHub Desktop.
Save ScriptAutomate/28712f09f5726394e55e5790d8c8ac62 to your computer and use it in GitHub Desktop.
PowerShell Helpers Proof-of-Concept for Comment-Based Help Generation via Parsing of AWS CFN UserGuide GitHub Docs
<#
Tested On:
PSVersion PSEdition
--------- ---------
6.2.2 Core
Prereqs:
AWS DOCS
- git clone https://github.com/awsdocs/aws-cloudformation-user-guide.git
CFN Spec File
- Invoke-WebRequest 'https://d1uauaxba7bl26.cloudfront.net/latest/gzip/CloudFormationResourceSpecification.json' -OutFile 'CloudFormationResourceSpecification.json'
Run:
- Import-Module AWSCFNDocHelpers.psm1
- $HelpDocs = New-CFNHelpDoc # Generates help doc objects
#>
function ConvertTo-CFNBasePoshObject {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[Object]$CFNRawResourceObject,
[String]$CFNRawResourceName
)
process {
$FunctionNoun = "VS{0}{1}{2}" -f $CFNRawResourceName.split('::')[0], $CFNRawResourceName.split('::')[1], $CFNRawResourceName.split('::')[2]
$FunctionNoun = $FunctionNoun.replace(".", "")
$NewFunctionSplat = @{
'FunctionName' = "New-$FunctionNoun"
'Link' = $CFNRawResourceObject.Documentation
}
$ParameterObjects = @()
if ($CFNRawResourceObject.Properties) {
foreach ($ParameterProperty in ($CFNRawResourceObject.Properties | Get-Member -MemberType NoteProperty).Name) {
$CFNResourcePropertyObject = $CFNRawResourceObject.Properties."$ParameterProperty"
if ($CFNResourcePropertyObject.PrimitiveType) {
$ParameterType = $CFNResourcePropertyObject.PrimitiveType
}
else {
$ParameterType = $CFNResourcePropertyObject.Type
}
$ParameterObject = [PSCustomObject]@{
'ParameterName' = "$ParameterProperty"
'ParameterType' = $ParameterType
'ParameterMandatory' = $CFNResourcePropertyObject.Required
}
$ParameterObjects += $ParameterObject
}
$NewFunctionSplat.Add('Parameters', $ParameterObjects)
}
[PSCustomObject]$NewFunctionSplat
}
}
function Get-CFNPoshHelp {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
[String]$Link,
[Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
[String[]]$Parameters,
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
[String]$FunctionName,
[String]$DocRepoRoot = 'aws-cloudformation-user-guide' # aws docs repo default name
)
Write-Verbose "Checking help: $Link"
$DocPath = "$DocRepoRoot/doc_source/$($Link.split('/')[-1] -replace ".html",".md")"
if (Test-Path $DocPath) {
$HelpDocs = Get-Content $DocPath | ? { $_ }
# Create Description from everything before Syntax section
$NotesPosition = 2
foreach ($Help in $HelpDocs[2..($HelpDocs.count - 1)]) {
if ($Help -like "## Syntax*") {
break
}
else {
$NotesPosition++
}
}
$Description = @()
foreach ($Help in $HelpDocs[1..($NotesPosition - 1)]) {
$Description += ($Help.Trim() -replace '`', '' -replace '\\', '' -replace '[[]', '' -replace '\)', '').Replace('](', ': ')
}
$NotesEnd = $NotesPosition
foreach ($Help in $HelpDocs[($NotesPosition + 1)..($HelpDocs.count - 1)]) {
if ($Help -like "## *") {
break
}
else {
$NotesEnd++
}
}
$ParamHelp = @()
if ($Parameters) {
foreach ($Parameter in $Parameters) {
$ParameterDescription = @()
$ParameterStart = $NotesEnd
$ParameterDescription = @()
foreach ($Help in $HelpDocs[($NotesEnd + 1)..($HelpDocs.count - 1)]) {
Write-Verbose "Checking Index $ParameterStart"
Write-Verbose "$($Help -replace '``','')"
if (($Help -replace '`', '') -like "$Parameter <a*") {
Write-Verbose "$Help"
Write-Verbose "Position: $Found"
break
}
$ParameterStart++
}
Write-Verbose "$Parameter Index Start Found: $ParameterStart"
foreach ($Help in $HelpDocs[($ParameterStart + 2)..($HelpDocs.count - 1)]) {
if ($Help -like "`*Required`*: *") {
break
}
$ParameterDescription += ($Help.Trim() -replace '`', '' -replace '\\', '' -replace '[[]', '' -replace '\)', '').Replace('](', ': ').Replace('(', '')
}
Write-Verbose "$ParameterDescription"
$ParamHelp += [PSCustomObject]@{
'ParameterName' = $Parameter
'ParameterDescription' = $ParameterDescription -join "`n"
}
}
}
$Links = @()
$Links += "$Link"
$DocHash = @{
'FunctionName' = $FunctionName
'Links' = $Links
'Synopsis' = $Description[0]
'Description' = $Description -join "`n"
}
if ($Parameters) {
$DocHash += @{'Parameters' = $ParamHelp }
}
[PSCustomObject]$DocHash
}
else {
Write-Warning "[$FunctionName] Broken link. No documentation Found. Skipping."
Write-Warning "[$FunctionName] Expected: $DocPath"
}
}
function New-CFNHelpDoc {
param(
[String]$CFNSpecFile = 'CloudFormationResourceSpecification.json'
)
$CFNSpec = Get-Content $CFNSpecFile | ConvertFrom-Json
foreach ($Resource in ($CFNSpec.ResourceTypes | Get-Member -MemberType NoteProperty).Name) {
$ResourceBase = $CFNSpec.ResourceTypes."$Resource" | ConvertTo-CFNBasePoshObject -CFNRawResourceName "$Resource"
Get-CFNPoshHelp -FunctionName "$($ResourceBase.FunctionName)" -Link $ResourceBase.Link -Parameters $ResourceBase.Parameters.ParameterName
}
foreach ($ResourceProperty in ($CFNSpec.PropertyTypes | Get-Member -MemberType NoteProperty).Name) {
$ResourcePropertyBase = $CFNSpec.PropertyTypes."$ResourceProperty" | ConvertTo-CFNBasePoshObject -CFNRawResourceName "$ResourceProperty"
$ParamSplat = @{'FunctionName' = "$($ResourcePropertyBase.FunctionName)" }
if ($ResourcePropertyBase.Link) {
$ParamSplat += @{'Link' = $ResourcePropertyBase.Link }
if ($ResourcePropertyBase.Parameters) {
$ParamSplat += @{'Parameters' = $ResourcePropertyBase.Parameters.ParameterName }
}
Get-CFNPoshHelp @ParamSplat
}
else {
Write-Warning "[$($ResourcePropertyBase.FunctionName)] No Documentation Property / Link for $ResourceProperty. Skipping."
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment