diff --git a/Makefile b/Makefile index 114be1b..cef85ae 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ LDFLAGS:=-X jira.VERSION=$(CURVER) -w ifneq ($(DEBUG),) GOBUILD=go get -v github.com/mailgun/godebug && else - GOBUILD=go build -v -ldflags "$(LDFLAGS) -s" + GOBUILD=go build -gcflags="-e -complete" -v -ldflags "$(LDFLAGS) -s" endif build: diff --git a/cmd/jira/main.go b/cmd/jira/main.go index d5979b3..b74dcd6 100644 --- a/cmd/jira/main.go +++ b/cmd/jira/main.go @@ -3,8 +3,10 @@ package main import ( "fmt" "os" + "path/filepath" "runtime/debug" + "github.com/coryb/figtree" "github.com/coryb/oreo" jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" @@ -63,205 +65,209 @@ func main() { return nil }).Counter() - cli := jiracli.New(".jira.d") + fig := figtree.NewFigTree() + fig.EnvPrefix = "JIRA" + fig.ConfigDir = ".jira.d" + + o := oreo.New().WithCookieFile(filepath.Join(jiracli.Homedir(), fig.ConfigDir, "cookies.js")) registry := []jiracli.CommandRegistry{ jiracli.CommandRegistry{ Command: "login", - Entry: cli.CmdLoginRegistry(), + Entry: jiracli.CmdLoginRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "logout", - Entry: cli.CmdLogoutRegistry(), + Entry: jiracli.CmdLogoutRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "list", Aliases: []string{"ls"}, - Entry: cli.CmdListRegistry(), + Entry: jiracli.CmdListRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "view", - Entry: cli.CmdViewRegistry(), + Entry: jiracli.CmdViewRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "create", - Entry: cli.CmdCreateRegistry(), + Entry: jiracli.CmdCreateRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "edit", - Entry: cli.CmdEditRegistry(), + Entry: jiracli.CmdEditRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "comment", - Entry: cli.CmdCommentRegistry(), + Entry: jiracli.CmdCommentRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "worklog list", - Entry: cli.CmdWorklogListRegistry(), + Entry: jiracli.CmdWorklogListRegistry(fig, o), Default: true, }, jiracli.CommandRegistry{ Command: "worklog add", - Entry: cli.CmdWorklogAddRegistry(), + Entry: jiracli.CmdWorklogAddRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "fields", - Entry: cli.CmdFieldsRegistry(), + Entry: jiracli.CmdFieldsRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "createmeta", - Entry: cli.CmdCreateMetaRegistry(), + Entry: jiracli.CmdCreateMetaRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "editmeta", - Entry: cli.CmdEditMetaRegistry(), + Entry: jiracli.CmdEditMetaRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "subtask", - Entry: cli.CmdSubtaskRegistry(), + Entry: jiracli.CmdSubtaskRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "dup", - Entry: cli.CmdDupRegistry(), + Entry: jiracli.CmdDupRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "block", - Entry: cli.CmdBlockRegistry(), + Entry: jiracli.CmdBlockRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "issuelink", - Entry: cli.CmdIssueLinkRegistry(), + Entry: jiracli.CmdIssueLinkRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "issuelinktypes", - Entry: cli.CmdIssueLinkTypesRegistry(), + Entry: jiracli.CmdIssueLinkTypesRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "transition", Aliases: []string{"trans"}, - Entry: cli.CmdTransitionRegistry(""), + Entry: jiracli.CmdTransitionRegistry(fig, o, ""), }, jiracli.CommandRegistry{ Command: "transitions", - Entry: cli.CmdTransitionsRegistry("transitions"), + Entry: jiracli.CmdTransitionsRegistry(fig, o, "transitions"), }, jiracli.CommandRegistry{ Command: "transmeta", - Entry: cli.CmdTransitionsRegistry("debug"), + Entry: jiracli.CmdTransitionsRegistry(fig, o, "debug"), }, jiracli.CommandRegistry{ Command: "close", - Entry: cli.CmdTransitionRegistry("close"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "close"), }, jiracli.CommandRegistry{ Command: "acknowledge", Aliases: []string{"ack"}, - Entry: cli.CmdTransitionRegistry("acknowledge"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "acknowledge"), }, jiracli.CommandRegistry{ Command: "reopen", - Entry: cli.CmdTransitionRegistry("reopen"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "reopen"), }, jiracli.CommandRegistry{ Command: "resolve", - Entry: cli.CmdTransitionRegistry("resolve"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "resolve"), }, jiracli.CommandRegistry{ Command: "start", - Entry: cli.CmdTransitionRegistry("start"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "start"), }, jiracli.CommandRegistry{ Command: "stop", - Entry: cli.CmdTransitionRegistry("stop"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "stop"), }, jiracli.CommandRegistry{ Command: "todo", - Entry: cli.CmdTransitionRegistry("To Do"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "To Do"), }, jiracli.CommandRegistry{ Command: "backlog", - Entry: cli.CmdTransitionRegistry("Backlog"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "Backlog"), }, jiracli.CommandRegistry{ Command: "done", - Entry: cli.CmdTransitionRegistry("Done"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "Done"), }, jiracli.CommandRegistry{ Command: "in-progress", Aliases: []string{"prog", "progress"}, - Entry: cli.CmdTransitionRegistry("Progress"), + Entry: jiracli.CmdTransitionRegistry(fig, o, "Progress"), }, jiracli.CommandRegistry{ Command: "vote", - Entry: cli.CmdVoteRegistry(), + Entry: jiracli.CmdVoteRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "rank", - Entry: cli.CmdRankRegistry(), + Entry: jiracli.CmdRankRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "watch", - Entry: cli.CmdWatchRegistry(), + Entry: jiracli.CmdWatchRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "labels add", - Entry: cli.CmdLabelsAddRegistry(), + Entry: jiracli.CmdLabelsAddRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "labels set", - Entry: cli.CmdLabelsAddRegistry(), + Entry: jiracli.CmdLabelsAddRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "labels remove", - Entry: cli.CmdLabelsAddRegistry(), + Entry: jiracli.CmdLabelsAddRegistry(fig, o), Aliases: []string{"rm"}, }, jiracli.CommandRegistry{ Command: "take", - Entry: cli.CmdTakeRegistry(), + Entry: jiracli.CmdTakeRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "assign", - Entry: cli.CmdAssignRegistry(), + Entry: jiracli.CmdAssignRegistry(fig, o), Aliases: []string{"give"}, }, jiracli.CommandRegistry{ Command: "unassign", - Entry: cli.CmdUnassignRegistry(), + Entry: jiracli.CmdUnassignRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "component add", - Entry: cli.CmdComponentAddRegistry(), + Entry: jiracli.CmdComponentAddRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "components", - Entry: cli.CmdComponentsRegistry(), + Entry: jiracli.CmdComponentsRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "issuetypes", - Entry: cli.CmdIssueTypesRegistry(), + Entry: jiracli.CmdIssueTypesRegistry(fig, o), }, jiracli.CommandRegistry{ Command: "export-templates", - Entry: cli.CmdExportTemplatesRegistry(), + Entry: jiracli.CmdExportTemplatesRegistry(fig), }, jiracli.CommandRegistry{ Command: "unexport-templates", - Entry: cli.CmdUnexportTemplatesRegistry(), + Entry: jiracli.CmdUnexportTemplatesRegistry(fig), }, jiracli.CommandRegistry{ Command: "browse", - Entry: cli.CmdBrowseRegistry(), + Entry: jiracli.CmdBrowseRegistry(fig), Aliases: []string{"b"}, }, jiracli.CommandRegistry{ Command: "request", - Entry: cli.CmdRequestRegistry(), + Entry: jiracli.CmdRequestRegistry(fig, o), Aliases: []string{"req"}, }, } - cli.Register(app, registry) + jiracli.Register(app, registry) app.Terminate(func(status int) { for _, arg := range os.Args { diff --git a/component.go b/component.go index a5b7fc8..6a85bc9 100644 --- a/component.go +++ b/component.go @@ -14,13 +14,17 @@ type ComponentProvider interface { // https://docs.atlassian.com/jira/REST/cloud/#api/2/component-createComponent func (j *Jira) CreateComponent(cp ComponentProvider) (*jiradata.Component, error) { + return CreateComponent(j.UA, j.Endpoint, cp) +} + +func CreateComponent(ua HttpClient, endpoint string, cp ComponentProvider) (*jiradata.Component, error) { req := cp.ProvideComponent() encoded, err := json.Marshal(req) if err != nil { return nil, err } - uri := fmt.Sprintf("%s/rest/api/2/component", j.Endpoint) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/component", endpoint) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return nil, err } diff --git a/fields.go b/fields.go index 68cdcb1..9af1c86 100644 --- a/fields.go +++ b/fields.go @@ -8,8 +8,12 @@ import ( // https://docs.atlassian.com/jira/REST/cloud/#api/2/field-getFields func (j *Jira) GetFields() ([]jiradata.Field, error) { - uri := fmt.Sprintf("%s/rest/api/2/field", j.Endpoint) - resp, err := j.UA.GetJSON(uri) + return GetFields(j.UA, j.Endpoint) +} + +func GetFields(ua HttpClient, endpoint string) ([]jiradata.Field, error) { + uri := fmt.Sprintf("%s/rest/api/2/field", endpoint) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } diff --git a/glide.lock b/glide.lock index 32c219a..488f116 100644 --- a/glide.lock +++ b/glide.lock @@ -17,9 +17,9 @@ imports: subpackages: - generic - name: github.com/coryb/figtree - version: 97f630386644abe852de0f4df3befd74bf0a5f9e + version: 405935ba249b758f31f4ca2132c4fed7702cc622 - name: github.com/coryb/oreo - version: a99f8c323f9746fc5b576349f1ffee4af0bc5ff2 + version: b59de1c7ff7fe9e084278487f69a07cb667de9b3 - name: github.com/fatih/camelcase version: f6a740d52f961c60348ebb109adde9f4635d7540 - name: github.com/guelfey/go.dbus diff --git a/issue.go b/issue.go index 77ace43..579e615 100644 --- a/issue.go +++ b/issue.go @@ -46,12 +46,16 @@ func (o *IssueOptions) ProvideIssueQueryString() string { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getIssue func (j *Jira) GetIssue(issue string, iqg IssueQueryProvider) (*jiradata.Issue, error) { + return GetIssue(j.UA, j.Endpoint, issue, iqg) +} + +func GetIssue(ua HttpClient, endpoint string, issue string, iqg IssueQueryProvider) (*jiradata.Issue, error) { query := "" if iqg != nil { query = iqg.ProvideIssueQueryString() } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s%s", j.Endpoint, issue, query) - resp, err := j.UA.GetJSON(uri) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s%s", endpoint, issue, query) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -64,15 +68,19 @@ func (j *Jira) GetIssue(issue string, iqg IssueQueryProvider) (*jiradata.Issue, return nil, responseError(resp) } -// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-getIssueWorklog func (j *Jira) GetIssueWorklog(issue string) (*jiradata.Worklogs, error) { + return GetIssueWorklog(j.UA, j.Endpoint, issue) +} + +// https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-getIssueWorklog +func GetIssueWorklog(ua HttpClient, endpoint string, issue string) (*jiradata.Worklogs, error) { startAt := 0 total := 1 maxResults := 100 worklogs := jiradata.Worklogs{} for startAt < total { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog?startAt=%d&maxResults=%d", j.Endpoint, issue, startAt, maxResults) - resp, err := j.UA.GetJSON(uri) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog?startAt=%d&maxResults=%d", endpoint, issue, startAt, maxResults) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -102,13 +110,17 @@ type WorklogProvider interface { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/worklog-addWorklog func (j *Jira) AddIssueWorklog(issue string, wp WorklogProvider) (*jiradata.Worklog, error) { + return AddIssueWorklog(j.UA, j.Endpoint, issue, wp) +} + +func AddIssueWorklog(ua HttpClient, endpoint string, issue string, wp WorklogProvider) (*jiradata.Worklog, error) { req := wp.ProvideWorklog() encoded, err := json.Marshal(req) if err != nil { return nil, err } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog", j.Endpoint, issue) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/worklog", endpoint, issue) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return nil, err } @@ -123,8 +135,12 @@ func (j *Jira) AddIssueWorklog(issue string, wp WorklogProvider) (*jiradata.Work // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getEditIssueMeta func (j *Jira) GetIssueEditMeta(issue string) (*jiradata.EditMeta, error) { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/editmeta", j.Endpoint, issue) - resp, err := j.UA.GetJSON(uri) + return GetIssueEditMeta(j.UA, j.Endpoint, issue) +} + +func GetIssueEditMeta(ua HttpClient, endpoint string, issue string) (*jiradata.EditMeta, error) { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/editmeta", endpoint, issue) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -143,13 +159,17 @@ type IssueUpdateProvider interface { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue func (j *Jira) EditIssue(issue string, iup IssueUpdateProvider) error { + return EditIssue(j.UA, j.Endpoint, issue, iup) +} + +func EditIssue(ua HttpClient, endpoint string, issue string, iup IssueUpdateProvider) error { req := iup.ProvideIssueUpdate() encoded, err := json.Marshal(req) if err != nil { return err } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s", j.Endpoint, issue) - resp, err := j.UA.Put(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s", endpoint, issue) + resp, err := ua.Put(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return err } @@ -163,13 +183,17 @@ func (j *Jira) EditIssue(issue string, iup IssueUpdateProvider) error { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-createIssue func (j *Jira) CreateIssue(iup IssueUpdateProvider) (*jiradata.IssueCreateResponse, error) { + return CreateIssue(j.UA, j.Endpoint, iup) +} + +func CreateIssue(ua HttpClient, endpoint string, iup IssueUpdateProvider) (*jiradata.IssueCreateResponse, error) { req := iup.ProvideIssueUpdate() encoded, err := json.Marshal(req) if err != nil { return nil, err } - uri := fmt.Sprintf("%s/rest/api/2/issue", j.Endpoint) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issue", endpoint) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return nil, err } @@ -184,8 +208,12 @@ func (j *Jira) CreateIssue(iup IssueUpdateProvider) (*jiradata.IssueCreateRespon // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getCreateIssueMeta func (j *Jira) GetIssueCreateMetaProject(projectKey string) (*jiradata.CreateMetaProject, error) { - uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&expand=projects.issuetypes.fields", j.Endpoint, projectKey) - resp, err := j.UA.GetJSON(uri) + return GetIssueCreateMetaProject(j.UA, j.Endpoint, projectKey) +} + +func GetIssueCreateMetaProject(ua HttpClient, endpoint string, projectKey string) (*jiradata.CreateMetaProject, error) { + uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&expand=projects.issuetypes.fields", endpoint, projectKey) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -209,8 +237,12 @@ func (j *Jira) GetIssueCreateMetaProject(projectKey string) (*jiradata.CreateMet // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getCreateIssueMeta func (j *Jira) GetIssueCreateMetaIssueType(projectKey, issueTypeName string) (*jiradata.CreateMetaIssueType, error) { - uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", j.Endpoint, projectKey, issueTypeName) - resp, err := j.UA.GetJSON(uri) + return GetIssueCreateMetaIssueType(j.UA, j.Endpoint, projectKey, issueTypeName) +} + +func GetIssueCreateMetaIssueType(ua HttpClient, endpoint string, projectKey, issueTypeName string) (*jiradata.CreateMetaIssueType, error) { + uri := fmt.Sprintf("%s/rest/api/2/issue/createmeta?projectKeys=%s&issuetypeNames=%s&expand=projects.issuetypes.fields", endpoint, projectKey, issueTypeName) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -242,13 +274,17 @@ type LinkIssueProvider interface { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issueLink-linkIssues func (j *Jira) LinkIssues(lip LinkIssueProvider) error { + return LinkIssues(j.UA, j.Endpoint, lip) +} + +func LinkIssues(ua HttpClient, endpoint string, lip LinkIssueProvider) error { req := lip.ProvideLinkIssueRequest() encoded, err := json.Marshal(req) if err != nil { return err } - uri := fmt.Sprintf("%s/rest/api/2/issueLink", j.Endpoint) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issueLink", endpoint) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return err } @@ -262,8 +298,12 @@ func (j *Jira) LinkIssues(lip LinkIssueProvider) error { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-getTransitions func (j *Jira) GetIssueTransitions(issue string) (*jiradata.TransitionsMeta, error) { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions?expand=transitions.fields", j.Endpoint, issue) - resp, err := j.UA.GetJSON(uri) + return GetIssueTransitions(j.UA, j.Endpoint, issue) +} + +func GetIssueTransitions(ua HttpClient, endpoint string, issue string) (*jiradata.TransitionsMeta, error) { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions?expand=transitions.fields", endpoint, issue) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -278,13 +318,17 @@ func (j *Jira) GetIssueTransitions(issue string) (*jiradata.TransitionsMeta, err // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-doTransition func (j *Jira) TransitionIssue(issue string, iup IssueUpdateProvider) error { + return TransitionIssue(j.UA, j.Endpoint, issue, iup) +} + +func TransitionIssue(ua HttpClient, endpoint string, issue string, iup IssueUpdateProvider) error { req := iup.ProvideIssueUpdate() encoded, err := json.Marshal(req) if err != nil { return err } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions", j.Endpoint, issue) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/transitions", endpoint, issue) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return err } @@ -298,8 +342,12 @@ func (j *Jira) TransitionIssue(issue string, iup IssueUpdateProvider) error { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issueLinkType-getIssueLinkTypes func (j *Jira) GetIssueLinkTypes() (*jiradata.IssueLinkTypes, error) { - uri := fmt.Sprintf("%s/rest/api/2/issueLinkType", j.Endpoint) - resp, err := j.UA.GetJSON(uri) + return GetIssueLinkTypes(j.UA, j.Endpoint) +} + +func GetIssueLinkTypes(ua HttpClient, endpoint string) (*jiradata.IssueLinkTypes, error) { + uri := fmt.Sprintf("%s/rest/api/2/issueLinkType", endpoint) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -318,8 +366,12 @@ func (j *Jira) GetIssueLinkTypes() (*jiradata.IssueLinkTypes, error) { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-addVote func (j *Jira) IssueAddVote(issue string) error { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", j.Endpoint, issue) - resp, err := j.UA.Post(uri, "application/json", strings.NewReader("{}")) + return IssueAddVote(j.UA, j.Endpoint, issue) +} + +func IssueAddVote(ua HttpClient, endpoint string, issue string) error { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", endpoint, issue) + resp, err := ua.Post(uri, "application/json", strings.NewReader("{}")) if err != nil { return err } @@ -333,8 +385,12 @@ func (j *Jira) IssueAddVote(issue string) error { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-removeVote func (j *Jira) IssueRemoveVote(issue string) error { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", j.Endpoint, issue) - resp, err := j.UA.Delete(uri) + return IssueRemoveVote(j.UA, j.Endpoint, issue) +} + +func IssueRemoveVote(ua HttpClient, endpoint string, issue string) error { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/votes", endpoint, issue) + resp, err := ua.Delete(uri) if err != nil { return err } @@ -352,13 +408,17 @@ type RankRequestProvider interface { // https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/issue-rankIssues func (j *Jira) RankIssues(rrp RankRequestProvider) error { + return RankIssues(j.UA, j.Endpoint, rrp) +} + +func RankIssues(ua HttpClient, endpoint string, rrp RankRequestProvider) error { req := rrp.ProvideRankRequest() encoded, err := json.Marshal(req) if err != nil { return err } - uri := fmt.Sprintf("%s/rest/agile/1.0/issue/rank", j.Endpoint) - resp, err := j.UA.Put(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/agile/1.0/issue/rank", endpoint) + resp, err := ua.Put(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return err } @@ -372,8 +432,12 @@ func (j *Jira) RankIssues(rrp RankRequestProvider) error { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-addWatcher func (j *Jira) IssueAddWatcher(issue, user string) error { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers", j.Endpoint, issue) - resp, err := j.UA.Post(uri, "application/json", strings.NewReader(fmt.Sprintf("%q", user))) + return IssueAddWatcher(j.UA, j.Endpoint, issue, user) +} + +func IssueAddWatcher(ua HttpClient, endpoint string, issue, user string) error { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers", endpoint, issue) + resp, err := ua.Post(uri, "application/json", strings.NewReader(fmt.Sprintf("%q", user))) if err != nil { return err } @@ -387,8 +451,12 @@ func (j *Jira) IssueAddWatcher(issue, user string) error { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-addWatcher func (j *Jira) IssueRemoveWatcher(issue, user string) error { - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers?username=%s", j.Endpoint, issue, user) - resp, err := j.UA.Delete(uri) + return IssueRemoveWatcher(j.UA, j.Endpoint, issue, user) +} + +func IssueRemoveWatcher(ua HttpClient, endpoint string, issue, user string) error { + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/watchers?username=%s", endpoint, issue, user) + resp, err := ua.Delete(uri) if err != nil { return err } @@ -406,13 +474,17 @@ type CommentProvider interface { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue/{issueIdOrKey}/comment-addComment func (j *Jira) IssueAddComment(issue string, cp CommentProvider) (*jiradata.Comment, error) { + return IssueAddComment(j.UA, j.Endpoint, issue, cp) +} + +func IssueAddComment(ua HttpClient, endpoint string, issue string, cp CommentProvider) (*jiradata.Comment, error) { req := cp.ProvideComment() encoded, err := json.Marshal(req) if err != nil { return nil, err } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/comment", j.Endpoint, issue) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/comment", endpoint, issue) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return nil, err } @@ -431,6 +503,10 @@ type UserProvider interface { // https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-assign func (j *Jira) IssueAssign(issue, name string) error { + return IssueAssign(j.UA, j.Endpoint, issue, name) +} + +func IssueAssign(ua HttpClient, endpoint string, issue, name string) error { // this is special, not using the jiradata.User structure // because we need to be able to send `null` as the name param // when we want to un-assign the issue @@ -445,8 +521,8 @@ func (j *Jira) IssueAssign(issue, name string) error { if err != nil { return err } - uri := fmt.Sprintf("%s/rest/api/2/issue/%s/assignee", j.Endpoint, issue) - resp, err := j.UA.Put(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/issue/%s/assignee", endpoint, issue) + resp, err := ua.Put(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return err } diff --git a/jiracli/assign.go b/jiracli/assign.go index 3e3aa68..758dcfc 100644 --- a/jiracli/assign.go +++ b/jiracli/assign.go @@ -3,34 +3,39 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type AssignOptions struct { - GlobalOptions - Issue string - Assignee string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string + Assignee string } -func (jc *JiraCli) CmdAssignRegistry() *CommandRegistryEntry { +func CmdAssignRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := AssignOptions{} return &CommandRegistryEntry{ "Assign user to issue", func() error { - return jc.CmdAssign(&opts) + return CmdAssign(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdAssignUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdAssignUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdAssignUsage(cmd *kingpin.CmdClause, opts *AssignOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdAssignUsage(cmd *kingpin.CmdClause, opts *AssignOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Flag("default", "use default user for assignee").PreAction(func(ctx *kingpin.ParseContext) error { if flagValue(ctx, "default") == "true" { opts.Assignee = "-1" @@ -43,16 +48,16 @@ func (jc *JiraCli) CmdAssignUsage(cmd *kingpin.CmdClause, opts *AssignOptions) e } // CmdAssign will assign an issue to a user -func (jc *JiraCli) CmdAssign(opts *AssignOptions) error { - err := jc.IssueAssign(opts.Issue, opts.Assignee) +func CmdAssign(o *oreo.Client, opts *AssignOptions) error { + err := jira.IssueAssign(o, opts.Endpoint.Value, opts.Issue, opts.Assignee) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil diff --git a/jiracli/block.go b/jiracli/block.go index cac4f1d..bb2dacb 100644 --- a/jiracli/block.go +++ b/jiracli/block.go @@ -4,19 +4,21 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type BlockOptions struct { - GlobalOptions - jiradata.LinkIssueRequest - Blocker string - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.LinkIssueRequest `yaml:",inline" figtree:",inline"` + Blocker string + Issue string } -func (jc *JiraCli) CmdBlockRegistry() *CommandRegistryEntry { +func CmdBlockRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := BlockOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("edit"), @@ -33,21 +35,22 @@ func (jc *JiraCli) CmdBlockRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Mark issues as blocker", func() error { - return jc.CmdBlock(&opts) + return CmdBlock(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdBlockUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdBlockUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdBlockUsage(cmd *kingpin.CmdClause, opts *BlockOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdBlockUsage(cmd *kingpin.CmdClause, opts *BlockOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("comment", "Comment message when marking issue as blocker").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { opts.Comment = &jiradata.Comment{ Body: flagValue(ctx, "comment"), @@ -61,17 +64,17 @@ func (jc *JiraCli) CmdBlockUsage(cmd *kingpin.CmdClause, opts *BlockOptions) err // CmdBlock will update the given issue as being a duplicate by the given dup issue // and will attempt to resolve the dup issue -func (jc *JiraCli) CmdBlock(opts *BlockOptions) error { - if err := jc.LinkIssues(&opts.LinkIssueRequest); err != nil { +func CmdBlock(o *oreo.Client, opts *BlockOptions) error { + if err := jira.LinkIssues(o, opts.Endpoint.Value, &opts.LinkIssueRequest); err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) - fmt.Printf("OK %s %s/browse/%s\n", opts.Blocker, jc.Endpoint, opts.Blocker) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Blocker, opts.Endpoint.Value, opts.Blocker) if opts.Browse.Value { - if err := jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}); err != nil { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Blocker}) + if err := CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}); err != nil { + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Blocker}) } } diff --git a/jiracli/browse.go b/jiracli/browse.go index 9c0bfb8..2c83567 100644 --- a/jiracli/browse.go +++ b/jiracli/browse.go @@ -3,31 +3,33 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" "github.com/pkg/browser" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type BrowseOptions struct { - GlobalOptions - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string } -func (jc *JiraCli) CmdBrowseRegistry() *CommandRegistryEntry { +func CmdBrowseRegistry(fig *figtree.FigTree) *CommandRegistryEntry { opts := BrowseOptions{} return &CommandRegistryEntry{ "Open issue in browser", func() error { - return jc.CmdBrowse(&opts) + return CmdBrowse(&opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdBrowseUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdBrowseUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdBrowseUsage(cmd *kingpin.CmdClause, opts *BrowseOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdBrowseUsage(cmd *kingpin.CmdClause, opts *BrowseOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } cmd.Arg("ISSUE", "Issue to browse to").Required().StringVar(&opts.Issue) @@ -36,6 +38,6 @@ func (jc *JiraCli) CmdBrowseUsage(cmd *kingpin.CmdClause, opts *BrowseOptions) e } // CmdBrowse open the default system browser to the provided issue -func (jc *JiraCli) CmdBrowse(opts *BrowseOptions) error { - return browser.OpenURL(fmt.Sprintf("%s/browse/%s", jc.Endpoint, opts.Issue)) +func CmdBrowse(opts *BrowseOptions) error { + return browser.OpenURL(fmt.Sprintf("%s/browse/%s", opts.Endpoint.Value, opts.Issue)) } diff --git a/jiracli/cli.go b/jiracli/cli.go index 14804fe..e67cc82 100644 --- a/jiracli/cli.go +++ b/jiracli/cli.go @@ -7,17 +7,13 @@ import ( "io/ioutil" "os" "os/exec" - "path" - "path/filepath" "reflect" "strings" "github.com/AlecAivazis/survey" "github.com/coryb/figtree" - "github.com/coryb/oreo" "github.com/jinzhu/copier" shellquote "github.com/kballard/go-shellquote" - jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" yaml "gopkg.in/coryb/yaml.v2" logging "gopkg.in/op/go-logging.v1" @@ -25,11 +21,11 @@ import ( var log = logging.MustGetLogger("jira") -type JiraCli struct { - jira.Jira `yaml:",inline"` - ConfigDir string - oreoAgent *oreo.Client -} +// type JiraCli struct { +// jira.Jira `yaml:",inline"` +// ConfigDir string +// oreoAgent *oreo.Client +// } type Exit struct { Code int @@ -38,10 +34,11 @@ type Exit struct { type GlobalOptions struct { Browse figtree.BoolOption `json:"browse,omitempty" yaml:"browse,omitempty"` Editor figtree.StringOption `json:"editor,omitempty" yaml:"editor,omitempty"` + Endpoint figtree.StringOption `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` SkipEditing figtree.BoolOption `json:"noedit,omitempty" yaml:"noedit,omitempty"` PasswordSource figtree.StringOption `json:"password-source,omitempty" yaml:"password-source,omitempty"` Template figtree.StringOption `json:"template,omitempty" yaml:"template,omitempty"` - User figtree.StringOption `json:"user,omitempty", yaml:"user,omitempty"` + User figtree.StringOption `json:"user,omitempty" yaml:"user,omitempty"` } type CommandRegistryEntry struct { @@ -63,18 +60,18 @@ type kingpinAppOrCommand interface { GetCommand(string) *kingpin.CmdClause } -func New(configDir string) *JiraCli { - agent := oreo.New().WithCookieFile(filepath.Join(homedir(), configDir, "cookies.js")) - return &JiraCli{ - ConfigDir: configDir, - Jira: jira.Jira{ - UA: agent, - }, - oreoAgent: agent, - } -} +// func New(configDir string) *JiraCli { +// agent := oreo.New().WithCookieFile(filepath.Join(homedir(), configDir, "cookies.js")) +// return &JiraCli{ +// ConfigDir: configDir, +// Jira: jira.Jira{ +// UA: agent, +// }, +// oreoAgent: agent, +// } +// } -func (jc *JiraCli) Register(app *kingpin.Application, reg []CommandRegistry) { +func Register(app *kingpin.Application, reg []CommandRegistry) { for _, command := range reg { copy := command commandFields := strings.Fields(copy.Command) @@ -108,50 +105,39 @@ func (jc *JiraCli) Register(app *kingpin.Application, reg []CommandRegistry) { } } -func (jc *JiraCli) GlobalUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) error { - jc.LoadConfigs(cmd, opts) +func GlobalUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) error { cmd.PreAction(func(_ *kingpin.ParseContext) error { - os.Setenv("JIRA_OPERATION", cmd.FullCommand()) - fig := figtree.NewFigTree() - fig.EnvPrefix = "JIRA" - // populate JiraCli fields if defined in configs (ie for Endpoint) - if err := fig.LoadAllConfigs(path.Join(jc.ConfigDir, "config.yml"), jc); err != nil { - return err - } if opts.User.Value == "" { opts.User = figtree.NewStringOption(os.Getenv("USER")) } return nil }) - cmd.Flag("endpoint", "URI to use for Jira").Short('e').StringVar(&jc.Endpoint) - cmd.Flag("user", "Login mame used for authentication with Jira service").Short('u').SetValue(&opts.User) + cmd.Flag("endpoint", "Base URI to use for Jira").Short('e').SetValue(&opts.Endpoint) + cmd.Flag("user", "Login name used for authentication with Jira service").Short('u').SetValue(&opts.User) return nil } -func (jc *JiraCli) LoadConfigs(cmd *kingpin.CmdClause, opts interface{}) { +func LoadConfigs(cmd *kingpin.CmdClause, fig *figtree.FigTree, opts interface{}) { cmd.PreAction(func(_ *kingpin.ParseContext) error { os.Setenv("JIRA_OPERATION", cmd.FullCommand()) - fig := figtree.NewFigTree() - fig.EnvPrefix = "JIRA" - fig.Defaults = opts // load command specific configs first - if err := fig.LoadAllConfigs(path.Join(jc.ConfigDir, strings.Join(strings.Fields(cmd.FullCommand()), "_")+".yml"), opts); err != nil { + if err := fig.LoadAllConfigs(strings.Join(strings.Fields(cmd.FullCommand()), "_")+".yml", opts); err != nil { return err } // then load generic configs if not already populated above - return fig.LoadAllConfigs(path.Join(jc.ConfigDir, "config.yml"), opts) + return fig.LoadAllConfigs("config.yml", opts) }) } -func (jc *JiraCli) BrowseUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) { +func BrowseUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) { cmd.Flag("browse", "Open issue(s) in browser after operation").Short('b').SetValue(&opts.Browse) } -func (jc *JiraCli) EditorUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) { +func EditorUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) { cmd.Flag("editor", "Editor to use").SetValue(&opts.Editor) } -func (jc *JiraCli) TemplateUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) { +func TemplateUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) { cmd.Flag("template", "Template to use for output").Short('t').SetValue(&opts.Template) } @@ -218,8 +204,8 @@ func (o *GlobalOptions) editFile(fileName string) (changes bool, err error) { return false, err } -func (jc *JiraCli) editLoop(opts *GlobalOptions, input interface{}, output interface{}, submit func() error) error { - tmpFile, err := jc.tmpTemplate(opts.Template.Value, input) +func editLoop(opts *GlobalOptions, input interface{}, output interface{}, submit func() error) error { + tmpFile, err := tmpTemplate(opts.Template.Value, input) if err != nil { return err } diff --git a/jiracli/comment.go b/jiracli/comment.go index c29ae98..c94505c 100644 --- a/jiracli/comment.go +++ b/jiracli/comment.go @@ -4,18 +4,20 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type CommentOptions struct { - GlobalOptions - Overrides map[string]string - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + Overrides map[string]string + Issue string } -func (jc *JiraCli) CmdCommentRegistry() *CommandRegistryEntry { +func CmdCommentRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := CommentOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("comment"), @@ -26,21 +28,22 @@ func (jc *JiraCli) CmdCommentRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Add comment to issue", func() error { - return jc.CmdComment(&opts) + return CmdComment(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdCommentUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdCommentUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdCommentUsage(cmd *kingpin.CmdClause, opts *CommentOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdCommentUsage(cmd *kingpin.CmdClause, opts *CommentOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { opts.Overrides["comment"] = flagValue(ctx, "comment") return nil @@ -50,25 +53,25 @@ func (jc *JiraCli) CmdCommentUsage(cmd *kingpin.CmdClause, opts *CommentOptions) } // CmdComment will update issue with comment -func (jc *JiraCli) CmdComment(opts *CommentOptions) error { +func CmdComment(o *oreo.Client, opts *CommentOptions) error { comment := jiradata.Comment{} input := struct { Overrides map[string]string }{ opts.Overrides, } - err := jc.editLoop(&opts.GlobalOptions, &input, &comment, func() error { - _, err := jc.IssueAddComment(opts.Issue, &comment) + err := editLoop(&opts.GlobalOptions, &input, &comment, func() error { + _, err := jira.IssueAddComment(o, opts.Endpoint.Value, opts.Issue, &comment) return err }) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil diff --git a/jiracli/componentAdd.go b/jiracli/componentAdd.go index e5883fc..b1733bc 100644 --- a/jiracli/componentAdd.go +++ b/jiracli/componentAdd.go @@ -4,17 +4,19 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type ComponentAddOptions struct { - GlobalOptions - jiradata.Component + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.Component `yaml:",inline" figtree:",inline"` } -func (jc *JiraCli) CmdComponentAddRegistry() *CommandRegistryEntry { +func CmdComponentAddRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := ComponentAddOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("component-add"), @@ -24,20 +26,21 @@ func (jc *JiraCli) CmdComponentAddRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Add component", func() error { - return jc.CmdComponentAdd(&opts) + return CmdComponentAdd(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdComponentAddUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdComponentAddUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdComponentAddUsage(cmd *kingpin.CmdClause, opts *ComponentAddOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdComponentAddUsage(cmd *kingpin.CmdClause, opts *ComponentAddOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing) cmd.Flag("project", "project to create component in").Short('p').StringVar(&opts.Project) cmd.Flag("name", "name of component").Short('n').StringVar(&opts.Name) @@ -48,12 +51,12 @@ func (jc *JiraCli) CmdComponentAddUsage(cmd *kingpin.CmdClause, opts *ComponentA // CmdComponentAdd sends the provided overrides to the "component-add" template for editing, then // will parse the edited document as YAML and submit the document to jira. -func (jc *JiraCli) CmdComponentAdd(opts *ComponentAddOptions) error { +func CmdComponentAdd(o *oreo.Client, opts *ComponentAddOptions) error { var err error component := &jiradata.Component{} var resp *jiradata.Component - err = jc.editLoop(&opts.GlobalOptions, &opts.Component, component, func() error { - resp, err = jc.CreateComponent(component) + err = editLoop(&opts.GlobalOptions, &opts.Component, component, func() error { + resp, err = jira.CreateComponent(o, opts.Endpoint.Value, component) return err }) if err != nil { diff --git a/jiracli/components.go b/jiracli/components.go index cdd9f33..2de11b5 100644 --- a/jiracli/components.go +++ b/jiracli/components.go @@ -4,16 +4,18 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type ComponentsOptions struct { - GlobalOptions - Project string + GlobalOptions `yaml:",inline" figtree:",inline"` + Project string } -func (jc *JiraCli) CmdComponentsRegistry() *CommandRegistryEntry { +func CmdComponentsRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := ComponentsOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("components"), @@ -23,32 +25,33 @@ func (jc *JiraCli) CmdComponentsRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Show components for a project", func() error { - return jc.CmdComponents(&opts) + return CmdComponents(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdComponentsUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdComponentsUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdComponentsUsage(cmd *kingpin.CmdClause, opts *ComponentsOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdComponentsUsage(cmd *kingpin.CmdClause, opts *ComponentsOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.TemplateUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("project", "project to list components").Short('p').StringVar(&opts.Project) return nil } // CmdComponents will get available components for project and send to the "components" template -func (jc *JiraCli) CmdComponents(opts *ComponentsOptions) error { +func CmdComponents(o *oreo.Client, opts *ComponentsOptions) error { if opts.Project == "" { return fmt.Errorf("Project Required.") } - data, err := jc.GetProjectComponents(opts.Project) + data, err := jira.GetProjectComponents(o, opts.Endpoint.Value, opts.Project) if err != nil { return err } - return jc.runTemplate(opts.Template.Value, data, nil) + return runTemplate(opts.Template.Value, data, nil) } diff --git a/jiracli/create.go b/jiracli/create.go index 9c03bef..ee1a95f 100644 --- a/jiracli/create.go +++ b/jiracli/create.go @@ -4,20 +4,22 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type CreateOptions struct { - GlobalOptions - jiradata.IssueUpdate - Project string - IssueType string - Overrides map[string]string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.IssueUpdate `yaml:",inline" figtree:",inline"` + Project string + IssueType string + Overrides map[string]string } -func (jc *JiraCli) CmdCreateRegistry() *CommandRegistryEntry { +func CmdCreateRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := CreateOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("create"), @@ -28,21 +30,22 @@ func (jc *JiraCli) CmdCreateRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Create issue", func() error { - return jc.CmdCreate(&opts) + return CmdCreate(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdCreateUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdCreateUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdCreateUsage(cmd *kingpin.CmdClause, opts *CreateOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdCreateUsage(cmd *kingpin.CmdClause, opts *CreateOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing) cmd.Flag("project", "project to create issue in").Short('p').StringVar(&opts.Project) cmd.Flag("issuetype", "issuetype in to create").Short('i').StringVar(&opts.IssueType) @@ -56,16 +59,16 @@ func (jc *JiraCli) CmdCreateUsage(cmd *kingpin.CmdClause, opts *CreateOptions) e // CmdCreate sends the create-metadata to the "create" template for editing, then // will parse the edited document as YAML and submit the document to jira. -func (jc *JiraCli) CmdCreate(opts *CreateOptions) error { +func CmdCreate(o *oreo.Client, opts *CreateOptions) error { type templateInput struct { Meta *jiradata.CreateMetaIssueType `yaml:"meta" json:"meta"` Overrides map[string]string `yaml:"overrides" json:"overrides"` } - if err := jc.defaultIssueType(&opts.Project, &opts.IssueType); err != nil { + if err := defaultIssueType(o, opts.Endpoint.Value, &opts.Project, &opts.IssueType); err != nil { return err } - createMeta, err := jc.GetIssueCreateMetaIssueType(opts.Project, opts.IssueType) + createMeta, err := jira.GetIssueCreateMetaIssueType(o, opts.Endpoint.Value, opts.Project, opts.IssueType) if err != nil { return err } @@ -80,30 +83,30 @@ func (jc *JiraCli) CmdCreate(opts *CreateOptions) error { input.Overrides["user"] = opts.User.Value var issueResp *jiradata.IssueCreateResponse - err = jc.editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { - issueResp, err = jc.CreateIssue(&issueUpdate) + err = editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { + issueResp, err = jira.CreateIssue(o, opts.Endpoint.Value, &issueUpdate) return err }) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", issueResp.Key, jc.Endpoint, issueResp.Key) + fmt.Printf("OK %s %s/browse/%s\n", issueResp.Key, opts.Endpoint.Value, issueResp.Key) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, issueResp.Key}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, issueResp.Key}) } return nil } -func (jc *JiraCli) defaultIssueType(project, issuetype *string) error { +func defaultIssueType(o *oreo.Client, endpoint string, project, issuetype *string) error { if project == nil || *project == "" { return fmt.Errorf("Project undefined, please use --project argument or set the `project` config property") } if issuetype != nil && *issuetype != "" { return nil } - projectMeta, err := jc.GetIssueCreateMetaProject(*project) + projectMeta, err := jira.GetIssueCreateMetaProject(o, endpoint, *project) if err != nil { return err } diff --git a/jiracli/createmeta.go b/jiracli/createmeta.go index daeaaa7..73b4486 100644 --- a/jiracli/createmeta.go +++ b/jiracli/createmeta.go @@ -2,16 +2,18 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type CreateMetaOptions struct { - GlobalOptions - Project string `yaml:"project,omitempty" json:"project,omitempty"` - IssueType string `yaml:"issuetype,omitempty" json:"issuetype,omitempty"` + GlobalOptions `yaml:",inline" figtree:",inline"` + Project string `yaml:"project,omitempty" json:"project,omitempty"` + IssueType string `yaml:"issuetype,omitempty" json:"issuetype,omitempty"` } -func (jc *JiraCli) CmdCreateMetaRegistry() *CommandRegistryEntry { +func CmdCreateMetaRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := CreateMetaOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("createmeta"), @@ -21,32 +23,33 @@ func (jc *JiraCli) CmdCreateMetaRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "View 'create' metadata", func() error { - return jc.CmdCreateMeta(&opts) + return CmdCreateMeta(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdCreateMetaUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdCreateMetaUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdCreateMetaUsage(cmd *kingpin.CmdClause, opts *CreateMetaOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdCreateMetaUsage(cmd *kingpin.CmdClause, opts *CreateMetaOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.TemplateUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("project", "project to fetch create metadata").Short('p').StringVar(&opts.Project) cmd.Flag("issuetype", "issuetype in project to fetch create metadata").Short('i').StringVar(&opts.IssueType) return nil } // Create will get issue create metadata and send to "createmeta" template -func (jc *JiraCli) CmdCreateMeta(opts *CreateMetaOptions) error { - if err := jc.defaultIssueType(&opts.Project, &opts.IssueType); err != nil { +func CmdCreateMeta(o *oreo.Client, opts *CreateMetaOptions) error { + if err := defaultIssueType(o, opts.Endpoint.Value, &opts.Project, &opts.IssueType); err != nil { return err } - createMeta, err := jc.GetIssueCreateMetaIssueType(opts.Project, opts.IssueType) + createMeta, err := jira.GetIssueCreateMetaIssueType(o, opts.Endpoint.Value, opts.Project, opts.IssueType) if err != nil { return err } - return jc.runTemplate(opts.Template.Value, createMeta, nil) + return runTemplate(opts.Template.Value, createMeta, nil) } diff --git a/jiracli/dup.go b/jiracli/dup.go index 316537b..33c9148 100644 --- a/jiracli/dup.go +++ b/jiracli/dup.go @@ -4,19 +4,21 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type DupOptions struct { - GlobalOptions - jiradata.LinkIssueRequest - Duplicate string - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.LinkIssueRequest `yaml:",inline" figtree:",inline"` + Duplicate string + Issue string } -func (jc *JiraCli) CmdDupRegistry() *CommandRegistryEntry { +func CmdDupRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := DupOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("edit"), @@ -33,21 +35,22 @@ func (jc *JiraCli) CmdDupRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Mark issues as duplicate", func() error { - return jc.CmdDup(&opts) + return CmdDup(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdDupUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdDupUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdDupUsage(cmd *kingpin.CmdClause, opts *DupOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdDupUsage(cmd *kingpin.CmdClause, opts *DupOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("comment", "Comment message when marking issue as duplicate").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { opts.Comment = &jiradata.Comment{ Body: flagValue(ctx, "comment"), @@ -61,13 +64,13 @@ func (jc *JiraCli) CmdDupUsage(cmd *kingpin.CmdClause, opts *DupOptions) error { // CmdDups will update the given issue as being a duplicate by the given dup issue // and will attempt to resolve the dup issue -func (jc *JiraCli) CmdDup(opts *DupOptions) error { - if err := jc.LinkIssues(&opts.LinkIssueRequest); err != nil { +func CmdDup(o *oreo.Client, opts *DupOptions) error { + if err := jira.LinkIssues(o, opts.Endpoint.Value, &opts.LinkIssueRequest); err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, jc.Endpoint, opts.OutwardIssue.Key) + fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, opts.Endpoint.Value, opts.OutwardIssue.Key) - meta, err := jc.GetIssueTransitions(opts.InwardIssue.Key) + meta, err := jira.GetIssueTransitions(o, opts.Endpoint.Value, opts.InwardIssue.Key) if err != nil { return err } @@ -77,7 +80,7 @@ func (jc *JiraCli) CmdDup(opts *DupOptions) error { issueUpdate := jiradata.IssueUpdate{ Transition: transMeta, } - if err = jc.TransitionIssue(opts.InwardIssue.Key, &issueUpdate); err != nil { + if err = jira.TransitionIssue(o, opts.Endpoint.Value, opts.InwardIssue.Key, &issueUpdate); err != nil { return err } // if we just started the issue now we need to stop it @@ -87,12 +90,12 @@ func (jc *JiraCli) CmdDup(opts *DupOptions) error { } } - fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, jc.Endpoint, opts.OutwardIssue.Key) - fmt.Printf("OK %s %s/browse/%s\n", opts.InwardIssue.Key, jc.Endpoint, opts.InwardIssue.Key) + fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, opts.Endpoint.Value, opts.OutwardIssue.Key) + fmt.Printf("OK %s %s/browse/%s\n", opts.InwardIssue.Key, opts.Endpoint.Value, opts.InwardIssue.Key) if opts.Browse.Value { - if err := jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.OutwardIssue.Key}); err != nil { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.InwardIssue.Key}) + if err := CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.OutwardIssue.Key}); err != nil { + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.InwardIssue.Key}) } } diff --git a/jiracli/edit.go b/jiracli/edit.go index fd9ded4..636895d 100644 --- a/jiracli/edit.go +++ b/jiracli/edit.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" @@ -11,14 +12,14 @@ import ( ) type EditOptions struct { - GlobalOptions - jiradata.IssueUpdate - jira.SearchOptions - Overrides map[string]string - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.IssueUpdate `yaml:",inline" figtree:",inline"` + jira.SearchOptions `yaml:",inline" figtree:",inline"` + Overrides map[string]string + Issue string } -func (jc *JiraCli) CmdEditRegistry() *CommandRegistryEntry { +func CmdEditRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := EditOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("edit"), @@ -29,21 +30,22 @@ func (jc *JiraCli) CmdEditRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Edit issue details", func() error { - return jc.CmdEdit(&opts) + return CmdEdit(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdEditUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdEditUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing) cmd.Flag("query", "Jira Query Language (JQL) expression for the search to edit multiple issues").Short('q').StringVar(&opts.Query) cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { @@ -56,18 +58,18 @@ func (jc *JiraCli) CmdEditUsage(cmd *kingpin.CmdClause, opts *EditOptions) error } // Edit will get issue data and send to "edit" template -func (jc *JiraCli) CmdEdit(opts *EditOptions) error { +func CmdEdit(o *oreo.Client, opts *EditOptions) error { type templateInput struct { *jiradata.Issue `yaml:",inline"` Meta *jiradata.EditMeta `yaml:"meta" json:"meta"` Overrides map[string]string `yaml:"overrides" json:"overrides"` } if opts.Issue != "" { - issueData, err := jc.GetIssue(opts.Issue, nil) + issueData, err := jira.GetIssue(o, opts.Endpoint.Value, opts.Issue, nil) if err != nil { return err } - editMeta, err := jc.GetIssueEditMeta(opts.Issue) + editMeta, err := jira.GetIssueEditMeta(o, opts.Endpoint.Value, opts.Issue) if err != nil { return err } @@ -78,24 +80,24 @@ func (jc *JiraCli) CmdEdit(opts *EditOptions) error { Meta: editMeta, Overrides: opts.Overrides, } - err = jc.editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { - return jc.EditIssue(opts.Issue, &issueUpdate) + err = editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { + return jira.EditIssue(o, opts.Endpoint.Value, opts.Issue, &issueUpdate) }) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } } - results, err := jc.Search(opts) + results, err := jira.Search(o, opts.Endpoint.Value, opts) if err != nil { return err } for _, issueData := range results.Issues { - editMeta, err := jc.GetIssueEditMeta(issueData.Key) + editMeta, err := jira.GetIssueEditMeta(o, opts.Endpoint.Value, issueData.Key) if err != nil { return err } @@ -105,16 +107,16 @@ func (jc *JiraCli) CmdEdit(opts *EditOptions) error { Issue: issueData, Meta: editMeta, } - err = jc.editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { - return jc.EditIssue(issueData.Key, &issueUpdate) + err = editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { + return jira.EditIssue(o, opts.Endpoint.Value, issueData.Key, &issueUpdate) }) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", issueData.Key, jc.Endpoint, issueData.Key) + fmt.Printf("OK %s %s/browse/%s\n", issueData.Key, opts.Endpoint.Value, issueData.Key) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, issueData.Key}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, issueData.Key}) } } return nil diff --git a/jiracli/editmeta.go b/jiracli/editmeta.go index 7ed0e5f..cc56bdc 100644 --- a/jiracli/editmeta.go +++ b/jiracli/editmeta.go @@ -2,15 +2,17 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type EditMetaOptions struct { - GlobalOptions - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string } -func (jc *JiraCli) CmdEditMetaRegistry() *CommandRegistryEntry { +func CmdEditMetaRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := EditMetaOptions{ GlobalOptions: GlobalOptions{ @@ -21,35 +23,36 @@ func (jc *JiraCli) CmdEditMetaRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "View 'edit' metadata", func() error { - return jc.CmdEditMeta(&opts) + return CmdEditMeta(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdEditMetaUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdEditMetaUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdEditMetaUsage(cmd *kingpin.CmdClause, opts *EditMetaOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdEditMetaUsage(cmd *kingpin.CmdClause, opts *EditMetaOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "edit metadata for issue id").Required().StringVar(&opts.Issue) return nil } // EditMeta will get issue edit metadata and send to "editmeta" template -func (jc *JiraCli) CmdEditMeta(opts *EditMetaOptions) error { - editMeta, err := jc.GetIssueEditMeta(opts.Issue) +func CmdEditMeta(o *oreo.Client, opts *EditMetaOptions) error { + editMeta, err := jira.GetIssueEditMeta(o, opts.Endpoint.Value, opts.Issue) if err != nil { return err } - if err := jc.runTemplate(opts.Template.Value, editMeta, nil); err != nil { + if err := runTemplate(opts.Template.Value, editMeta, nil); err != nil { return err } if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/exportTemplates.go b/jiracli/exportTemplates.go index 9930e3a..18df0ef 100644 --- a/jiracli/exportTemplates.go +++ b/jiracli/exportTemplates.go @@ -5,6 +5,8 @@ import ( "os" "path" + "github.com/coryb/figtree" + kingpin "gopkg.in/alecthomas/kingpin.v2" ) @@ -13,23 +15,24 @@ type ExportTemplatesOptions struct { Dir string } -func (jc *JiraCli) CmdExportTemplatesRegistry() *CommandRegistryEntry { +func CmdExportTemplatesRegistry(fig *figtree.FigTree) *CommandRegistryEntry { opts := ExportTemplatesOptions{ - Dir: fmt.Sprintf("%s/.jira.d/templates", homedir()), + Dir: fmt.Sprintf("%s/.jira.d/templates", Homedir()), } return &CommandRegistryEntry{ "Export templates for customizations", func() error { - return jc.CmdExportTemplates(&opts) + return CmdExportTemplates(&opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdExportTemplatesUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdExportTemplatesUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdExportTemplatesUsage(cmd *kingpin.CmdClause, opts *ExportTemplatesOptions) error { +func CmdExportTemplatesUsage(cmd *kingpin.CmdClause, opts *ExportTemplatesOptions) error { cmd.Flag("template", "Template to export").Short('t').StringVar(&opts.Template) cmd.Flag("dir", "directory to write tempates to").Short('d').StringVar(&opts.Dir) @@ -37,7 +40,7 @@ func (jc *JiraCli) CmdExportTemplatesUsage(cmd *kingpin.CmdClause, opts *ExportT } // CmdExportTemplates will export templates to directory -func (jc *JiraCli) CmdExportTemplates(opts *ExportTemplatesOptions) error { +func CmdExportTemplates(opts *ExportTemplatesOptions) error { if err := os.MkdirAll(opts.Dir, 0755); err != nil { return err } diff --git a/jiracli/fields.go b/jiracli/fields.go index 061e2cc..4c506a1 100644 --- a/jiracli/fields.go +++ b/jiracli/fields.go @@ -2,31 +2,34 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) -func (jc *JiraCli) CmdFieldsRegistry() *CommandRegistryEntry { +func CmdFieldsRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := GlobalOptions{ Template: figtree.NewStringOption("fields"), } return &CommandRegistryEntry{ "Prints all fields, both System and Custom", func() error { - return jc.CmdFields(&opts) + return CmdFields(o, &opts) }, func(cmd *kingpin.CmdClause) error { - err := jc.GlobalUsage(cmd, &opts) - jc.TemplateUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + err := GlobalUsage(cmd, &opts) + TemplateUsage(cmd, &opts) return err }, } } // Fields will send data from /rest/api/2/field API to "fields" template -func (jc *JiraCli) CmdFields(opts *GlobalOptions) error { - data, err := jc.GetFields() +func CmdFields(o *oreo.Client, opts *GlobalOptions) error { + data, err := jira.GetFields(o, opts.Endpoint.Value) if err != nil { return err } - return jc.runTemplate(opts.Template.Value, data, nil) + return runTemplate(opts.Template.Value, data, nil) } diff --git a/jiracli/issuelink.go b/jiracli/issuelink.go index 0d30187..d128e6d 100644 --- a/jiracli/issuelink.go +++ b/jiracli/issuelink.go @@ -3,17 +3,21 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type IssueLinkOptions struct { - GlobalOptions - jiradata.LinkIssueRequest - LinkType string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.LinkIssueRequest `yaml:",inline" figtree:",inline"` + LinkType string } -func (jc *JiraCli) CmdIssueLinkRegistry() *CommandRegistryEntry { +func CmdIssueLinkRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := IssueLinkOptions{ LinkIssueRequest: jiradata.LinkIssueRequest{ Type: &jiradata.IssueLinkType{}, @@ -24,21 +28,22 @@ func (jc *JiraCli) CmdIssueLinkRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Link two issues", func() error { - return jc.CmdIssueLink(&opts) + return CmdIssueLink(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdIssueLinkUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdIssueLinkUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdIssueLinkUsage(cmd *kingpin.CmdClause, opts *IssueLinkOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdIssueLinkUsage(cmd *kingpin.CmdClause, opts *IssueLinkOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("comment", "Comment message when linking issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { opts.Comment = &jiradata.Comment{ Body: flagValue(ctx, "comment"), @@ -53,17 +58,17 @@ func (jc *JiraCli) CmdIssueLinkUsage(cmd *kingpin.CmdClause, opts *IssueLinkOpti // CmdBlock will update the given issue as being a duplicate by the given dup issue // and will attempt to resolve the dup issue -func (jc *JiraCli) CmdIssueLink(opts *IssueLinkOptions) error { - if err := jc.LinkIssues(&opts.LinkIssueRequest); err != nil { +func CmdIssueLink(o *oreo.Client, opts *IssueLinkOptions) error { + if err := jira.LinkIssues(o, opts.Endpoint.Value, &opts.LinkIssueRequest); err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.InwardIssue.Key, jc.Endpoint, opts.InwardIssue.Key) - fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, jc.Endpoint, opts.OutwardIssue.Key) + fmt.Printf("OK %s %s/browse/%s\n", opts.InwardIssue.Key, opts.Endpoint.Value, opts.InwardIssue.Key) + fmt.Printf("OK %s %s/browse/%s\n", opts.OutwardIssue.Key, opts.Endpoint.Value, opts.OutwardIssue.Key) if opts.Browse.Value { - if err := jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.OutwardIssue.Key}); err != nil { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.InwardIssue.Key}) + if err := CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.OutwardIssue.Key}); err != nil { + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.InwardIssue.Key}) } } diff --git a/jiracli/issuelinktypes.go b/jiracli/issuelinktypes.go index b214e37..f529a94 100644 --- a/jiracli/issuelinktypes.go +++ b/jiracli/issuelinktypes.go @@ -2,10 +2,12 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) -func (jc *JiraCli) CmdIssueLinkTypesRegistry() *CommandRegistryEntry { +func CmdIssueLinkTypesRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := GlobalOptions{ Template: figtree.NewStringOption("issuelinktypes"), } @@ -13,27 +15,28 @@ func (jc *JiraCli) CmdIssueLinkTypesRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Show the issue link types", func() error { - return jc.CmdIssueLinkTypes(&opts) + return CmdIssueLinkTypes(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdIssueLinkTypesUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdIssueLinkTypesUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdIssueLinkTypesUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) error { - if err := jc.GlobalUsage(cmd, opts); err != nil { +func CmdIssueLinkTypesUsage(cmd *kingpin.CmdClause, opts *GlobalOptions) error { + if err := GlobalUsage(cmd, opts); err != nil { return err } - jc.TemplateUsage(cmd, opts) + TemplateUsage(cmd, opts) return nil } // CmdIssueLinkTypes will get issue link type data and send to "issuelinktypes" template -func (jc *JiraCli) CmdIssueLinkTypes(opts *GlobalOptions) error { - data, err := jc.GetIssueLinkTypes() +func CmdIssueLinkTypes(o *oreo.Client, opts *GlobalOptions) error { + data, err := jira.GetIssueLinkTypes(o, opts.Endpoint.Value) if err != nil { return err } - return jc.runTemplate(opts.Template.Value, data, nil) + return runTemplate(opts.Template.Value, data, nil) } diff --git a/jiracli/issuetypes.go b/jiracli/issuetypes.go index 269f7b5..15fc8e9 100644 --- a/jiracli/issuetypes.go +++ b/jiracli/issuetypes.go @@ -4,16 +4,18 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type IssueTypesOptions struct { - GlobalOptions - Project string + GlobalOptions `yaml:",inline" figtree:",inline"` + Project string } -func (jc *JiraCli) CmdIssueTypesRegistry() *CommandRegistryEntry { +func CmdIssueTypesRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := IssueTypesOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("issuetypes"), @@ -23,32 +25,33 @@ func (jc *JiraCli) CmdIssueTypesRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Show issue types for a project", func() error { - return jc.CmdIssueTypes(&opts) + return CmdIssueTypes(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdIssueTypesUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdIssueTypesUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdIssueTypesUsage(cmd *kingpin.CmdClause, opts *IssueTypesOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdIssueTypesUsage(cmd *kingpin.CmdClause, opts *IssueTypesOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.TemplateUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("project", "project to list issueTypes").Short('p').StringVar(&opts.Project) return nil } // CmdIssueTypes will get available issueTypes for project and send to the "issueTypes" template -func (jc *JiraCli) CmdIssueTypes(opts *IssueTypesOptions) error { +func CmdIssueTypes(o *oreo.Client, opts *IssueTypesOptions) error { if opts.Project == "" { return fmt.Errorf("Project Required.") } - data, err := jc.GetIssueCreateMetaProject(opts.Project) + data, err := jira.GetIssueCreateMetaProject(o, opts.Endpoint.Value, opts.Project) if err != nil { return err } - return jc.runTemplate(opts.Template.Value, data, nil) + return runTemplate(opts.Template.Value, data, nil) } diff --git a/jiracli/labelsAdd.go b/jiracli/labelsAdd.go index 8aaa999..944c6ef 100644 --- a/jiracli/labelsAdd.go +++ b/jiracli/labelsAdd.go @@ -3,41 +3,46 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type LabelsAddOptions struct { - GlobalOptions - Issue string - Labels []string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string + Labels []string } -func (jc *JiraCli) CmdLabelsAddRegistry() *CommandRegistryEntry { +func CmdLabelsAddRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := LabelsAddOptions{} return &CommandRegistryEntry{ "Add labels to an issue", func() error { - return jc.CmdLabelsAdd(&opts) + return CmdLabelsAdd(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdLabelsAddUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdLabelsAddUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdLabelsAddUsage(cmd *kingpin.CmdClause, opts *LabelsAddOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdLabelsAddUsage(cmd *kingpin.CmdClause, opts *LabelsAddOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue id to modify labels").Required().StringVar(&opts.Issue) cmd.Arg("LABEL", "label to add to issue").Required().StringsVar(&opts.Labels) return nil } // CmdLabels will add labels on a given issue -func (jc *JiraCli) CmdLabelsAdd(opts *LabelsAddOptions) error { +func CmdLabelsAdd(o *oreo.Client, opts *LabelsAddOptions) error { ops := jiradata.FieldOperations{} for _, label := range opts.Labels { ops = append(ops, jiradata.FieldOperation{ @@ -50,12 +55,12 @@ func (jc *JiraCli) CmdLabelsAdd(opts *LabelsAddOptions) error { }, } - if err := jc.EditIssue(opts.Issue, &issueUpdate); err != nil { + if err := jira.EditIssue(o, opts.Endpoint.Value, opts.Issue, &issueUpdate); err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/labelsRemove.go b/jiracli/labelsRemove.go index bd5df20..170458e 100644 --- a/jiracli/labelsRemove.go +++ b/jiracli/labelsRemove.go @@ -3,41 +3,46 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type LabelsRemoveOptions struct { - GlobalOptions - Issue string - Labels []string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string + Labels []string } -func (jc *JiraCli) CmdLabelsRemoveRegistry() *CommandRegistryEntry { +func CmdLabelsRemoveRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := LabelsRemoveOptions{} return &CommandRegistryEntry{ "Remove labels from an issue", func() error { - return jc.CmdLabelsRemove(&opts) + return CmdLabelsRemove(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdLabelsRemoveUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdLabelsRemoveUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdLabelsRemoveUsage(cmd *kingpin.CmdClause, opts *LabelsRemoveOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdLabelsRemoveUsage(cmd *kingpin.CmdClause, opts *LabelsRemoveOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue id to modify labels").Required().StringVar(&opts.Issue) cmd.Arg("LABEL", "label to remove from issue").Required().StringsVar(&opts.Labels) return nil } // CmdLabels will remove labels on a given issue -func (jc *JiraCli) CmdLabelsRemove(opts *LabelsRemoveOptions) error { +func CmdLabelsRemove(o *oreo.Client, opts *LabelsRemoveOptions) error { ops := jiradata.FieldOperations{} for _, label := range opts.Labels { ops = append(ops, jiradata.FieldOperation{ @@ -50,13 +55,13 @@ func (jc *JiraCli) CmdLabelsRemove(opts *LabelsRemoveOptions) error { }, } - err := jc.EditIssue(opts.Issue, &issueUpdate) + err := jira.EditIssue(o, opts.Endpoint.Value, opts.Issue, &issueUpdate) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/labelsSet.go b/jiracli/labelsSet.go index d6c7866..ea3d923 100644 --- a/jiracli/labelsSet.go +++ b/jiracli/labelsSet.go @@ -3,41 +3,46 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type LabelsSetOptions struct { - GlobalOptions - Issue string - Labels []string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string + Labels []string } -func (jc *JiraCli) CmdLabelsSetRegistry() *CommandRegistryEntry { +func CmdLabelsSetRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := LabelsSetOptions{} return &CommandRegistryEntry{ "Set labels on an issue", func() error { - return jc.CmdLabelsSet(&opts) + return CmdLabelsSet(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdLabelsSetUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdLabelsSetUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdLabelsSetUsage(cmd *kingpin.CmdClause, opts *LabelsSetOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdLabelsSetUsage(cmd *kingpin.CmdClause, opts *LabelsSetOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue id to modify labels").Required().StringVar(&opts.Issue) cmd.Arg("LABEL", "label to set on issue").Required().StringsVar(&opts.Labels) return nil } // CmdLabels will set labels on a given issue -func (jc *JiraCli) CmdLabelsSet(opts *LabelsSetOptions) error { +func CmdLabelsSet(o *oreo.Client, opts *LabelsSetOptions) error { issueUpdate := jiradata.IssueUpdate{ Update: jiradata.FieldOperationsMap{ "labels": jiradata.FieldOperations{ @@ -48,12 +53,12 @@ func (jc *JiraCli) CmdLabelsSet(opts *LabelsSetOptions) error { }, } - if err := jc.EditIssue(opts.Issue, &issueUpdate); err != nil { + if err := jira.EditIssue(o, opts.Endpoint.Value, opts.Issue, &issueUpdate); err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/list.go b/jiracli/list.go index 7439d6f..ea3c72c 100644 --- a/jiracli/list.go +++ b/jiracli/list.go @@ -2,6 +2,7 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) @@ -11,7 +12,7 @@ type ListOptions struct { jira.SearchOptions `yaml:",inline" figtree:",inline"` } -func (jc *JiraCli) CmdListRegistry() *CommandRegistryEntry { +func CmdListRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := ListOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("list"), @@ -26,22 +27,20 @@ func (jc *JiraCli) CmdListRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Prints list of issues for given search criteria", func() error { - return jc.CmdList(&opts) + return CmdList(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdListUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdListUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions) error { - log.Debugf("Configs: %#v", opts) - jc.LoadConfigs(cmd, opts) - log.Debugf("Configs: %#v", opts) - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.TemplateUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("assignee", "User assigned the issue").Short('a').StringVar(&opts.Assignee) cmd.Flag("component", "Component to search for").Short('c').StringVar(&opts.Component) cmd.Flag("issuetype", "Issue type to search for").Short('i').StringVar(&opts.IssueType) @@ -56,11 +55,10 @@ func (jc *JiraCli) CmdListUsage(cmd *kingpin.CmdClause, opts *ListOptions) error } // List will query jira and send data to "list" template -func (jc *JiraCli) CmdList(opts *ListOptions) error { - log.Debugf("Configs: %#v", opts) - data, err := jc.Search(opts) +func CmdList(o *oreo.Client, opts *ListOptions) error { + data, err := jira.Search(o, opts.Endpoint.Value, opts) if err != nil { return err } - return jc.runTemplate(opts.Template.Value, data, nil) + return runTemplate(opts.Template.Value, data, nil) } diff --git a/jiracli/login.go b/jiracli/login.go index c6cb30e..ef7c980 100644 --- a/jiracli/login.go +++ b/jiracli/login.go @@ -4,20 +4,23 @@ import ( "fmt" "net/http" + "github.com/coryb/figtree" + "github.com/coryb/oreo" "github.com/mgutz/ansi" jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) -func (jc *JiraCli) CmdLoginRegistry() *CommandRegistryEntry { +func CmdLoginRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := GlobalOptions{} return &CommandRegistryEntry{ "Attempt to login into jira server", func() error { - return jc.CmdLogin(&opts) + return CmdLogin(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.GlobalUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return GlobalUsage(cmd, &opts) }, } } @@ -41,15 +44,11 @@ func authCallback(req *http.Request, resp *http.Response) (*http.Response, error } // CmdLogin will attempt to login into jira server -func (jc *JiraCli) CmdLogin(opts *GlobalOptions) error { - defer func(h jira.HttpClient) { - log.Debugf("Client: %#v", h) - jc.UA = h - }(jc.UA) - if session, err := jc.GetSession(); err != nil { - jc.UA = jc.oreoAgent.WithoutRedirect().WithRetries(0).WithPostCallback(authCallback) +func CmdLogin(o *oreo.Client, opts *GlobalOptions) error { + if session, err := jira.GetSession(o, opts.Endpoint.Value); err != nil { + ua := o.WithoutRedirect().WithRetries(0).WithPostCallback(authCallback) // No active session so try to create a new one - _, err := jc.NewSession(opts) + _, err := jira.NewSession(ua, opts.Endpoint.Value, opts) if err != nil { // reset password on failed session opts.SetPass("") diff --git a/jiracli/logout.go b/jiracli/logout.go index 35f4592..0aa2a6d 100644 --- a/jiracli/logout.go +++ b/jiracli/logout.go @@ -3,27 +3,31 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" "github.com/mgutz/ansi" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) -func (jc *JiraCli) CmdLogoutRegistry() *CommandRegistryEntry { +func CmdLogoutRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := GlobalOptions{} return &CommandRegistryEntry{ "Deactivate sesssion with Jira server", func() error { - return jc.CmdLogout(&opts) + return CmdLogout(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.GlobalUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return GlobalUsage(cmd, &opts) }, } } // CmdLogout will attempt to terminate an active Jira session -func (jc *JiraCli) CmdLogout(opts *GlobalOptions) error { - jc.UA = jc.oreoAgent.WithoutRedirect().WithRetries(0) - err := jc.DeleteSession() +func CmdLogout(o *oreo.Client, opts *GlobalOptions) error { + ua := o.WithoutRedirect().WithRetries(0) + err := jira.DeleteSession(ua, opts.Endpoint.Value) if err == nil { fmt.Println(ansi.Color("OK", "green"), "Terminated session for", opts.User) } else { diff --git a/jiracli/rank.go b/jiracli/rank.go index cc4d029..525c113 100644 --- a/jiracli/rank.go +++ b/jiracli/rank.go @@ -3,18 +3,22 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type RankOptions struct { - GlobalOptions - First string - Second string - Order string + GlobalOptions `yaml:",inline" figtree:",inline"` + First string + Second string + Order string } -func (jc *JiraCli) CmdRankRegistry() *CommandRegistryEntry { +func CmdRankRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := RankOptions{ GlobalOptions: GlobalOptions{}, } @@ -22,19 +26,20 @@ func (jc *JiraCli) CmdRankRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Mark issues as blocker", func() error { - return jc.CmdRank(&opts) + return CmdRank(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdRankUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdRankUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdRankUsage(cmd *kingpin.CmdClause, opts *RankOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdRankUsage(cmd *kingpin.CmdClause, opts *RankOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Arg("FIRST-ISSUE", "first issue").Required().StringVar(&opts.First) cmd.Arg("after|before", "rank ordering").Required().HintOptions("after", "before").EnumVar(&opts.Order, "after", "before") cmd.Arg("SECOND-ISSUE", "second issue").Required().StringVar(&opts.Second) @@ -42,7 +47,7 @@ func (jc *JiraCli) CmdRankUsage(cmd *kingpin.CmdClause, opts *RankOptions) error } // CmdRank order two issue -func (jc *JiraCli) CmdRank(opts *RankOptions) error { +func CmdRank(o *oreo.Client, opts *RankOptions) error { req := &jiradata.RankRequest{ Issues: []string{opts.First}, } @@ -53,16 +58,16 @@ func (jc *JiraCli) CmdRank(opts *RankOptions) error { req.RankBeforeIssue = opts.Second } - if err := jc.RankIssues(req); err != nil { + if err := jira.RankIssues(o, opts.Endpoint.Value, req); err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", opts.First, jc.Endpoint, opts.First) - fmt.Printf("OK %s %s/browse/%s\n", opts.Second, jc.Endpoint, opts.Second) + fmt.Printf("OK %s %s/browse/%s\n", opts.First, opts.Endpoint.Value, opts.First) + fmt.Printf("OK %s %s/browse/%s\n", opts.Second, opts.Endpoint.Value, opts.Second) if opts.Browse.Value { - if err := jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.First}); err != nil { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Second}) + if err := CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.First}); err != nil { + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Second}) } } diff --git a/jiracli/request.go b/jiracli/request.go index ffbde36..0c1f0aa 100644 --- a/jiracli/request.go +++ b/jiracli/request.go @@ -14,13 +14,13 @@ import ( ) type RequestOptions struct { - GlobalOptions - Method string - URI string - Data string + GlobalOptions `yaml:",inline" figtree:",inline"` + Method string + URI string + Data string } -func (jc *JiraCli) CmdRequestRegistry() *CommandRegistryEntry { +func CmdRequestRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := RequestOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("request"), @@ -31,16 +31,17 @@ func (jc *JiraCli) CmdRequestRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Open issue in requestr", func() error { - return jc.CmdRequest(&opts) + return CmdRequest(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdRequestUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdRequestUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdRequestUsage(cmd *kingpin.CmdClause, opts *RequestOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdRequestUsage(cmd *kingpin.CmdClause, opts *RequestOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } cmd.Flag("method", "HTTP request method to use").Short('m').EnumVar(&opts.Method, "GET", "PUT", "POST", "DELETE") @@ -51,10 +52,10 @@ func (jc *JiraCli) CmdRequestUsage(cmd *kingpin.CmdClause, opts *RequestOptions) } // CmdRequest open the default system requestr to the provided issue -func (jc *JiraCli) CmdRequest(opts *RequestOptions) error { +func CmdRequest(o *oreo.Client, opts *RequestOptions) error { uri := opts.URI if !strings.HasPrefix(uri, "http") { - uri = jc.Endpoint + uri + uri = opts.Endpoint.Value + uri } parsedURI, err := url.Parse(uri) @@ -66,7 +67,7 @@ func (jc *JiraCli) CmdRequest(opts *RequestOptions) error { builder = builder.WithJSON(opts.Data) } - resp, err := jc.UA.Do(builder.Build()) + resp, err := o.Do(builder.Build()) if err != nil { return err } @@ -86,5 +87,5 @@ func (jc *JiraCli) CmdRequest(opts *RequestOptions) error { return fmt.Errorf("JSON Parse Error: %s from %q", err, content) } - return jc.runTemplate(opts.Template.Value, &data, nil) + return runTemplate(opts.Template.Value, &data, nil) } diff --git a/jiracli/subtask.go b/jiracli/subtask.go index 22f4c88..121e72c 100644 --- a/jiracli/subtask.go +++ b/jiracli/subtask.go @@ -4,21 +4,23 @@ import ( "fmt" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type SubtaskOptions struct { - GlobalOptions - jiradata.IssueUpdate - Project string - IssueType string - Overrides map[string]string - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.IssueUpdate `yaml:",inline" figtree:",inline"` + Project string + IssueType string + Overrides map[string]string + Issue string } -func (jc *JiraCli) CmdSubtaskRegistry() *CommandRegistryEntry { +func CmdSubtaskRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := SubtaskOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("subtask"), @@ -30,21 +32,22 @@ func (jc *JiraCli) CmdSubtaskRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Subtask issue", func() error { - return jc.CmdSubtask(&opts) + return CmdSubtask(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdSubtaskUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdSubtaskUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdSubtaskUsage(cmd *kingpin.CmdClause, opts *SubtaskOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdSubtaskUsage(cmd *kingpin.CmdClause, opts *SubtaskOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing) cmd.Flag("project", "project to subtask issue in").Short('p').StringVar(&opts.Project) cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { @@ -58,14 +61,14 @@ func (jc *JiraCli) CmdSubtaskUsage(cmd *kingpin.CmdClause, opts *SubtaskOptions) // CmdSubtask sends the subtask-metadata to the "subtask" template for editing, then // will parse the edited document as YAML and submit the document to jira. -func (jc *JiraCli) CmdSubtask(opts *SubtaskOptions) error { +func CmdSubtask(o *oreo.Client, opts *SubtaskOptions) error { type templateInput struct { Meta *jiradata.CreateMetaIssueType `yaml:"meta" json:"meta"` Overrides map[string]string `yaml:"overrides" json:"overrides"` Parent *jiradata.Issue `yaml:"parent" json:"parent"` } - parent, err := jc.GetIssue(opts.Issue, nil) + parent, err := jira.GetIssue(o, opts.Endpoint.Value, opts.Issue, nil) if err != nil { return err } @@ -80,7 +83,7 @@ func (jc *JiraCli) CmdSubtask(opts *SubtaskOptions) error { return fmt.Errorf("Failed to find Project field in parent issue") } - createMeta, err := jc.GetIssueCreateMetaIssueType(opts.Project, opts.IssueType) + createMeta, err := jira.GetIssueCreateMetaIssueType(o, opts.Endpoint.Value, opts.Project, opts.IssueType) if err != nil { return err } @@ -96,18 +99,18 @@ func (jc *JiraCli) CmdSubtask(opts *SubtaskOptions) error { input.Overrides["user"] = opts.User.Value var issueResp *jiradata.IssueCreateResponse - err = jc.editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { - issueResp, err = jc.CreateIssue(&issueUpdate) + err = editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { + issueResp, err = jira.CreateIssue(o, opts.Endpoint.Value, &issueUpdate) return err }) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", issueResp.Key, jc.Endpoint, issueResp.Key) + fmt.Printf("OK %s %s/browse/%s\n", issueResp.Key, opts.Endpoint.Value, issueResp.Key) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, issueResp.Key}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, issueResp.Key}) } return nil } diff --git a/jiracli/take.go b/jiracli/take.go index ae63415..a82ea1e 100644 --- a/jiracli/take.go +++ b/jiracli/take.go @@ -1,27 +1,32 @@ package jiracli -import kingpin "gopkg.in/alecthomas/kingpin.v2" +import ( + "github.com/coryb/figtree" + "github.com/coryb/oreo" + kingpin "gopkg.in/alecthomas/kingpin.v2" +) -func (jc *JiraCli) CmdTakeRegistry() *CommandRegistryEntry { +func CmdTakeRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := AssignOptions{} return &CommandRegistryEntry{ "Assign issue to yourself", func() error { opts.Assignee = opts.User.Value - return jc.CmdAssign(&opts) + return CmdAssign(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdAssignUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdAssignUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdTakeUsage(cmd *kingpin.CmdClause, opts *AssignOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdTakeUsage(cmd *kingpin.CmdClause, opts *AssignOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue to assign").Required().StringVar(&opts.Issue) return nil } diff --git a/jiracli/templates.go b/jiracli/templates.go index 8e33617..a57f5b2 100644 --- a/jiracli/templates.go +++ b/jiracli/templates.go @@ -28,7 +28,7 @@ func findTemplate(name string) ([]byte, error) { return nil, nil } -func (jc *JiraCli) getTemplate(name string) (string, error) { +func getTemplate(name string) (string, error) { if _, err := os.Stat(name); err == nil { b, err := ioutil.ReadFile(name) if err != nil { @@ -48,18 +48,18 @@ func (jc *JiraCli) getTemplate(name string) (string, error) { return "", fmt.Errorf("No Template found for %q", name) } -func (jc *JiraCli) tmpTemplate(templateName string, data interface{}) (string, error) { - tmpFile, err := jc.tmpYml(templateName) +func tmpTemplate(templateName string, data interface{}) (string, error) { + tmpFile, err := tmpYml(templateName) if err != nil { return "", err } defer tmpFile.Close() - return tmpFile.Name(), jc.runTemplate(templateName, data, tmpFile) + return tmpFile.Name(), runTemplate(templateName, data, tmpFile) } -func (jc *JiraCli) runTemplate(templateName string, data interface{}, out io.Writer) error { +func runTemplate(templateName string, data interface{}, out io.Writer) error { - templateContent, err := jc.getTemplate(templateName) + templateContent, err := getTemplate(templateName) if err != nil { return err } diff --git a/jiracli/transition.go b/jiracli/transition.go index d23c5b5..c399561 100644 --- a/jiracli/transition.go +++ b/jiracli/transition.go @@ -5,20 +5,22 @@ import ( "strings" "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type TransitionOptions struct { - GlobalOptions - Overrides map[string]string - Transition string - Issue string - Resolution string + GlobalOptions `yaml:",inline" figtree:",inline"` + Overrides map[string]string + Transition string + Issue string + Resolution string } -func (jc *JiraCli) CmdTransitionRegistry(transition string) *CommandRegistryEntry { +func CmdTransitionRegistry(fig *figtree.FigTree, o *oreo.Client, transition string) *CommandRegistryEntry { opts := TransitionOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("transition"), @@ -35,20 +37,21 @@ func (jc *JiraCli) CmdTransitionRegistry(transition string) *CommandRegistryEntr return &CommandRegistryEntry{ help, func() error { - return jc.CmdTransition(&opts) + return CmdTransition(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdTransitionUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdTransitionUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdTransitionUsage(cmd *kingpin.CmdClause, opts *TransitionOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdTransitionUsage(cmd *kingpin.CmdClause, opts *TransitionOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("comment", "Comment message for issue").Short('m').PreAction(func(ctx *kingpin.ParseContext) error { opts.Overrides["comment"] = flagValue(ctx, "comment") return nil @@ -62,13 +65,13 @@ func (jc *JiraCli) CmdTransitionUsage(cmd *kingpin.CmdClause, opts *TransitionOp } // CmdTransition will move state of the given issue to the given transtion -func (jc *JiraCli) CmdTransition(opts *TransitionOptions) error { - issueData, err := jc.GetIssue(opts.Issue, nil) +func CmdTransition(o *oreo.Client, opts *TransitionOptions) error { + issueData, err := jira.GetIssue(o, opts.Endpoint.Value, opts.Issue, nil) if err != nil { return err } - meta, err := jc.GetIssueTransitions(opts.Issue) + meta, err := jira.GetIssueTransitions(o, opts.Endpoint.Value, opts.Issue) if err != nil { return err } @@ -120,16 +123,16 @@ func (jc *JiraCli) CmdTransition(opts *TransitionOptions) error { Transition: transMeta, Overrides: opts.Overrides, } - err = jc.editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { - return jc.TransitionIssue(opts.Issue, &issueUpdate) + err = editLoop(&opts.GlobalOptions, &input, &issueUpdate, func() error { + return jira.TransitionIssue(o, opts.Endpoint.Value, opts.Issue, &issueUpdate) }) if err != nil { return err } - fmt.Printf("OK %s %s/browse/%s\n", issueData.Key, jc.Endpoint, issueData.Key) + fmt.Printf("OK %s %s/browse/%s\n", issueData.Key, opts.Endpoint.Value, issueData.Key) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/transitions.go b/jiracli/transitions.go index bfee7c8..0596c05 100644 --- a/jiracli/transitions.go +++ b/jiracli/transitions.go @@ -2,15 +2,17 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type TransitionsOptions struct { - GlobalOptions - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string } -func (jc *JiraCli) CmdTransitionsRegistry(defaultTemplate string) *CommandRegistryEntry { +func CmdTransitionsRegistry(fig *figtree.FigTree, o *oreo.Client, defaultTemplate string) *CommandRegistryEntry { opts := TransitionsOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption(defaultTemplate), @@ -20,35 +22,36 @@ func (jc *JiraCli) CmdTransitionsRegistry(defaultTemplate string) *CommandRegist return &CommandRegistryEntry{ "List valid issue transitions", func() error { - return jc.CmdTransitions(&opts) + return CmdTransitions(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdTransitionsUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdTransitionsUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdTransitionsUsage(cmd *kingpin.CmdClause, opts *TransitionsOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdTransitionsUsage(cmd *kingpin.CmdClause, opts *TransitionsOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue to list valid transitions").Required().StringVar(&opts.Issue) return nil } // Transitions will get issue edit metadata and send to "editmeta" template -func (jc *JiraCli) CmdTransitions(opts *TransitionsOptions) error { - editMeta, err := jc.GetIssueTransitions(opts.Issue) +func CmdTransitions(o *oreo.Client, opts *TransitionsOptions) error { + editMeta, err := jira.GetIssueTransitions(o, opts.Endpoint.Value, opts.Issue) if err != nil { return err } - if err := jc.runTemplate(opts.Template.Value, editMeta, nil); err != nil { + if err := runTemplate(opts.Template.Value, editMeta, nil); err != nil { return err } if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/unassign.go b/jiracli/unassign.go index 093ac93..49d4ac8 100644 --- a/jiracli/unassign.go +++ b/jiracli/unassign.go @@ -1,26 +1,31 @@ package jiracli -import kingpin "gopkg.in/alecthomas/kingpin.v2" +import ( + "github.com/coryb/figtree" + "github.com/coryb/oreo" + kingpin "gopkg.in/alecthomas/kingpin.v2" +) -func (jc *JiraCli) CmdUnassignRegistry() *CommandRegistryEntry { +func CmdUnassignRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := AssignOptions{} return &CommandRegistryEntry{ "Unassign an issue", func() error { - return jc.CmdAssign(&opts) + return CmdAssign(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdAssignUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdAssignUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdUnassignUsage(cmd *kingpin.CmdClause, opts *AssignOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdUnassignUsage(cmd *kingpin.CmdClause, opts *AssignOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue to unassign").Required().StringVar(&opts.Issue) return nil } diff --git a/jiracli/unexportTemplates.go b/jiracli/unexportTemplates.go index c40d648..4416330 100644 --- a/jiracli/unexportTemplates.go +++ b/jiracli/unexportTemplates.go @@ -7,27 +7,30 @@ import ( "os" "path" + "github.com/coryb/figtree" + kingpin "gopkg.in/alecthomas/kingpin.v2" ) -func (jc *JiraCli) CmdUnexportTemplatesRegistry() *CommandRegistryEntry { +func CmdUnexportTemplatesRegistry(fig *figtree.FigTree) *CommandRegistryEntry { opts := ExportTemplatesOptions{ - Dir: fmt.Sprintf("%s/.jira.d/templates", homedir()), + Dir: fmt.Sprintf("%s/.jira.d/templates", Homedir()), } return &CommandRegistryEntry{ "Remove unmodified exported templates", func() error { - return jc.CmdUnexportTemplates(&opts) + return CmdUnexportTemplates(&opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdExportTemplatesUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdExportTemplatesUsage(cmd, &opts) }, } } // CmdUnexportTemplates will remove unmodified templates from export directory -func (jc *JiraCli) CmdUnexportTemplates(opts *ExportTemplatesOptions) error { +func CmdUnexportTemplates(opts *ExportTemplatesOptions) error { for name, template := range allTemplates { if opts.Template != "" && opts.Template != name { continue diff --git a/jiracli/util.go b/jiracli/util.go index 7e866c4..a32ec48 100644 --- a/jiracli/util.go +++ b/jiracli/util.go @@ -6,7 +6,6 @@ import ( "io" "io/ioutil" "os" - "path/filepath" "runtime" "time" @@ -15,7 +14,7 @@ import ( "github.com/coryb/figtree" ) -func homedir() string { +func Homedir() string { if runtime.GOOS == "windows" { return os.Getenv("USERPROFILE") } @@ -30,13 +29,8 @@ func findClosestParentPath(fileName string) (string, error) { return "", errors.New(fmt.Sprintf("%s not found in parent directory hierarchy", fileName)) } -func (jc *JiraCli) tmpYml(tmpFilePrefix string) (*os.File, error) { - tmpdir := filepath.Join(homedir(), jc.ConfigDir, "tmp") - if err := os.MkdirAll(tmpdir, 0755); err != nil { - return nil, err - } - - fh, err := ioutil.TempFile(tmpdir, tmpFilePrefix) +func tmpYml(tmpFilePrefix string) (*os.File, error) { + fh, err := ioutil.TempFile("", tmpFilePrefix) if err != nil { return nil, err } diff --git a/jiracli/view.go b/jiracli/view.go index a7f6479..ce199f4 100644 --- a/jiracli/view.go +++ b/jiracli/view.go @@ -2,17 +2,18 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type ViewOptions struct { - GlobalOptions - jira.IssueOptions - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + jira.IssueOptions `yaml:",inline" figtree:",inline"` + Issue string } -func (jc *JiraCli) CmdViewRegistry() *CommandRegistryEntry { +func CmdViewRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := ViewOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("view"), @@ -22,20 +23,21 @@ func (jc *JiraCli) CmdViewRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Prints issue details", func() error { - return jc.CmdView(&opts) + return CmdView(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdViewUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdViewUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdViewUsage(cmd *kingpin.CmdClause, opts *ViewOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdViewUsage(cmd *kingpin.CmdClause, opts *ViewOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("expand", "field to expand for the issue").StringsVar(&opts.Expand) cmd.Flag("field", "field to return for the issue").StringsVar(&opts.Fields) cmd.Flag("property", "property to return for issue").StringsVar(&opts.Properties) @@ -44,16 +46,16 @@ func (jc *JiraCli) CmdViewUsage(cmd *kingpin.CmdClause, opts *ViewOptions) error } // View will get issue data and send to "view" template -func (jc *JiraCli) CmdView(opts *ViewOptions) error { - data, err := jc.GetIssue(opts.Issue, opts) +func CmdView(o *oreo.Client, opts *ViewOptions) error { + data, err := jira.GetIssue(o, opts.Endpoint.Value, opts.Issue, opts) if err != nil { return err } - if err := jc.runTemplate(opts.Template.Value, data, nil); err != nil { + if err := runTemplate(opts.Template.Value, data, nil); err != nil { return err } if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/vote.go b/jiracli/vote.go index 950de9e..5cb7938 100644 --- a/jiracli/vote.go +++ b/jiracli/vote.go @@ -3,6 +3,10 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) @@ -14,12 +18,12 @@ const ( ) type VoteOptions struct { - GlobalOptions - Issue string - Action VoteAction + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string + Action VoteAction } -func (jc *JiraCli) CmdVoteRegistry() *CommandRegistryEntry { +func CmdVoteRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := VoteOptions{ GlobalOptions: GlobalOptions{}, Action: VoteUP, @@ -28,19 +32,20 @@ func (jc *JiraCli) CmdVoteRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Vote up/down an issue", func() error { - return jc.CmdVote(&opts) + return CmdVote(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdVoteUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdVoteUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdVoteUsage(cmd *kingpin.CmdClause, opts *VoteOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdVoteUsage(cmd *kingpin.CmdClause, opts *VoteOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Flag("down", "downvote the issue").Short('d').PreAction(func(ctx *kingpin.ParseContext) error { opts.Action = VoteDown return nil @@ -50,20 +55,20 @@ func (jc *JiraCli) CmdVoteUsage(cmd *kingpin.CmdClause, opts *VoteOptions) error } // Vote will up/down vote an issue -func (jc *JiraCli) CmdVote(opts *VoteOptions) error { +func CmdVote(o *oreo.Client, opts *VoteOptions) error { if opts.Action == VoteUP { - if err := jc.IssueAddVote(opts.Issue); err != nil { + if err := jira.IssueAddVote(o, opts.Endpoint.Value, opts.Issue); err != nil { return err } } else { - if err := jc.IssueRemoveVote(opts.Issue); err != nil { + if err := jira.IssueRemoveVote(o, opts.Endpoint.Value, opts.Issue); err != nil { return err } } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/watch.go b/jiracli/watch.go index f1a5cbd..2997131 100644 --- a/jiracli/watch.go +++ b/jiracli/watch.go @@ -3,6 +3,10 @@ package jiracli import ( "fmt" + "github.com/coryb/figtree" + "github.com/coryb/oreo" + + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) @@ -14,13 +18,13 @@ const ( ) type WatchOptions struct { - GlobalOptions - Issue string - Watcher string - Action WatchAction + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string + Watcher string + Action WatchAction } -func (jc *JiraCli) CmdWatchRegistry() *CommandRegistryEntry { +func CmdWatchRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := WatchOptions{ GlobalOptions: GlobalOptions{}, Action: WatcherAdd, @@ -29,19 +33,20 @@ func (jc *JiraCli) CmdWatchRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Add/Remove watcher to issue", func() error { - return jc.CmdWatch(&opts) + return CmdWatch(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdWatchUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdWatchUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdWatchUsage(cmd *kingpin.CmdClause, opts *WatchOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdWatchUsage(cmd *kingpin.CmdClause, opts *WatchOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) cmd.Flag("remove", "remove watcher from issue").Short('r').PreAction(func(ctx *kingpin.ParseContext) error { opts.Action = WatcherRemove return nil @@ -53,24 +58,24 @@ func (jc *JiraCli) CmdWatchUsage(cmd *kingpin.CmdClause, opts *WatchOptions) err // CmdWatch will add the given watcher to the issue (or remove the watcher // with the 'remove' flag) -func (jc *JiraCli) CmdWatch(opts *WatchOptions) error { +func CmdWatch(o *oreo.Client, opts *WatchOptions) error { if opts.Watcher == "" { opts.Watcher = opts.User.Value } if opts.Action == WatcherAdd { - if err := jc.IssueAddWatcher(opts.Issue, opts.Watcher); err != nil { + if err := jira.IssueAddWatcher(o, opts.Endpoint.Value, opts.Issue, opts.Watcher); err != nil { return err } } else { - if err := jc.IssueRemoveWatcher(opts.Issue, opts.Watcher); err != nil { + if err := jira.IssueRemoveWatcher(o, opts.Endpoint.Value, opts.Issue, opts.Watcher); err != nil { return err } } - fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, jc.Endpoint, opts.Issue) + fmt.Printf("OK %s %s/browse/%s\n", opts.Issue, opts.Endpoint.Value, opts.Issue) if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil diff --git a/jiracli/worklogAdd.go b/jiracli/worklogAdd.go index 24d6de2..1c0c711 100644 --- a/jiracli/worklogAdd.go +++ b/jiracli/worklogAdd.go @@ -2,17 +2,19 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" "gopkg.in/Netflix-Skunkworks/go-jira.v1/jiradata" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type WorklogAddOptions struct { - GlobalOptions - jiradata.Worklog - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + jiradata.Worklog `yaml:",inline" figtree:",inline"` + Issue string } -func (jc *JiraCli) CmdWorklogAddRegistry() *CommandRegistryEntry { +func CmdWorklogAddRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := WorklogAddOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("worklog"), @@ -21,21 +23,22 @@ func (jc *JiraCli) CmdWorklogAddRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Add a worklog to an issue", func() error { - return jc.CmdWorklogAdd(&opts) + return CmdWorklogAdd(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdWorklogAddUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdWorklogAddUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdWorklogAddUsage(cmd *kingpin.CmdClause, opts *WorklogAddOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdWorklogAddUsage(cmd *kingpin.CmdClause, opts *WorklogAddOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.EditorUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + EditorUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Flag("noedit", "Disable opening the editor").SetValue(&opts.SkipEditing) cmd.Flag("comment", "Comment message for worklog").Short('m').StringVar(&opts.Comment) cmd.Flag("time-spent", "Time spent working on issue").Short('T').StringVar(&opts.TimeSpent) @@ -46,16 +49,16 @@ func (jc *JiraCli) CmdWorklogAddUsage(cmd *kingpin.CmdClause, opts *WorklogAddOp // CmdWorklogAdd 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 (jc *JiraCli) CmdWorklogAdd(opts *WorklogAddOptions) error { - err := jc.editLoop(&opts.GlobalOptions, &opts.Worklog, &opts.Worklog, func() error { - _, err := jc.AddIssueWorklog(opts.Issue, opts) +func CmdWorklogAdd(o *oreo.Client, opts *WorklogAddOptions) error { + err := editLoop(&opts.GlobalOptions, &opts.Worklog, &opts.Worklog, func() error { + _, err := jira.AddIssueWorklog(o, opts.Endpoint.Value, opts.Issue, opts) return err }) if err != nil { return err } if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/jiracli/worklogList.go b/jiracli/worklogList.go index 1b8510e..a7277ef 100644 --- a/jiracli/worklogList.go +++ b/jiracli/worklogList.go @@ -2,15 +2,17 @@ package jiracli import ( "github.com/coryb/figtree" + "github.com/coryb/oreo" + jira "gopkg.in/Netflix-Skunkworks/go-jira.v1" kingpin "gopkg.in/alecthomas/kingpin.v2" ) type WorklogListOptions struct { - GlobalOptions - Issue string + GlobalOptions `yaml:",inline" figtree:",inline"` + Issue string } -func (jc *JiraCli) CmdWorklogListRegistry() *CommandRegistryEntry { +func CmdWorklogListRegistry(fig *figtree.FigTree, o *oreo.Client) *CommandRegistryEntry { opts := WorklogListOptions{ GlobalOptions: GlobalOptions{ Template: figtree.NewStringOption("worklogs"), @@ -19,35 +21,36 @@ func (jc *JiraCli) CmdWorklogListRegistry() *CommandRegistryEntry { return &CommandRegistryEntry{ "Prints the worklog data for given issue", func() error { - return jc.CmdWorklogList(&opts) + return CmdWorklogList(o, &opts) }, func(cmd *kingpin.CmdClause) error { - return jc.CmdWorklogListUsage(cmd, &opts) + LoadConfigs(cmd, fig, &opts) + return CmdWorklogListUsage(cmd, &opts) }, } } -func (jc *JiraCli) CmdWorklogListUsage(cmd *kingpin.CmdClause, opts *WorklogListOptions) error { - if err := jc.GlobalUsage(cmd, &opts.GlobalOptions); err != nil { +func CmdWorklogListUsage(cmd *kingpin.CmdClause, opts *WorklogListOptions) error { + if err := GlobalUsage(cmd, &opts.GlobalOptions); err != nil { return err } - jc.BrowseUsage(cmd, &opts.GlobalOptions) - jc.TemplateUsage(cmd, &opts.GlobalOptions) + BrowseUsage(cmd, &opts.GlobalOptions) + TemplateUsage(cmd, &opts.GlobalOptions) cmd.Arg("ISSUE", "issue id to fetch worklogs").Required().StringVar(&opts.Issue) return nil } // // CmdWorklogList will get worklog data for given issue and sent to the "worklogs" template -func (jc *JiraCli) CmdWorklogList(opts *WorklogListOptions) error { - data, err := jc.GetIssueWorklog(opts.Issue) +func CmdWorklogList(o *oreo.Client, opts *WorklogListOptions) error { + data, err := jira.GetIssueWorklog(o, opts.Endpoint.Value, opts.Issue) if err != nil { return err } - if err := jc.runTemplate(opts.Template.Value, data, nil); err != nil { + if err := runTemplate(opts.Template.Value, data, nil); err != nil { return err } if opts.Browse.Value { - return jc.CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) + return CmdBrowse(&BrowseOptions{opts.GlobalOptions, opts.Issue}) } return nil } diff --git a/project.go b/project.go index ab84a57..b4cc711 100644 --- a/project.go +++ b/project.go @@ -8,8 +8,12 @@ import ( // https://docs.atlassian.com/jira/REST/cloud/#api/2/project-getProjectComponents func (j *Jira) GetProjectComponents(project string) (*jiradata.Components, error) { - uri := fmt.Sprintf("%s/rest/api/2/project/%s/components", j.Endpoint, project) - resp, err := j.UA.GetJSON(uri) + return GetProjectComponents(j.UA, j.Endpoint, project) +} + +func GetProjectComponents(ua HttpClient, endpoint string, project string) (*jiradata.Components, error) { + uri := fmt.Sprintf("%s/rest/api/2/project/%s/components", endpoint, project) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } diff --git a/search.go b/search.go index 2a51dac..c7a4fdb 100644 --- a/search.go +++ b/search.go @@ -70,13 +70,17 @@ func (o *SearchOptions) ProvideSearchRequest() *jiradata.SearchRequest { // https://docs.atlassian.com/jira/REST/cloud/#api/2/search-searchUsingSearchRequest func (j *Jira) Search(sp SearchProvider) (*jiradata.SearchResults, error) { + return Search(j.UA, j.Endpoint, sp) +} + +func Search(ua HttpClient, endpoint string, sp SearchProvider) (*jiradata.SearchResults, error) { req := sp.ProvideSearchRequest() encoded, err := json.Marshal(req) if err != nil { return nil, err } - uri := fmt.Sprintf("%s/rest/api/2/search", j.Endpoint) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/api/2/search", endpoint) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return nil, err } diff --git a/session.go b/session.go index a37dd4b..e0c2cd4 100644 --- a/session.go +++ b/session.go @@ -26,13 +26,17 @@ func (a *AuthOptions) AuthParams() *jiradata.AuthParams { // https://docs.atlassian.com/jira/REST/cloud/#auth/1/session-login func (j *Jira) NewSession(ap AuthProvider) (*jiradata.AuthSuccess, error) { + return NewSession(j.UA, j.Endpoint, ap) +} + +func NewSession(ua HttpClient, endpoint string, ap AuthProvider) (*jiradata.AuthSuccess, error) { req := ap.ProvideAuthParams() encoded, err := json.Marshal(req) if err != nil { return nil, err } - uri := fmt.Sprintf("%s/rest/auth/1/session", j.Endpoint) - resp, err := j.UA.Post(uri, "application/json", bytes.NewBuffer(encoded)) + uri := fmt.Sprintf("%s/rest/auth/1/session", endpoint) + resp, err := ua.Post(uri, "application/json", bytes.NewBuffer(encoded)) if err != nil { return nil, err } @@ -47,8 +51,12 @@ func (j *Jira) NewSession(ap AuthProvider) (*jiradata.AuthSuccess, error) { // https://docs.atlassian.com/jira/REST/cloud/#auth/1/session-currentUser func (j *Jira) GetSession() (*jiradata.CurrentUser, error) { - uri := fmt.Sprintf("%s/rest/auth/1/session", j.Endpoint) - resp, err := j.UA.GetJSON(uri) + return GetSession(j.UA, j.Endpoint) +} + +func GetSession(ua HttpClient, endpoint string) (*jiradata.CurrentUser, error) { + uri := fmt.Sprintf("%s/rest/auth/1/session", endpoint) + resp, err := ua.GetJSON(uri) if err != nil { return nil, err } @@ -63,8 +71,12 @@ func (j *Jira) GetSession() (*jiradata.CurrentUser, error) { // https://docs.atlassian.com/jira/REST/cloud/#auth/1/session-logout func (j *Jira) DeleteSession() error { - uri := fmt.Sprintf("%s/rest/auth/1/session", j.Endpoint) - resp, err := j.UA.Delete(uri) + return DeleteSession(j.UA, j.Endpoint) +} + +func DeleteSession(ua HttpClient, endpoint string) error { + uri := fmt.Sprintf("%s/rest/auth/1/session", endpoint) + resp, err := ua.Delete(uri) if err != nil { return err } diff --git a/vendor/github.com/coryb/figtree/figtree.go b/vendor/github.com/coryb/figtree/figtree.go index 66d1373..260f387 100644 --- a/vendor/github.com/coryb/figtree/figtree.go +++ b/vendor/github.com/coryb/figtree/figtree.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "os/exec" + "path" "path/filepath" "reflect" "strings" @@ -22,6 +23,7 @@ import ( var log = logging.MustGetLogger("figtree") type FigTree struct { + ConfigDir string Defaults interface{} EnvPrefix string stop bool @@ -44,7 +46,10 @@ func LoadConfig(configFile string, options interface{}) error { func (f *FigTree) LoadAllConfigs(configFile string, options interface{}) error { // reset from any previous config parsing runs f.stop = false - // assert options is a pointer + + if f.ConfigDir != "" { + configFile = path.Join(f.ConfigDir, configFile) + } paths := FindParentPaths(configFile) paths = append([]string{fmt.Sprintf("/etc/%s", configFile)}, paths...) diff --git a/vendor/github.com/coryb/oreo/oreo.go b/vendor/github.com/coryb/oreo/oreo.go index a236bf4..057a05d 100644 --- a/vendor/github.com/coryb/oreo/oreo.go +++ b/vendor/github.com/coryb/oreo/oreo.go @@ -322,7 +322,6 @@ func (c *Client) Do(req *http.Request) (resp *http.Response, err error) { if err != nil { return nil, err } - // log any cookies sent b/c they will not be present until // afater we call the `Do` func if log.IsEnabledFor(logging.DEBUG) && TraceRequestBody { @@ -335,6 +334,11 @@ func (c *Client) Do(req *http.Request) (resp *http.Response, err error) { } } + if log.IsEnabledFor(logging.DEBUG) && TraceResponseBody { + out, _ := httputil.DumpResponse(resp, true) + log.Debugf("Response: %s", out) + } + err = c.saveCookies(resp) if err != nil { return resp, err