diff --git a/commands/issuable/list/issuable_list.go b/commands/issuable/list/issuable_list.go index b76c30fc53092adacdf8c4acb6c8a056e1054b57..2b765521a2e851935c531cdfa0d1e2368677cb7b 100644 --- a/commands/issuable/list/issuable_list.go +++ b/commands/issuable/list/issuable_list.go @@ -63,6 +63,8 @@ type ListOptions struct { HTTPClient func() (*gitlab.Client, error) JSONOutput bool + + IterationID int } func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error, issueType issuable.IssueType) *cobra.Command { @@ -272,6 +274,10 @@ func listRun(opts *ListOptions) error { opts.ListType = "search" } + if opts.IterationID != 0 { + listOpts.IterationID = gitlab.Ptr(opts.IterationID) + } + issueType := "issue" if opts.IssueType != "" { listOpts.IssueType = gitlab.Ptr(opts.IssueType) diff --git a/commands/issue/list/issue_list.go b/commands/issue/list/issue_list.go index 6fb9c25eec865b64e3242e5fd6b57522821dd86e..21447e8689cdcc035254ae736aee1ea78bde4a42 100644 --- a/commands/issue/list/issue_list.go +++ b/commands/issue/list/issue_list.go @@ -8,5 +8,8 @@ import ( ) func NewCmdList(f *cmdutils.Factory, runE func(opts *issuableListCmd.ListOptions) error) *cobra.Command { - return issuableListCmd.NewCmdList(f, runE, issuable.TypeIssue) + opts := &issuableListCmd.ListOptions{} + cmd := issuableListCmd.NewCmdList(f, runE, issuable.TypeIssue) + cmd.Flags().IntVar(&opts.IterationID, "iteration-id", 0, "Filter issues by iteration ID") + return cmd } diff --git a/commands/iteration/iteration.go b/commands/iteration/iteration.go new file mode 100644 index 0000000000000000000000000000000000000000..e33ccc73417643f1828b2cb0f3130c1a9bed3d25 --- /dev/null +++ b/commands/iteration/iteration.go @@ -0,0 +1,19 @@ +package iteration + +import ( + "github.com/spf13/cobra" + "gitlab.com/gitlab-org/cli/commands/cmdutils" + "gitlab.com/gitlab-org/cli/commands/iteration/list" +) + +func NewCmdIteration(f *cmdutils.Factory) *cobra.Command { + cmd := &cobra.Command{ + Use: "iteration ", + Short: "Work with GitLab iterations", + Long: ``, + } + + cmd.AddCommand(list.NewCmdList(f)) + + return cmd +} diff --git a/commands/iteration/list/iteration_list.go b/commands/iteration/list/iteration_list.go new file mode 100644 index 0000000000000000000000000000000000000000..80b85d1c3b7af0e61684ae9b235b7d1b1193411d --- /dev/null +++ b/commands/iteration/list/iteration_list.go @@ -0,0 +1,90 @@ +package list + +import ( + "encoding/json" + "fmt" + + "github.com/MakeNowJust/heredoc/v2" + "github.com/spf13/cobra" + gitlab "gitlab.com/gitlab-org/api/client-go" + "gitlab.com/gitlab-org/cli/commands/cmdutils" +) + +func NewCmdList(f *cmdutils.Factory) *cobra.Command { + var outputFormat string + var groupName string + var state string + + iterationListCmd := &cobra.Command{ + Use: "list [flags]", + Short: `List iterations in the group.`, + Long: ``, + Aliases: []string{"ls"}, + Example: heredoc.Doc(` + glab iteration list + glab iteration ls + glab iteration list --group mygroup + glab iteration list --state active --output json + `), + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + // Retrieve the configuration object + cfg, err := f.Config() + if err != nil { + return err + } + + // Get the token from the configuration using the correct section and key + token, err := cfg.Get("auth", "token") + if err != nil || token == "" { + return fmt.Errorf("failed to retrieve GitLab token from configuration") + } + + // Create a new GitLab client using the token + apiClient, err := gitlab.NewClient(token) + if err != nil { + return err + } + + // Set up the options for listing iterations + listOptions := &gitlab.ListGroupIterationsOptions{} + + if p, _ := cmd.Flags().GetInt("page"); p != 0 { + listOptions.Page = p + } + if p, _ := cmd.Flags().GetInt("per-page"); p != 0 { + listOptions.PerPage = p + } + if state != "" { + listOptions.State = gitlab.Ptr(state) + } + + // Fetch the iterations for the specified group + iterations, _, err := apiClient.GroupIterations.ListGroupIterations(groupName, listOptions) + if err != nil { + return err + } + + // Output the result in the specified format + if outputFormat == "json" { + iterationsJSON, _ := json.Marshal(iterations) + fmt.Fprintln(f.IO.StdOut, string(iterationsJSON)) + } else { + fmt.Fprintf(f.IO.StdOut, "Showing %d iterations for group %s.\n\n", len(iterations), groupName) + for _, iteration := range iterations { + fmt.Fprintf(f.IO.StdOut, "ID: %d, Title: %s, State: %d\n", iteration.ID, iteration.Title, iteration.State) + } + } + + return nil + }, + } + + iterationListCmd.Flags().IntP("page", "p", 1, "Page number.") + iterationListCmd.Flags().IntP("per-page", "P", 30, "Number of items to list per page.") + iterationListCmd.Flags().StringVarP(&outputFormat, "output", "F", "text", "Format output as: text, json.") + iterationListCmd.Flags().StringVarP(&groupName, "group", "g", "", "Name of the group") + iterationListCmd.Flags().StringVarP(&state, "state", "s", "", "Filter iterations by state (active, upcoming, opened, closed, or all)") + + return iterationListCmd +} diff --git a/commands/iteration/list/iteration_list_test.go b/commands/iteration/list/iteration_list_test.go new file mode 100644 index 0000000000000000000000000000000000000000..aca3f1ff0d733af95ae72ba3f3d49d811fd35b97 --- /dev/null +++ b/commands/iteration/list/iteration_list_test.go @@ -0,0 +1,47 @@ +package list + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "gitlab.com/gitlab-org/cli/commands/cmdutils" +) + +func TestNewCmdList(t *testing.T) { + f := cmdutils.NewFactory() + cmd := NewCmdList(f) + + assert.Equal(t, "list", cmd.Name()) + assert.Equal(t, []string{"ls"}, cmd.Aliases) + assert.Equal(t, "List iterations in the group.", cmd.Short) +} + +func TestListOptions(t *testing.T) { + f := cmdutils.NewFactory() + cmd := NewCmdList(f) + + // Test page flag + cmd.Flags().Set("page", "2") + page, _ := cmd.Flags().GetInt("page") + assert.Equal(t, 2, page) + + // Test per-page flag + cmd.Flags().Set("per-page", "50") + perPage, _ := cmd.Flags().GetInt("per-page") + assert.Equal(t, 50, perPage) + + // Test output format flag + cmd.Flags().Set("output", "json") + output, _ := cmd.Flags().GetString("output") + assert.Equal(t, "json", output) + + // Test group flag + cmd.Flags().Set("group", "mygroup") + group, _ := cmd.Flags().GetString("group") + assert.Equal(t, "mygroup", group) + + // Test state flag + cmd.Flags().Set("state", "active") + state, _ := cmd.Flags().GetString("state") + assert.Equal(t, "active", state) +} \ No newline at end of file diff --git a/commands/root.go b/commands/root.go index ee4c4b62f15a30b7ee41b834ad38c970a0ea3453..f0f667d44dad2c9e44a26e64ed8bd4bc28d5eb50 100644 --- a/commands/root.go +++ b/commands/root.go @@ -34,6 +34,7 @@ import ( userCmd "gitlab.com/gitlab-org/cli/commands/user" variableCmd "gitlab.com/gitlab-org/cli/commands/variable" versionCmd "gitlab.com/gitlab-org/cli/commands/version" + iterationCmd "gitlab.com/gitlab-org/cli/commands/iteration" "gitlab.com/gitlab-org/cli/internal/glrepo" ) @@ -143,6 +144,7 @@ func NewCmdRoot(f *cmdutils.Factory, version, commit string) *cobra.Command { rootCmd.AddCommand(duoCmd.NewCmdDuo(f)) rootCmd.AddCommand(tokenCmd.NewTokenCmd(f)) rootCmd.AddCommand(stackCmd.NewCmdStack(f)) + rootCmd.AddCommand(iterationCmd.NewCmdIteration(f)) rootCmd.Flags().BoolP("version", "v", false, "show glab version information") return rootCmd diff --git a/docs/source/issue/list.md b/docs/source/issue/list.md index f92d6bd8d6837fda47816c0981c5eadc3b74f09b..7a0c7df443db6978485f651c955380f18036d054 100644 --- a/docs/source/issue/list.md +++ b/docs/source/issue/list.md @@ -46,6 +46,7 @@ ls --in string search in: title, description. (default "title,description") -t, --issue-type string Filter issue by its type. Options: issue, incident, test_case. -i, --iteration int Filter issue by iteration . + --iteration-id int Filter issues by iteration ID -l, --label strings Filter issue by label . -m, --milestone string Filter issue by milestone . --not-assignee string Filter issue by not being assigned to . diff --git a/docs/source/iteration/help.md b/docs/source/iteration/help.md new file mode 100644 index 0000000000000000000000000000000000000000..33359248eef3f3074496aedb1195030b3d4406a0 --- /dev/null +++ b/docs/source/iteration/help.md @@ -0,0 +1,24 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab iteration help` + +Help about any command + +```plaintext +glab iteration help [command] [flags] +``` + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +``` diff --git a/docs/source/iteration/index.md b/docs/source/iteration/index.md new file mode 100644 index 0000000000000000000000000000000000000000..e6339e001a14b4fb64418207d72f7e6092f4b3e9 --- /dev/null +++ b/docs/source/iteration/index.md @@ -0,0 +1,24 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab iteration` + +Work with GitLab iterations + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +``` + +## Subcommands + +- [`list`](list.md) diff --git a/docs/source/iteration/list.md b/docs/source/iteration/list.md new file mode 100644 index 0000000000000000000000000000000000000000..47a665330e7707f30e44b0f32e5500c8a919fb46 --- /dev/null +++ b/docs/source/iteration/list.md @@ -0,0 +1,50 @@ +--- +stage: Create +group: Code Review +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + + + +# `glab iteration list` + +List iterations in the group. + +```plaintext +glab iteration list [flags] +``` + +## Aliases + +```plaintext +ls +``` + +## Examples + +```console +glab iteration list +glab iteration ls +glab iteration list --group mygroup +glab iteration list --state active --output json + +``` + +## Options + +```plaintext + -g, --group string Name of the group + -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, --state string Filter iterations by state (active, upcoming, opened, closed, or all) +``` + +## Options inherited from parent commands + +```plaintext + --help Show help for this command. +```