mirror of https://gitlab.com/gitlab-org/cli.git
Merge branch 'json-output' into 'main'
feat: Json output Closes #828 See merge request https://gitlab.com/gitlab-org/cli/-/merge_requests/1031 Merged-by: Jay McCure <jmccure@gitlab.com> Approved-by: Amy Qualls <aqualls@gitlab.com> Approved-by: Jay McCure <jmccure@gitlab.com> Reviewed-by: Jay McCure <jmccure@gitlab.com> Co-authored-by: Dmitry Makovey <dmakovey@gitlab.com>
This commit is contained in:
commit
4983225503
|
@ -95,8 +95,9 @@ func NewCmdGet(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
outputFormat, _ := cmd.Flags().GetString("output-format")
|
||||
if outputFormat == "json" {
|
||||
printJSON(*mergedPipelineObject)
|
||||
output, _ := cmd.Flags().GetString("output")
|
||||
if output == "json" || outputFormat == "json" {
|
||||
printJSON(*mergedPipelineObject, f.IO.StdOut)
|
||||
} else {
|
||||
showJobDetails, _ := cmd.Flags().GetBool("with-job-details")
|
||||
printTable(*mergedPipelineObject, f.IO.StdOut, showJobDetails)
|
||||
|
@ -108,16 +109,19 @@ func NewCmdGet(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
pipelineGetCmd.Flags().StringP("branch", "b", "", "Check pipeline status for a branch. (Default is current branch)")
|
||||
pipelineGetCmd.Flags().IntP("pipeline-id", "p", 0, "Provide pipeline ID")
|
||||
pipelineGetCmd.Flags().StringP("output-format", "o", "text", "Format output as: text, json")
|
||||
pipelineGetCmd.Flags().StringP("output", "F", "text", "Format output as: text, json")
|
||||
pipelineGetCmd.Flags().StringP("output-format", "o", "text", "Use output")
|
||||
_ = pipelineGetCmd.Flags().MarkHidden("output-format")
|
||||
_ = pipelineGetCmd.Flags().MarkDeprecated("output-format", "Deprecated use output")
|
||||
pipelineGetCmd.Flags().BoolP("with-job-details", "d", false, "Show extended job information")
|
||||
pipelineGetCmd.Flags().Bool("with-variables", false, "Show variables in pipeline (maintainer role required)")
|
||||
|
||||
return pipelineGetCmd
|
||||
}
|
||||
|
||||
func printJSON(p PipelineMergedResponse) {
|
||||
func printJSON(p PipelineMergedResponse, dest io.Writer) {
|
||||
JSONStr, _ := json.Marshal(p)
|
||||
fmt.Println(string(JSONStr))
|
||||
fmt.Fprintln(dest, string(JSONStr))
|
||||
}
|
||||
|
||||
func printTable(p PipelineMergedResponse, dest io.Writer, showJobDetails bool) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package status
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/commands/cmdtest"
|
||||
|
@ -24,19 +25,26 @@ func runCommand(rt http.RoundTripper, isTTY bool, args string) (*test.CmdOut, er
|
|||
return cmdtest.ExecuteCommand(cmd, args, stdout, stderr)
|
||||
}
|
||||
|
||||
const (
|
||||
FileBody = 1
|
||||
InlineBody = 2
|
||||
)
|
||||
|
||||
func TestCIGet(t *testing.T) {
|
||||
type httpMock struct {
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
method string
|
||||
path string
|
||||
status int
|
||||
body string
|
||||
bodyType int
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args string
|
||||
httpMocks []httpMock
|
||||
expectedOut string
|
||||
name string
|
||||
args string
|
||||
httpMocks []httpMock
|
||||
expectedOut string
|
||||
expectedOutType int
|
||||
}{
|
||||
{
|
||||
name: "when get is called on an existing pipeline",
|
||||
|
@ -61,12 +69,14 @@ func TestCIGet(t *testing.T) {
|
|||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
|
@ -109,12 +119,14 @@ updated: 2023-10-10 00:00:00 +0000 UTC
|
|||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
|
@ -125,6 +137,7 @@ updated: 2023-10-10 00:00:00 +0000 UTC
|
|||
"id": 123
|
||||
}
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
|
@ -167,6 +180,7 @@ updated: 2023-10-10 00:00:00 +0000 UTC
|
|||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
|
@ -177,6 +191,7 @@ updated: 2023-10-10 00:00:00 +0000 UTC
|
|||
"name": "publish",
|
||||
"status": "failed"
|
||||
}]`,
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
|
@ -220,6 +235,7 @@ publish: failed
|
|||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
|
@ -231,6 +247,7 @@ publish: failed
|
|||
"status": "failed",
|
||||
"failure_reason": "bad timing"
|
||||
}]`,
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
|
@ -276,12 +293,14 @@ ID Name Status Duration Failure reason
|
|||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
|
@ -292,6 +311,7 @@ ID Name Status Duration Failure reason
|
|||
"variable_type": "env_var",
|
||||
"value": "true"
|
||||
}]`,
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
|
@ -338,18 +358,21 @@ RUN_NIGHTLY_BUILD: true
|
|||
"started_at": "2023-10-10T00:00:00Z",
|
||||
"updated_at": "2023-10-10T00:00:00Z"
|
||||
}`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/123/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
`[]`,
|
||||
InlineBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/5/pipelines/123/variables",
|
||||
http.StatusOK,
|
||||
"[]",
|
||||
InlineBody,
|
||||
},
|
||||
},
|
||||
expectedOut: `# Pipeline:
|
||||
|
@ -371,6 +394,28 @@ updated: 2023-10-10 00:00:00 +0000 UTC
|
|||
No variables found in pipeline.
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "when getting JSON for pipeline",
|
||||
args: "-p 452959326 -F json -b main",
|
||||
httpMocks: []httpMock{
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/452959326",
|
||||
http.StatusOK,
|
||||
"testdata/ci_get-0.json",
|
||||
FileBody,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/api/v4/projects/OWNER%2FREPO/pipelines/452959326/jobs?per_page=100",
|
||||
http.StatusOK,
|
||||
"testdata/ci_get-1.json",
|
||||
FileBody,
|
||||
},
|
||||
},
|
||||
expectedOut: "testdata/ci_get.result",
|
||||
expectedOutType: FileBody,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
@ -381,13 +426,30 @@ No variables found in pipeline.
|
|||
defer fakeHTTP.Verify(t)
|
||||
|
||||
for _, mock := range tc.httpMocks {
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, mock.body))
|
||||
var body string
|
||||
if mock.bodyType == FileBody {
|
||||
bodyBytes, _ := os.ReadFile(mock.body)
|
||||
body = string(bodyBytes)
|
||||
} else {
|
||||
body = mock.body
|
||||
}
|
||||
fakeHTTP.RegisterResponder(mock.method, mock.path, httpmock.NewStringResponse(mock.status, body))
|
||||
}
|
||||
|
||||
output, err := runCommand(fakeHTTP, false, tc.args)
|
||||
require.Nil(t, err)
|
||||
var expectedOut string
|
||||
var expectedOutBytes []byte
|
||||
|
||||
assert.Equal(t, tc.expectedOut, output.String())
|
||||
if tc.expectedOutType == FileBody {
|
||||
expectedOutBytes, err = os.ReadFile(tc.expectedOut)
|
||||
expectedOut = string(expectedOutBytes)
|
||||
require.Nil(t, err)
|
||||
} else {
|
||||
expectedOut = tc.expectedOut
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedOut, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"id": 452959326,
|
||||
"iid": 14,
|
||||
"project_id": 29316529,
|
||||
"sha": "44eb489568f7cb1a5a730fce6b247cd3797172ca",
|
||||
"ref": "1-fake-issue-3",
|
||||
"status": "success",
|
||||
"source": "push",
|
||||
"created_at": "2022-01-20T21:47:16.276Z",
|
||||
"updated_at": "2022-01-20T21:47:31.358Z",
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/pipelines/452959326",
|
||||
"before_sha": "001eb421e586a3f07f90aea102c8b2d4068ab5b6",
|
||||
"tag": false,
|
||||
"yaml_errors": null,
|
||||
"user": {
|
||||
"id": 8814129,
|
||||
"username": "OWNER",
|
||||
"name": "Some User",
|
||||
"state": "active",
|
||||
"locked": false,
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/8814129/avatar.png",
|
||||
"web_url": "https://gitlab.com/OWNER"
|
||||
},
|
||||
"started_at": "2022-01-20T21:47:17.448Z",
|
||||
"finished_at": "2022-01-20T21:47:31.350Z",
|
||||
"committed_at": null,
|
||||
"duration": 14,
|
||||
"queued_duration": 1,
|
||||
"coverage": null,
|
||||
"detailed_status": {
|
||||
"icon": "status_success",
|
||||
"text": "Passed",
|
||||
"label": "passed",
|
||||
"group": "success",
|
||||
"tooltip": "passed",
|
||||
"has_details": true,
|
||||
"details_path": "/OWNER/REPO/-/pipelines/452959326",
|
||||
"illustration": null,
|
||||
"favicon": "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png"
|
||||
},
|
||||
"name": null
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
[
|
||||
{
|
||||
"id": 1999017704,
|
||||
"status": "success",
|
||||
"stage": "test",
|
||||
"name": "test_vars",
|
||||
"ref": "1-fake-issue-3",
|
||||
"tag": false,
|
||||
"coverage": null,
|
||||
"allow_failure": false,
|
||||
"created_at": "2022-01-20T21:47:16.291Z",
|
||||
"started_at": "2022-01-20T21:47:16.693Z",
|
||||
"finished_at": "2022-01-20T21:47:31.274Z",
|
||||
"erased_at": null,
|
||||
"duration": 14.580467,
|
||||
"queued_duration": 0.211715,
|
||||
"user": {
|
||||
"id": 8814129,
|
||||
"username": "OWNER",
|
||||
"name": "Some User",
|
||||
"state": "active",
|
||||
"locked": false,
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/8814129/avatar.png",
|
||||
"web_url": "https://gitlab.com/OWNER",
|
||||
"created_at": "2021-05-03T14:58:50.059Z",
|
||||
"bio": "",
|
||||
"location": "Canada",
|
||||
"public_email": "",
|
||||
"skype": "",
|
||||
"linkedin": "",
|
||||
"twitter": "",
|
||||
"discord": "",
|
||||
"website_url": "",
|
||||
"organization": "GitLab",
|
||||
"job_title": "Sr Backend Engineer",
|
||||
"pronouns": "",
|
||||
"bot": false,
|
||||
"work_information": "Sr Backend Engineer at GitLab",
|
||||
"followers": 2,
|
||||
"following": 0,
|
||||
"local_time": "10:48 AM"
|
||||
},
|
||||
"commit": {
|
||||
"id": "44eb489568f7cb1a5a730fce6b247cd3797172ca",
|
||||
"short_id": "44eb4895",
|
||||
"created_at": "2022-01-20T21:47:15.000+00:00",
|
||||
"parent_ids": [
|
||||
"001eb421e586a3f07f90aea102c8b2d4068ab5b6"
|
||||
],
|
||||
"title": "Add new file",
|
||||
"message": "Add new file",
|
||||
"author_name": "Some User",
|
||||
"author_email": "OWNER@gitlab.com",
|
||||
"authored_date": "2022-01-20T21:47:15.000+00:00",
|
||||
"committer_name": "Some User",
|
||||
"committer_email": "OWNER@gitlab.com",
|
||||
"committed_date": "2022-01-20T21:47:15.000+00:00",
|
||||
"trailers": {},
|
||||
"extended_trailers": {},
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/commit/44eb489568f7cb1a5a730fce6b247cd3797172ca"
|
||||
},
|
||||
"pipeline": {
|
||||
"id": 452959326,
|
||||
"iid": 14,
|
||||
"project_id": 29316529,
|
||||
"sha": "44eb489568f7cb1a5a730fce6b247cd3797172ca",
|
||||
"ref": "1-fake-issue-3",
|
||||
"status": "success",
|
||||
"source": "push",
|
||||
"created_at": "2022-01-20T21:47:16.276Z",
|
||||
"updated_at": "2022-01-20T21:47:31.358Z",
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/pipelines/452959326"
|
||||
},
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/jobs/1999017704",
|
||||
"project": {
|
||||
"ci_job_token_scope_enabled": false
|
||||
},
|
||||
"artifacts": [
|
||||
{
|
||||
"file_type": "trace",
|
||||
"size": 2770,
|
||||
"filename": "job.log",
|
||||
"file_format": null
|
||||
}
|
||||
],
|
||||
"runner": {
|
||||
"id": 12270859,
|
||||
"description": "5-green.saas-linux-small-amd64.runners-manager.gitlab.com/default",
|
||||
"ip_address": "10.1.5.249",
|
||||
"active": true,
|
||||
"paused": false,
|
||||
"is_shared": true,
|
||||
"runner_type": "instance_type",
|
||||
"name": "gitlab-runner",
|
||||
"online": false,
|
||||
"status": "offline"
|
||||
},
|
||||
"artifacts_expire_at": null,
|
||||
"archived": false,
|
||||
"tag_list": []
|
||||
}
|
||||
]
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,7 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/api"
|
||||
|
@ -38,6 +39,10 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
l := &gitlab.ListProjectPipelinesOptions{}
|
||||
|
||||
format, _ := cmd.Flags().GetString("output")
|
||||
jsonOut := format == "json"
|
||||
|
||||
l.Page = 1
|
||||
l.PerPage = 30
|
||||
|
||||
|
@ -68,7 +73,12 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
title.Page = l.Page
|
||||
title.CurrentPageTotal = len(pipes)
|
||||
|
||||
fmt.Fprintf(f.IO.StdOut, "%s\n%s\n", title.Describe(), ciutils.DisplayMultiplePipelines(f.IO, pipes, repo.FullName()))
|
||||
if jsonOut {
|
||||
pipeListJSON, _ := json.Marshal(pipes)
|
||||
fmt.Fprintln(f.IO.StdOut, string(pipeListJSON))
|
||||
} else {
|
||||
fmt.Fprintf(f.IO.StdOut, "%s\n%s\n", title.Describe(), ciutils.DisplayMultiplePipelines(f.IO, pipes, repo.FullName()))
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -77,6 +87,7 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
pipelineListCmd.Flags().StringP("sort", "", "desc", "Sort pipeline by {asc|desc}")
|
||||
pipelineListCmd.Flags().IntP("page", "p", 1, "Page number")
|
||||
pipelineListCmd.Flags().IntP("per-page", "P", 30, "Number of items to list per page")
|
||||
pipelineListCmd.Flags().StringP("output", "F", "text", "Format output as: text, json")
|
||||
|
||||
return pipelineListCmd
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -15,19 +15,16 @@ import (
|
|||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := iostreams.Test()
|
||||
func runCommand(rt http.RoundTripper, args string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(false, "")
|
||||
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
_, _ = factory.HttpClient()
|
||||
|
||||
cmd := NewCmdList(factory)
|
||||
|
||||
_, err := cmd.ExecuteC()
|
||||
return &test.CmdOut{
|
||||
OutBuf: stdout,
|
||||
ErrBuf: stderr,
|
||||
}, err
|
||||
return cmdtest.ExecuteCommand(cmd, args, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestCiList(t *testing.T) {
|
||||
|
@ -64,7 +61,7 @@ func TestCiList(t *testing.T) {
|
|||
]
|
||||
`))
|
||||
|
||||
output, err := runCommand(fakeHTTP)
|
||||
output, err := runCommand(fakeHTTP, "")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `ci list`: %v", err)
|
||||
}
|
||||
|
@ -82,3 +79,26 @@ func TestCiList(t *testing.T) {
|
|||
`), out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
||||
func TestCiListJSON(t *testing.T) {
|
||||
fakeHTTP := httpmock.New()
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/api/v4/projects/OWNER/REPO/pipelines",
|
||||
httpmock.NewFileResponse(http.StatusOK, "testdata/ciList.json"))
|
||||
|
||||
output, err := runCommand(fakeHTTP, "-F json")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `ci list -F json`: %v", err)
|
||||
}
|
||||
|
||||
b, err := os.ReadFile("testdata/ciList.json")
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
|
||||
expectedOut := string(b)
|
||||
|
||||
assert.JSONEq(t, expectedOut, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
{
|
||||
"id": 1172622998,
|
||||
"iid": 338,
|
||||
"project_id": 37777023,
|
||||
"status": "success",
|
||||
"source": "schedule",
|
||||
"ref": "#test#",
|
||||
"sha": "3c890c11d784329052aa4ff63526dde2fa65b320",
|
||||
"web_url": "https://gitlab.com/jay_mccure/test2target/-/pipelines/1172622998",
|
||||
"updated_at": "2024-02-11T18:56:07.777Z",
|
||||
"created_at": "2024-02-11T18:55:08.793Z"
|
||||
},
|
||||
{
|
||||
"id": 1172086480,
|
||||
"iid": 337,
|
||||
"project_id": 37777023,
|
||||
"status": "success",
|
||||
"source": "schedule",
|
||||
"ref": "#test#",
|
||||
"sha": "3c890c11d784329052aa4ff63526dde2fa65b320",
|
||||
"web_url": "https://gitlab.com/jay_mccure/test2target/-/pipelines/1172086480",
|
||||
"updated_at": "2024-02-10T18:56:13.972Z",
|
||||
"created_at": "2024-02-10T18:55:16.722Z"
|
||||
}
|
||||
]
|
|
@ -1,6 +1,7 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
@ -56,6 +57,8 @@ type ListOptions struct {
|
|||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (glrepo.Interface, error)
|
||||
HTTPClient func() (*gitlab.Client, error)
|
||||
|
||||
JSONOutput bool
|
||||
}
|
||||
|
||||
func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error, issueType issuable.IssueType) *cobra.Command {
|
||||
|
@ -135,7 +138,7 @@ func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error, issueTy
|
|||
issueListCmd.Flags().BoolVarP(&opts.All, "all", "A", false, fmt.Sprintf("Get all %ss", issueType))
|
||||
issueListCmd.Flags().BoolVarP(&opts.Closed, "closed", "c", false, fmt.Sprintf("Get only closed %ss", issueType))
|
||||
issueListCmd.Flags().BoolVarP(&opts.Confidential, "confidential", "C", false, fmt.Sprintf("Filter by confidential %ss", issueType))
|
||||
issueListCmd.Flags().StringVarP(&opts.OutputFormat, "output-format", "F", "details", "One of 'details', 'ids', or 'urls'")
|
||||
issueListCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "details", "One of 'details', 'ids', 'urls' or 'json'")
|
||||
issueListCmd.Flags().IntVarP(&opts.Page, "page", "p", 1, "Page number")
|
||||
issueListCmd.Flags().IntVarP(&opts.PerPage, "per-page", "P", 30, "Number of items to list per page.")
|
||||
issueListCmd.PersistentFlags().StringP("group", "g", "", "Select a group/subgroup. This option is ignored if a repo argument is set.")
|
||||
|
@ -260,6 +263,12 @@ func listRun(opts *ListOptions) error {
|
|||
title.ListActionType = opts.ListType
|
||||
title.CurrentPageTotal = len(issues)
|
||||
|
||||
if opts.OutputFormat == "json" {
|
||||
issueListJSON, _ := json.Marshal(issues)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(issueListJSON))
|
||||
return nil
|
||||
}
|
||||
|
||||
if opts.OutputFormat == "ids" {
|
||||
for _, i := range issues {
|
||||
fmt.Fprintf(opts.IO.StdOut, "%d\n", i.IID)
|
||||
|
|
|
@ -3,6 +3,7 @@ package list
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -350,3 +351,30 @@ func TestIssueList_hyperlinks(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueListJSON(t *testing.T) {
|
||||
fakeHTTP := httpmock.New()
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/issues",
|
||||
httpmock.NewFileResponse(http.StatusOK, "./testdata/issueListFull.json"))
|
||||
|
||||
output, err := runCommand("issue", fakeHTTP, true, "-F json", nil, "")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `issue list -F json`: %v", err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b, err := os.ReadFile("./testdata/issueListFull.json")
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
|
||||
expectedOut := string(b)
|
||||
|
||||
assert.JSONEq(t, expectedOut, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
[
|
||||
{
|
||||
"id": 141525495,
|
||||
"iid": 15,
|
||||
"external_id": "",
|
||||
"project_id": 37777023,
|
||||
"title": "tem",
|
||||
"description": "",
|
||||
"state": "opened",
|
||||
"created_at": "2024-01-31T05:37:57.883Z",
|
||||
"updated_at": "2024-02-02T00:54:02.842Z",
|
||||
"closed_at": null,
|
||||
"epic": null,
|
||||
"epic_issue_id": 0,
|
||||
"iteration": null,
|
||||
"label_details": null,
|
||||
"subscribed": false,
|
||||
"closed_by": null,
|
||||
"labels":"",
|
||||
"milestone": null,
|
||||
"assignees":
|
||||
[],
|
||||
"author":
|
||||
{
|
||||
"id": 11809982,
|
||||
"username": "jay_mccure",
|
||||
"name": "Jay McCure",
|
||||
"state": "active",
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/11809982/avatar.png",
|
||||
"web_url": "https://gitlab.com/jay_mccure"
|
||||
},
|
||||
"assignee": null,
|
||||
"user_notes_count": 0,
|
||||
"issue_link_id": 0,
|
||||
"merge_requests_count": 0,
|
||||
"upvotes": 0,
|
||||
"downvotes": 0,
|
||||
"due_date": null,
|
||||
"confidential": false,
|
||||
"discussion_locked": false,
|
||||
"issue_type": "issue",
|
||||
"web_url": "https://gitlab.com/jay_mccure/test2target/-/issues/15",
|
||||
"time_stats":
|
||||
{
|
||||
"time_estimate": 0,
|
||||
"total_time_spent": 0,
|
||||
"human_time_estimate": "",
|
||||
"human_total_time_spent": ""
|
||||
},
|
||||
"task_completion_status":
|
||||
{
|
||||
"count": 0,
|
||||
"completed_count": 0
|
||||
},
|
||||
"weight": 0,
|
||||
"_links":
|
||||
{
|
||||
"self": "https://gitlab.com/api/v4/projects/37777023/issues/15",
|
||||
"notes": "https://gitlab.com/api/v4/projects/37777023/issues/15/notes",
|
||||
"award_emoji": "https://gitlab.com/api/v4/projects/37777023/issues/15/award_emoji",
|
||||
"project": "https://gitlab.com/api/v4/projects/37777023"
|
||||
},
|
||||
"references":
|
||||
{
|
||||
"short": "#15",
|
||||
"relative": "#15",
|
||||
"full": "jay_mccure/test2target#15"
|
||||
},
|
||||
"moved_to_id": 0,
|
||||
"health_status": ""
|
||||
}
|
||||
]
|
|
@ -1,6 +1,7 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -18,11 +19,17 @@ import (
|
|||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
type IssueWithNotes struct {
|
||||
*gitlab.Issue
|
||||
Notes []*gitlab.Note
|
||||
}
|
||||
|
||||
type ViewOpts struct {
|
||||
ShowComments bool
|
||||
ShowSystemLogs bool
|
||||
OpenInBrowser bool
|
||||
Web bool
|
||||
OutputFormat string
|
||||
|
||||
CommentPageNumber int
|
||||
CommentLimit int
|
||||
|
@ -109,6 +116,9 @@ func NewCmdView(f *cmdutils.Factory, issueType issuable.IssueType) *cobra.Comman
|
|||
return err
|
||||
}
|
||||
defer f.IO.StopPager()
|
||||
if opts.OutputFormat == "json" {
|
||||
return printJSONIssue(opts)
|
||||
}
|
||||
if f.IO.IsErrTTY && f.IO.IsaTTY {
|
||||
return printTTYIssuePreview(opts)
|
||||
}
|
||||
|
@ -121,6 +131,7 @@ func NewCmdView(f *cmdutils.Factory, issueType issuable.IssueType) *cobra.Comman
|
|||
issueViewCmd.Flags().BoolVarP(&opts.Web, "web", "w", false, fmt.Sprintf("Open %s in a browser. Uses default browser or browser specified in BROWSER variable", issueType))
|
||||
issueViewCmd.Flags().IntVarP(&opts.CommentPageNumber, "page", "p", 1, "Page number")
|
||||
issueViewCmd.Flags().IntVarP(&opts.CommentLimit, "per-page", "P", 20, "Number of items to list per page")
|
||||
issueViewCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
|
||||
return issueViewCmd
|
||||
}
|
||||
|
@ -275,3 +286,17 @@ func RawIssuableNotes(notes []*gitlab.Note, showComments bool, showSystemLogs bo
|
|||
|
||||
return out
|
||||
}
|
||||
|
||||
func printJSONIssue(opts *ViewOpts) error {
|
||||
// var notes []gitlab.Note
|
||||
if opts.ShowComments {
|
||||
|
||||
extendedIssue := IssueWithNotes{opts.Issue, opts.Notes}
|
||||
issueJSON, _ := json.Marshal(extendedIssue)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(issueJSON))
|
||||
} else {
|
||||
issueJSON, _ := json.Marshal(opts.Issue)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(issueJSON))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package view
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
|
@ -499,3 +500,15 @@ func Test_assigneesList(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssueViewJSON(t *testing.T) {
|
||||
cmd := NewCmdView(stubFactory, issuable.TypeIssue)
|
||||
|
||||
output, err := cmdtest.ExecuteCommand(cmd, "1 -F json", stdout, stderr)
|
||||
if err != nil {
|
||||
t.Errorf("error running command `issue view 1 -F json`: %v", err)
|
||||
}
|
||||
|
||||
assert.True(t, json.Valid([]byte(output.String())))
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
|
@ -13,6 +14,8 @@ import (
|
|||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
var OutputFormat string
|
||||
|
||||
func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
||||
labelListCmd := &cobra.Command{
|
||||
Use: "list [flags]",
|
||||
|
@ -54,16 +57,22 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(f.IO.StdOut, "Showing label %d of %d on %s\n\n", len(labels), len(labels), repo.FullName())
|
||||
var labelPrintInfo string
|
||||
for _, label := range labels {
|
||||
var description string
|
||||
if label.Description != "" {
|
||||
description = fmt.Sprintf(" -> %s", label.Description)
|
||||
if OutputFormat == "json" {
|
||||
labelListJSON, _ := json.Marshal(labels)
|
||||
fmt.Fprintln(f.IO.StdOut, string(labelListJSON))
|
||||
|
||||
} else {
|
||||
fmt.Fprintf(f.IO.StdOut, "Showing label %d of %d on %s\n\n", len(labels), len(labels), repo.FullName())
|
||||
var labelPrintInfo string
|
||||
for _, label := range labels {
|
||||
var description string
|
||||
if label.Description != "" {
|
||||
description = fmt.Sprintf(" -> %s", label.Description)
|
||||
}
|
||||
labelPrintInfo += fmt.Sprintf("%s%s (%s)\n", label.Name, description, label.Color)
|
||||
}
|
||||
labelPrintInfo += fmt.Sprintf("%s%s (%s)\n", label.Name, description, label.Color)
|
||||
fmt.Fprintln(f.IO.StdOut, utils.Indent(labelPrintInfo, " "))
|
||||
}
|
||||
fmt.Fprintln(f.IO.StdOut, utils.Indent(labelPrintInfo, " "))
|
||||
|
||||
// Cache labels for host
|
||||
//labelNames := make([]string, 0, len(labels))
|
||||
|
@ -81,6 +90,7 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
labelListCmd.Flags().IntP("page", "p", 1, "Page number")
|
||||
labelListCmd.Flags().IntP("per-page", "P", 30, "Number of items to list per page")
|
||||
labelListCmd.Flags().StringVarP(&OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
|
||||
return labelListCmd
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -14,8 +12,8 @@ import (
|
|||
"gitlab.com/gitlab-org/cli/test"
|
||||
)
|
||||
|
||||
func runCommand(rt http.RoundTripper) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := iostreams.Test()
|
||||
func runCommand(rt http.RoundTripper, cli string) (*test.CmdOut, error) {
|
||||
ios, _, stdout, stderr := cmdtest.InitIOStreams(true, "")
|
||||
factory := cmdtest.InitFactory(ios, rt)
|
||||
|
||||
// TODO: shouldn't be there but the stub doesn't work without it
|
||||
|
@ -23,11 +21,7 @@ func runCommand(rt http.RoundTripper) (*test.CmdOut, error) {
|
|||
|
||||
cmd := NewCmdList(factory)
|
||||
|
||||
_, err := cmd.ExecuteC()
|
||||
return &test.CmdOut{
|
||||
OutBuf: stdout,
|
||||
ErrBuf: stderr,
|
||||
}, err
|
||||
return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr)
|
||||
}
|
||||
|
||||
func TestLabelList(t *testing.T) {
|
||||
|
@ -58,7 +52,7 @@ func TestLabelList(t *testing.T) {
|
|||
]
|
||||
`))
|
||||
|
||||
output, err := runCommand(fakeHTTP)
|
||||
output, err := runCommand(fakeHTTP, "")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `label list`: %v", err)
|
||||
}
|
||||
|
@ -74,3 +68,51 @@ func TestLabelList(t *testing.T) {
|
|||
`), out)
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
||||
func TestLabelListJSON(t *testing.T) {
|
||||
fakeHTTP := httpmock.New()
|
||||
fakeHTTP.MatchURL = httpmock.PathAndQuerystring
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
expectedBody := `[
|
||||
{
|
||||
"id": 29739671,
|
||||
"name": "my label",
|
||||
"color": "#00b140",
|
||||
"text_color": "#FFFFFF",
|
||||
"description": "Simple label",
|
||||
"open_issues_count": 0,
|
||||
"closed_issues_count": 0,
|
||||
"open_merge_requests_count": 0,
|
||||
"subscribed": false,
|
||||
"priority": 0,
|
||||
"is_project_label": true
|
||||
}
|
||||
]`
|
||||
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/api/v4/projects/OWNER%2FREPO/labels?page=1&per_page=30&with_counts=true",
|
||||
httpmock.NewStringResponse(http.StatusOK, `[
|
||||
{
|
||||
"id": 29739671,
|
||||
"name": "my label",
|
||||
"description": "Simple label",
|
||||
"description_html": "Simple label",
|
||||
"text_color": "#FFFFFF",
|
||||
"color": "#00b140",
|
||||
"open_issues_count": 0,
|
||||
"closed_issues_count": 0,
|
||||
"open_merge_requests_count": 0,
|
||||
"subscribed": false,
|
||||
"priority": null,
|
||||
"is_project_label": true
|
||||
}
|
||||
]`))
|
||||
|
||||
output, err := runCommand(fakeHTTP, "-F json")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `label list -F json`: %v", err)
|
||||
}
|
||||
|
||||
assert.JSONEq(t, expectedBody, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
@ -41,8 +42,9 @@ type ListOptions struct {
|
|||
Draft bool
|
||||
|
||||
// Pagination
|
||||
Page int
|
||||
PerPage int
|
||||
Page int
|
||||
PerPage int
|
||||
OutputFormat string
|
||||
|
||||
// display opts
|
||||
ListType string
|
||||
|
@ -132,12 +134,13 @@ func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error) *cobra.
|
|||
mrListCmd.Flags().BoolVarP(&opts.Closed, "closed", "c", false, "Get only closed merge requests")
|
||||
mrListCmd.Flags().BoolVarP(&opts.Merged, "merged", "M", false, "Get only merged merge requests")
|
||||
mrListCmd.Flags().BoolVarP(&opts.Draft, "draft", "d", false, "Filter by draft merge requests")
|
||||
mrListCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
mrListCmd.Flags().IntVarP(&opts.Page, "page", "p", 1, "Page number")
|
||||
mrListCmd.Flags().IntVarP(&opts.PerPage, "per-page", "P", 30, "Number of items to list per page")
|
||||
mrListCmd.Flags().StringSliceVarP(&opts.Assignee, "assignee", "a", []string{}, "Get only merge requests assigned to users")
|
||||
mrListCmd.Flags().StringSliceVarP(&opts.Reviewer, "reviewer", "r", []string{}, "Get only merge requests with users as reviewer")
|
||||
|
||||
mrListCmd.Flags().BoolP("opened", "o", false, "Get only open merge requests")
|
||||
mrListCmd.Flags().BoolP("opened", "O", false, "Get only open merge requests")
|
||||
_ = mrListCmd.Flags().MarkHidden("opened")
|
||||
_ = mrListCmd.Flags().MarkDeprecated("opened", "default value if neither --closed, --locked or --merged is used")
|
||||
|
||||
|
@ -165,8 +168,14 @@ func listRun(opts *ListOptions) error {
|
|||
l := &gitlab.ListProjectMergeRequestsOptions{
|
||||
State: gitlab.String(opts.State),
|
||||
}
|
||||
l.Page = 1
|
||||
l.PerPage = 30
|
||||
jsonOutput := opts.OutputFormat == "json"
|
||||
if jsonOutput {
|
||||
l.Page = 0
|
||||
l.PerPage = 0
|
||||
} else {
|
||||
l.Page = 1
|
||||
l.PerPage = 30
|
||||
}
|
||||
|
||||
if opts.Author != "" {
|
||||
u, err := api.UserByName(apiClient, opts.Author)
|
||||
|
@ -256,11 +265,15 @@ func listRun(opts *ListOptions) error {
|
|||
title.ListActionType = opts.ListType
|
||||
title.CurrentPageTotal = len(mergeRequests)
|
||||
|
||||
if err = opts.IO.StartPager(); err != nil {
|
||||
return err
|
||||
if jsonOutput {
|
||||
mrListJSON, _ := json.Marshal(mergeRequests)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(mrListJSON))
|
||||
} else {
|
||||
if err = opts.IO.StartPager(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer opts.IO.StopPager()
|
||||
fmt.Fprintf(opts.IO.StdOut, "%s\n%s\n", title.Describe(), mrutils.DisplayAllMRs(opts.IO, mergeRequests))
|
||||
}
|
||||
defer opts.IO.StopPager()
|
||||
fmt.Fprintf(opts.IO.StdOut, "%s\n%s\n", title.Describe(), mrutils.DisplayAllMRs(opts.IO, mergeRequests))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package list
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -355,3 +356,31 @@ func TestMergeRequestList_labels(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMrListJSON(t *testing.T) {
|
||||
fakeHTTP := httpmock.New()
|
||||
fakeHTTP.MatchURL = httpmock.PathAndQuerystring
|
||||
defer fakeHTTP.Verify(t)
|
||||
|
||||
fakeHTTP.RegisterResponder(http.MethodGet, "/api/v4/projects/OWNER/REPO/merge_requests?page=1&per_page=30&state=opened",
|
||||
httpmock.NewFileResponse(http.StatusOK, "./testdata/mrList.json"))
|
||||
|
||||
output, err := runCommand(fakeHTTP, true, "-F json", nil, "")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `mr list -F json`: %v", err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b, err := os.ReadFile("./testdata/mrList.json")
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
|
||||
expectedOut := string(b)
|
||||
|
||||
assert.JSONEq(t, expectedOut, output.String())
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
[
|
||||
{
|
||||
"id": 136297744,
|
||||
"iid": 4,
|
||||
"target_branch": "main",
|
||||
"source_branch": "1-fake-issue-3",
|
||||
"project_id": 29316529,
|
||||
"title": "Draft: Resolve \"fake issue\"",
|
||||
"state": "opened",
|
||||
"created_at": "2022-01-20T21:20:50.665Z",
|
||||
"updated_at": "2022-01-20T21:47:54.11Z",
|
||||
"upvotes": 0,
|
||||
"downvotes": 0,
|
||||
"author":
|
||||
{
|
||||
"id": 8814129,
|
||||
"username": "OWNER",
|
||||
"name": "Some User",
|
||||
"state": "active",
|
||||
"created_at": null,
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/8814129/avatar.png",
|
||||
"web_url": "https://gitlab.com/OWNER"
|
||||
},
|
||||
"assignee":
|
||||
{
|
||||
"id": 8814129,
|
||||
"username": "OWNER",
|
||||
"name": "Some User",
|
||||
"state": "active",
|
||||
"created_at": null,
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/8814129/avatar.png",
|
||||
"web_url": "https://gitlab.com/OWNER"
|
||||
},
|
||||
"assignees":
|
||||
[
|
||||
{
|
||||
"id": 8814129,
|
||||
"username": "OWNER",
|
||||
"name": "Some User",
|
||||
"state": "active",
|
||||
"created_at": null,
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/8814129/avatar.png",
|
||||
"web_url": "https://gitlab.com/OWNER"
|
||||
}
|
||||
],
|
||||
"reviewers":
|
||||
[],
|
||||
"source_project_id": 29316529,
|
||||
"target_project_id": 29316529,
|
||||
"labels": "",
|
||||
"label_details": null,
|
||||
"description": "Closes #1",
|
||||
"draft": true,
|
||||
"work_in_progress": true,
|
||||
"milestone": null,
|
||||
"merge_when_pipeline_succeeds": false,
|
||||
"detailed_merge_status": "draft_status",
|
||||
"merge_error": "",
|
||||
"merged_by": null,
|
||||
"merged_at": null,
|
||||
"closed_by": null,
|
||||
"closed_at": null,
|
||||
"subscribed": false,
|
||||
"sha": "44eb489568f7cb1a5a730fce6b247cd3797172ca",
|
||||
"merge_commit_sha": "",
|
||||
"squash_commit_sha": "",
|
||||
"user_notes_count": 0,
|
||||
"changes_count": "",
|
||||
"should_remove_source_branch": false,
|
||||
"force_remove_source_branch": true,
|
||||
"allow_collaboration": false,
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/merge_requests/4",
|
||||
"references":
|
||||
{
|
||||
"short": "!4",
|
||||
"relative": "!4",
|
||||
"full": "OWNER/REPO!4"
|
||||
},
|
||||
"discussion_locked": false,
|
||||
"changes": null,
|
||||
"user":
|
||||
{
|
||||
"can_merge": false
|
||||
},
|
||||
"time_stats":
|
||||
{
|
||||
"human_time_estimate": "",
|
||||
"human_total_time_spent": "",
|
||||
"time_estimate": 0,
|
||||
"total_time_spent": 0
|
||||
},
|
||||
"squash": false,
|
||||
"pipeline": null,
|
||||
"head_pipeline": null,
|
||||
"diff_refs":
|
||||
{
|
||||
"base_sha": "",
|
||||
"head_sha": "",
|
||||
"start_sha": ""
|
||||
},
|
||||
"diverged_commits_count": 0,
|
||||
"rebase_in_progress": false,
|
||||
"approvals_before_merge": 0,
|
||||
"reference": "!4",
|
||||
"first_contribution": false,
|
||||
"task_completion_status":
|
||||
{
|
||||
"count": 0,
|
||||
"completed_count": 0
|
||||
},
|
||||
"has_conflicts": false,
|
||||
"blocking_discussions_resolved": true,
|
||||
"overflow": false,
|
||||
"merge_status": "can_be_merged"
|
||||
},
|
||||
{
|
||||
"id": 135750125,
|
||||
"iid": 1,
|
||||
"target_branch": "main",
|
||||
"source_branch": "OWNER-main-patch-25608",
|
||||
"project_id": 29316529,
|
||||
"title": "Update .gitlab-ci.yml",
|
||||
"state": "opened",
|
||||
"created_at": "2022-01-18T17:02:23.27Z",
|
||||
"updated_at": "2022-01-18T18:06:50.054Z",
|
||||
"upvotes": 0,
|
||||
"downvotes": 0,
|
||||
"author":
|
||||
{
|
||||
"id": 8814129,
|
||||
"username": "OWNER",
|
||||
"name": "Some User",
|
||||
"state": "active",
|
||||
"created_at": null,
|
||||
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/8814129/avatar.png",
|
||||
"web_url": "https://gitlab.com/OWNER"
|
||||
},
|
||||
"assignee": null,
|
||||
"assignees":
|
||||
[],
|
||||
"reviewers":
|
||||
[],
|
||||
"source_project_id": 29316529,
|
||||
"target_project_id": 29316529,
|
||||
"labels": "",
|
||||
"label_details": null,
|
||||
"description": "",
|
||||
"draft": false,
|
||||
"work_in_progress": false,
|
||||
"milestone": null,
|
||||
"merge_when_pipeline_succeeds": false,
|
||||
"detailed_merge_status": "mergeable",
|
||||
"merge_error": "",
|
||||
"merged_by": null,
|
||||
"merged_at": null,
|
||||
"closed_by": null,
|
||||
"closed_at": null,
|
||||
"subscribed": false,
|
||||
"sha": "123f34ebfd5d97ef562974e55e01b83f06ae7b4a",
|
||||
"merge_commit_sha": "",
|
||||
"squash_commit_sha": "",
|
||||
"user_notes_count": 0,
|
||||
"changes_count": "",
|
||||
"should_remove_source_branch": false,
|
||||
"force_remove_source_branch": true,
|
||||
"allow_collaboration": false,
|
||||
"web_url": "https://gitlab.com/OWNER/REPO/-/merge_requests/1",
|
||||
"references":
|
||||
{
|
||||
"short": "!1",
|
||||
"relative": "!1",
|
||||
"full": "OWNER/REPO!1"
|
||||
},
|
||||
"discussion_locked": false,
|
||||
"changes": null,
|
||||
"user":
|
||||
{
|
||||
"can_merge": false
|
||||
},
|
||||
"time_stats":
|
||||
{
|
||||
"human_time_estimate": "",
|
||||
"human_total_time_spent": "",
|
||||
"time_estimate": 0,
|
||||
"total_time_spent": 0
|
||||
},
|
||||
"squash": false,
|
||||
"pipeline": null,
|
||||
"head_pipeline": null,
|
||||
"diff_refs":
|
||||
{
|
||||
"base_sha": "",
|
||||
"head_sha": "",
|
||||
"start_sha": ""
|
||||
},
|
||||
"diverged_commits_count": 0,
|
||||
"rebase_in_progress": false,
|
||||
"approvals_before_merge": 0,
|
||||
"reference": "!1",
|
||||
"first_contribution": false,
|
||||
"task_completion_status":
|
||||
{
|
||||
"count": 0,
|
||||
"completed_count": 0
|
||||
},
|
||||
"has_conflicts": false,
|
||||
"blocking_discussions_resolved": true,
|
||||
"overflow": false,
|
||||
"merge_status": "can_be_merged"
|
||||
}
|
||||
]
|
|
@ -1,6 +1,7 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -21,6 +22,7 @@ type ViewOpts struct {
|
|||
ShowComments bool
|
||||
ShowSystemLogs bool
|
||||
OpenInBrowser bool
|
||||
OutputFormat string
|
||||
|
||||
CommentPageNumber int
|
||||
CommentLimit int
|
||||
|
@ -28,6 +30,11 @@ type ViewOpts struct {
|
|||
IO *iostreams.IOStreams
|
||||
}
|
||||
|
||||
type MRWithNotes struct {
|
||||
*gitlab.MergeRequest
|
||||
Notes []*gitlab.Note
|
||||
}
|
||||
|
||||
func NewCmdView(f *cmdutils.Factory) *cobra.Command {
|
||||
opts := &ViewOpts{
|
||||
IO: f.IO,
|
||||
|
@ -96,6 +103,9 @@ func NewCmdView(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
defer f.IO.StopPager()
|
||||
|
||||
if opts.OutputFormat == "json" {
|
||||
return printJSONMR(opts, mr, notes)
|
||||
}
|
||||
if f.IO.IsOutputTTY() {
|
||||
return printTTYMRPreview(opts, mr, mrApprovals, notes)
|
||||
}
|
||||
|
@ -105,6 +115,7 @@ func NewCmdView(f *cmdutils.Factory) *cobra.Command {
|
|||
|
||||
mrViewCmd.Flags().BoolVarP(&opts.ShowComments, "comments", "c", false, "Show mr comments and activities")
|
||||
mrViewCmd.Flags().BoolVarP(&opts.ShowSystemLogs, "system-logs", "s", false, "Show system activities / logs")
|
||||
mrViewCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
mrViewCmd.Flags().BoolVarP(&opts.OpenInBrowser, "web", "w", false, "Open mr in a browser. Uses default browser or browser specified in BROWSER variable")
|
||||
mrViewCmd.Flags().IntVarP(&opts.CommentPageNumber, "page", "p", 0, "Page number")
|
||||
mrViewCmd.Flags().IntVarP(&opts.CommentLimit, "per-page", "P", 20, "Number of items to list per page")
|
||||
|
@ -281,3 +292,15 @@ func rawMRPreview(opts *ViewOpts, mr *gitlab.MergeRequest, notes []*gitlab.Note)
|
|||
|
||||
return out
|
||||
}
|
||||
|
||||
func printJSONMR(opts *ViewOpts, mr *gitlab.MergeRequest, notes []*gitlab.Note) error {
|
||||
if opts.ShowComments {
|
||||
extendedMR := MRWithNotes{mr, notes}
|
||||
mrJSON, _ := json.Marshal(extendedMR)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(mrJSON))
|
||||
} else {
|
||||
mrJSON, _ := json.Marshal(mr)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(mrJSON))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package view
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
|
@ -465,3 +466,17 @@ func Test_reviewersList(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMrViewJSON(t *testing.T) {
|
||||
cmd := NewCmdView(stubFactory)
|
||||
stdout.Reset()
|
||||
stderr.Reset()
|
||||
|
||||
output, err := cmdtest.ExecuteCommand(cmd, "1 -F json", stdout, stderr)
|
||||
if err != nil {
|
||||
t.Errorf("error running command `mr view 1 -F json`: %v", err)
|
||||
}
|
||||
|
||||
assert.True(t, json.Valid([]byte(output.String())))
|
||||
assert.Empty(t, output.Stderr())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
||||
|
@ -18,6 +19,7 @@ type Options struct {
|
|||
Group string
|
||||
PerPage int
|
||||
Page int
|
||||
OutputFormat string
|
||||
FilterAll bool
|
||||
FilterOwned bool
|
||||
FilterMember bool
|
||||
|
@ -51,6 +53,7 @@ func NewCmdList(f *cmdutils.Factory) *cobra.Command {
|
|||
repoListCmd.Flags().StringVarP(&opts.Group, "group", "g", "", "Return only repositories in the given group and its subgroups")
|
||||
repoListCmd.Flags().IntVarP(&opts.Page, "page", "p", 1, "Page number")
|
||||
repoListCmd.Flags().IntVarP(&opts.PerPage, "per-page", "P", 30, "Number of items to list per page")
|
||||
repoListCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
repoListCmd.Flags().BoolVarP(&opts.FilterAll, "all", "a", false, "List all projects on the instance")
|
||||
repoListCmd.Flags().BoolVarP(&opts.FilterOwned, "mine", "m", false, "Only list projects you own (default if no filters are passed)")
|
||||
repoListCmd.Flags().BoolVar(&opts.FilterMember, "member", false, "Only list projects which you are a member")
|
||||
|
@ -79,17 +82,25 @@ func runE(opts *Options) error {
|
|||
return err
|
||||
}
|
||||
|
||||
title := fmt.Sprintf("Showing %d of %d projects (Page %d of %d)\n", len(projects), resp.TotalItems, resp.CurrentPage, resp.TotalPages)
|
||||
if opts.OutputFormat == "json" {
|
||||
projectListJSON, _ := json.Marshal(projects)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(projectListJSON))
|
||||
} else {
|
||||
// Title
|
||||
title := fmt.Sprintf("Showing %d of %d projects (Page %d of %d)\n", len(projects), resp.TotalItems, resp.CurrentPage, resp.TotalPages)
|
||||
|
||||
table := tableprinter.NewTablePrinter()
|
||||
for _, prj := range projects {
|
||||
table.AddCell(c.Blue(prj.PathWithNamespace))
|
||||
table.AddCell(prj.SSHURLToRepo)
|
||||
table.AddCell(prj.Description)
|
||||
table.EndRow()
|
||||
// List
|
||||
table := tableprinter.NewTablePrinter()
|
||||
for _, prj := range projects {
|
||||
table.AddCell(c.Blue(prj.PathWithNamespace))
|
||||
table.AddCell(prj.SSHURLToRepo)
|
||||
table.AddCell(prj.Description)
|
||||
table.EndRow()
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.StdOut, "%s\n%s\n", title, table.String())
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.StdOut, "%s\n%s\n", title, table.String())
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package view
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -20,6 +21,7 @@ type ViewOptions struct {
|
|||
ProjectID string
|
||||
APIClient *gitlab.Client
|
||||
Web bool
|
||||
OutputFormat string
|
||||
Branch string
|
||||
Browser string
|
||||
GlamourStyle string
|
||||
|
@ -120,6 +122,7 @@ func NewCmdView(f *cmdutils.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
projectViewCmd.Flags().BoolVarP(&opts.Web, "web", "w", false, "Open a project in the browser")
|
||||
projectViewCmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
projectViewCmd.Flags().StringVarP(&opts.Branch, "branch", "b", "", "View a specific branch of the repository")
|
||||
|
||||
return projectViewCmd
|
||||
|
@ -146,22 +149,24 @@ func runViewProject(opts *ViewOptions) error {
|
|||
generateProjectOpenURL(projectURL, project.DefaultBranch, opts.Branch),
|
||||
opts.Browser,
|
||||
)
|
||||
}
|
||||
|
||||
readmeFile, err := getReadmeFile(opts, project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.IO.IsaTTY {
|
||||
if err := opts.IO.StartPager(); err != nil {
|
||||
} else if opts.OutputFormat == "json" {
|
||||
printProjectContentJSON(opts, project)
|
||||
} else {
|
||||
readmeFile, err := getReadmeFile(opts, project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer opts.IO.StopPager()
|
||||
|
||||
printProjectContentTTY(opts, project, readmeFile)
|
||||
} else {
|
||||
printProjectContentRaw(opts, project, readmeFile)
|
||||
if opts.IO.IsaTTY {
|
||||
if err := opts.IO.StartPager(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer opts.IO.StopPager()
|
||||
|
||||
printProjectContentTTY(opts, project, readmeFile)
|
||||
} else {
|
||||
printProjectContentRaw(opts, project, readmeFile)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -257,3 +262,8 @@ func printProjectContentRaw(opts *ViewOptions, project *gitlab.Project, readme *
|
|||
fmt.Fprintln(opts.IO.StdOut)
|
||||
}
|
||||
}
|
||||
|
||||
func printProjectContentJSON(opts *ViewOptions, project *gitlab.Project) {
|
||||
projectJSON, _ := json.Marshal(project)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(projectJSON))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package get
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
@ -19,9 +20,11 @@ type GetOps struct {
|
|||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (glrepo.Interface, error)
|
||||
|
||||
Key string
|
||||
Group string
|
||||
Scope string
|
||||
Scope string
|
||||
Key string
|
||||
Group string
|
||||
OutputFormat string
|
||||
JSONOutput bool
|
||||
}
|
||||
|
||||
func NewCmdSet(f *cmdutils.Factory, runE func(opts *GetOps) error) *cobra.Command {
|
||||
|
@ -65,6 +68,7 @@ func NewCmdSet(f *cmdutils.Factory, runE func(opts *GetOps) error) *cobra.Comman
|
|||
|
||||
cmd.Flags().StringVarP(&opts.Scope, "scope", "s", "*", "The environment_scope of the variable. All (*), or specific environments.")
|
||||
cmd.Flags().StringVarP(&opts.Group, "group", "g", "", "Get variable for a group")
|
||||
cmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -81,6 +85,10 @@ func getRun(opts *GetOps) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.OutputFormat == "json" {
|
||||
varJSON, _ := json.Marshal(variable)
|
||||
fmt.Println(string(varJSON))
|
||||
}
|
||||
variableValue = variable.Value
|
||||
} else {
|
||||
baseRepo, err := opts.BaseRepo()
|
||||
|
@ -92,9 +100,15 @@ func getRun(opts *GetOps) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.OutputFormat == "json" {
|
||||
varJSON, _ := json.Marshal(variable)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(varJSON))
|
||||
}
|
||||
variableValue = variable.Value
|
||||
}
|
||||
|
||||
fmt.Fprint(opts.IO.StdOut, variableValue)
|
||||
if opts.OutputFormat != "json" {
|
||||
fmt.Fprint(opts.IO.StdOut, variableValue)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
|
@ -18,8 +21,9 @@ type ListOpts struct {
|
|||
IO *iostreams.IOStreams
|
||||
BaseRepo func() (glrepo.Interface, error)
|
||||
|
||||
ValueSet bool
|
||||
Group string
|
||||
ValueSet bool
|
||||
Group string
|
||||
OutputFormat string
|
||||
}
|
||||
|
||||
func NewCmdSet(f *cmdutils.Factory, runE func(opts *ListOpts) error) *cobra.Command {
|
||||
|
@ -64,6 +68,7 @@ func NewCmdSet(f *cmdutils.Factory, runE func(opts *ListOpts) error) *cobra.Comm
|
|||
"",
|
||||
"Select a group/subgroup. This option is ignored if a repo argument is set.",
|
||||
)
|
||||
cmd.Flags().StringVarP(&opts.OutputFormat, "output", "F", "text", "Format output as: text, json")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -90,8 +95,14 @@ func listRun(opts *ListOpts) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, variable := range variables {
|
||||
table.AddRow(variable.Key, variable.Protected, variable.Masked, !variable.Raw, variable.EnvironmentScope)
|
||||
if opts.OutputFormat == "json" {
|
||||
varListJSON, _ := json.Marshal(variables)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(varListJSON))
|
||||
|
||||
} else {
|
||||
for _, variable := range variables {
|
||||
table.AddRow(variable.Key, variable.Protected, variable.Masked, !variable.Raw, variable.EnvironmentScope)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
opts.IO.Logf("Listing variables for the %s project:\n\n", color.Bold(repo.FullName()))
|
||||
|
@ -100,11 +111,18 @@ func listRun(opts *ListOpts) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, variable := range variables {
|
||||
table.AddRow(variable.Key, variable.Protected, variable.Masked, !variable.Raw, variable.EnvironmentScope)
|
||||
if opts.OutputFormat == "json" {
|
||||
varListJSON, _ := json.Marshal(variables)
|
||||
fmt.Fprintln(opts.IO.StdOut, string(varListJSON))
|
||||
} else {
|
||||
for _, variable := range variables {
|
||||
table.AddRow(variable.Key, variable.Protected, variable.Masked, !variable.Raw, variable.EnvironmentScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opts.IO.Log(table.String())
|
||||
if opts.OutputFormat != "json" {
|
||||
opts.IO.Log(table.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@ glab ci -R some/project -p 12345
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-b, --branch string Check pipeline status for a branch. (Default is current branch)
|
||||
-o, --output-format string Format output as: text, json (default "text")
|
||||
-p, --pipeline-id int Provide pipeline ID
|
||||
-d, --with-job-details Show extended job information
|
||||
--with-variables Show variables in pipeline (maintainer role required)
|
||||
-b, --branch string Check pipeline status for a branch. (Default is current branch)
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --pipeline-id int Provide pipeline ID
|
||||
-d, --with-job-details Show extended job information
|
||||
--with-variables Show variables in pipeline (maintainer role required)
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -29,6 +29,7 @@ glab ci list --status=failed
|
|||
|
||||
```plaintext
|
||||
-o, --orderBy string Order pipeline by {id|status|ref|updated_at|user_id} (default "id")
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 30)
|
||||
--sort string Sort pipeline by {asc|desc} (default "desc")
|
||||
|
|
|
@ -48,7 +48,7 @@ glab incident list --milestone release-2.0.0 --opened
|
|||
--not-assignee strings Filter incident by not being assigneed to <username>
|
||||
--not-author strings Filter by not being by author(s) <username>
|
||||
--not-label strings Filter incident by lack of label <name>
|
||||
-F, --output-format string One of 'details', 'ids', or 'urls' (default "details")
|
||||
-F, --output string One of 'details', 'ids', 'urls' or 'json' (default "details")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page. (default 30)
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
|
|
|
@ -37,11 +37,12 @@ glab incident view https://gitlab.com/NAMESPACE/REPO/-/issues/incident/123
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-c, --comments Show incident comments and activities
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 20)
|
||||
-s, --system-logs Show system activities / logs
|
||||
-w, --web Open incident in a browser. Uses default browser or browser specified in BROWSER variable
|
||||
-c, --comments Show incident comments and activities
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 20)
|
||||
-s, --system-logs Show system activities / logs
|
||||
-w, --web Open incident in a browser. Uses default browser or browser specified in BROWSER variable
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -49,7 +49,7 @@ glab issue list --milestone release-2.0.0 --opened
|
|||
--not-assignee strings Filter issue by not being assigneed to <username>
|
||||
--not-author strings Filter by not being by author(s) <username>
|
||||
--not-label strings Filter issue by lack of label <name>
|
||||
-F, --output-format string One of 'details', 'ids', or 'urls' (default "details")
|
||||
-F, --output string One of 'details', 'ids', 'urls' or 'json' (default "details")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page. (default 30)
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
|
|
|
@ -37,11 +37,12 @@ glab issue view https://gitlab.com/NAMESPACE/REPO/-/issues/123
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-c, --comments Show issue comments and activities
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 20)
|
||||
-s, --system-logs Show system activities / logs
|
||||
-w, --web Open issue in a browser. Uses default browser or browser specified in BROWSER variable
|
||||
-c, --comments Show issue comments and activities
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 20)
|
||||
-s, --system-logs Show system activities / logs
|
||||
-w, --web Open issue in a browser. Uses default browser or browser specified in BROWSER variable
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -35,8 +35,9 @@ glab label list -R owner/repository
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 30)
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 30)
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -52,6 +52,7 @@ glab mr list -M --per-page 10
|
|||
-M, --merged Get only merged merge requests
|
||||
-m, --milestone string Filter merge request by milestone <id>
|
||||
--not-label strings Filter merge requests by not having label <name>
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 30)
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
|
|
|
@ -26,11 +26,12 @@ show
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-c, --comments Show mr comments and activities
|
||||
-p, --page int Page number
|
||||
-P, --per-page int Number of items to list per page (default 20)
|
||||
-s, --system-logs Show system activities / logs
|
||||
-w, --web Open mr in a browser. Uses default browser or browser specified in BROWSER variable
|
||||
-c, --comments Show mr comments and activities
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number
|
||||
-P, --per-page int Number of items to list per page (default 20)
|
||||
-s, --system-logs Show system activities / logs
|
||||
-w, --web Open mr in a browser. Uses default browser or browser specified in BROWSER variable
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -33,15 +33,16 @@ glab repo list
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-a, --all List all projects on the instance
|
||||
-g, --group string Return only repositories in the given group and its subgroups
|
||||
--member Only list projects which you are a member
|
||||
-m, --mine Only list projects you own (default if no filters are passed)
|
||||
-o, --order string Return repositories ordered by id, created_at, or other fields (default "last_activity_at")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 30)
|
||||
-s, --sort string Return repositories sorted in asc or desc order
|
||||
--starred Only list starred projects
|
||||
-a, --all List all projects on the instance
|
||||
-g, --group string Return only repositories in the given group and its subgroups
|
||||
--member Only list projects which you are a member
|
||||
-m, --mine Only list projects you own (default if no filters are passed)
|
||||
-o, --order string Return repositories ordered by id, created_at, or other fields (default "last_activity_at")
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-p, --page int Page number (default 1)
|
||||
-P, --per-page int Number of items to list per page (default 30)
|
||||
-s, --sort string Return repositories sorted in asc or desc order
|
||||
--starred Only list starred projects
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -43,6 +43,7 @@ $ glab repo view https://gitlab.company.org/user/repo.git
|
|||
|
||||
```plaintext
|
||||
-b, --branch string View a specific branch of the repository
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-w, --web Open a project in the browser
|
||||
```
|
||||
|
||||
|
|
|
@ -29,8 +29,9 @@ glab variable get -s SCOPE VAR_KEY
|
|||
## Options
|
||||
|
||||
```plaintext
|
||||
-g, --group string Get variable for a group
|
||||
-s, --scope string The environment_scope of the variable. All (*), or specific environments. (default "*")
|
||||
-g, --group string Get variable for a group
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-s, --scope string The environment_scope of the variable. All (*), or specific environments. (default "*")
|
||||
```
|
||||
|
||||
## Options inherited from parent commands
|
||||
|
|
|
@ -34,6 +34,7 @@ glab variable list
|
|||
|
||||
```plaintext
|
||||
-g, --group string Select a group/subgroup. This option is ignored if a repo argument is set.
|
||||
-F, --output string Format output as: text, json (default "text")
|
||||
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue