refactor trivial objects in favor of arguments to static functions

This commit is contained in:
Cory Bennett
2017-08-27 00:47:11 -07:00
parent 5716a7cb59
commit 1f345cedee
49 changed files with 840 additions and 629 deletions
+1 -1
View File
@@ -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:
+54 -48
View File
@@ -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 {
+6 -2
View File
@@ -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
}
+6 -2
View File
@@ -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
}
Generated
+2 -2
View File
@@ -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
+115 -39
View File
@@ -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
}
+16 -11
View File
@@ -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
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
+19 -16
View File
@@ -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
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})
}
}
+10 -8
View File
@@ -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
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))
}
+29 -43
View File
@@ -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
}
+17 -14
View File
@@ -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
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
+15 -12
View File
@@ -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 {
+13 -10
View File
@@ -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
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)
}
+22 -19
View File
@@ -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
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
}
+14 -11
View File
@@ -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
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)
}
+22 -19
View File
@@ -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
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})
}
}
+26 -24
View File
@@ -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
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
+15 -12
View File
@@ -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
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
}
+9 -6
View File
@@ -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
}
+10 -7
View File
@@ -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)
}
+21 -16
View File
@@ -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
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})
}
}
+12 -9
View File
@@ -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)
}
+13 -10
View File
@@ -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
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)
}
+16 -11
View File
@@ -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
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
}
+16 -11
View File
@@ -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
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
}
+16 -11
View File
@@ -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
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
}
+11 -13
View File
@@ -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)
}
+10 -11
View File
@@ -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("")
+10 -6
View File
@@ -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 {
+18 -13
View File
@@ -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
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})
}
}
+11 -10
View File
@@ -14,13 +14,13 @@ import (
)
type RequestOptions struct {
GlobalOptions
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)
}
+20 -17
View File
@@ -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
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
}
+12 -7
View File
@@ -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
}
+6 -6
View File
@@ -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
}
+18 -15
View File
@@ -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
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
}
+15 -12
View File
@@ -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
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
}
+12 -7
View File
@@ -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
}
+8 -5
View File
@@ -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
+3 -9
View File
@@ -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
}
+15 -13
View File
@@ -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
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
}
+17 -12
View File
@@ -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
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
}
+17 -12
View File
@@ -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
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
+17 -14
View File
@@ -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
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
}
+15 -12
View File
@@ -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
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
}
+6 -2
View File
@@ -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
}
+6 -2
View File
@@ -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
}
+18 -6
View File
@@ -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
}
+6 -1
View File
@@ -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...)
+5 -1
View File
@@ -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