mirror of
https://github.com/Threnklyn/jira.git
synced 2026-05-19 04:33:28 +02:00
add rank ISSUE after|before ISSUE command
This commit is contained in:
+4
-9
@@ -191,6 +191,10 @@ func main() {
|
||||
Command: "vote",
|
||||
Entry: cli.CmdVoteRegistry(),
|
||||
},
|
||||
jiracli.CommandRegistry{
|
||||
Command: "rank",
|
||||
Entry: cli.CmdRankRegistry(),
|
||||
},
|
||||
}
|
||||
|
||||
cli.Register(app, registry)
|
||||
@@ -229,7 +233,6 @@ func main() {
|
||||
// }
|
||||
// output := fmt.Sprintf(`
|
||||
// Usage:
|
||||
// jira rank ISSUE (after|before) ISSUE
|
||||
// jira watch ISSUE [-w WATCHER] [--remove]
|
||||
// jira comment ISSUE [--noedit] <Edit Options>
|
||||
// jira (set,add,remove) labels ISSUE [LABEL] ...
|
||||
@@ -303,7 +306,6 @@ func main() {
|
||||
// "browse": "browse",
|
||||
// "req": "request",
|
||||
// "request": "request",
|
||||
// "rank": "rank",
|
||||
// "unassign": "unassign",
|
||||
// }
|
||||
|
||||
@@ -504,13 +506,6 @@ func main() {
|
||||
// case "unassign":
|
||||
// requireArgs(1)
|
||||
// err = c.CmdUnassign(args[0])
|
||||
// case "rank":
|
||||
// requireArgs(3)
|
||||
// if args[1] == "after" {
|
||||
// err = c.CmdRankAfter(args[0], args[2])
|
||||
// } else {
|
||||
// err = c.CmdRankBefore(args[0], args[2])
|
||||
// }
|
||||
// case "request":
|
||||
// requireArgs(1)
|
||||
// data := ""
|
||||
|
||||
@@ -345,3 +345,27 @@ func (j *Jira) IssueRemoveVote(issue string) error {
|
||||
}
|
||||
return responseError(resp)
|
||||
}
|
||||
|
||||
type RankRequestProvider interface {
|
||||
ProvideRankRequest() *jiradata.RankRequest
|
||||
}
|
||||
|
||||
// https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/issue-rankIssues
|
||||
func (j *Jira) RankIssues(rrp RankRequestProvider) error {
|
||||
req := rrp.ProvideRankRequest()
|
||||
encoded, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("%s/rest/agile/1.0/issue/rank", j.Endpoint)
|
||||
resp, err := j.UA.Put(uri, "application/json", bytes.NewBuffer(encoded))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == 204 {
|
||||
return nil
|
||||
}
|
||||
return responseError(resp)
|
||||
}
|
||||
|
||||
@@ -553,55 +553,6 @@ func (jc *JiraCli) editLoop(opts *GlobalOptions, input interface{}, output inter
|
||||
// return data, nil
|
||||
// }
|
||||
|
||||
// // RankOrder type used to specify before/after ranking arguments to RankIssue
|
||||
// type RankOrder int
|
||||
|
||||
// const (
|
||||
// // RANKBEFORE should be used to rank issue before the target issue
|
||||
// RANKBEFORE RankOrder = iota
|
||||
// // RANKAFTER should be used to rank issue after the target issue
|
||||
// RANKAFTER RankOrder = iota
|
||||
// )
|
||||
|
||||
// // RankIssue will modify issue to have rank before or after the target issue
|
||||
// func (c *Cli) RankIssue(issue, target string, order RankOrder) error {
|
||||
// type RankRequest struct {
|
||||
// Issues []string `json:"issues"`
|
||||
// Before string `json:"rankBeforeIssue,omitempty"`
|
||||
// After string `json:"rankAfterIssue,omitempty"`
|
||||
// }
|
||||
// req := &RankRequest{
|
||||
// Issues: []string{
|
||||
// issue,
|
||||
// },
|
||||
// }
|
||||
// if order == RANKBEFORE {
|
||||
// req.Before = target
|
||||
// } else {
|
||||
// req.After = target
|
||||
// }
|
||||
|
||||
// json, err := jsonEncode(req)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// uri := fmt.Sprintf("%s/rest/agile/1.0/issue/rank", c.endpoint)
|
||||
// if c.getOptBool("dryrun", false) {
|
||||
// log.Debugf("PUT: %s", json)
|
||||
// log.Debugf("Dryrun mode, skipping PUT")
|
||||
// return nil
|
||||
// }
|
||||
// resp, err := c.put(uri, json)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if resp.StatusCode != 204 {
|
||||
// return fmt.Errorf("failed to modify issue rank: %s", resp.Status)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// // GetOptString will extract the string from the Cli object options
|
||||
// // otherwise return the provided default
|
||||
// func (c *Cli) GetOptString(optName string, dflt string) string {
|
||||
|
||||
@@ -168,30 +168,6 @@ func (jc *JiraCli) Register(app *kingpin.Application, reg []CommandRegistry) {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// // CmdRankAfter rank issue after target issue
|
||||
// func (c *Cli) CmdRankAfter(issue, after string) error {
|
||||
// err := c.RankIssue(issue, after, RANKAFTER)
|
||||
// if err != nil {
|
||||
// return nil
|
||||
// }
|
||||
// if !c.GetOptBool("quiet", false) {
|
||||
// fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// // CmdRankBefore rank issue before target issue
|
||||
// func (c *Cli) CmdRankBefore(issue, before string) error {
|
||||
// err := c.RankIssue(issue, before, RANKBEFORE)
|
||||
// if err != nil {
|
||||
// return nil
|
||||
// }
|
||||
// if !c.GetOptBool("quiet", false) {
|
||||
// fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// // CmdComment will open up editor with "comment" template and submit
|
||||
// // YAML output to jira
|
||||
// func (c *Cli) CmdComment(issue string) error {
|
||||
|
||||
@@ -37,13 +37,16 @@ func (jc *JiraCli) CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions) error
|
||||
cmd.Flag("assignee", "User assigned the issue").Short('a').StringVar(&opts.Assignee)
|
||||
cmd.Flag("component", "Component to search for").Short('c').StringVar(&opts.Component)
|
||||
cmd.Flag("issuetype", "Issue type to search for").Short('i').StringVar(&opts.IssueType)
|
||||
// FIXME Default
|
||||
cmd.Flag("limit", "Maximum number of results to return in search").Short('l').Default("500").IntVar(&opts.MaxResults)
|
||||
cmd.Flag("project", "Project to search for").Short('p').StringVar(&opts.Project)
|
||||
cmd.Flag("query", "Jira Query Language (JQL) expression for the search").Short('q').StringVar(&opts.Query)
|
||||
// FIXME Default
|
||||
cmd.Flag("queryfields", "Fields that are used in \"list\" template").Short('f').Default(
|
||||
"assignee,created,priority,reporter,status,summary,updated",
|
||||
).StringVar(&opts.QueryFields)
|
||||
cmd.Flag("reporter", "Reporter to search for").Short('r').StringVar(&opts.Reporter)
|
||||
// FIXME Default
|
||||
cmd.Flag("sort", "Sort order to return").Short('s').Default("priority asc, key").StringVar(&opts.Sort)
|
||||
cmd.Flag("watcher", "Watcher to search for").Short('w').StringVar(&opts.Watcher)
|
||||
return nil
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package jiracli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata"
|
||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
type RankOptions struct {
|
||||
GlobalOptions
|
||||
First string
|
||||
Second string
|
||||
Order string
|
||||
}
|
||||
|
||||
func (jc *JiraCli) CmdRankRegistry() *CommandRegistryEntry {
|
||||
opts := RankOptions{
|
||||
GlobalOptions: GlobalOptions{},
|
||||
}
|
||||
|
||||
return &CommandRegistryEntry{
|
||||
"Mark issues as blocker",
|
||||
func() error {
|
||||
return jc.CmdRank(&opts)
|
||||
},
|
||||
func(cmd *kingpin.CmdClause) error {
|
||||
return jc.CmdRankUsage(cmd, &opts)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (jc *JiraCli) CmdRankUsage(cmd *kingpin.CmdClause, opts *RankOptions) error {
|
||||
if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Arg("FIRST-ISSUE", "first issue").Required().StringVar(&opts.First)
|
||||
cmd.Arg("after|before", "rank ordering").Required().HintOptions("after", "before").EnumVar(&opts.Order, "after", "before")
|
||||
cmd.Arg("SECOND-ISSUE", "second issue").Required().StringVar(&opts.Second)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CmdRank order two issue
|
||||
func (jc *JiraCli) CmdRank(opts *RankOptions) error {
|
||||
req := &jiradata.RankRequest{
|
||||
Issues: []string{opts.First},
|
||||
}
|
||||
|
||||
if opts.Order == "after" {
|
||||
req.RankAfterIssue = opts.Second
|
||||
} else {
|
||||
req.RankBeforeIssue = opts.Second
|
||||
}
|
||||
|
||||
if err := jc.RankIssues(req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.First, jc.Endpoint, opts.First)
|
||||
fmt.Printf("OK %s %s/browse/%s\n", opts.Second, jc.Endpoint, opts.Second)
|
||||
|
||||
// FIXME implement browse
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package jiradata
|
||||
|
||||
type RankRequest struct {
|
||||
Issues []string `json:"issues,omitempty" yaml:"issues,omitempty"`
|
||||
RankBeforeIssue string `json:"rankBeforeIssue,omitempty" yaml:"rankBeforeIssue,omitempty"`
|
||||
RankAfterIssue string `json:"rankAfterIssue,omitempty" yaml:"rankAfterIssue,omitempty"`
|
||||
}
|
||||
@@ -13,3 +13,7 @@ func (w *Worklog) ProvideWorklog() *Worklog {
|
||||
func (l *LinkIssueRequest) ProvideLinkIssueRequest() *LinkIssueRequest {
|
||||
return l
|
||||
}
|
||||
|
||||
func (r *RankRequest) ProvideRankRequest() *RankRequest {
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user