add experimental powershell support for shell aliases
This commit is contained in:
parent
3a9167cfe4
commit
c3a5384895
3 changed files with 121 additions and 15 deletions
|
|
@ -40,9 +40,10 @@ var aliasSetCmd = &cobra.Command{
|
|||
includes positional placeholders such as '$1', '$2', etc., any extra arguments
|
||||
that follow the invocation of an alias will be inserted appropriately.
|
||||
|
||||
If '--shell' is specified, the alias will be run through a shell interpreter (sh). This allows you
|
||||
to compose commands with "|" or redirect output with ">". Note that extra arguments are not passed
|
||||
to shell-interpreted aliases; only placeholders ("$1", "$2", etc) are supported.
|
||||
If '--shell' is specified, the alias will be run through a shell interpreter (sh or pwsh). This allows you
|
||||
to compose commands with "|" or redirect output. Note that extra arguments are not passed to
|
||||
shell-interpreted aliases; only placeholders ("$1", "$2" on *nix, "$args" in powershell) are
|
||||
supported.
|
||||
|
||||
Quotes must always be used when defining a command as in the examples.`),
|
||||
Example: heredoc.Doc(`
|
||||
|
|
@ -56,9 +57,15 @@ var aliasSetCmd = &cobra.Command{
|
|||
$ gh epicsBy vilmibm
|
||||
#=> gh issue list --author="vilmibm" --label="epic"
|
||||
|
||||
# On macOS and Linux:
|
||||
$ gh alias set --shell igrep 'gh issue list --label="$1" | grep $2'
|
||||
$ gh igrep epic foo
|
||||
#=> gh issue list --label="epic" | grep "foo"`),
|
||||
#=> gh issue list --label="epic" | grep "foo"
|
||||
|
||||
# On Windows (Powershell):
|
||||
$ gh alias set --shell igrep 'gh issue list --label=$args[0] | Select-String -Pattern $args[1]
|
||||
$ gh igrep epic foo
|
||||
#=> gh issue list --label=epic | Select-String -Pattern foo`),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: aliasSet,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package command
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -177,12 +177,39 @@ aliases:
|
|||
|
||||
}
|
||||
|
||||
func TestExpandAlias_external(t *testing.T) {
|
||||
func TestExpandAlias_shell_nix(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping test on windows")
|
||||
}
|
||||
cfg := `---
|
||||
aliases:
|
||||
ig: '!gh issue list | grep cool'
|
||||
`
|
||||
initBlankContext(cfg, "OWNER/REPO", "trunk")
|
||||
|
||||
cs, teardown := test.InitCmdStubber()
|
||||
defer teardown()
|
||||
cs.Stub("")
|
||||
|
||||
_, err := ExpandAlias([]string{"gh", "ig"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 1, len(cs.Calls))
|
||||
|
||||
expected := []string{"sh", "-c", "gh issue list | grep cool"}
|
||||
|
||||
assert.Equal(t, expected, cs.Calls[0].Args)
|
||||
}
|
||||
|
||||
func TestExpandAlias_shell_nix_extra_args(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping test on windows")
|
||||
}
|
||||
cfg := `---
|
||||
aliases:
|
||||
co: pr checkout
|
||||
il: issue list --author="$1" --label="$2"
|
||||
ia: issue list --author="$1" --assignee="$1"
|
||||
ig: '!gh issue list --label=$1 | grep'
|
||||
`
|
||||
initBlankContext(cfg, "OWNER/REPO", "trunk")
|
||||
|
|
@ -199,13 +226,66 @@ aliases:
|
|||
|
||||
assert.Equal(t, 1, len(cs.Calls))
|
||||
|
||||
fmt.Printf("DEBUG %#v\n", cs.Calls[0])
|
||||
|
||||
expected := []string{"sh", "-c", "gh issue list --label=$1 | grep", "--", "bug", "foo"}
|
||||
|
||||
assert.Equal(t, expected, cs.Calls[0].Args)
|
||||
}
|
||||
|
||||
func TestExpandAlias_shell_windows(t *testing.T) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("skipping test on non-windows")
|
||||
}
|
||||
cfg := `---
|
||||
aliases:
|
||||
ig: '!gh issue list | select-string -Pattern cool'
|
||||
`
|
||||
initBlankContext(cfg, "OWNER/REPO", "trunk")
|
||||
|
||||
cs, teardown := test.InitCmdStubber()
|
||||
defer teardown()
|
||||
cs.Stub("")
|
||||
|
||||
_, err := ExpandAlias([]string{"gh", "ig"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 1, len(cs.Calls))
|
||||
|
||||
expected := []string{"pwsh", "-Command", "Invoke-Command -ScriptBlock { gh issue list | select-string -Pattern cool } "}
|
||||
|
||||
assert.Equal(t, expected, cs.Calls[0].Args)
|
||||
}
|
||||
|
||||
func TestExpandAlias_shell_windows_extra_args(t *testing.T) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("skipping test on non-windows")
|
||||
}
|
||||
cfg := `---
|
||||
aliases:
|
||||
co: pr checkout
|
||||
ig: '!gh issue list --label=$args[0] | select-string -Pattern $args[1]'
|
||||
`
|
||||
initBlankContext(cfg, "OWNER/REPO", "trunk")
|
||||
|
||||
cs, teardown := test.InitCmdStubber()
|
||||
defer teardown()
|
||||
cs.Stub("")
|
||||
|
||||
_, err := ExpandAlias([]string{"gh", "ig", "bug", "foo"})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, 1, len(cs.Calls))
|
||||
|
||||
expected := []string{"pwsh", "-Command", "Invoke-Command -ScriptBlock { gh issue list --label=$args[0] | select-string -Pattern $args[1] } -ArgumentList @('bug','foo')"}
|
||||
|
||||
assert.Equal(t, expected, cs.Calls[0].Args)
|
||||
}
|
||||
|
||||
func TestExpandAlias(t *testing.T) {
|
||||
cfg := `---
|
||||
aliases:
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
|
|
@ -385,11 +386,29 @@ func ExpandAlias(args []string) ([]string, error) {
|
|||
if ok {
|
||||
if strings.HasPrefix(expansion, "!") {
|
||||
shellArgs := []string{"-c", expansion[1:]}
|
||||
if len(args[2:]) > 0 {
|
||||
shellArgs = append(shellArgs, "--")
|
||||
shellArgs = append(shellArgs, args[2:]...)
|
||||
shellCmd := "sh"
|
||||
if runtime.GOOS == "windows" {
|
||||
shellCmd = "pwsh"
|
||||
argList := ""
|
||||
if len(args[2:]) > 0 {
|
||||
argList = " -ArgumentList @("
|
||||
for i, arg := range args[2:] {
|
||||
argList += fmt.Sprintf("'%s'", arg)
|
||||
if i < len(args[2:])-1 {
|
||||
argList += ","
|
||||
}
|
||||
}
|
||||
argList += ")"
|
||||
}
|
||||
invoke := fmt.Sprintf("Invoke-Command -ScriptBlock { %s } %s", expansion[1:], argList)
|
||||
shellArgs = []string{"-Command", invoke}
|
||||
} else {
|
||||
if len(args[2:]) > 0 {
|
||||
shellArgs = append(shellArgs, "--")
|
||||
shellArgs = append(shellArgs, args[2:]...)
|
||||
}
|
||||
}
|
||||
externalCmd := exec.Command("sh", shellArgs...)
|
||||
externalCmd := exec.Command(shellCmd, shellArgs...)
|
||||
externalCmd.Stderr = os.Stderr
|
||||
externalCmd.Stdout = os.Stdout
|
||||
externalCmd.Stdin = os.Stdin
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue