diff --git a/pkg/cmd/api/api.go b/pkg/cmd/api/api.go index e1edabbc0..170c41b55 100644 --- a/pkg/cmd/api/api.go +++ b/pkg/cmd/api/api.go @@ -34,6 +34,7 @@ type ApiOptions struct { RequestHeaders []string ShowResponseHeaders bool Paginate bool + Silent bool HttpClient func() (*http.Client, error) BaseRepo func() (ghrepo.Interface, error) @@ -134,6 +135,7 @@ original query accepts an '$endCursor: String' variable and that it fetches the cmd.Flags().BoolVarP(&opts.ShowResponseHeaders, "include", "i", false, "Include HTTP response headers in the output") cmd.Flags().BoolVar(&opts.Paginate, "paginate", false, "Make additional HTTP requests to fetch all pages of results") cmd.Flags().StringVar(&opts.RequestInputFile, "input", "", "The file to use as body for the HTTP request") + cmd.Flags().BoolVar(&opts.Silent, "silent", false, "Do not print the response body") return cmd } @@ -178,6 +180,11 @@ func apiRun(opts *ApiOptions) error { return err } + headersOutputStream := opts.IO.Out + if opts.Silent { + opts.IO.Out = ioutil.Discard + } + hasNextPage := true for hasNextPage { resp, err := httpRequest(httpClient, method, requestPath, requestBody, requestHeaders) @@ -185,7 +192,7 @@ func apiRun(opts *ApiOptions) error { return err } - endCursor, err := processResponse(resp, opts) + endCursor, err := processResponse(resp, opts, headersOutputStream) if err != nil { return err } @@ -211,11 +218,11 @@ func apiRun(opts *ApiOptions) error { return nil } -func processResponse(resp *http.Response, opts *ApiOptions) (endCursor string, err error) { +func processResponse(resp *http.Response, opts *ApiOptions, headersOutputStream io.Writer) (endCursor string, err error) { if opts.ShowResponseHeaders { - fmt.Fprintln(opts.IO.Out, resp.Proto, resp.Status) - printHeaders(opts.IO.Out, resp.Header, opts.IO.ColorEnabled()) - fmt.Fprint(opts.IO.Out, "\r\n") + fmt.Fprintln(headersOutputStream, resp.Proto, resp.Status) + printHeaders(headersOutputStream, resp.Header, opts.IO.ColorEnabled()) + fmt.Fprint(headersOutputStream, "\r\n") } if resp.StatusCode == 204 { diff --git a/pkg/cmd/api/api_test.go b/pkg/cmd/api/api_test.go index 7b89d715c..f590d93b4 100644 --- a/pkg/cmd/api/api_test.go +++ b/pkg/cmd/api/api_test.go @@ -39,6 +39,7 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string(nil), ShowResponseHeaders: false, Paginate: false, + Silent: false, }, wantsErr: false, }, @@ -55,6 +56,7 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string(nil), ShowResponseHeaders: false, Paginate: false, + Silent: false, }, wantsErr: false, }, @@ -71,6 +73,7 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string(nil), ShowResponseHeaders: false, Paginate: false, + Silent: false, }, wantsErr: false, }, @@ -87,6 +90,7 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string{"accept: text/plain"}, ShowResponseHeaders: true, Paginate: false, + Silent: false, }, wantsErr: false, }, @@ -103,6 +107,24 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string(nil), ShowResponseHeaders: false, Paginate: true, + Silent: false, + }, + wantsErr: false, + }, + { + name: "with silenced output", + cli: "repos/OWNER/REPO/issues --silent", + wants: ApiOptions{ + RequestMethod: "GET", + RequestMethodPassed: false, + RequestPath: "repos/OWNER/REPO/issues", + RequestInputFile: "", + RawFields: []string(nil), + MagicFields: []string(nil), + RequestHeaders: []string(nil), + ShowResponseHeaders: false, + Paginate: false, + Silent: true, }, wantsErr: false, }, @@ -124,6 +146,7 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string(nil), ShowResponseHeaders: false, Paginate: true, + Silent: false, }, wantsErr: false, }, @@ -145,6 +168,7 @@ func Test_NewCmdApi(t *testing.T) { RequestHeaders: []string(nil), ShowResponseHeaders: false, Paginate: false, + Silent: false, }, wantsErr: false, }, @@ -264,6 +288,36 @@ func Test_apiRun(t *testing.T) { stdout: `gateway timeout`, stderr: "gh: HTTP 502\n", }, + { + name: "silent", + options: ApiOptions{ + Silent: true, + }, + httpResponse: &http.Response{ + StatusCode: 200, + Body: ioutil.NopCloser(bytes.NewBufferString(`body`)), + }, + err: nil, + stdout: ``, + stderr: ``, + }, + { + name: "show response headers even when silent", + options: ApiOptions{ + ShowResponseHeaders: true, + Silent: true, + }, + httpResponse: &http.Response{ + Proto: "HTTP/1.1", + Status: "200 Okey-dokey", + StatusCode: 200, + Body: ioutil.NopCloser(bytes.NewBufferString(`body`)), + Header: http.Header{"Content-Type": []string{"text/plain"}}, + }, + err: nil, + stdout: "HTTP/1.1 200 Okey-dokey\nContent-Type: text/plain\r\n\r\n", + stderr: ``, + }, } for _, tt := range tests {