diff --git a/cli.go b/cli.go index 3cb649d1..88f3ef27 100644 --- a/cli.go +++ b/cli.go @@ -443,6 +443,16 @@ func (c *Cli) SaveData(data interface{}) error { return nil } +// ViewIssueWorkLogs gets the worklog data for the given issue +func (c *Cli) ViewIssueWorkLogs(issue string) (interface{}, error) { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog", c.endpoint, issue) + data, err := responseToJSON(c.get(uri)) + if err != nil { + return nil, err + } + return data, nil +} + // ViewIssue will return the details for the given issue id func (c *Cli) ViewIssue(issue string) (interface{}, error) { uri := fmt.Sprintf("%s/rest/api/2/issue/%s", c.endpoint, issue) diff --git a/commands.go b/commands.go index 7823dcac..684949c6 100644 --- a/commands.go +++ b/commands.go @@ -114,6 +114,68 @@ func (c *Cli) CmdView(issue string) error { return runTemplate(c.getTemplate("view"), data, nil) } +// CmdWorklogs will get worklog data for given issue and sent to the "worklogs" template +func (c *Cli) CmdWorklogs(issue string) error { + log.Debugf("worklogs called") + c.Browse(issue) + data, err := c.ViewIssueWorkLogs(issue) + if err != nil { + return err + } + return runTemplate(c.getTemplate("worklogs"), data, nil) +} + +// CmdWorklog will attempt to add (action=add) a worklog to the given issue. +// It will spawn the editor (unless --noedit isused) and post edited YAML +// content as JSON to the worklog endpoint +func (c *Cli) CmdWorklog(action string, issue string) error { + log.Debugf("%s worklog called", action) + c.Browse(issue) + if action == "add" { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog", c.endpoint, issue) + + worklogData := map[string]interface{}{ + "issue": issue, + "comment": c.opts["comment"], + } + + if v, ok := c.opts["time-spent"].(string); ok { + worklogData["timeSpent"] = v + } + + return c.editTemplate( + c.getTemplate("worklog"), + fmt.Sprintf("%s-worklog-", issue), + worklogData, + func(json string) error { + if c.getOptBool("dryrun", false) { + log.Debugf("POST: %s", json) + log.Debugf("Dryrun mode, skipping POST") + return nil + } + resp, err := c.post(uri, json) + if err != nil { + return err + } + + if resp.StatusCode == 201 { + c.Browse(issue) + if !c.opts["quiet"].(bool) { + fmt.Printf("OK %s %s/browse/%s\n", issue, c.endpoint, issue) + } + return nil + } + logBuffer := bytes.NewBuffer(make([]byte, 0)) + resp.Write(logBuffer) + err = fmt.Errorf("Unexpected Response From POST") + log.Errorf("%s:\n%s", err, logBuffer) + return err + }, + ) + } + return nil +} + // CmdEdit will populate "edit" template with issue data and issue "editmeta" data. // Then will parse yaml template and submit data to jira. func (c *Cli) CmdEdit(issue string) error { diff --git a/main/main.go b/main/main.go index 36be4137..f99e36fb 100644 --- a/main/main.go +++ b/main/main.go @@ -56,6 +56,8 @@ func main() { Usage: jira (ls|list) jira view ISSUE + jira worklog ISSUE + jira add worklog ISSUE jira edit [--noedit] [ISSUE | ] jira create [--noedit] [-p PROJECT] jira DUPLICATE dups ISSUE @@ -125,6 +127,10 @@ Create Options: -m --comment=COMMENT Comment message for transition -o --override=KEY=VAL Set custom key/value pairs +Worklog Options: + -T --time-spent=TIMESPENT Time spent working on issue + -m --comment=COMMENT Comment message for worklog + Command Options: -d --directory=DIR Directory to export templates to (default: %s) `, user, defaultQueryFields, defaultMaxResults, defaultSort, user, fmt.Sprintf("%s/.jira.d/templates", home)) @@ -177,6 +183,8 @@ Command Options: "req": "request", "request": "request", "vote": "vote", + "worklog": "worklog", + "addworklog": "addworklog", } defaults := map[string]interface{}{ @@ -229,6 +237,7 @@ Command Options: "d|dir|directory=s": setopt, "M|method=s": setopt, "S|saveFile=s": setopt, + "T|time-spent=s": setopt, "Q|quiet": setopt, "down": setopt, }) @@ -482,6 +491,15 @@ Command Options: 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 { diff --git a/t/100basic.t b/t/100basic.t index 4b6e27df..f6372bcd 100755 --- a/t/100basic.t +++ b/t/100basic.t @@ -6,13 +6,13 @@ export JIRA_LOG_FORMAT="%{level:-5s} %{message}" PLAN 84 -# cleanup from previous failed test executions -($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g' - # reset login RUNS $jira logout echo "gojira123" | RUNS $jira login +# cleanup from previous failed test executions +($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g' + ############################################################################### ## Create an issue ############################################################################### diff --git a/t/110basic-worklog.t b/t/110basic-worklog.t new file mode 100755 index 00000000..ddc91a67 --- /dev/null +++ b/t/110basic-worklog.t @@ -0,0 +1,43 @@ +#!/bin/bash +eval "$(curl -q -s https://raw.githubusercontent.com/coryb/osht/master/osht.sh)" +cd $(dirname $0) +jira="../jira --project BASIC" +export JIRA_LOG_FORMAT="%{level:-5s} %{message}" + +PLAN 8 + +# reset login +RUNS $jira logout +echo "gojira123" | RUNS $jira login + +# cleanup from previous failed test executions +($jira ls | awk -F: '{print $1}' | while read issue; do ../jira done $issue; done) | sed 's/^/# CLEANUP: /g' + +############################################################################### +## Create an issue +############################################################################### +RUNS $jira create -o summary=summary -o description=description --noedit --saveFile issue.props +issue=$(awk '/issue/{print $2}' issue.props) + +DIFF <