Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 137 additions & 5 deletions src/GitParamTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,150 @@ $shortVstsParams = @{
update = "d i $shortVstsGlobal"
}

$shortAzGlobal = 'h o'
$shortAzParams = @{
checkout = " $shortAzGlobal"
create = "d p r s t $shortAzGlobal"
list = "p r s t $shortAzGlobal"
'set-vote' = " $shortAzGlobal"
show = " $shortAzGlobal"
update = "d $shortAzGlobal"
}

$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"
list = "creator detect include-links instance project repository reviewer skip source-branch status= target-branch top $longVstsGlobal"
reactivate = "id detect instance $longVstsGlobal"
'set-vote' = "id vote detect instance $longVstsGlobal"
show = "id detect instance open $longVstsGlobal"
update = "id auto-complete delete-source-branch bypass-policy bypass-policy-reason description detect instance merge-commit-message squash title transition-work-items $longVstsGlobal"
}

$longAzGlobal = 'debug help output query verbose'
$longAzParams = @{
checkout = "id remote-name $longAzGlobal"
create = "auto-complete delete-source-branch work-items bypass-policy bypass-policy-reason description detect draft merge-commit-message open organization project repository reviewers source-branch squash target-branch title transition-work-items work-items $longAzGlobal"
list = "creator include-links detect organization repository reviewer skip source-branch status= target-branch top $longAzGlobal"
'set-vote' = "id vote= $longAzGlobal"
show = "id detect open organization $longAzGlobal"
update = "id auto-complete bypass-policy bypass-policy-reason delete-source-branch description detect draft merge-commit-message organization squash status= title transition-work-items $longAzGlobal"
}

$vstsCommandsWithSubCommands = @{
policies = "list queue"
reviewers = "add list remove"
'work-items' = "add list remove"
}

$azCommandsWithSubCommands = @{
policy = "list queue"
reviewer = "add list remove"
'work-item' = "add list remove"
}

$shortVstsSubCommandParams = @{
policies = @{
list = "i $shortVstsGlobal"
queue = "e i $shortVstsGlobal"
}
reviewers = @{
add = "i $shortVstsGlobal"
list = "i $shortVstsGlobal"
remove = "i $shortVstsGlobal"
}
'work-items' = @{
add = "i $shortVstsGlobal"
list = "i $shortVstsGlobal"
remove = "i $shortVstsGlobal"
}
}

$shortAzSubCommandParams = @{
policy = @{
list = " $shortAzGlobal"
queue = "e $shortAzGlobal"
}
reviewer = @{
add = " $shortAzGlobal"
list = " $shortAzGlobal"
remove = " $shortAzGlobal"
}
'work-item' = @{
add = " $shortAzGlobal"
list = " $shortAzGlobal"
remove = " $shortAzGlobal"
}
}

# these aren't "global" commands, but *are* common to each of the below
$longAzSubCommandCommon = "id detect organization"

$longAzSubCommandParams = @{
policy = @{
list = "$longAzSubCommandCommon skip top $longAzGlobal"
queue = "$longAzSubCommandCommon evaluation-id $longAzGlobal"
}
reviewer = @{
add = "$longAzSubCommandCommon reviewers $longAzGlobal"
list = "$longAzSubCommandCommon $longAzGlobal"
remove = "$longAzSubCommandCommon reviewers $longAzGlobal"
}
'work-item' = @{
add = "$longAzSubCommandCommon work-items $longAzGlobal"
list = "$longAzSubCommandCommon $longAzGlobal"
remove = "$longAzSubCommandCommon work-items $longAzGlobal"
}
}

$longVstsSubCommandCommon = "id detect instance"
$longVstsSubCommandParams = @{
policies = @{
list = "$longVstsSubCommandCommon skip top $longVstsGlobal"
queue = "$longVstsSubCommandCommon evaluation-id $longVstsGlobal"
}
reviewers = @{
add = "$longVstsSubCommandCommon reviewers $longVstsGlobal"
list = "$longVstsSubCommandCommon $longVstsGlobal"
remove = "$longVstsSubCommandCommon reviewers $longVstsGlobal"
}
'work-items' = @{
add = "$longVstsSubCommandCommon work-items $longVstsGlobal"
list = "$longVstsSubCommandCommon $longVstsGlobal"
remove = "$longVstsSubCommandCommon work-items $longVstsGlobal"
}
}

$vstsParamValues = @{
'set-vote' = @{
vote = 'approve approve-with-suggestions reject reset wait-for-author'
}
list = @{
status = 'abandoned active all completed'
}
'**' = @{
output = 'json jsonc table tsv'
}
}

$azParamValues = @{
update = @{
status = 'abandoned active completed'
}
'set-vote' = @{
vote = 'approve approve-with-suggestions reject reset wait-for-author'
}
list = @{
status = 'abandoned active all completed'
}
'**' = @{
output = 'json jsonc table tsv'
}
}


# Variable is used in GitTabExpansion.ps1
$gitParamValues = @{
blame = @{
Expand Down
111 changes: 99 additions & 12 deletions src/GitTabExpansion.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ $Global:GitTabSettings = New-Object PSObject -Property @{
AllCommands = $false
KnownAliases = @{
'!f() { exec vsts code pr "$@"; }; f' = 'vsts.pr'
'!f() { exec az.cmd repos pr "$@"; }; f' = 'az.pr'
'!f() { exec az.cmd repos "$@"; }; f' = 'az.repo'
}
}

$subcommands = @{
bisect = "start bad good skip reset visualize replay log run"
notes = 'add append copy edit get-ref list merge prune remove show'
'vsts.pr' = 'create update show list complete abandon reactivate reviewers work-items set-vote policies'
'az.pr' = 'create update show list checkout reviewer work-item set-vote policy'
'az.repo' = 'list show'
reflog = "show delete expire"
remote = "
add rename remove set-head set-branches
Expand Down Expand Up @@ -64,8 +68,29 @@ if ((($PSVersionTable.PSVersion.Major -eq 5) -or $IsWindows) -and ($script:GitVe
$script:gitCommandsWithLongParams = $longGitParams.Keys -join '|'
$script:gitCommandsWithShortParams = $shortGitParams.Keys -join '|'
$script:gitCommandsWithParamValues = $gitParamValues.Keys -join '|'
$script:vstsAllCommands = $subCommands['vsts.pr'].Split(' ', [StringSplitOptions]::RemoveEmptyEntries) -join '|'
$script:vstsCommandsWithShortParams = $shortVstsParams.Keys -join '|'
$script:vstsCommandsWithLongParams = $longVstsParams.Keys -join '|'
$script:vstsCommandsWithParamValues = ( $vstsParamValues.Keys | Where-Object { $_ -ne '**' } ) -join '|'
$script:vstsSubCommandCommands = $vstsCommandsWithSubCommands.Keys -join '|'
$script:azAllCommands = $subCommands['az.pr'].Split(' ', [StringSplitOptions]::RemoveEmptyEntries) -join '|'
$script:azCommandsWithShortParams = $shortAzParams.Keys -join '|'
$script:azCommandsWithLongParams = $longAzParams.Keys -join '|'
$script:azCommandsWithParamValues = ( $azParamValues.Keys | Where-Object { $_ -ne '**' } ) -join '|'
$script:azSubCommandCommands = $azCommandsWithSubCommands.Keys -join '|'

# constructs (?:(?<cmd>Name) (?<subcmd>a|b|c))|(?:(?<cmd>Name2) (?<subcmd>d|e|f))
# only one group will match, so repeat of capture name is perfectly legal for our use-case
$script:azSubCommandsWithLongParams = `
($longAzSubCommandParams.Keys | ForEach-Object { "(?:(?<cmd>$_) (?<subcmd>$( $longAzSubCommandParams[$_].Keys -join '|' )))" }) -join '|'
$script:azSubCommandsWithShortParams = `
($shortAzSubCommandParams.Keys | ForEach-Object { "(?:(?<cmd>$_) (?<subcmd>$( $shortAzSubCommandParams[$_].Keys -join '|' )))" }) -join '|'

$script:vstsSubCommandsWithLongParams = `
($longVstsSubCommandParams.Keys | ForEach-Object { "(?:(?<cmd>$_) (?<subcmd>$( $longVstsSubCommandParams[$_].Keys -join '|' )))" }) -join '|'
$script:vstsSubCommandsWithShortParams = `
($shortVstsSubCommandParams.Keys | ForEach-Object { "(?:(?<cmd>$_) (?<subcmd>$( $shortVstsSubCommandParams[$_].Keys -join '|' )))" }) -join '|'


try {
if ($null -ne (git help -a 2>&1 | Select-String flow)) {
Expand Down Expand Up @@ -190,6 +215,7 @@ function script:gitCheckoutFiles($GitStatus, $filter) {
gitFiles $filter (@($GitStatus.Working.Unmerged) + @($GitStatus.Working.Modified) + @($GitStatus.Working.Deleted))
}


function script:gitDiffFiles($GitStatus, $filter, $staged) {
if ($staged) {
gitFiles $filter $GitStatus.Index.Modified
Expand Down Expand Up @@ -248,11 +274,17 @@ function script:expandShortParams($hash, $cmd, $filter) {
ForEach-Object { -join ("-", $_) }
}

function script:expandParamValues($cmd, $param, $filter) {
$gitParamValues[$cmd][$param].Trim() -split ' ' |
function script:expandParamValues($hash, $cmd, $param, $filter, $full = $TRUE) {
$hash[$cmd][$param].Trim() -split ' ' |
Where-Object { $_ -like "$filter*" } |
Sort-Object |
ForEach-Object { -join ("--", $param, "=", $_) }
ForEach-Object {
if ($full) {
-join ("--", $param, "=", $_)
} else {
$_
}
}
}

function Expand-GitCommand($Command) {
Expand Down Expand Up @@ -394,6 +426,7 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) {
gitMergeFiles $GitStatus $matches['files']
}


# Handles git checkout <ref>
"^(?:checkout).* (?<ref>\S*)$" {
& {
Expand All @@ -417,7 +450,7 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) {

# Handles git <cmd> --<param>=<value>
"^(?<cmd>$gitCommandsWithParamValues).* --(?<param>[^=]+)=(?<value>\S*)$" {
expandParamValues $matches['cmd'] $matches['param'] $matches['value']
expandParamValues $gitParamValues $matches['cmd'] $matches['param'] $matches['value']
}

# Handles git <cmd> --<param>
Expand All @@ -430,21 +463,75 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) {
expandShortParams $shortGitParams $matches['cmd'] $matches['shortparam']
}

# Handles the vsts/azure CLI commands
# Assumption is that the majority of commands will NOT invoke these CLI's. In order to reduce
# amount of matching we will do in general, first detect the az.pr / vsts.pr aliases
# and THEN perform secondary matches
"(?<alias>(?:az|vsts)\.pr)\s+(?<rest>.*)$" {
expandVstsAndAzureCli $matches['alias'] $matches['rest']
}

}
}

function script:expandVstsAndAzureCli($alias, $rest) {

# will be "az" or "vsts"
$cliType = $alias.Split('.')[0]

switch -regex ($rest) {

# Handles git pr alias
"vsts\.pr\s+(?<op>\S*)$" {
gitCmdOperations $subcommands 'vsts.pr' $matches['op']
"^(?<op>\S*)$" {
gitCmdOperations $subcommands $alias $matches['op']
}

# Handles all git pr aliases with expansion for --output/-o formats
# matches vstsAllCommands or azAllCommands
"^(?:$(Get-Variable ('{0}AllCommands' -f $cliType) -ValueOnly)).* (?:(--out(put)?(?<eq>=|\s+))|(-o\s+))(?<value>\S*)$" {
expandParamValues (Get-Variable "$($cliType)ParamValues" -ValueOnly) '**' 'output' $matches['value'] -Full ($matches['eq'] -and $matches['eq'].Trim())
}

# Handles git pr <cmd> --<param>=<value>
# matches vstsCommandsWithParamValues or azCommandsWithParamValues
"^(?<cmd>$(Get-Variable ('{0}CommandsWithParamValues' -f $cliType) -ValueOnly)).* --(?!\*+)(?<param>[^=]+)=(?<value>\S*)$" {
expandParamValues (Get-Variable "$($cliType)ParamValues" -ValueOnly) $matches['cmd'] $matches['param'] $matches['value']
}

# add branch expansion for git PR target/source branch
"^(?:create|list)\s+.*?(?:--(?:target|source)-branch|-(?:t|s))\s+(?<ref>\S*)$" {
# should only return non-remote-qualified name of remote branches
gitRemoteUniqueBranches $matches['ref']
}

# handles git pr <cmd> <subcmd> => git pr policy list
# matches vstsSubCommandCommands or azSubCommandCommands
"^(?<subcmd>$(Get-Variable ('{0}SubCommandCommands' -f $cliType) -ValueOnly))\s+(?<op>\S*)$" {
gitCmdOperations (Get-Variable "$($cliType)CommandsWithSubCommands" -ValueOnly) $matches['subcmd'] $matches['op']
}

# Handles git pr <cmd> --<param>
"vsts\.pr\s+(?<cmd>$vstsCommandsWithLongParams).*--(?<param>\S*)$"
{
expandLongParams $longVstsParams $matches['cmd'] $matches['param']
# matches vstsCommandsWithLongParams or azCommandsWithLongParams
"^(?<cmd>$(Get-Variable ('{0}CommandsWithLongParams' -f $cliType) -ValueOnly)).* --(?!\*+)(?<param>\S*)$" {
expandLongParams (Get-Variable "long$($cliType)Params" -ValueOnly) $matches['cmd'] $matches['param']
}

# Handles git pr <cmd> <subcmd> --<param> => git pr policy list --debug
# matches vstsSubCommandsWithLongParams or azSubCommandsWithLongParams
"^(?:$(Get-Variable ('{0}SubCommandsWithLongParams' -f $cliType) -ValueOnly)).* --(?!\*+)(?<param>\S*)$" {
expandLongParams (Get-Variable "long$($cliType)SubCommandParams" -ValueOnly)[$Matches['cmd']] $Matches['subcmd'] $matches['param']
}

# Handles git pr <cmd> -<shortparam>
"vsts\.pr\s+(?<cmd>$vstsCommandsWithShortParams).*-(?<shortparam>\S*)$"
{
expandShortParams $shortVstsParams $matches['cmd'] $matches['shortparam']
# matches vstsCommandsWithShortParams or azCommandsWithShortParams
"^(?<cmd>$(Get-Variable ('{0}CommandsWithShortParams' -f $cliType) -ValueOnly)).* -(?!-)(?<shortparam>\S*)$" {
expandShortParams (Get-Variable "short$($cliType)Params" -ValueOnly) $matches['cmd'] $matches['shortparam']
}

# Handles git pr <cmd> <subcmd> -<shortparam> => git pr policy list -d
# matches vstsSubCommandsWithShortParams or azSubCommandsWithShortParams
"^(?:$(Get-Variable ('{0}SubCommandsWithShortParams' -f $cliType) -ValueOnly)).* -(?!-)(?<shortparam>\S*)$" {
expandShortParams (Get-Variable "short$($cliType)SubCommandParams" -ValueOnly)[$Matches['cmd']] $Matches['subcmd'] $matches['shortparam']
}
}
}
Expand Down
Loading