Commands/Measure-Help.ps1
function Measure-Help { <# .Synopsis Determines the percentage of documentation .Description Determines the percentage of documentation in a given script .Example dir -Filter *.ps1 | Measure-Help .EXAMPLE Get-Command -Module HelpOut | Measure-Help .Example Measure-Help { # This script has some documentation, and then a bunch of code that literally does nothing $null = $null # The null equivilancy $null * 500 # x times nothing is still nothing $null / 100 # Nothing out of 100 } | Select-Object -ExpandProperty PercentageDocumented .LINK Get-Help #> [CmdletBinding(DefaultParameterSetName='FilePath')] param( # The path to the file [Parameter(Mandatory,ValueFromPipelineByPropertyName,Position=0,ParameterSetName='FilePath')] [Alias('Fullname')] [string] $FilePath, # A PowerShell script block [Parameter(Mandatory,ParameterSetName='ScriptBlock',ValueFromPipelineByPropertyName)] [ScriptBlock] $ScriptBlock, # The name of the script being measured. [Parameter(ParameterSetName='ScriptBlock',ValueFromPipelineByPropertyName)] [string] $Name ) begin { $fileList = New-Object Collections.ArrayList $ScriptBlockList = New-Object Collections.ArrayList $NameList = New-Object Collections.ArrayList filter OutputDocRatio { $scriptText = $_ $scriptToken = [Management.Automation.PSParser]::Tokenize($scriptText, [ref]$null) # A quick tight little loop to sum # the lengths of different types in one # pass (Group-Object would work, but would be slower) $commentLength= 0 $otherLength = 0 $blockCommentLength = 0 $inlineCommentLength = 0 $blockComments = @() $inlineComments = @() $totalLength = 0 foreach ($token in $ScriptToken) { $totalLength+=$token.Length if ($token.Type -eq 'Comment') { if ($token.Content.StartsWith('<#')) { $blockComments+=$token $blockCommentLength += $token.Length } else { $inlineComments+=$token $inlineCommentLength += $token.Length } $commentLength+=$token.Length } else { $otherLength+=$token.Length } } # The percent is easy to calculate $percent =$commentLength * 100 / $totalLength @{ CommentLength = $commentLength TokenLength = $otherLength CommentPercent = $percent BlockComments = $blockComments BlockCommentLength = $blockCommentLength InlineComments = $inlineComments InlineCommentLength = $inlineCommentLength } } } process { if ($PSCmdlet.ParameterSetName -eq 'FilePath') { $fileList.AddRange(@($FilePath)) } elseif ($PSCmdlet.ParameterSetName -eq 'ScriptBlock') { $null = $ScriptBlockList.Add($ScriptBlock) $null = $NameList.Add($Name) } } end { if ($ScriptBlockList.Count) { $scriptBlockIndex =0 foreach ($sb in $ScriptBlockList) { [PSCustomObject]([Ordered]@{ PSTypeName = "Documentation.Percentage" Name = $NameList[$scriptBlockIndex] ScriptBlock = $sb } + ($sb | OutputDocRatio)) $scriptBlockIndex++ } } if ($fileList.Count) { foreach ($f in $fileList) { $RF = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($F) if (-not $rf) { continue } $fileItem = Get-Item -LiteralPath $RF $sb = $null $sb = try { [ScriptBlock]::Create([IO.File]::ReadAllText($RF)) } catch { $null } if ($sb) { [PSCustomObject]([Ordered]@{ PSTypeName = "File.Documentation.Percentage" Name = $fileItem.Name FilePath = "$rf" ScriptBlock = $sb } + ($sb | OutputDocRatio)) } } } } } |