Skip to content

Instantly share code, notes, and snippets.

@ninmonkey
Last active June 26, 2020 15:08
Show Gist options
  • Save ninmonkey/6f01162b6ee792d36a6df315b2a4e56d to your computer and use it in GitHub Desktop.
Save ninmonkey/6f01162b6ee792d36a6df315b2a4e56d to your computer and use it in GitHub Desktop.
Compare Command docs across powershell versions
@'
Usage:
> cd c:\github\powershell
> git clone https://github.com/MicrosoftDocs/PowerShell-Docs.git
set $doc_path
$doc_path = 'c:\github\powershell\PowerShell-Docs\reference'
Example:
> Compare-DocVersion 5.1 7.0 Get-WinEvent
Tip 1]
If Git is installed on windows, enable 'diff.exe' by adding it to your path
This gives you several linux cli commands: grep, less, tail, diff, etc.
$BashFromGit = "$Env:ProgramFiles\Git\usr\bin"
$Env:Path, $BashFromGit -join ';'
Tip 2]
Powershell tab-complete shows one match (it uses function 'TabCompleteNext')
You can display all choices using the function 'MenuComplete'
Try:
# Description: autocomplete opens a menu to select valid choices
ps> Set-PSReadLineKeyHandler -Key "Ctrl+Spacebar" -Function MenuComplete
Now type 'ls -' and then ctrl+space
ls -
This works on positional parameters like:
> Compare-DocVersion <ctrl+space here>
5.1 6 7.0 7.1 # displays this
for 'diff.exe' and 'diff' usage see:
> diff.exe --help | code -
or 'man diff' in bash
'@
$doc_path = 'G:\2020-github-downloads\powershell\powershell-core\PowerShell-Docs\reference' | Get-Item -ea Stop
$regex = @{
version_number = '(?x)
# or prefix relative $doc_path
PowerShell-Docs\\reference\\
(?<version>
[\d\.]+
)
'
}
function hr {
<#
.synopsis
cli visual separation / horizontal rule
.example
> hr
Full bar
.example
hr 3
Bar surrounded by 3 lines
#>
@(
"`n",
("=" * $host.ui.RawUI.WindowSize.Width),
"`n"
) -join ''
}
function Get-ValidDocVersion {
<#
.synopsis
initial test, diff help file on commands across versions
.example
Get-ValidDocVersion
Version FullName
------- --------
5.1 c:\...\PowerShell-Docs\reference\5.1
6 c:\...\PowerShell-Docs\reference\6
7.0 c:\...\PowerShell-Docs\reference\7.0
7.1 c:\...\PowerShell-Docs\reference\7.1
#>
param(
[Parameter(Mandatory=$false, HelpMessage="only return array of version numbers", ParameterSetName="ListOnly")]
[switch]$AsList,
[Parameter(Position = 0, Mandatory, HelpMessage = "Specify version number", ParameterSetName="VersionNum")]
[ArgumentCompleter( {
param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
Get-ValidDocVersion -AsList
})]
[ValidateScript( {
$_ -in (Get-ValidDocVersion -AsList)
})]
[string]$Version
)
$results = Get-ChildItem $doc_path -Directory | ForEach-Object {
if ($_.FullName -match $regex.version_number ) {
[PSCustomObject]@{
Version = $Matches.Version
FullName = $_.FullName
}
}
}
$AsList ? $results.Version : $results
}
function Compare-DocVersion {
<#
.SYNOPSIS
Compare docs from different versions of powershell 5.1 and newer
.DESCRIPTION
Searches and autocompletes using a local clone of: <https://github.com/MicrosoftDocs/PowerShell-Docs.git>
You can test run using -WhatIf or -Confirm
Most parameters autocomplete
.EXAMPLE
ps> Compare-DocVersion 5.1 7.0 Export-Csv
Default comparison uses VS Code
.EXAMPLE
ps> Compare-DocVersion 5.1 7.0 get-winevent -ViewMode diff
Compare with 'diff.exe' when it's in $Env:PAth
.EXAMPLE
ps> Compare-DocVersion -CommandName Get-Unique 5.1 7.0
.NOTES
for dynamic completion, see also: [Dynamic ValdateSet](https://vexx32.github.io/2018/11/29/Dynamic-ValidateSet/)\
#>
[CmdletBinding(SupportsShouldProcess)]
param (
[Parameter(Position = 0, Mandatory, HelpMessage = "First version to test (use autocomplete)")]
[ArgumentCompleter( {
param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
Get-ValidDocVersion -AsList
})]
[ValidateScript( {
$_ -in (Get-ValidDocVersion -AsList)
})]
[string]$Version1,
[Parameter(Position = 1, Mandatory, HelpMessage = "Second version to test")]
[ArgumentCompleter( {
param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
Get-ValidDocVersion -AsList
})]
[ValidateScript( {
$_ -in (Get-ValidDocVersion -AsList)
})]
[string]$Version2,
[Parameter(Position = 2, Mandatory, HelpMessage = "Command to compare")]
[String]$CommandName,
[Parameter(Mandatory=$false, Position=3, HelpMessage='Which mode: use VS Code or diff.exe?')]
[ValidateSet('VSCode', 'diff')]
$ViewMode = 'VSCode'
)
begin {}
process {
hr 4
'{0}: Version {1} -> {2}' -f ($CommandName, $Version1, $Version2)# | Write-Verbose
$version_info = Get-ValidDocVersion
$BasePath1 = Get-Item ($version_info | Where-Object { $_.Version -eq $Version1 }).FullName
$BasePath2 = Get-Item ($version_info | Where-Object { $_.Version -eq $Version2 }).FullName
Test-Path $BasePath1 -ErrorAction Stop | Write-Verbose
Test-Path $BasePath2 -ErrorAction Stop | Write-Verbose
$File1 = Get-ChildItem $BasePath1 -Recurse "${commandname}.md"
$File2 = Get-ChildItem $BasePath2 -Recurse "${commandname}.md"
if($File1.count -gt 1) { Write-Error "multiple results for: $BasePath1`n$File1" }
if($File2.count -gt 1) { Write-Error "multiple results for: $BasePath2`n$File2" }
Test-Path $File1 -ErrorAction Stop | Write-Verbose
Test-Path $File2 -ErrorAction Stop | Write-Verbose
switch($ViewMode) {
'diff' {
if ($PSCmdlet.ShouldProcess("$File1 $File2", "diff.exe file1 file2")) {
# explicit because powershell aliases 'diff'
diff.exe $file1 $file2 --color=always
}
}
default {
if ($PSCmdlet.ShouldProcess("$File1 $File2", "code --diff")) {
code --diff "$file1" "$file2"
}
}
}
}
end {}
}
if($run_test) {
hr
Get-ValidDocVersion
hr
Compare-DocVersion 5.1 7.0 get-winevent -WhatIf
Compare-DocVersion 5.1 7.0 get-winevent -ViewMode diff
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment