mirror of
https://github.com/Threnklyn/jira.git
synced 2026-05-19 04:33:28 +02:00
use optigo for option parsing, drop docopt
This commit is contained in:
+8
-8
@@ -22,18 +22,18 @@ var log = logging.MustGetLogger("jira.cli")
|
||||
|
||||
type Cli struct {
|
||||
endpoint *url.URL
|
||||
opts map[string]string
|
||||
opts map[string]interface{}
|
||||
cookieFile string
|
||||
ua *http.Client
|
||||
}
|
||||
|
||||
func New(opts map[string]string) *Cli {
|
||||
func New(opts map[string]interface{}) *Cli {
|
||||
homedir := os.Getenv("HOME")
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
endpoint, _ := opts["endpoint"]
|
||||
endpoint, _ := opts["endpoint"].(string)
|
||||
url, _ := url.Parse(strings.TrimRight(endpoint, "/"))
|
||||
|
||||
if project, ok := opts["project"]; ok {
|
||||
if project, ok := opts["project"].(string); ok {
|
||||
opts["project"] = strings.ToUpper(project)
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ func (c *Cli) makeRequest(req *http.Request) (resp *http.Response, err error) {
|
||||
}
|
||||
|
||||
func (c *Cli) getTemplate(name string) string {
|
||||
if override, ok := c.opts["template"]; ok {
|
||||
if override, ok := c.opts["template"].(string); ok {
|
||||
if _, err := os.Stat(override); err == nil {
|
||||
return readFile(override)
|
||||
} else {
|
||||
@@ -233,7 +233,7 @@ func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData m
|
||||
|
||||
fh.Close()
|
||||
|
||||
editor, ok := c.opts["editor"]
|
||||
editor, ok := c.opts["editor"].(string)
|
||||
if !ok {
|
||||
editor = os.Getenv("JIRA_EDITOR")
|
||||
if editor == "" {
|
||||
@@ -245,7 +245,7 @@ func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData m
|
||||
}
|
||||
|
||||
editing := true
|
||||
if val, ok := c.opts["edit"]; ok && val == "false" {
|
||||
if val, ok := c.opts["edit"].(bool); ok && !val {
|
||||
editing = false
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData m
|
||||
}
|
||||
|
||||
func (c *Cli) Browse(issue string) error {
|
||||
if val, ok := c.opts["browse"]; ok && val == "true" {
|
||||
if val, ok := c.opts["browse"].(bool); ok && val {
|
||||
if runtime.GOOS == "darwin" {
|
||||
return exec.Command("open", fmt.Sprintf("%s/browse/%s", c.endpoint, issue)).Run()
|
||||
} else if runtime.GOOS == "linux" {
|
||||
|
||||
+14
-8
@@ -14,7 +14,7 @@ func (c *Cli) CmdLogin() error {
|
||||
uri := fmt.Sprintf("%s/rest/auth/1/session", c.endpoint)
|
||||
for true {
|
||||
req, _ := http.NewRequest("GET", uri, nil)
|
||||
user, _ := c.opts["user"]
|
||||
user, _ := c.opts["user"].(string)
|
||||
|
||||
prompt := fmt.Sprintf("Enter Password for %s: ", user)
|
||||
passwd, _ := gopass.GetPass(prompt)
|
||||
@@ -69,7 +69,7 @@ func (c *Cli) CmdList() error {
|
||||
var query string
|
||||
var ok bool
|
||||
// project = BAKERY and status not in (Resolved, Closed)
|
||||
if query, ok = c.opts["query"]; !ok {
|
||||
if query, ok = c.opts["query"].(string); !ok {
|
||||
qbuff := bytes.NewBufferString("resolution = unresolved")
|
||||
if project, ok := c.opts["project"]; !ok {
|
||||
err := fmt.Errorf("Missing required arguments, either 'query' or 'project' are required")
|
||||
@@ -107,7 +107,7 @@ func (c *Cli) CmdList() error {
|
||||
}
|
||||
|
||||
fields := make([]string, 0)
|
||||
if qf, ok := c.opts["queryfields"]; ok {
|
||||
if qf, ok := c.opts["queryfields"].(string); ok {
|
||||
fields = strings.Split(qf, ",")
|
||||
} else {
|
||||
fields = append(fields, "summary")
|
||||
@@ -213,7 +213,8 @@ func (c *Cli) CmdTransitionMeta(issue string) error {
|
||||
return runTemplate(c.getTemplate("transmeta"), data, nil)
|
||||
}
|
||||
|
||||
func (c *Cli) CmdIssueTypes(project string) error {
|
||||
func (c *Cli) CmdIssueTypes() error {
|
||||
project := c.opts["project"].(string)
|
||||
log.Debug("issueTypes called")
|
||||
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s", c.endpoint, project)
|
||||
data, err := responseToJson(c.get(uri))
|
||||
@@ -224,7 +225,9 @@ func (c *Cli) CmdIssueTypes(project string) error {
|
||||
return runTemplate(c.getTemplate("issuetypes"), data, nil)
|
||||
}
|
||||
|
||||
func (c *Cli) CmdCreateMeta(project string, issuetype string) error {
|
||||
func (c *Cli) CmdCreateMeta() error {
|
||||
project := c.opts["project"].(string)
|
||||
issuetype := c.opts["issuetype"].(string)
|
||||
log.Debug("createMeta called")
|
||||
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", c.endpoint, project, issuetype)
|
||||
data, err := responseToJson(c.get(uri))
|
||||
@@ -257,7 +260,9 @@ func (c *Cli) CmdTransitions(issue string) error {
|
||||
return runTemplate(c.getTemplate("transitions"), data, nil)
|
||||
}
|
||||
|
||||
func (c *Cli) CmdCreate(project string, issuetype string) error {
|
||||
func (c *Cli) CmdCreate() error {
|
||||
project := c.opts["project"].(string)
|
||||
issuetype := c.opts["issuetype"].(string)
|
||||
log.Debug("create called")
|
||||
|
||||
uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", c.endpoint, project, issuetype)
|
||||
@@ -399,7 +404,8 @@ func (c *Cli) CmdDups(duplicate string, issue string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cli) CmdWatch(issue string, watcher string) error {
|
||||
func (c *Cli) CmdWatch(issue string) error {
|
||||
watcher := c.opts["watcher"].(string)
|
||||
log.Debug("watch called")
|
||||
|
||||
json, err := jsonEncode(watcher)
|
||||
@@ -568,7 +574,7 @@ func (c *Cli) CmdAssign(issue string, user string) error {
|
||||
}
|
||||
|
||||
func (c *Cli) CmdExportTemplates() error {
|
||||
dir := c.opts["directory"]
|
||||
dir := c.opts["directory"].(string)
|
||||
if err := mkdir(dir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+229
-255
@@ -4,7 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/Netflix-Skunkworks/go-jira/jira/cli"
|
||||
"github.com/docopt/docopt-go"
|
||||
"github.com/coryb/optigo"
|
||||
"github.com/op/go-logging"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
@@ -17,39 +17,63 @@ var log = logging.MustGetLogger("jira")
|
||||
var format = "%{color}%{time:2006-01-02T15:04:05.000Z07:00} %{level:-5s} [%{shortfile}]%{color:reset} %{message}"
|
||||
|
||||
func main() {
|
||||
logBackend := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
logging.SetBackend(
|
||||
logging.NewBackendFormatter(
|
||||
logBackend,
|
||||
logging.MustStringFormatter(format),
|
||||
),
|
||||
)
|
||||
logging.SetLevel(logging.NOTICE, "")
|
||||
|
||||
user := os.Getenv("USER")
|
||||
home := os.Getenv("HOME")
|
||||
defaultMaxResults := "500"
|
||||
usage := fmt.Sprintf(`
|
||||
defaultMaxResults := 500
|
||||
|
||||
usage := func(ok bool) {
|
||||
printer := fmt.Printf
|
||||
if !ok {
|
||||
printer = func(format string, args ...interface{}) (int, error) {
|
||||
return fmt.Fprintf(os.Stderr, format, args...)
|
||||
}
|
||||
defer func() {
|
||||
os.Exit(1)
|
||||
}()
|
||||
} else {
|
||||
defer func() {
|
||||
os.Exit(0)
|
||||
}()
|
||||
}
|
||||
output := fmt.Sprintf(`
|
||||
Usage:
|
||||
jira [-v ...] [-u USER] [-e URI] [-t FILE] (ls|list) ( [-q JQL] | [-p PROJECT] [-c COMPONENT] [-a ASSIGNEE] [-i ISSUETYPE] [-w WATCHER] [-r REPORTER]) [-f FIELDS] [-s ORDER] [--max_results MAX_RESULTS]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] view ISSUE
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] edit ISSUE [--noedit] [-m COMMENT] [-o KEY=VAL]...
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] create [--noedit] [-p PROJECT] [-i ISSUETYPE] [-o KEY=VAL]...
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] DUPLICATE dups ISSUE
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] BLOCKER blocks ISSUE
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] watch ISSUE [-w WATCHER]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] (trans|transition) TRANSITION ISSUE [-m COMMENT] [-o KEY=VAL] [--noedit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] ack ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] close ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] resolve ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] reopen ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] start ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] stop ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] comment ISSUE [-m COMMENT]
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] take ISSUE
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] (assign|give) ISSUE ASSIGNEE
|
||||
jira [-v ...] [-u USER] [-e URI] [-t FILE] fields
|
||||
jira [-v ...] [-u USER] [-e URI] [-t FILE] issuelinktypes
|
||||
jira [-v ...] [-u USER] [-e URI] [-b][-t FILE] transmeta ISSUE
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] editmeta ISSUE
|
||||
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] [-b] [-t FILE] transitions ISSUE
|
||||
jira [-v ...] export-templates [-d DIR] [-t template]
|
||||
jira [-v ...] [-u USER] [-e URI] (b|browse) ISSUE
|
||||
jira [-v ...] [-u USER] [-e URI] [-t FILE] login
|
||||
jira [-v ...] [-u USER] [-e URI] [-b] [-t FILE] ISSUE
|
||||
jira (ls|list) ( [-q JQL] | [-p PROJECT] [-c COMPONENT] [-a ASSIGNEE] [-i ISSUETYPE] [-w WATCHER] [-r REPORTER]) [-f FIELDS] [-s ORDER] [--max_results MAX_RESULTS]
|
||||
jira view ISSUE
|
||||
jira edit ISSUE [--noedit] [-m COMMENT] [-o KEY=VAL]...
|
||||
jira create [--noedit] [-p PROJECT] [-i ISSUETYPE] [-o KEY=VAL]...
|
||||
jira DUPLICATE dups ISSUE
|
||||
jira BLOCKER blocks ISSUE
|
||||
jira watch ISSUE [-w WATCHER]
|
||||
jira (trans|transition) TRANSITION ISSUE [-m COMMENT] [-o KEY=VAL] [--noedit]
|
||||
jira ack ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira close ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira resolve ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira reopen ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira start ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira stop ISSUE [-m COMMENT] [-o KEY=VAL] [--edit]
|
||||
jira comment ISSUE [-m COMMENT]
|
||||
jira take ISSUE
|
||||
jira (assign|give) ISSUE ASSIGNEE
|
||||
jira fields
|
||||
jira issuelinktypes
|
||||
jira transmeta ISSUE
|
||||
jira editmeta ISSUE
|
||||
jira issuetypes [-p PROJECT]
|
||||
jira createmeta [-p PROJECT] [-i ISSUETYPE]
|
||||
jira transitions ISSUE
|
||||
jira export-templates [-d DIR] [-t template]
|
||||
jira (b|browse) ISSUE
|
||||
jira login
|
||||
jira ISSUE
|
||||
|
||||
General Options:
|
||||
-e --endpoint=URI URI to use for jira
|
||||
@@ -57,7 +81,6 @@ General Options:
|
||||
-t --template=FILE Template file to use for output/editing
|
||||
-u --user=USER Username to use for authenticaion (default: %s)
|
||||
-v --verbose Increase output logging
|
||||
--version Show this version
|
||||
|
||||
Command Options:
|
||||
-a --assignee=USER Username assigned the issue
|
||||
@@ -67,90 +90,118 @@ Command Options:
|
||||
-f --queryfields=FIELDS Fields that are used in "list" template: (default: summary,created,priority,status,reporter,assignee)
|
||||
-i --issuetype=ISSUETYPE Jira Issue Type (default: Bug)
|
||||
-m --comment=COMMENT Comment message for transition
|
||||
-o --override=KEY:VAL Set custom key/value pairs
|
||||
-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
|
||||
-r --reporter=USER Reporter to search for
|
||||
-s --sort=ORDER For list operations, sort issues (default: priority asc, created)
|
||||
-w --watcher=USER Watcher to add to issue (default: %s)
|
||||
or Watcher to search for
|
||||
--max_results=VAL Maximum number of results to return in query (default: %s)
|
||||
--max_results=VAL Maximum number of results to return in query (default: %d)
|
||||
`, user, fmt.Sprintf("%s/.jira.d/templates", home), user, defaultMaxResults)
|
||||
|
||||
args, err := docopt.Parse(usage, nil, true, "0.0.8", false, false)
|
||||
if err != nil {
|
||||
log.Error("Failed to parse options: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
logBackend := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
logging.SetBackend(
|
||||
logging.NewBackendFormatter(
|
||||
logBackend,
|
||||
logging.MustStringFormatter(format),
|
||||
),
|
||||
)
|
||||
logging.SetLevel(logging.NOTICE, "")
|
||||
if verbose, ok := args["--verbose"]; ok {
|
||||
if verbose.(int) > 1 {
|
||||
logging.SetLevel(logging.DEBUG, "")
|
||||
} else if verbose.(int) > 0 {
|
||||
logging.SetLevel(logging.INFO, "")
|
||||
}
|
||||
printer(output)
|
||||
}
|
||||
|
||||
log.Info("Args: %v", args)
|
||||
jiraCommands := map[string]string{
|
||||
"list": "list",
|
||||
"ls": "list",
|
||||
"view": "view",
|
||||
"edit": "edit",
|
||||
"create": "create",
|
||||
"dups": "dups",
|
||||
"blocks": "blocks",
|
||||
"watch": "watch",
|
||||
"trans": "transition",
|
||||
"transition": "transition",
|
||||
"ack": "acknowledge",
|
||||
"acknowledge": "acknowledge",
|
||||
"close": "close",
|
||||
"resolve": "resolve",
|
||||
"reopen": "reopen",
|
||||
"start": "start",
|
||||
"stop": "stop",
|
||||
"comment": "comment",
|
||||
"take": "take",
|
||||
"assign": "assign",
|
||||
"give": "assign",
|
||||
"fields": "fields",
|
||||
"issuelinktypes": "issuelinktypes",
|
||||
"transmeta": "transmeta",
|
||||
"editmeta": "editmeta",
|
||||
"issuetypes": "issuetypes",
|
||||
"createmeta": "createmeta",
|
||||
"transitions": "transitions",
|
||||
"export-templates": "export-templates",
|
||||
"browse": "browse",
|
||||
"login": "login",
|
||||
}
|
||||
|
||||
populateEnv(args)
|
||||
opts := map[string]interface{}{
|
||||
"user": user,
|
||||
"issuetype": "Bug",
|
||||
"watcher": user,
|
||||
"queryfields": "summary,created,priority,status,reporter,assignee",
|
||||
"directory": fmt.Sprintf("%s/.jira.d/templates", home),
|
||||
"sort": "priority asc, created",
|
||||
"max_results": defaultMaxResults,
|
||||
}
|
||||
overrides := make(map[string]string)
|
||||
|
||||
opts := make(map[string]string)
|
||||
loadConfigs(opts)
|
||||
setopt := func(name string, value interface{}) {
|
||||
opts[name] = value
|
||||
}
|
||||
|
||||
// strip the "--" off the command line options
|
||||
// and populate the opts that we pass to the cli ctor
|
||||
for key, val := range args {
|
||||
if val != nil && strings.HasPrefix(key, "--") {
|
||||
opt := key[2:]
|
||||
if opt == "override" {
|
||||
for _, v := range val.([]string) {
|
||||
if strings.Contains(v, "=") {
|
||||
kv := strings.SplitN(v, "=", 2)
|
||||
opts[kv[0]] = kv[1]
|
||||
} else {
|
||||
log.Error("Malformed override, expected KEY=VALUE, got %s", v)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch v := val.(type) {
|
||||
case string:
|
||||
opts[opt] = v
|
||||
case int:
|
||||
opts[opt] = fmt.Sprintf("%d", v)
|
||||
case bool:
|
||||
opts[opt] = fmt.Sprintf("%t", v)
|
||||
}
|
||||
op := optigo.NewDirectAssignParser(map[string]interface{}{
|
||||
"h|help": usage,
|
||||
"v|verbose+": func() {
|
||||
logging.SetLevel(logging.GetLevel("")+1, "")
|
||||
},
|
||||
"dryrun": setopt,
|
||||
"b|browse": setopt,
|
||||
"editor=s": setopt,
|
||||
"u|user=s": setopt,
|
||||
"endpoint=s": setopt,
|
||||
"t|template=s": setopt,
|
||||
"q|query=s": setopt,
|
||||
"p|project=s": setopt,
|
||||
"c|component=s": setopt,
|
||||
"a|assignee=s": setopt,
|
||||
"i|issuetype=s": setopt,
|
||||
"w|watcher=s": setopt,
|
||||
"r|reporter=s": setopt,
|
||||
"f|queryfields=s": setopt,
|
||||
"s|sort=s": setopt,
|
||||
"l|limit|max_results=i": setopt,
|
||||
"o|override=s%": &overrides,
|
||||
"noedit": setopt,
|
||||
"edit": setopt,
|
||||
"m|comment=s": setopt,
|
||||
"d|dir|directory=s": setopt,
|
||||
})
|
||||
|
||||
if err := op.ProcessAll(os.Args[1:]); err != nil {
|
||||
log.Error("%s", err)
|
||||
usage(false)
|
||||
}
|
||||
args := op.Args
|
||||
opts["overrides"] = overrides
|
||||
|
||||
command := "view"
|
||||
if len(args) > 0 {
|
||||
if alias, ok := jiraCommands[args[0]]; ok {
|
||||
command = alias
|
||||
args = args[1:]
|
||||
} else if len(args) > 1 {
|
||||
// look at second arg for "dups" and "blocks" commands
|
||||
if alias, ok := jiraCommands[args[1]]; ok {
|
||||
command = alias
|
||||
args = append(args[:1], args[2:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cant use proper [default:x] syntax in docopt
|
||||
// because only want to default if the option is not
|
||||
// already specified in some .jira.d/config.yml file
|
||||
if _, ok := opts["user"]; !ok {
|
||||
opts["user"] = user
|
||||
}
|
||||
if _, ok := opts["queryfields"]; !ok {
|
||||
opts["queryfields"] = "summary,created,priority,status,reporter,assignee"
|
||||
}
|
||||
if _, ok := opts["directory"]; !ok {
|
||||
opts["directory"] = fmt.Sprintf("%s/.jira.d/templates", home)
|
||||
}
|
||||
if _, ok := opts["sort"]; !ok {
|
||||
opts["sort"] = "priority asc, created"
|
||||
}
|
||||
if _, ok := opts["max_results"]; !ok {
|
||||
opts["max_results"] = defaultMaxResults
|
||||
}
|
||||
os.Setenv("JIRA_OPERATION", command)
|
||||
loadConfigs(opts)
|
||||
|
||||
if _, ok := opts["endpoint"]; !ok {
|
||||
log.Error("endpoint option required. Either use --endpoint or set a enpoint option in your ~/.jira.d/config.yml file")
|
||||
@@ -161,130 +212,90 @@ Command Options:
|
||||
|
||||
log.Debug("opts: %s", opts)
|
||||
|
||||
validCommand := func(cmd string) bool {
|
||||
if val, ok := args[cmd]; ok && val.(bool) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
validOpt := func(opt string, dflt interface{}) interface{} {
|
||||
if val, ok := opts[opt]; ok {
|
||||
return val
|
||||
}
|
||||
if dflt == nil {
|
||||
log.Error("Missing required option --%s or \"%s\" property override in the config file", opt, opt)
|
||||
os.Exit(1)
|
||||
}
|
||||
return dflt
|
||||
}
|
||||
|
||||
setEditing := func(dflt bool) {
|
||||
if dflt {
|
||||
if val, ok := opts["noedit"]; ok && val == "true" {
|
||||
opts["edit"] = "false"
|
||||
if val, ok := opts["noedit"].(bool); ok && val {
|
||||
opts["edit"] = false
|
||||
} else {
|
||||
opts["edit"] = "true"
|
||||
opts["edit"] = true
|
||||
}
|
||||
} else {
|
||||
if val, ok := opts["edit"]; ok && val != "true" {
|
||||
opts["edit"] = "false"
|
||||
if val, ok := opts["edit"].(bool); ok && !val {
|
||||
opts["edit"] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if validCommand("login") {
|
||||
var err error
|
||||
switch command {
|
||||
case "login":
|
||||
err = c.CmdLogin()
|
||||
} else if validCommand("fields") {
|
||||
case "fields":
|
||||
err = c.CmdFields()
|
||||
} else if validCommand("ls") || validCommand("list") {
|
||||
case "list":
|
||||
err = c.CmdList()
|
||||
} else if validCommand("edit") {
|
||||
case "edit":
|
||||
setEditing(true)
|
||||
err = c.CmdEdit(args["ISSUE"].(string))
|
||||
} else if validCommand("editmeta") {
|
||||
err = c.CmdEditMeta(args["ISSUE"].(string))
|
||||
} else if validCommand("transmeta") {
|
||||
err = c.CmdTransitionMeta(args["ISSUE"].(string))
|
||||
} else if validCommand("issuelinktypes") {
|
||||
err = c.CmdEdit(args[0])
|
||||
case "editmeta":
|
||||
err = c.CmdEditMeta(args[0])
|
||||
case "transmeta":
|
||||
err = c.CmdTransitionMeta(args[0])
|
||||
case "issuelinktypes":
|
||||
err = c.CmdIssueLinkTypes()
|
||||
} else if validCommand("issuetypes") {
|
||||
err = c.CmdIssueTypes(validOpt("project", nil).(string))
|
||||
} else if validCommand("createmeta") {
|
||||
err = c.CmdCreateMeta(
|
||||
validOpt("project", nil).(string),
|
||||
validOpt("issuetype", "Bug").(string),
|
||||
)
|
||||
} else if validCommand("create") {
|
||||
case "issuetypes":
|
||||
err = c.CmdIssueTypes()
|
||||
case "createmeta":
|
||||
err = c.CmdCreateMeta()
|
||||
case "create":
|
||||
setEditing(true)
|
||||
err = c.CmdCreate(
|
||||
validOpt("project", nil).(string),
|
||||
validOpt("issuetype", "Bug").(string),
|
||||
)
|
||||
} else if validCommand("transitions") {
|
||||
err = c.CmdTransitions(args["ISSUE"].(string))
|
||||
} else if validCommand("blocks") {
|
||||
err = c.CmdBlocks(
|
||||
args["BLOCKER"].(string),
|
||||
args["ISSUE"].(string),
|
||||
)
|
||||
} else if validCommand("dups") {
|
||||
if err = c.CmdDups(
|
||||
args["DUPLICATE"].(string),
|
||||
args["ISSUE"].(string),
|
||||
); err == nil {
|
||||
err = c.CmdCreate()
|
||||
case "transitions":
|
||||
err = c.CmdTransitions(args[0])
|
||||
case "blocks":
|
||||
err = c.CmdBlocks(args[0], args[1])
|
||||
case "dups":
|
||||
if err = c.CmdDups(args[0], args[1]); err == nil {
|
||||
opts["resolution"] = "Duplicate"
|
||||
err = c.CmdTransition(
|
||||
args["DUPLICATE"].(string),
|
||||
"close",
|
||||
)
|
||||
err = c.CmdTransition(args[0], "close")
|
||||
}
|
||||
} else if validCommand("watch") {
|
||||
err = c.CmdWatch(
|
||||
args["ISSUE"].(string),
|
||||
validOpt("watcher", user).(string),
|
||||
)
|
||||
} else if validCommand("trans") || validCommand("transition") {
|
||||
case "watch":
|
||||
err = c.CmdWatch(args[0])
|
||||
case "transition":
|
||||
setEditing(true)
|
||||
err = c.CmdTransition(
|
||||
args["ISSUE"].(string),
|
||||
args["TRANSITION"].(string),
|
||||
)
|
||||
} else if validCommand("close") {
|
||||
err = c.CmdTransition(args[0], args[1])
|
||||
case "close":
|
||||
setEditing(false)
|
||||
err = c.CmdTransition(args["ISSUE"].(string), "close")
|
||||
} else if validCommand("ack") {
|
||||
err = c.CmdTransition(args[0], "close")
|
||||
case "acknowledge":
|
||||
setEditing(false)
|
||||
err = c.CmdTransition(args["ISSUE"].(string), "acknowledge")
|
||||
} else if validCommand("reopen") {
|
||||
err = c.CmdTransition(args[0], "acknowledge")
|
||||
case "reopen":
|
||||
setEditing(false)
|
||||
err = c.CmdTransition(args["ISSUE"].(string), "reopen")
|
||||
} else if validCommand("resolve") {
|
||||
err = c.CmdTransition(args[0], "reopen")
|
||||
case "resolve":
|
||||
setEditing(false)
|
||||
err = c.CmdTransition(args["ISSUE"].(string), "resolve")
|
||||
} else if validCommand("start") {
|
||||
err = c.CmdTransition(args[0], "resolve")
|
||||
case "start":
|
||||
setEditing(false)
|
||||
err = c.CmdTransition(args["ISSUE"].(string), "start")
|
||||
} else if validCommand("stop") {
|
||||
err = c.CmdTransition(args[0], "start")
|
||||
case "stop":
|
||||
setEditing(false)
|
||||
err = c.CmdTransition(args["ISSUE"].(string), "stop")
|
||||
} else if validCommand("comment") {
|
||||
err = c.CmdTransition(args[0], "stop")
|
||||
case "comment":
|
||||
setEditing(true)
|
||||
err = c.CmdComment(args["ISSUE"].(string))
|
||||
} else if validCommand("take") {
|
||||
err = c.CmdAssign(args["ISSUE"].(string), opts["user"])
|
||||
} else if validCommand("browse") || validCommand("b") {
|
||||
opts["browse"] = "true"
|
||||
err = c.Browse(args["ISSUE"].(string))
|
||||
} else if validCommand("export-templates") {
|
||||
err = c.CmdComment(args[0])
|
||||
case "take":
|
||||
err = c.CmdAssign(args[0], opts["user"].(string))
|
||||
case "browse":
|
||||
opts["browse"] = true
|
||||
err = c.Browse(args[0])
|
||||
case "export-tempaltes":
|
||||
err = c.CmdExportTemplates()
|
||||
} else if validCommand("assign") || validCommand("give") {
|
||||
err = c.CmdAssign(
|
||||
args["ISSUE"].(string),
|
||||
args["ASSIGNEE"].(string),
|
||||
)
|
||||
} else if val, ok := args["ISSUE"]; ok {
|
||||
err = c.CmdView(val.(string))
|
||||
case "assign":
|
||||
err = c.CmdAssign(args[0], args[1])
|
||||
default:
|
||||
err = c.CmdView(args[0])
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -293,73 +304,35 @@ Command Options:
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func parseYaml(file string, opts map[string]string) {
|
||||
func parseYaml(file string, opts map[string]interface{}) {
|
||||
if fh, err := ioutil.ReadFile(file); err == nil {
|
||||
log.Debug("Found Config file: %s", file)
|
||||
yaml.Unmarshal(fh, &opts)
|
||||
}
|
||||
}
|
||||
|
||||
func populateEnv(args map[string]interface{}) {
|
||||
foundOp := false
|
||||
for key, val := range args {
|
||||
if val != nil && strings.HasPrefix(key, "--") {
|
||||
if key == "--override" {
|
||||
for _, v := range val.([]string) {
|
||||
if strings.Contains(v, "=") {
|
||||
kv := strings.SplitN(v, "=", 2)
|
||||
envName := fmt.Sprintf("JIRA_%s", strings.ToUpper(kv[0]))
|
||||
os.Setenv(envName, kv[1])
|
||||
} else {
|
||||
log.Error("Malformed override, expected KEY=VALUE, got %s", v)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
envName := fmt.Sprintf("JIRA_%s", strings.ToUpper(key[2:]))
|
||||
switch v := val.(type) {
|
||||
case []string:
|
||||
os.Setenv(envName, strings.Join(v, ","))
|
||||
case string:
|
||||
os.Setenv(envName, v)
|
||||
case bool:
|
||||
if v {
|
||||
os.Setenv(envName, "1")
|
||||
} else {
|
||||
os.Setenv(envName, "0")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if val != nil {
|
||||
// lower case strings are operations
|
||||
if strings.ToLower(key) == key {
|
||||
if key == "ls" && val.(bool) {
|
||||
foundOp = true
|
||||
os.Setenv("JIRA_OPERATION", "list")
|
||||
} else if key == "b" && val.(bool) {
|
||||
foundOp = true
|
||||
os.Setenv("JIRA_OPERATION", "browse")
|
||||
} else if key == "trans" && val.(bool) {
|
||||
foundOp = true
|
||||
os.Setenv("JIRA_OPERATION", "transition")
|
||||
} else if key == "give" && val.(bool) {
|
||||
foundOp = true
|
||||
os.Setenv("JIRA_OPERATION", "assign")
|
||||
} else if val.(bool) {
|
||||
foundOp = true
|
||||
os.Setenv("JIRA_OPERATION", key)
|
||||
}
|
||||
} else {
|
||||
os.Setenv(fmt.Sprintf("JIRA_%s", key), val.(string))
|
||||
}
|
||||
func populateEnv(opts map[string]interface{}) {
|
||||
for k, v := range opts {
|
||||
envName := fmt.Sprintf("JIRA_%s", strings.ToUpper(k))
|
||||
var val string
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
val = t
|
||||
case int, int8, int16, int32, int64:
|
||||
val = fmt.Sprintf("%d", t)
|
||||
case float32, float64:
|
||||
val = fmt.Sprintf("%f", t)
|
||||
case bool:
|
||||
val = fmt.Sprintf("%t", t)
|
||||
default:
|
||||
val = fmt.Sprintf("%v", t)
|
||||
}
|
||||
}
|
||||
if !foundOp {
|
||||
os.Setenv("JIRA_OPERATION", "view")
|
||||
os.Setenv(envName, val)
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfigs(opts map[string]string) {
|
||||
func loadConfigs(opts map[string]interface{}) {
|
||||
populateEnv(opts)
|
||||
paths := cli.FindParentPaths(".jira.d/config.yml")
|
||||
// prepend
|
||||
paths = append([]string{"/etc/jira-cli.yml"}, paths...)
|
||||
@@ -381,6 +354,7 @@ func loadConfigs(opts map[string]string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
yaml.Unmarshal(stdout.Bytes(), &opts)
|
||||
populateEnv(opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user