Skip to content

Commit ccfe38d

Browse files
committed
Add PAGER support to commands that produce significant output
1 parent d01355e commit ccfe38d

File tree

10 files changed

+86
-44
lines changed

10 files changed

+86
-44
lines changed

pkg/cmd/issue/list/fixtures/issueList.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"number": 1,
1010
"title": "number won",
1111
"url": "https://wow.com",
12+
"updatedAt": "2011-01-26T19:01:12Z",
1213
"labels": {
1314
"nodes": [
1415
{
@@ -22,6 +23,7 @@
2223
"number": 2,
2324
"title": "number too",
2425
"url": "https://wow.com",
26+
"updatedAt": "2011-01-26T19:01:12Z",
2527
"labels": {
2628
"nodes": [
2729
{
@@ -35,6 +37,7 @@
3537
"number": 4,
3638
"title": "number fore",
3739
"url": "https://wow.com",
40+
"updatedAt": "2011-01-26T19:01:12Z",
3841
"labels": {
3942
"nodes": [
4043
{

pkg/cmd/issue/list/list.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,16 @@ func listRun(opts *ListOptions) error {
116116
return err
117117
}
118118

119+
err = opts.IO.StartPager()
120+
if err != nil {
121+
return err
122+
}
123+
defer opts.IO.StopPager()
124+
119125
if isTerminal {
120126
hasFilters := opts.State != "open" || len(opts.Labels) > 0 || opts.Assignee != "" || opts.Author != "" || opts.Mention != "" || opts.Milestone != ""
121127
title := prShared.ListHeader(ghrepo.FullName(baseRepo), "issue", len(listResult.Issues), listResult.TotalCount, hasFilters)
122-
fmt.Fprintf(opts.IO.ErrOut, "\n%s\n\n", title)
128+
fmt.Fprintf(opts.IO.Out, "\n%s\n\n", title)
123129
}
124130

125131
issueShared.PrintIssues(opts.IO, "", len(listResult.Issues), listResult.Issues)

pkg/cmd/issue/list/list_test.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
"net/http"
88
"os/exec"
99
"reflect"
10+
"regexp"
1011
"testing"
1112

13+
"github.com/MakeNowJust/heredoc"
1214
"github.com/cli/cli/internal/config"
1315
"github.com/cli/cli/internal/ghrepo"
1416
"github.com/cli/cli/internal/run"
@@ -97,15 +99,19 @@ func TestIssueList_tty(t *testing.T) {
9799
t.Errorf("error running command `issue list`: %v", err)
98100
}
99101

100-
eq(t, output.Stderr(), `
101-
Showing 3 of 3 open issues in OWNER/REPO
102+
out := output.String()
103+
timeRE := regexp.MustCompile(`\d+ years`)
104+
out = timeRE.ReplaceAllString(out, "X years")
102105

103-
`)
106+
assert.Equal(t, heredoc.Doc(`
104107
105-
test.ExpectLines(t, output.String(),
106-
"number won",
107-
"number too",
108-
"number fore")
108+
Showing 3 of 3 open issues in OWNER/REPO
109+
110+
#1 number won (label) about X years ago
111+
#2 number too (label) about X years ago
112+
#4 number fore (label) about X years ago
113+
`), out)
114+
assert.Equal(t, ``, output.Stderr())
109115
}
110116

111117
func TestIssueList_tty_withFlags(t *testing.T) {
@@ -141,8 +147,8 @@ func TestIssueList_tty_withFlags(t *testing.T) {
141147
t.Errorf("error running command `issue list`: %v", err)
142148
}
143149

144-
eq(t, output.String(), "")
145-
eq(t, output.Stderr(), `
150+
eq(t, output.Stderr(), "")
151+
eq(t, output.String(), `
146152
No issues match your search in OWNER/REPO
147153
148154
`)

pkg/cmd/issue/status/status.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ func statusRun(opts *StatusOptions) error {
6868
return err
6969
}
7070

71+
err = opts.IO.StartPager()
72+
if err != nil {
73+
return err
74+
}
75+
defer opts.IO.StopPager()
76+
7177
out := opts.IO.Out
7278

7379
fmt.Fprintln(out, "")

pkg/cmd/issue/view/view.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,16 @@ func viewRun(opts *ViewOptions) error {
8686
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", openURL)
8787
return utils.OpenInBrowser(openURL)
8888
}
89+
90+
err = opts.IO.StartPager()
91+
if err != nil {
92+
return err
93+
}
94+
defer opts.IO.StopPager()
95+
8996
if opts.IO.IsStdoutTTY() {
9097
return printHumanIssuePreview(opts.IO.Out, issue)
9198
}
92-
9399
return printRawIssuePreview(opts.IO.Out, issue)
94100
}
95101

pkg/cmd/pr/list/list.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,16 @@ func listRun(opts *ListOptions) error {
133133
return err
134134
}
135135

136+
err = opts.IO.StartPager()
137+
if err != nil {
138+
return err
139+
}
140+
defer opts.IO.StopPager()
141+
136142
if opts.IO.IsStdoutTTY() {
137143
hasFilters := opts.State != "open" || len(opts.Labels) > 0 || opts.BaseBranch != "" || opts.Assignee != ""
138144
title := shared.ListHeader(ghrepo.FullName(baseRepo), "pull request", len(listResult.PullRequests), listResult.TotalCount, hasFilters)
139-
fmt.Fprintf(opts.IO.ErrOut, "\n%s\n\n", title)
145+
fmt.Fprintf(opts.IO.Out, "\n%s\n\n", title)
140146
}
141147

142148
table := utils.NewTablePrinter(opts.IO)

pkg/cmd/pr/list/list_test.go

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import (
66
"net/http"
77
"os/exec"
88
"reflect"
9-
"regexp"
109
"strings"
1110
"testing"
1211

12+
"github.com/MakeNowJust/heredoc"
1313
"github.com/cli/cli/internal/ghrepo"
1414
"github.com/cli/cli/internal/run"
1515
"github.com/cli/cli/pkg/cmdutil"
@@ -76,23 +76,15 @@ func TestPRList(t *testing.T) {
7676
t.Fatal(err)
7777
}
7878

79-
assert.Equal(t, `
80-
Showing 3 of 3 open pull requests in OWNER/REPO
79+
assert.Equal(t, heredoc.Doc(`
8180
82-
`, output.Stderr())
83-
84-
lines := strings.Split(output.String(), "\n")
85-
res := []*regexp.Regexp{
86-
regexp.MustCompile(`#32.*New feature.*feature`),
87-
regexp.MustCompile(`#29.*Fixed bad bug.*hubot:bug-fix`),
88-
regexp.MustCompile(`#28.*Improve documentation.*docs`),
89-
}
90-
91-
for i, r := range res {
92-
if !r.MatchString(lines[i]) {
93-
t.Errorf("%s did not match %s", lines[i], r)
94-
}
95-
}
81+
Showing 3 of 3 open pull requests in OWNER/REPO
82+
83+
#32 New feature feature
84+
#29 Fixed bad bug hubot:bug-fix
85+
#28 Improve documentation docs
86+
`), output.String())
87+
assert.Equal(t, ``, output.Stderr())
9688
}
9789

9890
func TestPRList_nontty(t *testing.T) {
@@ -130,8 +122,8 @@ func TestPRList_filtering(t *testing.T) {
130122
t.Fatal(err)
131123
}
132124

133-
eq(t, output.String(), "")
134-
eq(t, output.Stderr(), `
125+
eq(t, output.Stderr(), "")
126+
eq(t, output.String(), `
135127
No pull requests match your search in OWNER/REPO
136128
137129
`)
@@ -150,19 +142,12 @@ func TestPRList_filteringRemoveDuplicate(t *testing.T) {
150142
t.Fatal(err)
151143
}
152144

153-
lines := strings.Split(output.String(), "\n")
154-
155-
res := []*regexp.Regexp{
156-
regexp.MustCompile(`#32.*New feature.*feature`),
157-
regexp.MustCompile(`#29.*Fixed bad bug.*hubot:bug-fix`),
158-
regexp.MustCompile(`#28.*Improve documentation.*docs`),
159-
}
160-
161-
for i, r := range res {
162-
if !r.MatchString(lines[i]) {
163-
t.Errorf("%s did not match %s", lines[i], r)
164-
}
145+
out := output.String()
146+
idx := strings.Index(out, "New feature")
147+
if idx < 0 {
148+
t.Fatalf("text %q not found in %q", "New feature", out)
165149
}
150+
assert.Equal(t, idx, strings.LastIndex(out, "New feature"))
166151
}
167152

168153
func TestPRList_filteringClosed(t *testing.T) {

pkg/cmd/pr/status/status.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ func statusRun(opts *StatusOptions) error {
9797
return err
9898
}
9999

100+
err = opts.IO.StartPager()
101+
if err != nil {
102+
return err
103+
}
104+
defer opts.IO.StopPager()
105+
100106
out := opts.IO.Out
101107

102108
fmt.Fprintln(out, "")

pkg/cmd/pr/view/view.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ func viewRun(opts *ViewOptions) error {
9999
return utils.OpenInBrowser(openURL)
100100
}
101101

102+
err = opts.IO.StartPager()
103+
if err != nil {
104+
return err
105+
}
106+
defer opts.IO.StopPager()
107+
102108
if connectedToTerminal {
103109
return printHumanPrPreview(opts.IO.Out, pr)
104110
}

pkg/cmd/repo/view/view.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package view
22

33
import (
4+
"errors"
45
"fmt"
56
"html/template"
67
"net/http"
8+
"os"
79
"strings"
10+
"syscall"
811

912
"github.com/MakeNowJust/heredoc"
1013
"github.com/cli/cli/api"
@@ -107,6 +110,12 @@ func viewRun(opts *ViewOptions) error {
107110
return err
108111
}
109112

113+
err = opts.IO.StartPager()
114+
if err != nil {
115+
return err
116+
}
117+
defer opts.IO.StopPager()
118+
110119
stdout := opts.IO.Out
111120

112121
if !opts.IO.IsStdoutTTY() {
@@ -167,7 +176,10 @@ func viewRun(opts *ViewOptions) error {
167176

168177
err = tmpl.Execute(stdout, repoData)
169178
if err != nil {
170-
return err
179+
var pathError *os.PathError
180+
if !errors.As(err, &pathError) || pathError.Op != "write" || pathError.Unwrap() != syscall.EPIPE {
181+
return err
182+
}
171183
}
172184

173185
return nil

0 commit comments

Comments
 (0)