From b56f77b2e5a215aeabfa49a1490949849127e082 Mon Sep 17 00:00:00 2001 From: Kid <44045911+kidonng@users.noreply.github.com> Date: Thu, 26 Aug 2021 00:49:33 +0800 Subject: [PATCH 1/5] Use `/usr/bin/env bash` instead of `/bin/bash` in `gh extension create` --- pkg/cmd/extension/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cmd/extension/manager.go b/pkg/cmd/extension/manager.go index 42cd19041..c7a62ccbf 100644 --- a/pkg/cmd/extension/manager.go +++ b/pkg/cmd/extension/manager.go @@ -268,7 +268,7 @@ func (m *Manager) Create(name string) error { } fileTmpl := heredoc.Docf(` - #!/bin/bash + #!/usr/bin/env bash set -e echo "Hello %[1]s!" From 5dfeb1f7ce9be3a92fb33ac845d113ce51aa8f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 26 Aug 2021 15:48:08 +0200 Subject: [PATCH 2/5] Remove defunct link from `gh actions` The online guide that was GitHub CLI-specific no longer exists. Instead, "GitHub CLI" sections were added to existing individual articles about managing workflow runs. --- pkg/cmd/actions/actions.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/cmd/actions/actions.go b/pkg/cmd/actions/actions.go index 7880a9a6c..350a96b15 100644 --- a/pkg/cmd/actions/actions.go +++ b/pkg/cmd/actions/actions.go @@ -56,8 +56,5 @@ func actionsExplainer(cs *iostreams.ColorScheme) string { gh workflow run: Trigger a workflow_dispatch run for a workflow file To see more help, run 'gh help workflow ' - - For more in depth help including examples, see online documentation at: - `, header, runHeader, workflowHeader) } From 6cbc886c535bfead66476c061bd140dbea47265a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 26 Aug 2021 16:45:55 +0200 Subject: [PATCH 3/5] Use `x/term` package for repo garden instead of shelling out to stty Shelling out to stty seems hard to get right between Linux and macOS. --- pkg/cmd/repo/garden/garden.go | 98 ++++++++++++++--------------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/pkg/cmd/repo/garden/garden.go b/pkg/cmd/repo/garden/garden.go index c7ee048a7..ec2a2e2f5 100644 --- a/pkg/cmd/repo/garden/garden.go +++ b/pkg/cmd/repo/garden/garden.go @@ -8,11 +8,9 @@ import ( "net/http" "os" "os/exec" - "os/signal" "runtime" "strconv" "strings" - "syscall" "github.com/cli/cli/api" "github.com/cli/cli/internal/ghinstance" @@ -21,6 +19,7 @@ import ( "github.com/cli/cli/pkg/iostreams" "github.com/cli/cli/utils" "github.com/spf13/cobra" + "golang.org/x/term" ) type Geometry struct { @@ -51,10 +50,11 @@ type Cell struct { } const ( - DirUp = iota + DirUp Direction = iota DirDown DirLeft DirRight + Quit ) type Direction = int @@ -182,18 +182,6 @@ func gardenRun(opts *GardenOptions) error { maxCommits := (geo.Width * geo.Height) / 2 - sttyFileArg := "-F" - if runtime.GOOS == "darwin" { - sttyFileArg = "-f" - } - - oldTTYCommand := exec.Command("stty", sttyFileArg, "/dev/tty", "-g") - oldTTYSettings, err := oldTTYCommand.CombinedOutput() - if err != nil { - fmt.Fprintln(out, "getting TTY settings failed:", string(oldTTYSettings)) - return err - } - opts.IO.StartProgressIndicator() fmt.Fprintln(out, "gathering commits; this could take a minute...") commits, err := getCommits(httpClient, toView, maxCommits) @@ -215,57 +203,42 @@ func gardenRun(opts *GardenOptions) error { clear(opts.IO) drawGarden(opts.IO, garden, player) - // thanks stackoverflow https://stackoverflow.com/a/17278776 - _ = exec.Command("stty", sttyFileArg, "/dev/tty", "cbreak", "min", "1").Run() - _ = exec.Command("stty", sttyFileArg, "/dev/tty", "-echo").Run() - - walkAway := func() { - clear(opts.IO) - fmt.Fprint(out, "\033[?25h") - _ = exec.Command("stty", sttyFileArg, "/dev/tty", strings.TrimSpace(string(oldTTYSettings))).Run() - fmt.Fprintln(out) - fmt.Fprintln(out, cs.Bold("You turn and walk away from the wildflower garden...")) + // TODO: use opts.IO instead of os.Stdout + oldTermState, err := term.MakeRaw(int(os.Stdout.Fd())) + if err != nil { + return fmt.Errorf("term.MakeRaw: %w", err) } - c := make(chan os.Signal) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) + dirc := make(chan Direction) go func() { - <-c - walkAway() - os.Exit(0) + b := make([]byte, 3) + for { + _, _ = opts.IO.In.Read(b) + switch { + case isLeft(b): + dirc <- DirLeft + case isRight(b): + dirc <- DirRight + case isUp(b): + dirc <- DirUp + case isDown(b): + dirc <- DirDown + case isQuit(b): + dirc <- Quit + } + } }() - var b []byte = make([]byte, 3) +mainLoop: for { - _, _ = opts.IO.In.Read(b) - oldX := player.X oldY := player.Y - moved := false - quitting := false - continuing := false - switch { - case isLeft(b): - moved = player.move(DirLeft) - case isRight(b): - moved = player.move(DirRight) - case isUp(b): - moved = player.move(DirUp) - case isDown(b): - moved = player.move(DirDown) - case isQuit(b): - quitting = true - default: - continuing = true - } - - if quitting { - break - } - - if !moved || continuing { - continue + d := <-dirc + if d == Quit { + break mainLoop + } else if !player.move(d) { + continue mainLoop } underPlayer := garden[player.Y][player.X] @@ -315,7 +288,12 @@ func gardenRun(opts *GardenOptions) error { fmt.Fprint(out, cs.Bold(sl)) } - walkAway() + clear(opts.IO) + fmt.Fprint(out, "\033[?25h") + // TODO: use opts.IO instead of os.Stdout + _ = term.Restore(int(os.Stdout.Fd()), oldTermState) + fmt.Fprintln(out, cs.Bold("You turn and walk away from the wildflower garden...")) + return nil } @@ -343,8 +321,10 @@ func isUp(b []byte) bool { return bytes.EqualFold(b, up) || r == 'w' || r == 'k' } +var ctrlC = []byte{0x3, 0x5b, 0x43} + func isQuit(b []byte) bool { - return rune(b[0]) == 'q' + return rune(b[0]) == 'q' || bytes.Equal(b, ctrlC) } func plantGarden(commits []*Commit, geo *Geometry) [][]*Cell { From 1102de89be1f40512201f06b2ff9f8009ee12950 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 30 Aug 2021 09:13:43 -0500 Subject: [PATCH 4/5] add quotes around @me in documentation to ensure examples work on powershell --- pkg/cmd/issue/create/create.go | 2 +- pkg/cmd/issue/edit/edit.go | 2 +- pkg/cmd/issue/list/list.go | 2 +- pkg/cmd/pr/edit/edit.go | 2 +- pkg/cmd/pr/list/list.go | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/cmd/issue/create/create.go b/pkg/cmd/issue/create/create.go index 4ef2ab12f..258313b79 100644 --- a/pkg/cmd/issue/create/create.go +++ b/pkg/cmd/issue/create/create.go @@ -62,7 +62,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co $ gh issue create --label "bug,help wanted" $ gh issue create --label bug --label "help wanted" $ gh issue create --assignee monalisa,hubot - $ gh issue create --assignee @me + $ gh issue create --assignee "@me" $ gh issue create --project "Roadmap" `), Args: cmdutil.NoArgsQuoteReminder, diff --git a/pkg/cmd/issue/edit/edit.go b/pkg/cmd/issue/edit/edit.go index 5e6f0583e..53707e1f2 100644 --- a/pkg/cmd/issue/edit/edit.go +++ b/pkg/cmd/issue/edit/edit.go @@ -50,7 +50,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman Example: heredoc.Doc(` $ gh issue edit 23 --title "I found a bug" --body "Nothing works" $ gh issue edit 23 --add-label "bug,help wanted" --remove-label "core" - $ gh issue edit 23 --add-assignee @me --remove-assignee monalisa,hubot + $ gh issue edit 23 --add-assignee "@me" --remove-assignee monalisa,hubot $ gh issue edit 23 --add-project "Roadmap" --remove-project v1,v2 $ gh issue edit 23 --milestone "Version 1" $ gh issue edit 23 --body-file body.txt diff --git a/pkg/cmd/issue/list/list.go b/pkg/cmd/issue/list/list.go index b0efd75b7..69a18ae09 100644 --- a/pkg/cmd/issue/list/list.go +++ b/pkg/cmd/issue/list/list.go @@ -57,7 +57,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman Example: heredoc.Doc(` $ gh issue list -l "bug" -l "help wanted" $ gh issue list -A monalisa - $ gh issue list -a @me + $ gh issue list -a "@me" $ gh issue list --web $ gh issue list --milestone "The big 1.0" $ gh issue list --search "error no:assignee sort:created-asc" diff --git a/pkg/cmd/pr/edit/edit.go b/pkg/cmd/pr/edit/edit.go index 13481bcba..32b1161bf 100644 --- a/pkg/cmd/pr/edit/edit.go +++ b/pkg/cmd/pr/edit/edit.go @@ -55,7 +55,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman $ gh pr edit 23 --title "I found a bug" --body "Nothing works" $ gh pr edit 23 --add-label "bug,help wanted" --remove-label "core" $ gh pr edit 23 --add-reviewer monalisa,hubot --remove-reviewer myorg/team-name - $ gh pr edit 23 --add-assignee @me --remove-assignee monalisa,hubot + $ gh pr edit 23 --add-assignee "@me" --remove-assignee monalisa,hubot $ gh pr edit 23 --add-project "Roadmap" --remove-project v1,v2 $ gh pr edit 23 --milestone "Version 1" `), diff --git a/pkg/cmd/pr/list/list.go b/pkg/cmd/pr/list/list.go index b6bce300e..a7dd5886b 100644 --- a/pkg/cmd/pr/list/list.go +++ b/pkg/cmd/pr/list/list.go @@ -51,10 +51,10 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman Short: "List and filter pull requests in this repository", Example: heredoc.Doc(` List PRs authored by you - $ gh pr list --author @me + $ gh pr list --author "@me" List PRs assigned to you - $ gh pr list --assignee @me + $ gh pr list --assignee "@me" List PRs by label, combining multiple labels with AND $ gh pr list --label bug --label "priority 1" From dafd0bfbd1a60da186398fda138535f721904777 Mon Sep 17 00:00:00 2001 From: Des Preston Date: Tue, 31 Aug 2021 16:32:37 -0400 Subject: [PATCH 5/5] feat(4248): add support for line range w/ browse Allow using a range of lines when browsing files. For example: `gh browse test.go:10-20` Closes #4248 --- pkg/cmd/browse/browse.go | 22 +++++++++++++++++++--- pkg/cmd/browse/browse_test.go | 17 +++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/pkg/cmd/browse/browse.go b/pkg/cmd/browse/browse.go index 514477efc..6677e5d45 100644 --- a/pkg/cmd/browse/browse.go +++ b/pkg/cmd/browse/browse.go @@ -169,12 +169,28 @@ func parseFileArg(fileArg string) (string, error) { if len(arr) > 2 { return "", fmt.Errorf("invalid use of colon\nUse 'gh browse --help' for more information about browse\n") } + if len(arr) > 1 { - if !isNumber(arr[1]) { - return "", fmt.Errorf("invalid line number after colon\nUse 'gh browse --help' for more information about browse\n") + out := arr[0] + "#L" + lineRange := strings.Split(arr[1], "-") + + if len(lineRange) > 0 { + if !isNumber(lineRange[0]) { + return "", fmt.Errorf("invalid line number after colon\nUse 'gh browse --help' for more information about browse\n") + } + out += lineRange[0] } - return arr[0] + "#L" + arr[1], nil + + if len(lineRange) > 1 { + if !isNumber(lineRange[1]) { + return "", fmt.Errorf("invalid line range after colon\nUse 'gh browse --help' for more information about browse\n") + } + out += "-L" + lineRange[1] + } + + return out, nil } + return arr[0], nil } diff --git a/pkg/cmd/browse/browse_test.go b/pkg/cmd/browse/browse_test.go index d30a95024..e89863b89 100644 --- a/pkg/cmd/browse/browse_test.go +++ b/pkg/cmd/browse/browse_test.go @@ -215,6 +215,15 @@ func Test_runBrowse(t *testing.T) { defaultBranch: "trunk", expectedURL: "https://github.com/ravocean/angur/tree/trunk/path/to/file.txt#L32", }, + { + name: "file with line range", + opts: BrowseOptions{ + SelectorArg: "path/to/file.txt:32-40", + }, + baseRepo: ghrepo.New("ravocean", "angur"), + defaultBranch: "trunk", + expectedURL: "https://github.com/ravocean/angur/tree/trunk/path/to/file.txt#L32-L40", + }, { name: "file with invalid line number", opts: BrowseOptions{ @@ -223,6 +232,14 @@ func Test_runBrowse(t *testing.T) { baseRepo: ghrepo.New("ttran112", "ttrain211"), wantsErr: true, }, + { + name: "file with invalid line range", + opts: BrowseOptions{ + SelectorArg: "path/to/file.txt:32-abc", + }, + baseRepo: ghrepo.New("ttran112", "ttrain211"), + wantsErr: true, + }, { name: "branch with issue number", opts: BrowseOptions{