diff --git a/README.md b/README.md index 4d8636f..7dec6bb 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,9 @@ Usage: jira [-v ...] [-u USER] [-e URI] [-t FILE] issuelinktypes jira [-v ...] [-u USER] [-e URI] [-t FILE] transmeta ISSUE jira [-v ...] [-u USER] [-e URI] [-t FILE] editmeta ISSUE + jira [-v ...] export-templates [-d DIR] jira [-v ...] [-u USER] [-e URI] [-t FILE] ISSUE - jira [-v ...] [-u USER] [-e URI] [-t FILE] edit ISSUE [-o KEY=VAL]... + jira [-v ...] [-u USER] [-e URI] [-t FILE] edit ISSUE [-m COMMENT] [-o KEY=VAL]... jira [-v ...] [-u USER] [-e URI] [-t FILE] issuetypes [-p PROJECT] jira [-v ...] [-u USER] [-e URI] [-t FILE] createmeta [-p PROJECT] [-i ISSUETYPE] jira [-v ...] [-u USER] [-e URI] [-t FILE] transitions ISSUE @@ -65,6 +66,7 @@ General Options: Command Options: -a --assignee=USER Username assigned the issue -c --component=COMPONENT Component to Search for + -d --directory=DIR Directory to export templates to (default: /Users/cbennett/.jira.d/templates) -i --issuetype=ISSUETYPE Jira Issue Type (default: Bug) -m --comment=COMMENT Comment message for transition -o --override=KEY:VAL Set custom key/value pairs diff --git a/jira/cli/commands.go b/jira/cli/commands.go index a6ff432..24fa741 100644 --- a/jira/cli/commands.go +++ b/jira/cli/commands.go @@ -6,6 +6,7 @@ import ( "code.google.com/p/gopass" "bytes" "strings" + "os" // "github.com/kr/pretty" ) @@ -483,3 +484,38 @@ func (c *Cli) CmdAssign(issue string, user string) error { } return nil } + +func (c *Cli) CmdExportTemplates() error { + dir := c.opts["directory"] + if stat, err := os.Stat(dir); err != nil && !os.IsNotExist(err) { + log.Error("Failed to stat %s: %s", dir, err) + return err + } else if err == nil && !stat.IsDir() { + err := fmt.Errorf("%s exists and is not a directory!", dir) + log.Error("%s", err) + return err + } else { + // dir does not exist, so try to create it + if err := os.MkdirAll(dir, 0755); err != nil { + log.Error("Failed to mkdir -p %s: %s", dir, err) + return err + } + } + + for name, template := range all_templates { + templateFile := fmt.Sprintf("%s/%s", dir, name) + if _, err := os.Stat(templateFile); err == nil { + log.Warning("Skipping %s, already exists", templateFile) + continue + } + if fh, err := os.OpenFile(templateFile, os.O_WRONLY | os.O_CREATE, 0644); err != nil { + log.Error("Failed to open %s for writing: %s", templateFile, err) + return err + } else { + defer fh.Close() + log.Notice("Creating %s", templateFile) + fh.Write([]byte(template)) + } + } + return nil +} diff --git a/jira/cli/templates.go b/jira/cli/templates.go index d07f683..32f309f 100644 --- a/jira/cli/templates.go +++ b/jira/cli/templates.go @@ -1,5 +1,16 @@ package cli +var all_templates = map[string]string{ + "fields": default_fields_template, + "list": default_list_template, + "view": default_view_template, + "edit": default_edit_template, + "transitions": default_transitions_template, + "issuetypes": default_issuetypes_template, + "create": default_create_template, + "comment": default_comment_template, +} + const default_fields_template = "{{ . | toJson}}\n" const default_list_template = "{{ range .issues }}{{ .key | append \":\" | printf \"%-12s\"}} {{ .fields.summary }}\n{{ end }}" @@ -28,22 +39,24 @@ const default_edit_template = `update: comment: - add: body: | - + {{ or .overrides.comment ""}} fields: - summary: {{ .fields.summary }} - components: # {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range .fields.components }} - - name: {{ .name }}{{end}} + summary: {{ or .overrides.summary .fields.summary }} + components: # {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}} + - name: {{.}}{{end}}{{else}}{{ range .fields.components }} + - name: {{ .name }}{{end}}{{end}} assignee: - name: {{ if .fields.assignee }}{{ .fields.assignee.name }}{{end}} + name: {{ if .overrides.assignee }}{{.overrides.assignee}}{{else}}{{if .fields.assignee }}{{ .fields.assignee.name }}{{end}}{{end}} reporter: - name: {{ .fields.reporter.name }} + name: {{ or .overrides.reporter .fields.reporter.name }} # watchers customfield_10110: {{ range .fields.customfield_10110 }} - - name: {{ .name }}{{end}} + - name: {{ .name }}{{end}}{{if .overrides.watcher}} + - name: {{ .overrides.watcher}}{{end}} priority: # {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}} - name: {{ .fields.priority.name }} + name: {{ or .overrides.priority .fields.priority.name }} description: | - {{ or .fields.description "" | indent 4 }} + {{ or .overrides.description (or .fields.description "") | indent 4 }} ` const default_transitions_template = `{{ range .transitions }}{{.id }}: {{.name}} {{end}}` diff --git a/jira/main.go b/jira/main.go index d94b3b2..2695350 100644 --- a/jira/main.go +++ b/jira/main.go @@ -16,6 +16,7 @@ var format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shor func main() { user := os.Getenv("USER") + home := os.Getenv("HOME") usage := fmt.Sprintf(` Usage: jira [-v ...] [-u USER] [-e URI] [-t FILE] fields @@ -25,8 +26,9 @@ Usage: jira [-v ...] [-u USER] [-e URI] [-t FILE] issuelinktypes jira [-v ...] [-u USER] [-e URI] [-t FILE] transmeta ISSUE jira [-v ...] [-u USER] [-e URI] [-t FILE] editmeta ISSUE + jira [-v ...] export-templates [-d DIR] jira [-v ...] [-u USER] [-e URI] [-t FILE] ISSUE - jira [-v ...] [-u USER] [-e URI] [-t FILE] edit ISSUE [-o KEY=VAL]... + jira [-v ...] [-u USER] [-e URI] [-t FILE] edit ISSUE [-m COMMENT] [-o KEY=VAL]... jira [-v ...] [-u USER] [-e URI] [-t FILE] issuetypes [-p PROJECT] jira [-v ...] [-u USER] [-e URI] [-t FILE] createmeta [-p PROJECT] [-i ISSUETYPE] jira [-v ...] [-u USER] [-e URI] [-t FILE] transitions ISSUE @@ -56,13 +58,14 @@ General Options: Command Options: -a --assignee=USER Username assigned the issue -c --component=COMPONENT Component to Search for + -d --directory=DIR Directory to export templates to (default: %s) -i --issuetype=ISSUETYPE Jira Issue Type (default: Bug) -m --comment=COMMENT Comment message for transition -o --override=KEY:VAL Set custom key/value pairs -p --project=PROJECT Project to Search for -q --query=JQL Jira Query Language expression for the search -w --watcher=USER Watcher to add to issue (default: %s) -`, user, user) +`, user, fmt.Sprintf("%s/.jira.d/templates", home), user) args, err := docopt.Parse(usage, nil, true, "0.0.1", false, false); if err != nil { log.Error("Failed to parse options: %s", err) @@ -127,6 +130,9 @@ Command Options: if _, ok := opts["issuetype"]; !ok { opts["issuetype"] = "Bug" } + if _, ok := opts["directory"]; !ok { + opts["directory"] = fmt.Sprintf("%s/.jira.d/templates", home) + } c := cli.New(opts) @@ -214,6 +220,8 @@ Command Options: err = c.CmdComment(args["ISSUE"].(string)) } else if validCommand("take") { err = c.CmdAssign(args["ISSUE"].(string), user) + } else if validCommand("export-templates") { + err = c.CmdExportTemplates() } else if validCommand("assign") || validCommand("give") { err = c.CmdAssign( args["ISSUE"].(string),