diff --git a/issue.go b/issue.go index 09b6f45..41d0d50 100644 --- a/issue.go +++ b/issue.go @@ -255,24 +255,24 @@ func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, iss } defer resp.Body.Close() - if resp.StatusCode == 200 { - results := &jiradata.CreateMeta{} - err = json.NewDecoder(resp.Body).Decode(results) - if err != nil { - return nil, err + if resp.StatusCode != 200 { + return nil, responseError(resp) + } + results := &jiradata.CreateMeta{} + if err := json.NewDecoder(resp.Body).Decode(results); err != nil { + return nil, err + } + for _, project := range results.Projects { + if project.Key != projectKey { + continue } - for _, project := range results.Projects { - if project.Key == projectKey { - for _, issueType := range project.IssueTypes { - if issueType.Name == issueTypeName { - return issueType, nil - } - } + for _, issueType := range project.IssueTypes { + if issueType.Name == issueTypeName { + return issueType, nil } } - return nil, fmt.Errorf("project %s and IssueType %s not found", projectKey, issueTypeName) } - return nil, responseError(resp) + return nil, fmt.Errorf("project %s and IssueType %s not found", projectKey, issueTypeName) } type LinkIssueProvider interface { diff --git a/jiracli/cli.go b/jiracli/cli.go index f5ebc4a..614284d 100644 --- a/jiracli/cli.go +++ b/jiracli/cli.go @@ -150,43 +150,39 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) { app.Flag("user", "user name used within the Jira service").Short('u').SetValue(&globals.User) app.Flag("login", "login name that corresponds to the user used for authentication").SetValue(&globals.Login) - o = o.WithPreCallback( - func(req *http.Request) (*http.Request, error) { - if globals.AuthMethod() == "api-token" { - // need to set basic auth header with user@domain:api-token - token := globals.GetPass() - authHeader := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", globals.Login.Value, token)))) - req.Header.Add("Authorization", authHeader) - } - return req, nil - }, - ) + o = o.WithPreCallback(func(req *http.Request) (*http.Request, error) { + if globals.AuthMethod() == "api-token" { + // need to set basic auth header with user@domain:api-token + token := globals.GetPass() + authHeader := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", globals.Login.Value, token)))) + req.Header.Add("Authorization", authHeader) + } + return req, nil + }) - o = o.WithPostCallback( - func(req *http.Request, resp *http.Response) (*http.Response, error) { - if globals.AuthMethod() == "session" { - authUser := resp.Header.Get("X-Ausername") - if authUser == "" || authUser == "anonymous" { - // preserve the --quiet value, we need to temporarily disable it so - // the normal login output is surpressed - defer func(quiet bool) { - globals.Quiet.Value = quiet - }(globals.Quiet.Value) - globals.Quiet.Value = true + o = o.WithPostCallback(func(req *http.Request, resp *http.Response) (*http.Response, error) { + if globals.AuthMethod() == "session" { + authUser := resp.Header.Get("X-Ausername") + if authUser == "" || authUser == "anonymous" { + // preserve the --quiet value, we need to temporarily disable it so + // the normal login output is surpressed + defer func(quiet bool) { + globals.Quiet.Value = quiet + }(globals.Quiet.Value) + globals.Quiet.Value = true - // we are not logged in, so force login now by running the "login" command - app.Parse([]string{"login"}) + // we are not logged in, so force login now by running the "login" command + app.Parse([]string{"login"}) - // rerun the original request - return o.Do(req) - } - } else if globals.AuthMethod() == "api-token" && resp.StatusCode == 401 { - globals.SetPass("") + // rerun the original request return o.Do(req) } - return resp, nil - }, - ) + } else if globals.AuthMethod() == "api-token" && resp.StatusCode == 401 { + globals.SetPass("") + return o.Do(req) + } + return resp, nil + }) for _, command := range globalCommandRegistry { copy := command @@ -238,14 +234,12 @@ func register(app *kingpin.Application, o *oreo.Client, fig *figtree.FigTree) { copy.Entry.UsageFunc(fig, cmd) } - cmd.Action( - func(_ *kingpin.ParseContext) error { - if logging.GetLevel("") > logging.DEBUG { - o = o.WithTrace(true) - } - return copy.Entry.ExecuteFunc(o, &globals) - }, - ) + cmd.Action(func(_ *kingpin.ParseContext) error { + if logging.GetLevel("") > logging.DEBUG { + o = o.WithTrace(true) + } + return copy.Entry.ExecuteFunc(o, &globals) + }) } } @@ -321,35 +315,42 @@ func (o *CommonOptions) editFile(fileName string) (changes bool, err error) { } // now we just need to diff the files to see if there are any changes - var oldHandle, newHandle *os.File - var oldStat, newStat os.FileInfo - if oldHandle, err = os.Open(tmpFileNameOrig); err == nil { - if newHandle, err = os.Open(fileName); err == nil { - if oldStat, err = oldHandle.Stat(); err == nil { - if newStat, err = newHandle.Stat(); err == nil { - // different sizes, so must have changes - if oldStat.Size() != newStat.Size() { - return true, err - } - oldBuf, newBuf := make([]byte, 1024), make([]byte, 1024) - var oldCount, newCount int - // loop though 1024 bytes at a time comparing the buffers for changes - for err != io.EOF { - oldCount, _ = oldHandle.Read(oldBuf) - newCount, err = newHandle.Read(newBuf) - if oldCount != newCount { - return true, nil - } - if !bytes.Equal(oldBuf[:oldCount], newBuf[:newCount]) { - return true, nil - } - } - return false, nil - } - } + f1, err := os.Open(tmpFileNameOrig) + if err != nil { + return false, err + } + f2, err := os.Open(fileName) + if err != nil { + return false, err + } + + stat1, err := f1.Stat() + if err != nil { + return false, err + } + stat2, err := f2.Stat() + if err != nil { + return false, err + } + // different sizes, so must have changes + if stat1.Size() != stat2.Size() { + return true, nil + } + + p1, p2 := make([]byte, 1024), make([]byte, 1024) + var n1, n2 int + // loop though 1024 bytes at a time comparing the buffers for changes + for err != io.EOF { + n1, _ = f1.Read(p1) + n2, err = f2.Read(p2) + if n1 != n2 { + return true, nil + } + if !bytes.Equal(p1[:n1], p2[:n2]) { + return true, nil } } - return false, err + return false, nil } var EditLoopAbort = fmt.Errorf("edit Loop aborted by request") diff --git a/jiracli/templates.go b/jiracli/templates.go index d1e7675..8eb5b6b 100644 --- a/jiracli/templates.go +++ b/jiracli/templates.go @@ -44,7 +44,8 @@ func getTemplate(name string) (string, error) { b, err := findTemplate(name) if err != nil { return "", err - } else if b != nil { + } + if b != nil { return string(b), nil } if s, ok := AllTemplates[name]; ok { diff --git a/jiracli/usage.go b/jiracli/usage.go index 4f4c432..3c17810 100644 --- a/jiracli/usage.go +++ b/jiracli/usage.go @@ -187,13 +187,12 @@ func ParseCommandLine(app *kingpin.Application, args []string) { if _, ok := err.(*Error); ok { log.Errorf("%s", err) panic(Exit{Code: 1}) - } else { - ctx, _ := app.ParseContext(os.Args[1:]) - if ctx != nil { - app.UsageForContext(ctx) - } - log.Errorf("Invalid Usage: %s", err) - panic(Exit{Code: 1}) } + ctx, _ := app.ParseContext(os.Args[1:]) + if ctx != nil { + app.UsageForContext(ctx) + } + log.Errorf("Invalid Usage: %s", err) + panic(Exit{Code: 1}) } } diff --git a/jiracmd/dup.go b/jiracmd/dup.go index a5edaba..d15b19f 100644 --- a/jiracmd/dup.go +++ b/jiracmd/dup.go @@ -76,30 +76,31 @@ func CmdDup(o *oreo.Client, globals *jiracli.GlobalOptions, opts *DupOptions) er } for _, trans := range []string{"close", "done", "cancel", "start", "stop"} { transMeta := meta.Transitions.Find(trans) - if transMeta != nil { - issueUpdate := jiradata.IssueUpdate{ - Transition: transMeta, - } - resolution := defaultResolution(transMeta) - if resolution != "" { - issueUpdate.Fields = map[string]interface{}{ - "resolution": map[string]interface{}{ - "name": resolution, - }, - } - } - if err = jira.TransitionIssue(o, globals.Endpoint.Value, opts.InwardIssue.Key, &issueUpdate); err != nil { - return err - } - if trans != "start" { - break - } - // if we are here then we must be stopping, so need to reset the meta - meta, err = jira.GetIssueTransitions(o, globals.Endpoint.Value, opts.InwardIssue.Key) - if err != nil { - return err + if transMeta == nil { + continue + } + issueUpdate := jiradata.IssueUpdate{ + Transition: transMeta, + } + resolution := defaultResolution(transMeta) + if resolution != "" { + issueUpdate.Fields = map[string]interface{}{ + "resolution": map[string]interface{}{ + "name": resolution, + }, } } + if err = jira.TransitionIssue(o, globals.Endpoint.Value, opts.InwardIssue.Key, &issueUpdate); err != nil { + return err + } + if trans != "start" { + break + } + // if we are here then we must be stopping, so need to reset the meta + meta, err = jira.GetIssueTransitions(o, globals.Endpoint.Value, opts.InwardIssue.Key) + if err != nil { + return err + } } if !globals.Quiet.Value { diff --git a/jiracmd/edit.go b/jiracmd/edit.go index 65ad881..f77416e 100644 --- a/jiracmd/edit.go +++ b/jiracmd/edit.go @@ -124,22 +124,20 @@ func CmdEdit(o *oreo.Client, globals *jiracli.GlobalOptions, opts *EditOptions) err = jiracli.EditLoop(&opts.CommonOptions, &input, &issueUpdate, func() error { return jira.EditIssue(o, globals.Endpoint.Value, issueData.Key, &issueUpdate) }) - if err == jiracli.EditLoopAbort { - if len(results.Issues) > i+1 { - var answer bool - survey.AskOne( - &survey.Confirm{ - Message: fmt.Sprintf("Continue to edit next issue %s?", results.Issues[i+1].Key), - Default: true, - }, - &answer, - nil, - ) - if answer { - continue - } - panic(jiracli.Exit{1}) + if err == jiracli.EditLoopAbort && len(results.Issues) > i+1 { + var answer bool + survey.AskOne( + &survey.Confirm{ + Message: fmt.Sprintf("Continue to edit next issue %s?", results.Issues[i+1].Key), + Default: true, + }, + &answer, + nil, + ) + if answer { + continue } + panic(jiracli.Exit{1}) } if err != nil { return err diff --git a/jiracmd/transition.go b/jiracmd/transition.go index 361a1c5..359b22e 100644 --- a/jiracmd/transition.go +++ b/jiracmd/transition.go @@ -110,15 +110,13 @@ func CmdTransition(o *oreo.Client, globals *jiracli.GlobalOptions, opts *Transit } // need to default the Resolution, usually Fixed works but sometime need Done - if opts.Resolution == "" { - if resField, ok := transMeta.Fields["resolution"]; ok { - for _, allowedValueRaw := range resField.AllowedValues { - if allowedValue, ok := allowedValueRaw.(map[string]interface{}); ok { - if allowedValue["name"] == "Fixed" { - opts.Resolution = "Fixed" - } else if allowedValue["name"] == "Done" { - opts.Resolution = "Done" - } + if resField, ok := transMeta.Fields["resolution"]; ok && opts.Resolution == "" { + for _, allowedValueRaw := range resField.AllowedValues { + if allowedValue, ok := allowedValueRaw.(map[string]interface{}); ok { + if allowedValue["name"] == "Fixed" { + opts.Resolution = "Fixed" + } else if allowedValue["name"] == "Done" { + opts.Resolution = "Done" } } }