diff --git a/issue.go b/issue.go index d36ad27a..9fb0f733 100644 --- a/issue.go +++ b/issue.go @@ -338,6 +338,40 @@ func LinkIssues(ua HttpClient, endpoint string, lip LinkIssueProvider) error { return responseError(resp) } +// https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-remote-links/#api-rest-api-2-issue-issueidorkey-remotelink-post +func (j *Jira) LinkRemoteIssue(issue string, url string, title string) error { + return LinkRemoteIssue(j.UA, j.Endpoint, issue, url, title) +} + +func LinkRemoteIssue(ua HttpClient, endpoint string, issue string, url string, title string) error { + req := struct { + Object struct { + Url string `json:"url"` + Title string `json:"title"` + } `json:"object"` + }{} + req.Object.Url = url + req.Object.Title = title + + encoded, err := json.Marshal(req) + if err != nil { + return err + } + + uri := URLJoin(endpoint, "rest/api/2/issue", issue, "remotelink") + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode == 201 { + return nil + } + return responseError(resp) +} + + // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getTransitions func (j *Jira) GetIssueTransitions(issue string) (*jiradata.TransitionsMeta, error) { return GetIssueTransitions(j.UA, j.Endpoint, issue) diff --git a/jiracmd/issuelink.go b/jiracmd/issuelink.go index 60f64a23..82f5b08c 100644 --- a/jiracmd/issuelink.go +++ b/jiracmd/issuelink.go @@ -57,8 +57,6 @@ func CmdIssueLinkUsage(cmd *kingpin.CmdClause, opts *IssueLinkOptions) error { return nil } -// CmdIssueLink will update the given issue as being a duplicate by the given dup issue -// and will attempt to resolve the dup issue func CmdIssueLink(o *oreo.Client, globals *jiracli.GlobalOptions, opts *IssueLinkOptions) error { if err := jira.LinkIssues(o, globals.Endpoint.Value, &opts.LinkIssueRequest); err != nil { return err diff --git a/jiracmd/registry.go b/jiracmd/registry.go index 0dad82c6..36bfe034 100644 --- a/jiracmd/registry.go +++ b/jiracmd/registry.go @@ -30,6 +30,7 @@ func RegisterAllCommands() { jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "fields", Entry: CmdFieldsRegistry()}) jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "in-progress", Entry: CmdTransitionRegistry("Progress"), Aliases: []string{"prog", "progress"}}) jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "issuelink", Entry: CmdIssueLinkRegistry()}) + jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "remotelink", Entry: CmdRemoteLinkRegistry()}) jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "issuelinktypes", Entry: CmdIssueLinkTypesRegistry()}) jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "issuetypes", Entry: CmdIssueTypesRegistry()}) jiracli.RegisterCommand(jiracli.CommandRegistry{Command: "labels add", Entry: CmdLabelsAddRegistry()}) diff --git a/jiracmd/remotelink.go b/jiracmd/remotelink.go new file mode 100644 index 00000000..d813e12b --- /dev/null +++ b/jiracmd/remotelink.go @@ -0,0 +1,56 @@ +package jiracmd + +import ( + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + "github.com/go-jira/jira" + "github.com/go-jira/jira/jiracli" + kingpin "gopkg.in/alecthomas/kingpin.v2" +) + +type RemoteLinkOptions struct { + jiracli.CommonOptions `yaml:",inline" json:",inline" figtree:",inline"` + Issue string `yaml:"issue,omitempty" json:"issue,omitempty"` + Project string `yaml:"project,omitempty" json:"project,omitempty"` + // There is no existing jiradata definition for RemoteObject + URL string + Title string +} + +func CmdRemoteLinkRegistry() *jiracli.CommandRegistryEntry { + opts := RemoteLinkOptions {} + return &jiracli.CommandRegistryEntry{ + "Link an issue to a remote URI", + func(fig *figtree.FigTree, cmd *kingpin.CmdClause) error { + jiracli.LoadConfigs(cmd, fig, &opts) + return CmdRemoteLinkUsage(cmd, &opts) + }, + func(o *oreo.Client, globals *jiracli.GlobalOptions) error { + opts.Issue = jiracli.FormatIssue(opts.Issue, opts.Project) + return CmdRemoteLink(o, globals, &opts) + }, + } +} + +func CmdRemoteLinkUsage(cmd *kingpin.CmdClause, opts *RemoteLinkOptions) error { + jiracli.BrowseUsage(cmd, &opts.CommonOptions) + jiracli.EditorUsage(cmd, &opts.CommonOptions) + jiracli.TemplateUsage(cmd, &opts.CommonOptions) + + cmd.Arg("ISSUE", "issue").Required().StringVar(&opts.Issue) + cmd.Arg("TITLE", "Link title").Required().StringVar(&opts.Title) + cmd.Arg("URL", "Link URL").Required().StringVar(&opts.URL) + + return nil +} + +func CmdRemoteLink(o *oreo.Client, globals *jiracli.GlobalOptions, opts *RemoteLinkOptions) error { + if err := jira.LinkRemoteIssue(o, globals.Endpoint.Value, opts.Issue, opts.URL, opts.Title); err != nil { + return err + } + // unhandled if !globals.Quiet.Value { + // unhandled if opts.Browse.Value { + + return nil +}