mirror of
https://github.com/Threnklyn/jira.git
synced 2026-05-19 12:43:30 +02:00
add issuelink command
This commit is contained in:
+4
-94
@@ -124,6 +124,10 @@ func main() {
|
||||
Command: "block",
|
||||
Entry: cli.CmdBlockRegistry(),
|
||||
},
|
||||
jiracli.CommandRegistry{
|
||||
Command: "issuelink",
|
||||
Entry: cli.CmdIssueLinkRegistry(),
|
||||
},
|
||||
jiracli.CommandRegistry{
|
||||
Command: "transition",
|
||||
Aliases: []string{"trans"},
|
||||
@@ -217,8 +221,6 @@ func main() {
|
||||
// }
|
||||
// output := fmt.Sprintf(`
|
||||
// Usage:
|
||||
// jira BLOCKER blocks ISSUE
|
||||
// jira issuelink OUTWARDISSUE ISSUELINKTYPE INWARDISSUE
|
||||
// jira vote ISSUE [--down]
|
||||
// jira rank ISSUE (after|before) ISSUE
|
||||
// jira watch ISSUE [-w WATCHER] [--remove]
|
||||
@@ -285,8 +287,6 @@ func main() {
|
||||
// }
|
||||
|
||||
// jiraCommands := map[string]string{
|
||||
// "blocks": "blocks",
|
||||
// "issuelink": "issuelink",
|
||||
// "watch": "watch",
|
||||
// "comment": "comment",
|
||||
// "label": "labels",
|
||||
@@ -456,93 +456,15 @@ func main() {
|
||||
|
||||
// var err error
|
||||
// switch command {
|
||||
// case "issuelink":
|
||||
// requireArgs(3)
|
||||
// err = c.CmdIssueLink(args[0], args[1], args[2])
|
||||
// case "login":
|
||||
// err = c.CmdLogin()
|
||||
// case "logout":
|
||||
// err = c.CmdLogout()
|
||||
// case "fields":
|
||||
// err = c.CmdFields()
|
||||
// case "list":
|
||||
// err = c.CmdList()
|
||||
// case "edit":
|
||||
// setEditing(true)
|
||||
// if len(args) > 0 {
|
||||
// err = c.CmdEdit(args[0])
|
||||
// } else {
|
||||
// var data interface{}
|
||||
// if data, err = c.FindIssues(); err == nil {
|
||||
// issues := data.(map[string]interface{})["issues"].([]interface{})
|
||||
// for _, issue := range issues {
|
||||
// if err = c.CmdEdit(issue.(map[string]interface{})["key"].(string)); err != nil {
|
||||
// switch err.(type) {
|
||||
// case jira.NoChangesFound:
|
||||
// log.Warning("No Changes found: %s", err)
|
||||
// err = nil
|
||||
// continue
|
||||
// }
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// case "editmeta":
|
||||
// requireArgs(1)
|
||||
// err = c.CmdEditMeta(args[0])
|
||||
// case "transmeta":
|
||||
// requireArgs(1)
|
||||
// err = c.CmdTransitionMeta(args[0])
|
||||
// case "issuelinktypes":
|
||||
// err = c.CmdIssueLinkTypes()
|
||||
// case "issuetypes":
|
||||
// err = c.CmdIssueTypes()
|
||||
// case "createmeta":
|
||||
// err = c.CmdCreateMeta()
|
||||
// case "create":
|
||||
// setEditing(true)
|
||||
// err = c.CmdCreate()
|
||||
// case "subtask":
|
||||
// setEditing(true)
|
||||
// err = c.CmdSubtask(args[0])
|
||||
// case "transitions":
|
||||
// requireArgs(1)
|
||||
// err = c.CmdTransitions(args[0])
|
||||
// case "blocks":
|
||||
// requireArgs(2)
|
||||
// err = c.CmdBlocks(args[0], args[1])
|
||||
// case "dups":
|
||||
// setEditing(true)
|
||||
// requireArgs(2)
|
||||
// if err = c.CmdDups(args[0], args[1]); err == nil {
|
||||
// opts["resolution"] = "Duplicate"
|
||||
// trans, err := c.ValidTransitions(args[0])
|
||||
// if err == nil {
|
||||
// if trans.Find("close") != nil {
|
||||
// err = c.CmdTransition(args[0], "close")
|
||||
// } else if trans.Find("done") != nil {
|
||||
// // for now just assume if there is no "close", then
|
||||
// // there is a "done" state
|
||||
// err = c.CmdTransition(args[0], "done")
|
||||
// } else if trans.Find("start") != nil {
|
||||
// err = c.CmdTransition(args[0], "start")
|
||||
// if err == nil {
|
||||
// err = c.CmdTransition(args[0], "stop")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
// case "watch":
|
||||
// requireArgs(1)
|
||||
// watcher := c.GetOptString("watcher", opts["user"].(string))
|
||||
// remove := c.GetOptBool("remove", false)
|
||||
// err = c.CmdWatch(args[0], watcher, remove)
|
||||
// case "transition":
|
||||
// requireArgs(2)
|
||||
// setEditing(true)
|
||||
// err = c.CmdTransition(args[1], args[0])
|
||||
// case "comment":
|
||||
// requireArgs(1)
|
||||
// setEditing(true)
|
||||
@@ -589,18 +511,6 @@ func main() {
|
||||
// case "unassign":
|
||||
// requireArgs(1)
|
||||
// err = c.CmdUnassign(args[0])
|
||||
// case "view":
|
||||
// requireArgs(1)
|
||||
// err = c.CmdView(args[0])
|
||||
// case "worklog":
|
||||
// if len(args) > 0 && args[0] == "add" {
|
||||
// setEditing(true)
|
||||
// requireArgs(2)
|
||||
// err = c.CmdWorklog(args[0], args[1])
|
||||
// } else {
|
||||
// requireArgs(1)
|
||||
// err = c.CmdWorklogs(args[0])
|
||||
// }
|
||||
// case "vote":
|
||||
// requireArgs(1)
|
||||
// if val, ok := opts["down"]; ok {
|
||||
|
||||
+10
-13
@@ -19,6 +19,14 @@ func (jc *JiraCli) CmdBlockRegistry() *CommandRegistryEntry {
|
||||
GlobalOptions: GlobalOptions{
|
||||
Template: "edit",
|
||||
},
|
||||
LinkIssueRequest: jiradata.LinkIssueRequest{
|
||||
Type: &jiradata.IssueLinkType{
|
||||
// FIXME is this consitent across multiple jira installs?
|
||||
Name: "Blocks",
|
||||
},
|
||||
InwardIssue: &jiradata.IssueRef{},
|
||||
OutwardIssue: &jiradata.IssueRef{},
|
||||
},
|
||||
}
|
||||
|
||||
return &CommandRegistryEntry{
|
||||
@@ -44,25 +52,14 @@ func (jc *JiraCli) CmdBlockUsage(cmd *kingpin.CmdClause, opts *BlockOptions) err
|
||||
}
|
||||
return nil
|
||||
}).String()
|
||||
cmd.Arg("BLOCKER", "blocker issue").Required().StringVar(&opts.Blocker)
|
||||
cmd.Arg("ISSUE", "issue that is blocked").Required().StringVar(&opts.Issue)
|
||||
cmd.Arg("BLOCKER", "blocker issue").Required().StringVar(&opts.OutwardIssue.Key)
|
||||
cmd.Arg("ISSUE", "issue that is blocked").Required().StringVar(&opts.InwardIssue.Key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CmdBlock will update the given issue as being a duplicate by the given dup issue
|
||||
// and will attempt to resolve the dup issue
|
||||
func (jc *JiraCli) CmdBlock(opts *BlockOptions) error {
|
||||
opts.Type = &jiradata.IssueLinkType{
|
||||
// FIXME is this consitent across multiple jira installs?
|
||||
Name: "Blocks",
|
||||
}
|
||||
opts.InwardIssue = &jiradata.IssueRef{
|
||||
Key: opts.Issue,
|
||||
}
|
||||
opts.OutwardIssue = &jiradata.IssueRef{
|
||||
Key: opts.Blocker,
|
||||
}
|
||||
|
||||
if err := jc.LinkIssues(&opts.LinkIssueRequest); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+14
-17
@@ -19,6 +19,14 @@ func (jc *JiraCli) CmdDupRegistry() *CommandRegistryEntry {
|
||||
GlobalOptions: GlobalOptions{
|
||||
Template: "edit",
|
||||
},
|
||||
LinkIssueRequest: jiradata.LinkIssueRequest{
|
||||
Type: &jiradata.IssueLinkType{
|
||||
// FIXME is this consitent across multiple jira installs?
|
||||
Name: "Duplicate",
|
||||
},
|
||||
InwardIssue: &jiradata.IssueRef{},
|
||||
OutwardIssue: &jiradata.IssueRef{},
|
||||
},
|
||||
}
|
||||
|
||||
return &CommandRegistryEntry{
|
||||
@@ -44,31 +52,20 @@ func (jc *JiraCli) CmdDupUsage(cmd *kingpin.CmdClause, opts *DupOptions) error {
|
||||
}
|
||||
return nil
|
||||
}).String()
|
||||
cmd.Arg("DUPLICATE", "duplicate issue to mark closed").Required().StringVar(&opts.Duplicate)
|
||||
cmd.Arg("ISSUE", "duplicate issue to leave open").Required().StringVar(&opts.Issue)
|
||||
cmd.Arg("DUPLICATE", "duplicate issue to mark closed").Required().StringVar(&opts.InwardIssue.Key)
|
||||
cmd.Arg("ISSUE", "duplicate issue to leave open").Required().StringVar(&opts.OutwardIssue.Key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CmdDups will update the given issue as being a duplicate by the given dup issue
|
||||
// and will attempt to resolve the dup issue
|
||||
func (jc *JiraCli) CmdDup(opts *DupOptions) error {
|
||||
opts.Type = &jiradata.IssueLinkType{
|
||||
// FIXME is this consitent across multiple jira installs?
|
||||
Name: "Duplicate",
|
||||
}
|
||||
opts.InwardIssue = &jiradata.IssueRef{
|
||||
Key: opts.Duplicate,
|
||||
}
|
||||
opts.OutwardIssue = &jiradata.IssueRef{
|
||||
Key: opts.Issue,
|
||||
}
|
||||
|
||||
if err := jc.LinkIssues(&opts.LinkIssueRequest); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue)
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, jc.Endpoint, opts.OutwardIssue.Key)
|
||||
|
||||
meta, err := jc.GetIssueTransitions(opts.Duplicate)
|
||||
meta, err := jc.GetIssueTransitions(opts.InwardIssue.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -78,7 +75,7 @@ func (jc *JiraCli) CmdDup(opts *DupOptions) error {
|
||||
issueUpdate := jiradata.IssueUpdate{
|
||||
Transition: transMeta,
|
||||
}
|
||||
if err = jc.TransitionIssue(opts.Duplicate, &issueUpdate); err != nil {
|
||||
if err = jc.TransitionIssue(opts.InwardIssue.Key, &issueUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
// if we just started the issue now we need to stop it
|
||||
@@ -88,7 +85,7 @@ func (jc *JiraCli) CmdDup(opts *DupOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.Duplicate, jc.Endpoint, opts.Duplicate)
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.InwardIssue.Key, jc.Endpoint, opts.InwardIssue.Key)
|
||||
|
||||
// FIXME implement browse
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package jiracli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
|
||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
type IssueLinkOptions struct {
|
||||
GlobalOptions
|
||||
jiradata.LinkIssueRequest
|
||||
LinkType string
|
||||
}
|
||||
|
||||
func (jc *JiraCli) CmdIssueLinkRegistry() *CommandRegistryEntry {
|
||||
opts := IssueLinkOptions{
|
||||
GlobalOptions: GlobalOptions{
|
||||
Template: "edit",
|
||||
},
|
||||
LinkIssueRequest: jiradata.LinkIssueRequest{
|
||||
Type: &jiradata.IssueLinkType{},
|
||||
InwardIssue: &jiradata.IssueRef{},
|
||||
OutwardIssue: &jiradata.IssueRef{},
|
||||
},
|
||||
}
|
||||
return &CommandRegistryEntry{
|
||||
"Link two issues",
|
||||
func() error {
|
||||
return jc.CmdIssueLink(&opts)
|
||||
},
|
||||
func(cmd *kingpin.CmdClause) error {
|
||||
return jc.CmdIssueLinkUsage(cmd, &opts)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (jc *JiraCli) CmdIssueLinkUsage(cmd *kingpin.CmdClause, opts *IssueLinkOptions) error {
|
||||
if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
jc.EditorUsage(cmd, &opts.GlobalOptions)
|
||||
jc.TemplateUsage(cmd, &opts.GlobalOptions)
|
||||
cmd.Flag("comment", "Comment message when linking issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error {
|
||||
opts.Comment = &jiradata.Comment{
|
||||
Body: flagValue(ctx, "comment"),
|
||||
}
|
||||
return nil
|
||||
}).String()
|
||||
cmd.Arg("OUTWARDISSUE", "outward issue").Required().StringVar(&opts.OutwardIssue.Key)
|
||||
cmd.Arg("ISSUELINKTYPE", "issue link type").Required().StringVar(&opts.Type.Name)
|
||||
cmd.Arg("INWARDISSUE", "inward issue").Required().StringVar(&opts.InwardIssue.Key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CmdBlock will update the given issue as being a duplicate by the given dup issue
|
||||
// and will attempt to resolve the dup issue
|
||||
func (jc *JiraCli) CmdIssueLink(opts *IssueLinkOptions) error {
|
||||
if err := jc.LinkIssues(&opts.LinkIssueRequest); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.InwardIssue.Key, jc.Endpoint, opts.InwardIssue.Key)
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, jc.Endpoint, opts.OutwardIssue.Key)
|
||||
|
||||
// FIXME implement browse
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user