From a5702ff99488e5e6fe5d8bf2f4adce23b4db6136 Mon Sep 17 00:00:00 2001 From: David Gardiner Date: Sat, 10 Feb 2018 13:31:18 +1030 Subject: [PATCH 1/6] Initial support for vsts-cli - Add all pr commands and short commands - Add test for filtering params Implements #549 Not implemented in this PR: 'subgroups' (work-items set-vote policies) --- src/GitParamTabExpansion.ps1 | 24 ++++++++++++++ src/GitTabExpansion.ps1 | 32 ++++++++++++++---- test/GitParamTabExpansionVsts.Tests.ps1 | 43 +++++++++++++++++++++++++ test/TabExpansion.Tests.ps1 | 7 ++++ 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 test/GitParamTabExpansionVsts.Tests.ps1 diff --git a/src/GitParamTabExpansion.ps1 b/src/GitParamTabExpansion.ps1 index 1ee5f4782..5592a1834 100644 --- a/src/GitParamTabExpansion.ps1 +++ b/src/GitParamTabExpansion.ps1 @@ -81,6 +81,30 @@ $longGitParams = @{ whatchanged = 'since' } +$shortVstsGlobal = 'h o' +$shortVstsParams = @{ + abandon = "i $shortVstsGlobal" + create = "d i p r s t $shortVstsGlobal" + complete = "i $shortVstsGlobal" + list = "i p r s t $shortVstsGlobal" + reactivate = "i $shortVstsGlobal" + 'set-vote' = "i $shortVstsGlobal" + show = "i $shortVstsGlobal" + update = "d i $shortVstsGlobal" +} + +$longVstsGlobal = 'debug help output query verbose' +$longVstsParams = @{ + abandon = "id detect instance $longVstsGlobal" + create = "auto-complete delete-source-branch work-items bypass-policy bypass-policy-reason description detect instance merge-commit-message open project repository reviewers source-branch squash target-branch title $longVstsGlobal" + complete = "id detect instance $longVstsGlobal" + list = " $longVstsGlobal" + reactivate = " $longVstsGlobal" + 'set-vote' = " $longVstsGlobal" + show = " $longVstsGlobal" + update = " $longVstsGlobal" +} + # Variable is used in GitTabExpansion.ps1 $gitParamValues = @{ blame = @{ diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index d6a9c66cc..f0c3bea26 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -8,6 +8,7 @@ $Global:GitTabSettings = New-Object PSObject -Property @{ $subcommands = @{ bisect = "start bad good skip reset visualize replay log run" notes = 'add append copy edit get-ref list merge prune remove show' + pr = 'create update show list complete abandon reactivate reviewers work-items set-vote policies' reflog = "show delete expire" remote = " add rename remove set-head set-branches @@ -56,6 +57,8 @@ $script:someCommands = @('add','am','annotate','archive','bisect','blame','branc $script:gitCommandsWithLongParams = $longGitParams.Keys -join '|' $script:gitCommandsWithShortParams = $shortGitParams.Keys -join '|' $script:gitCommandsWithParamValues = $gitParamValues.Keys -join '|' +$script:vstsCommandsWithShortParams = $shortVstsParams.Keys -join '|' +$script:vstsCommandsWithLongParams = $longVstsParams.Keys -join '|' try { if ($null -ne (git help -a 2>&1 | Select-String flow)) { @@ -218,15 +221,15 @@ function script:expandGitAlias($cmd, $rest) { } } -function script:expandLongParams($cmd, $filter) { - $longGitParams[$cmd] -split ' ' | +function script:expandLongParams($hash, $cmd, $filter) { + $hash[$cmd] -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object | ForEach-Object { -join ("--", $_) } } -function script:expandShortParams($cmd, $filter) { - $shortGitParams[$cmd] -split ' ' | +function script:expandShortParams($hash, $cmd, $filter) { + $hash[$cmd] -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object | ForEach-Object { -join ("-", $_) } @@ -264,6 +267,23 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { switch -regex ($lastBlock -replace "^$(Get-AliasPattern git) ","") { + # Handles git pr alias + "\!f\(\) \{ exec vsts code pr `"\$\@`"; \}; f\s+(?\S*)$" { + gitCmdOperations $subcommands 'pr' $matches['op'] + } + + # Handles git pr -- + "\!f\(\) \{ exec vsts code pr `"\$\@`"; \}; f\s+(?$vstsCommandsWithLongParams).*--(?\S*)$" + { + expandLongParams $longVstsParams $matches['cmd'] $matches['param'] + } + + # Handles git pr - + "\!f\(\) \{ exec vsts code pr `"\$\@`"; \}; f\s+(?$vstsCommandsWithShortParams).*-(?\S*)$" + { + expandShortParams $shortVstsParams $matches['cmd'] $matches['shortparam'] + } + # Handles git "^(?$($subcommands.Keys -join '|'))\s+(?\S*)$" { gitCmdOperations $subcommands $matches['cmd'] $matches['op'] @@ -400,12 +420,12 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { # Handles git -- "^(?$gitCommandsWithLongParams).* --(?\S*)$" { - expandLongParams $matches['cmd'] $matches['param'] + expandLongParams $longGitParams $matches['cmd'] $matches['param'] } # Handles git - "^(?$gitCommandsWithShortParams).* -(?\S*)$" { - expandShortParams $matches['cmd'] $matches['shortparam'] + expandShortParams $shortGitParams $matches['cmd'] $matches['shortparam'] } } } diff --git a/test/GitParamTabExpansionVsts.Tests.ps1 b/test/GitParamTabExpansionVsts.Tests.ps1 new file mode 100644 index 000000000..d79ccb648 --- /dev/null +++ b/test/GitParamTabExpansionVsts.Tests.ps1 @@ -0,0 +1,43 @@ +. $PSScriptRoot\Shared.ps1 + +Describe 'ParamsTabExpansion VSTS Tests' { + Context 'Push Parameters TabExpansion Tests' { + # Create a git alias for 'pr', as if we'd installed vsts-cli + BeforeEach { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] + $origPath = Get-Location + $temp = [System.IO.Path]::GetTempPath() + $repoPath = Join-Path $temp ([IO.Path]::GetRandomFileName()) + + &$gitbin init $repoPath + Set-Location $repoPath + + &$gitbin config alias.pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" + } + AfterEach { + Set-Location $origPath + if (Test-Path $repoPath) { + Remove-Item $repoPath -Recurse -Force + } + } + + It 'Tab completes git pr create parameters values' { + $result = & $module GitTabExpansionInternal 'git pr create --' + $result -contains '--auto-complete' | Should Be $true + } + It 'Tab completes git pr create auto-complete parameters values' { + $result = & $module GitTabExpansionInternal 'git pr create --auto-complete --' + $result -contains '--delete-source-branch' | Should Be $true + } + It 'Tab completes git pr create all short push parameters' { + $result = & $module GitTabExpansionInternal 'git pr create -' + $result -contains '-d' | Should Be $true + $result -contains '-i' | Should Be $true + $result -contains '-p' | Should Be $true + $result -contains '-r' | Should Be $true + $result -contains '-s' | Should Be $true + $result -contains '-h' | Should Be $true + $result -contains '-o' | Should Be $true + } + } +} diff --git a/test/TabExpansion.Tests.ps1 b/test/TabExpansion.Tests.ps1 index 21179504b..d558e4a79 100644 --- a/test/TabExpansion.Tests.ps1 +++ b/test/TabExpansion.Tests.ps1 @@ -167,6 +167,13 @@ Describe 'TabExpansion Tests' { } } + Context 'Vsts' { + It 'Tab completes pr options' { + $result = & $module GitTabExpansionInternal 'git pr ' + $result -contains 'abandon' | Should Be $true + } + } + Context 'Add/Reset/Checkout TabExpansion Tests' { BeforeEach { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] From 13e7e5760acb99215890e569867f4917a9be3f24 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 19 May 2018 17:11:28 -0500 Subject: [PATCH 2/6] Use NewGitTempRepo --- test/GitParamTabExpansionVsts.Tests.ps1 | 13 ++----------- test/TabExpansion.Tests.ps1 | 8 ++++++++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/test/GitParamTabExpansionVsts.Tests.ps1 b/test/GitParamTabExpansionVsts.Tests.ps1 index d79ccb648..4c3de2b1a 100644 --- a/test/GitParamTabExpansionVsts.Tests.ps1 +++ b/test/GitParamTabExpansionVsts.Tests.ps1 @@ -5,20 +5,11 @@ Describe 'ParamsTabExpansion VSTS Tests' { # Create a git alias for 'pr', as if we'd installed vsts-cli BeforeEach { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] - $origPath = Get-Location - $temp = [System.IO.Path]::GetTempPath() - $repoPath = Join-Path $temp ([IO.Path]::GetRandomFileName()) - - &$gitbin init $repoPath - Set-Location $repoPath - + $repoPath = NewGitTempRepo &$gitbin config alias.pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" } AfterEach { - Set-Location $origPath - if (Test-Path $repoPath) { - Remove-Item $repoPath -Recurse -Force - } + RemoveGitTempRepo $repoPath } It 'Tab completes git pr create parameters values' { diff --git a/test/TabExpansion.Tests.ps1 b/test/TabExpansion.Tests.ps1 index d558e4a79..bdcfdac59 100644 --- a/test/TabExpansion.Tests.ps1 +++ b/test/TabExpansion.Tests.ps1 @@ -168,6 +168,14 @@ Describe 'TabExpansion Tests' { } Context 'Vsts' { + BeforeEach { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] + $repoPath = NewGitTempRepo + &$gitbin config alias.pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" + } + AfterEach { + RemoveGitTempRepo $repoPath + } It 'Tab completes pr options' { $result = & $module GitTabExpansionInternal 'git pr ' $result -contains 'abandon' | Should Be $true From b74ca5745f2b8393b4efdf55da9b25314b06bc60 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 19 May 2018 17:13:19 -0500 Subject: [PATCH 3/6] Add vsts.pr as a "known alias" The idea "known alias" is that we can standardize handling of a particular alias command (e.g. 'git pr' pass-through to 'vsts code pr') without hooking on the alias name. For example, 'pr' could reasonably be used to manage GitHub, so this allows us to avoid using vsts tab expansion in that case. Namespacing the alias ('vsts.pr') prevents conflicts with a real alias. --- src/GitTabExpansion.ps1 | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index f0c3bea26..309f5461e 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -3,12 +3,15 @@ $Global:GitTabSettings = New-Object PSObject -Property @{ AllCommands = $false + KnownAliases = @{ + '!f() { exec vsts code pr "$@"; }; f' = 'vsts.pr' + } } $subcommands = @{ bisect = "start bad good skip reset visualize replay log run" notes = 'add append copy edit get-ref list merge prune remove show' - pr = 'create update show list complete abandon reactivate reviewers work-items set-vote policies' + 'vsts.pr' = 'create update show list complete abandon reactivate reviewers work-items set-vote policies' reflog = "show delete expire" remote = " add rename remove set-head set-branches @@ -45,7 +48,7 @@ $gitflowsubcommands = @{ } function script:gitCmdOperations($commands, $command, $filter) { - $commands.$command.Trim() -split '\s+' | Where-Object { $_ -like "$filter*" } + $commands[$command].Trim() -split '\s+' | Where-Object { $_ -like "$filter*" } } $script:someCommands = @('add','am','annotate','archive','bisect','blame','branch','bundle','checkout','cherry', @@ -213,7 +216,13 @@ function script:gitAliases($filter) { function script:expandGitAlias($cmd, $rest) { $alias = git config "alias.$cmd" + if ($alias) { + $known = $Global:GitTabSettings.KnownAliases[$alias] + if ($known) { + return "git $known$rest" + } + return "git $alias$rest" } else { @@ -268,18 +277,18 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { switch -regex ($lastBlock -replace "^$(Get-AliasPattern git) ","") { # Handles git pr alias - "\!f\(\) \{ exec vsts code pr `"\$\@`"; \}; f\s+(?\S*)$" { - gitCmdOperations $subcommands 'pr' $matches['op'] + "vsts\.pr\s+(?\S*)$" { + gitCmdOperations $subcommands 'vsts.pr' $matches['op'] } # Handles git pr -- - "\!f\(\) \{ exec vsts code pr `"\$\@`"; \}; f\s+(?$vstsCommandsWithLongParams).*--(?\S*)$" + "vsts\.pr\s+(?$vstsCommandsWithLongParams).*--(?\S*)$" { expandLongParams $longVstsParams $matches['cmd'] $matches['param'] } # Handles git pr - - "\!f\(\) \{ exec vsts code pr `"\$\@`"; \}; f\s+(?$vstsCommandsWithShortParams).*-(?\S*)$" + "vsts\.pr\s+(?$vstsCommandsWithShortParams).*-(?\S*)$" { expandShortParams $shortVstsParams $matches['cmd'] $matches['shortparam'] } From 7028d74cf3cb3d6662fa2ea6714438835281b366 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 19 May 2018 17:30:38 -0500 Subject: [PATCH 4/6] Add edge case tests --- src/GitTabExpansion.ps1 | 6 +++--- test/GitParamTabExpansionVsts.Tests.ps1 | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index 309f5461e..1c8002e32 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -231,21 +231,21 @@ function script:expandGitAlias($cmd, $rest) { } function script:expandLongParams($hash, $cmd, $filter) { - $hash[$cmd] -split ' ' | + $hash[$cmd].Trim() -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object | ForEach-Object { -join ("--", $_) } } function script:expandShortParams($hash, $cmd, $filter) { - $hash[$cmd] -split ' ' | + $hash[$cmd].Trim() -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object | ForEach-Object { -join ("-", $_) } } function script:expandParamValues($cmd, $param, $filter) { - $gitParamValues[$cmd][$param] -split ' ' | + $gitParamValues[$cmd][$param].Trim() -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object | ForEach-Object { -join ("--", $param, "=", $_) } diff --git a/test/GitParamTabExpansionVsts.Tests.ps1 b/test/GitParamTabExpansionVsts.Tests.ps1 index 4c3de2b1a..f02c6a346 100644 --- a/test/GitParamTabExpansionVsts.Tests.ps1 +++ b/test/GitParamTabExpansionVsts.Tests.ps1 @@ -12,6 +12,16 @@ Describe 'ParamsTabExpansion VSTS Tests' { RemoveGitTempRepo $repoPath } + It 'Tab completes empty for git pr oops parameters values' { + $result = & $module GitTabExpansionInternal 'git pr oops --' + $result | Should Be @() + } + + It 'Tab completes empty for git pr oops short parameter values' { + $result = & $module GitTabExpansionInternal 'git pr oops -' + $result | Should Be @() + } + It 'Tab completes git pr create parameters values' { $result = & $module GitTabExpansionInternal 'git pr create --' $result -contains '--auto-complete' | Should Be $true @@ -20,6 +30,17 @@ Describe 'ParamsTabExpansion VSTS Tests' { $result = & $module GitTabExpansionInternal 'git pr create --auto-complete --' $result -contains '--delete-source-branch' | Should Be $true } + + It 'Tab completes git pr show all parameters values' { + $result = & $module GitTabExpansionInternal 'git pr show --' + $result -contains '--' | Should Be $false + $result -contains '--debug' | Should Be $true + $result -contains '--help' | Should Be $true + $result -contains '--output' | Should Be $true + $result -contains '--query' | Should Be $true + $result -contains '--verbose' | Should Be $true + } + It 'Tab completes git pr create all short push parameters' { $result = & $module GitTabExpansionInternal 'git pr create -' $result -contains '-d' | Should Be $true From 489dabce7076a5e7f521aec2ea430053925416a0 Mon Sep 17 00:00:00 2001 From: Keith Dahlby Date: Sat, 19 May 2018 17:39:13 -0500 Subject: [PATCH 5/6] Test with non-standard vsts pr alias name --- test/GitParamTabExpansionVsts.Tests.ps1 | 16 +++++++++------- test/TabExpansion.Tests.ps1 | 6 ++++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/test/GitParamTabExpansionVsts.Tests.ps1 b/test/GitParamTabExpansionVsts.Tests.ps1 index f02c6a346..d2e708723 100644 --- a/test/GitParamTabExpansionVsts.Tests.ps1 +++ b/test/GitParamTabExpansionVsts.Tests.ps1 @@ -6,33 +6,35 @@ Describe 'ParamsTabExpansion VSTS Tests' { BeforeEach { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] $repoPath = NewGitTempRepo - &$gitbin config alias.pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" + + # Test with non-standard vsts pr alias name + &$gitbin config alias.test-vsts-pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" } AfterEach { RemoveGitTempRepo $repoPath } It 'Tab completes empty for git pr oops parameters values' { - $result = & $module GitTabExpansionInternal 'git pr oops --' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr oops --' $result | Should Be @() } It 'Tab completes empty for git pr oops short parameter values' { - $result = & $module GitTabExpansionInternal 'git pr oops -' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr oops -' $result | Should Be @() } It 'Tab completes git pr create parameters values' { - $result = & $module GitTabExpansionInternal 'git pr create --' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr create --' $result -contains '--auto-complete' | Should Be $true } It 'Tab completes git pr create auto-complete parameters values' { - $result = & $module GitTabExpansionInternal 'git pr create --auto-complete --' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr create --auto-complete --' $result -contains '--delete-source-branch' | Should Be $true } It 'Tab completes git pr show all parameters values' { - $result = & $module GitTabExpansionInternal 'git pr show --' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr show --' $result -contains '--' | Should Be $false $result -contains '--debug' | Should Be $true $result -contains '--help' | Should Be $true @@ -42,7 +44,7 @@ Describe 'ParamsTabExpansion VSTS Tests' { } It 'Tab completes git pr create all short push parameters' { - $result = & $module GitTabExpansionInternal 'git pr create -' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr create -' $result -contains '-d' | Should Be $true $result -contains '-i' | Should Be $true $result -contains '-p' | Should Be $true diff --git a/test/TabExpansion.Tests.ps1 b/test/TabExpansion.Tests.ps1 index bdcfdac59..99ce4656c 100644 --- a/test/TabExpansion.Tests.ps1 +++ b/test/TabExpansion.Tests.ps1 @@ -171,13 +171,15 @@ Describe 'TabExpansion Tests' { BeforeEach { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] $repoPath = NewGitTempRepo - &$gitbin config alias.pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" + + # Test with non-standard vsts pr alias name + &$gitbin config alias.test-vsts-pr "!f() { exec vsts code pr \`"`$`@\`"; }; f" } AfterEach { RemoveGitTempRepo $repoPath } It 'Tab completes pr options' { - $result = & $module GitTabExpansionInternal 'git pr ' + $result = & $module GitTabExpansionInternal 'git test-vsts-pr ' $result -contains 'abandon' | Should Be $true } } From e60cbb81bb697de0a23d8d92dd498c376c11dc9d Mon Sep 17 00:00:00 2001 From: David Gardiner Date: Wed, 23 May 2018 08:42:55 +0930 Subject: [PATCH 6/6] Move switch cases to the end - Following @rkeithhill's suggestion --- src/GitTabExpansion.ps1 | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index 1c8002e32..52a9099e9 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -276,23 +276,6 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { switch -regex ($lastBlock -replace "^$(Get-AliasPattern git) ","") { - # Handles git pr alias - "vsts\.pr\s+(?\S*)$" { - gitCmdOperations $subcommands 'vsts.pr' $matches['op'] - } - - # Handles git pr -- - "vsts\.pr\s+(?$vstsCommandsWithLongParams).*--(?\S*)$" - { - expandLongParams $longVstsParams $matches['cmd'] $matches['param'] - } - - # Handles git pr - - "vsts\.pr\s+(?$vstsCommandsWithShortParams).*-(?\S*)$" - { - expandShortParams $shortVstsParams $matches['cmd'] $matches['shortparam'] - } - # Handles git "^(?$($subcommands.Keys -join '|'))\s+(?\S*)$" { gitCmdOperations $subcommands $matches['cmd'] $matches['op'] @@ -436,6 +419,24 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { "^(?$gitCommandsWithShortParams).* -(?\S*)$" { expandShortParams $shortGitParams $matches['cmd'] $matches['shortparam'] } + + # Handles git pr alias + "vsts\.pr\s+(?\S*)$" { + gitCmdOperations $subcommands 'vsts.pr' $matches['op'] + } + + # Handles git pr -- + "vsts\.pr\s+(?$vstsCommandsWithLongParams).*--(?\S*)$" + { + expandLongParams $longVstsParams $matches['cmd'] $matches['param'] + } + + # Handles git pr - + "vsts\.pr\s+(?$vstsCommandsWithShortParams).*-(?\S*)$" + { + expandShortParams $shortVstsParams $matches['cmd'] $matches['shortparam'] + } + } }