My purpose was to have a PowerShell perform that removes any remark inside my code besides assist feedback. Fortunately, with assist from Chris Dent, I created a technique that eliminates feedback from any given file and makes it manufacturing prepared. Whereas it is a part of my module builder PSPublishModule, I am attaching it if you wish to attempt it by yourself.
perform Take away-Feedback { <# .SYNOPSIS Take away feedback from PowerShell file .DESCRIPTION Take away feedback from PowerShell file and optionally take away empty strains By default feedback in param block will not be eliminated By default feedback earlier than param block will not be eliminated .PARAMETER SourceFilePath File path to the supply file .PARAMETER Content material Content material of the file .PARAMETER DestinationFilePath File path to the vacation spot file. If not offered, the content material shall be returned .PARAMETER RemoveEmptyLines Take away empty strains if a couple of empty line is discovered .PARAMETER RemoveAllEmptyLines Take away all empty strains from the content material .PARAMETER RemoveCommentsInParamBlock Take away feedback in param block. By default feedback in param block will not be eliminated .PARAMETER RemoveCommentsBeforeParamBlock Take away feedback earlier than param block. By default feedback earlier than param block will not be eliminated .EXAMPLE Take away-Feedback -SourceFilePath 'C:SupportGitHubPSPublishModuleExamplesTestScript.ps1' -DestinationFilePath 'C:SupportGitHubPSPublishModuleExamplesTestScript1.ps1' -RemoveAllEmptyLines -RemoveCommentsInParamBlock -RemoveCommentsBeforeParamBlock .NOTES Many of the work carried out by Chris Dent, with enhancements by Przemyslaw Klys #> [CmdletBinding(DefaultParameterSetName="FilePath")] param( [Parameter(Mandatory, ParameterSetName="FilePath")] [alias('FilePath', 'Path', 'LiteralPath')][string] $SourceFilePath, [Parameter(Mandatory, ParameterSetName="Content")][string] $Content material, [Parameter(ParameterSetName="Content")] [Parameter(ParameterSetName="FilePath")] [alias('Destination')][string] $DestinationFilePath, [Parameter(ParameterSetName="Content")] [Parameter(ParameterSetName="FilePath")] [switch] $RemoveAllEmptyLines, [Parameter(ParameterSetName="Content")] [Parameter(ParameterSetName="FilePath")] [switch] $RemoveEmptyLines, [Parameter(ParameterSetName="Content")] [Parameter(ParameterSetName="FilePath")] [switch] $RemoveCommentsInParamBlock, [Parameter(ParameterSetName="Content")] [Parameter(ParameterSetName="FilePath")] [switch] $RemoveCommentsBeforeParamBlock, [Parameter(ParameterSetName="Content")] [Parameter(ParameterSetName="FilePath")] [switch] $DoNotRemoveSignatureBlock ) if ($SourceFilePath) { $Fullpath = Resolve-Path -LiteralPath $SourceFilePath $Content material = [IO.File]::ReadAllText($FullPath, [System.Text.Encoding]::UTF8) } $Tokens = $Errors = @() $Ast = [System.Management.Automation.Language.Parser]::ParseInput($Content material, [ref]$Tokens, [ref]$Errors) #$functionDefinition = $ast.Discover({ $args[0] -is [FunctionDefinitionAst] }, $false) $groupedTokens = $Tokens | Group-Object { $_.Extent.StartLineNumber } $DoNotRemove = $false $DoNotRemoveCommentParam = $false $CountParams = 0 $ParamFound = $false $SignatureBlock = $false $toRemove = foreach ($line in $groupedTokens) { if ($Ast.Physique.ParamBlock.Extent.StartLineNumber -gt $line.Identify) { proceed } $tokens = $line.Group for ($i = 0; $i -lt $line.Rely; $i++) { $token = $tokens[$i] if ($token.Extent.StartOffset -lt $Ast.Physique.ParamBlock.Extent.StartOffset) { proceed } # Lets discover feedback between perform and param block and never take away them if ($token.Extent.Textual content -eq 'perform') { if (-not $RemoveCommentsBeforeParamBlock) { $DoNotRemove = $true } proceed } if ($token.Extent.Textual content -eq 'param') { $ParamFound = $true $DoNotRemove = $false } if ($DoNotRemove) { proceed } # lets discover feedback between param block and finish of param block if ($token.Extent.Textual content -eq 'param') { if (-not $RemoveCommentsInParamBlock) { $DoNotRemoveCommentParam = $true } proceed } if ($ParamFound -and ($token.Extent.Textual content -eq '(' -or $token.Extent.Textual content -eq '@(')) { $CountParams += 1 } elseif ($ParamFound -and $token.Extent.Textual content -eq ')') { $CountParams -= 1 } if ($ParamFound -and $token.Extent.Textual content -eq ')') { if ($CountParams -eq 0) { $DoNotRemoveCommentParam = $false $ParamFound = $false } } if ($DoNotRemoveCommentParam) { proceed } # if token not remark we go away it as is if ($token.Type -ne 'Remark') { proceed } # type of ineffective to not take away signature block if we're not eradicating feedback # this modifications the construction of a file and signature shall be invalid if ($DoNotRemoveSignatureBlock) { if ($token.Type -eq 'Remark' -and $token.Textual content -eq '# SIG # Start signature block') { $SignatureBlock = $true proceed } if ($SignatureBlock) { if ($token.Type -eq 'Remark' -and $token.Textual content -eq '# SIG # Finish signature block') { $SignatureBlock = $false } proceed } } $token } } $toRemove = $toRemove | Type-Object { $_.Extent.StartOffset } -Descending foreach ($token in $toRemove) { $StartIndex = $token.Extent.StartOffset $HowManyChars = $token.Extent.EndOffset - $token.Extent.StartOffset $content material = $content material.Take away($StartIndex, $HowManyChars) } if ($RemoveEmptyLines) { # Take away empty strains if a couple of empty line is discovered. If it is only one line, go away it as is #$Content material = $Content material -replace '(?m)^s*$', '' #$Content material = $Content material -replace "(`r?`n){2,}", "`r`n" # $Content material = $Content material -replace "(`r?`n){2,}", "`r`n`r`n" $Content material = $Content material -replace '(?m)^s*$', '' $Content material = $Content material -replace "(?:`r?`n|n|r)", "`r`n" } if ($RemoveAllEmptyLines) { # Take away all empty strains from the content material $Content material = $Content material -replace '(?m)^s*$(r?n)?', '' } if ($Content material) { $Content material = $Content material.Trim() } if ($DestinationFilePath) Set-Content material -Path $DestinationFilePath -Encoding utf8 else { $Content material } }
This perform has a few parameters:
- SourceFilePath – present a path to a file you need to clear up
- Content material – alternatively to file manner, you can even present a code (for instance
Get-Content material -Uncooked $FilePath)
- DestinationFilePath – path to file the place to save lots of the cleaned-up file. If not offered, the content material shall be returned immediately as a string.
- RemoveEmptyLines – as a part of the cleanup, it tries to take away empty strains, however provided that there’s a couple of. That is helpful in case you have assist with the perform
- RemoveAllEmptyLines – removes all empty strains from a file
- RemoveCommentsInParamBlock – by default, throughout cleanup, any feedback contained in the param block will not be eliminated, as these are sometimes associated to assist. However if you would like, you can even take away these with this swap.
- RemoveCommentsBeforeParamBlock – I do not take away something between the perform and param block by default. This ensures that the assistance I create for the perform stays the place it’s. However if you wish to take away it, that is how one can repair it.
- DoNotRemoveSignatureBlock – by default, we take away any signature from a file, however if you wish to forestall that from occurring, you should use this swap. It will not provide you with a lot as a result of the signature is not going to work after you take away something from the file anyhow – however it’s there.