diff --git a/commands/issue/create/issue_create.go b/commands/issue/create/issue_create.go index b45075267949c3d4d5c22d0999bf52d649092811..3e3fc22fa677aa78df5c9d543ed36334f463cf11 100644 --- a/commands/issue/create/issue_create.go +++ b/commands/issue/create/issue_create.go @@ -5,7 +5,6 @@ import ( "fmt" "net/url" "os" - "strconv" "strings" "gitlab.com/gitlab-org/cli/pkg/iostreams" @@ -397,15 +396,9 @@ func createRun(opts *CreateOpts) error { func postCreateActions(apiClient *gitlab.Client, issue *gitlab.Issue, opts *CreateOpts, repo glrepo.Interface) error { if len(opts.LinkedIssues) > 0 { var err error - for _, targetIssueIID := range opts.LinkedIssues { - fmt.Fprintln(opts.IO.StdErr, "- Linking to issue ", targetIssueIID) - issue, _, err = api.LinkIssues(apiClient, repo.FullName(), issue.IID, &gitlab.CreateIssueLinkOptions{ - TargetIssueIID: gitlab.Ptr(strconv.Itoa(targetIssueIID)), - LinkType: gitlab.Ptr(opts.IssueLinkType), - }) - if err != nil { - return err - } + err = issueutils.LinkIssues(apiClient, issue, opts.LinkedIssues, opts.IssueLinkType, repo) + if err != nil { + return err } } if opts.TimeEstimate != "" { diff --git a/commands/issue/issueutils/utils.go b/commands/issue/issueutils/utils.go index dea8b7affe3f2e72a2b7054e8ef8d2dc764c148f..4075068aaf5852ba24f39554eaa6dbf050686f03 100644 --- a/commands/issue/issueutils/utils.go +++ b/commands/issue/issueutils/utils.go @@ -180,3 +180,18 @@ func issueMetadataFromURL(s string) (int, glrepo.Interface) { func issueFromIID(apiClient *gitlab.Client, repo glrepo.Interface, issueIID int) (*gitlab.Issue, error) { return api.GetIssue(apiClient, repo.FullName(), issueIID) } + +func LinkIssues(apiClient *gitlab.Client, issue *gitlab.Issue, LinkedIssues []int, IssueLinkType string, repo glrepo.Interface) error { + var err error + for _, targetIssueIID := range LinkedIssues { + //fmt.Fprintln(opts.IO.StdErr, "- Linking to issue ", targetIssueIID) + issue, _, err = api.LinkIssues(apiClient, repo.FullName(), issue.IID, &gitlab.CreateIssueLinkOptions{ + TargetIssueIID: gitlab.Ptr(strconv.Itoa(targetIssueIID)), + LinkType: gitlab.Ptr(IssueLinkType), + }) + if err != nil { + return err + } + } + return nil +} diff --git a/commands/issue/update/issue_update.go b/commands/issue/update/issue_update.go index a72409147f1e1c40ba3cc7ef36633c31c73c5732..f6f6fecbd355ab99742f0a684d568b3e92d00f1a 100644 --- a/commands/issue/update/issue_update.go +++ b/commands/issue/update/issue_update.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "gitlab.com/gitlab-org/cli/pkg/iostreams" + "gitlab.com/gitlab-org/cli/api" "gitlab.com/gitlab-org/cli/commands/cmdutils" "gitlab.com/gitlab-org/cli/commands/issue/issueutils" @@ -14,7 +16,17 @@ import ( "github.com/xanzy/go-gitlab" ) +type LinkIssueOpts struct { + LinkedIssues []int `json:"linked_issues,omitempty"` + IssueLinkType string `json:"issue_link_type,omitempty"` + + IO *iostreams.IOStreams `json:"-"` +} + func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command { + opts := &LinkIssueOpts{ + IO: f.IO, + } issueUpdateCmd := &cobra.Command{ Use: "update ", Short: `Update issue`, @@ -165,13 +177,50 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command { fmt.Fprintf(out, "- Updating issue #%d\n", issue.IID) - issue, err = api.UpdateIssue(apiClient, repo.FullName(), issue.IID, l) - if err != nil { - return err + // If the linked-issues flag is passed call to update LinkedIssues + if len(opts.LinkedIssues) > 0 { + err = issueutils.LinkIssues(apiClient, issue, opts.LinkedIssues, opts.IssueLinkType, repo) + if err != nil { + return err + } } - for _, s := range actions { - fmt.Fprintln(out, c.GreenCheck(), s) + // We want to only run the UpdateIssue function if flags are passed + // and the passed flags are not `linked-issues` or `link-type`. + // First we check that some number of flags was passed. We then check that + // if the flags are `linked-issues` or `link-type`. If it is NOT a link flag + // we return nil and continue. + switch cmd.Flags().NFlag() { + case 1: + if cmd.Flags().Changed("linked-issues") { + return errors.New("cannot update issue when only --linked-issues is set") + } + if cmd.Flags().Changed("link-type") { + return errors.New("cannot update issue when only --link-type is set") + } + + // continue execution to api.UpdateIssue + fallthrough + case 2: + if cmd.Flags().Changed("linked-issues") && cmd.Flags().Changed("link-type") { + return errors.New("cannot update issue when only --link-type and --linked-issues are set") + } + + // continue execution to api.UpdateIssue + fallthrough + default: + if cmd.Flags().NFlag() < 0 { + return nil + } + + issue, err = api.UpdateIssue(apiClient, repo.FullName(), issue.IID, l) + if err != nil { + return err + } + + for _, s := range actions { + fmt.Fprintln(out, c.GreenCheck(), s) + } } fmt.Fprintln(out, issueutils.DisplayIssue(c, issue, f.IO.IsaTTY)) @@ -191,6 +240,8 @@ func NewCmdUpdate(f *cmdutils.Factory) *cobra.Command { issueUpdateCmd.Flags(). StringSliceP("assignee", "a", []string{}, "Assign users by username. Prefix with '!' or '-' to remove from existing assignees, or '+' to add new. Otherwise, replace existing assignees with these users.") issueUpdateCmd.Flags().Bool("unassign", false, "Unassign all users.") + issueUpdateCmd.Flags().IntSliceVarP(&opts.LinkedIssues, "linked-issues", "", []int{}, "The IIDs of issues that this issue links to") + issueUpdateCmd.Flags().StringVarP(&opts.IssueLinkType, "link-type", "", "relates_to", "Type for the issue link") return issueUpdateCmd }