diff --git a/cli.go b/cli.go index 3413a81..6d8baad 100644 --- a/cli.go +++ b/cli.go @@ -118,6 +118,24 @@ func (c *Cli) put(uri string, content string) (*http.Response, error) { return c.makeRequestWithContent("PUT", uri, content) } +func (c *Cli) delete(uri string) (*http.Response, error) { + method := "DELETE" + req, _ := http.NewRequest(method, uri, nil) + log.Info("%s %s", req.Method, req.URL.String()) + if resp, err := c.makeRequest(req); err != nil { + return nil, err + } else { + if resp.StatusCode == 401 { + if err := c.CmdLogin(); err != nil { + return nil, err + } + req, _ = http.NewRequest(method, uri, nil) + return c.makeRequest(req) + } + return resp, err + } +} + func (c *Cli) makeRequestWithContent(method string, uri string, content string) (*http.Response, error) { buffer := bytes.NewBufferString(content) req, _ := http.NewRequest(method, uri, buffer) @@ -456,6 +474,10 @@ func (c *Cli) FindIssues() (interface{}, error) { } } +func (c *Cli) GetOptString(optName string, dflt string) string { + return c.getOptString(optName, dflt) +} + func (c *Cli) getOptString(optName string, dflt string) string { if val, ok := c.opts[optName].(string); ok { return val @@ -464,6 +486,10 @@ func (c *Cli) getOptString(optName string, dflt string) string { } } +func (c *Cli) GetOptBool(optName string, dflt bool) bool { + return c.getOptBool(optName, dflt) +} + func (c *Cli) getOptBool(optName string, dflt bool) bool { if val, ok := c.opts[optName].(bool); ok { return val diff --git a/commands.go b/commands.go index 860df1a..589f3b6 100644 --- a/commands.go +++ b/commands.go @@ -385,22 +385,34 @@ func (c *Cli) CmdDups(duplicate string, issue string) error { return nil } -func (c *Cli) CmdWatch(issue string) error { - watcher := c.getOptString("watcher", c.opts["user"].(string)) - log.Debug("watch called") +func (c *Cli) CmdWatch(issue string, watcher string, remove bool) error { + log.Debug("watch called: watcher: %q, remove: %n", watcher, remove) + var uri string json, err := jsonEncode(watcher) if err != nil { return err } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers", c.endpoint, issue) if c.getOptBool("dryrun", false) { - log.Debug("POST: %s", json) - log.Debug("Dryrun mode, skipping POST") + if !remove { + log.Debug("POST: %s", json) + log.Debug("Dryrun mode, skipping POST") + } else { + log.Debug("DELETE: %s", watcher) + log.Debug("Dryrun mode, skipping POST") + } return nil } - resp, err := c.post(uri, json) + + var resp *http.Response + if !remove { + uri = fmt.Sprintf("%s/rest/api/2/issue/%s/watchers", c.endpoint, issue) + resp, err = c.post(uri, json) + } else { + uri = fmt.Sprintf("%s/rest/api/2/issue/%s/watchers?username=%s", c.endpoint, issue, watcher) + resp, err = c.delete(uri) + } if err != nil { return err } @@ -412,7 +424,54 @@ func (c *Cli) CmdWatch(issue string) error { } else { logBuffer := bytes.NewBuffer(make([]byte, 0)) resp.Write(logBuffer) - err := fmt.Errorf("Unexpected Response From POST") + if !remove { + err = fmt.Errorf("Unexpected Response From POST") + } else { + err = fmt.Errorf("Unexpected Response From DELETE") + } + log.Error("%s:\n%s", err, logBuffer) + return err + } + return nil +} + +func (c *Cli) CmdVote(issue string, up bool) error { + log.Debug("vote called, with up: %n", up) + + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", c.endpoint, issue) + if c.getOptBool("dryrun", false) { + if up { + log.Debug("POST: %s", "") + log.Debug("Dryrun mode, skipping POST") + } else { + log.Debug("DELETE: %s", "") + log.Debug("Dryrun mode, skipping DELETE") + } + return nil + } + var resp *http.Response + var err error + if up { + resp, err = c.post(uri, "") + } else { + resp, err = c.delete(uri) + } + if err != nil { + return err + } + if resp.StatusCode == 204 { + c.Browse(issue) + if !c.opts["quiet"].(bool) { + fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) + } + } else { + logBuffer := bytes.NewBuffer(make([]byte, 0)) + resp.Write(logBuffer) + if up { + err = fmt.Errorf("Unexpected Response From POST") + } else { + err = fmt.Errorf("Unexpected Response From DELETE") + } log.Error("%s:\n%s", err, logBuffer) return err } diff --git a/main/main.go b/main/main.go index bc5504f..f58979c 100644 --- a/main/main.go +++ b/main/main.go @@ -56,7 +56,8 @@ Usage: jira create [--noedit] [-p PROJECT] jira DUPLICATE dups ISSUE jira BLOCKER blocks ISSUE - jira watch ISSUE [-w WATCHER] + jira vote ISSUE [--down] + jira watch ISSUE [-w WATCHER] [--remove] jira (trans|transition) TRANSITION ISSUE [--noedit] jira ack ISSUE [--edit] jira close ISSUE [--edit] @@ -155,6 +156,7 @@ Command Options: "login": "login", "req": "request", "request": "request", + "vote": "vote", } defaults := map[string]interface{}{ @@ -194,6 +196,7 @@ Command Options: "a|assignee=s": setopt, "i|issuetype=s": setopt, "w|watcher=s": setopt, + "remove": setopt, "r|reporter=s": setopt, "f|queryfields=s": setopt, "s|sort=s": setopt, @@ -206,6 +209,7 @@ Command Options: "M|method=s": setopt, "S|saveFile=s": setopt, "Q|quiet": setopt, + "down": setopt, }) if err := op.ProcessAll(os.Args[1:]); err != nil { @@ -350,7 +354,9 @@ Command Options: } case "watch": requireArgs(1) - err = c.CmdWatch(args[0]) + 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) @@ -404,6 +410,13 @@ Command Options: case "view": requireArgs(1) err = c.CmdView(args[0]) + case "vote": + requireArgs(1) + if val, ok := opts["down"]; ok { + err = c.CmdVote(args[0], !val.(bool)) + } else { + err = c.CmdVote(args[0], true) + } case "request": requireArgs(1) data := ""