@@ -23,17 +23,20 @@ import (
23
23
)
24
24
25
25
var (
26
- log = logging .MustGetLogger ("jira" )
26
+ log = logging .MustGetLogger ("jira" )
27
+ // VERSION is the go-jira library version
27
28
VERSION string
28
29
)
29
30
31
+ // Cli is go-jira client object
30
32
type Cli struct {
31
33
endpoint * url.URL
32
34
opts map [string ]interface {}
33
35
cookieFile string
34
36
ua * http.Client
35
37
}
36
38
39
+ // New creates go-jira client object
37
40
func New (opts map [string ]interface {}) * Cli {
38
41
homedir := homedir ()
39
42
cookieJar , _ := cookiejar .New (nil )
@@ -120,7 +123,7 @@ func (c *Cli) loadCookies() []*http.Cookie {
120
123
log .Errorf ("Failed to open %s: %s" , c .cookieFile , err )
121
124
panic (err )
122
125
}
123
- cookies := make ( []* http.Cookie , 0 )
126
+ cookies := []* http.Cookie {}
124
127
err = json .Unmarshal (bytes , & cookies )
125
128
if err != nil {
126
129
log .Errorf ("Failed to parse json from file %s: %s" , c .cookieFile , err )
@@ -140,44 +143,42 @@ func (c *Cli) put(uri string, content string) (*http.Response, error) {
140
143
return c .makeRequestWithContent ("PUT" , uri , content )
141
144
}
142
145
143
- func (c * Cli ) delete (uri string ) (* http.Response , error ) {
146
+ func (c * Cli ) delete (uri string ) (resp * http.Response , err error ) {
144
147
method := "DELETE"
145
148
req , _ := http .NewRequest (method , uri , nil )
146
149
log .Infof ("%s %s" , req .Method , req .URL .String ())
147
- if resp , err : = c .makeRequest (req ); err != nil {
150
+ if resp , err = c .makeRequest (req ); err != nil {
148
151
return nil , err
149
- } else {
150
- if resp .StatusCode == 401 {
151
- if err := c .CmdLogin (); err != nil {
152
- return nil , err
153
- }
154
- req , _ = http .NewRequest (method , uri , nil )
155
- return c .makeRequest (req )
152
+ }
153
+ if resp .StatusCode == 401 {
154
+ if err = c .CmdLogin (); err != nil {
155
+ return nil , err
156
156
}
157
- return resp , err
157
+ req , _ = http .NewRequest (method , uri , nil )
158
+ return c .makeRequest (req )
158
159
}
160
+ return resp , err
159
161
}
160
162
161
- func (c * Cli ) makeRequestWithContent (method string , uri string , content string ) (* http.Response , error ) {
163
+ func (c * Cli ) makeRequestWithContent (method string , uri string , content string ) (resp * http.Response , err error ) {
162
164
buffer := bytes .NewBufferString (content )
163
165
req , _ := http .NewRequest (method , uri , buffer )
164
166
165
167
log .Infof ("%s %s" , req .Method , req .URL .String ())
166
- if resp , err : = c .makeRequest (req ); err != nil {
168
+ if resp , err = c .makeRequest (req ); err != nil {
167
169
return nil , err
168
- } else {
169
- if resp .StatusCode == 401 {
170
- if err := c .CmdLogin (); err != nil {
171
- return nil , err
172
- }
173
- req , _ = http .NewRequest (method , uri , bytes .NewBufferString (content ))
174
- return c .makeRequest (req )
170
+ }
171
+ if resp .StatusCode == 401 {
172
+ if err = c .CmdLogin (); err != nil {
173
+ return nil , err
175
174
}
176
- return resp , err
175
+ req , _ = http .NewRequest (method , uri , bytes .NewBufferString (content ))
176
+ return c .makeRequest (req )
177
177
}
178
+ return resp , err
178
179
}
179
180
180
- func (c * Cli ) get (uri string ) (* http.Response , error ) {
181
+ func (c * Cli ) get (uri string ) (resp * http.Response , err error ) {
181
182
req , _ := http .NewRequest ("GET" , uri , nil )
182
183
log .Infof ("%s %s" , req .Method , req .URL .String ())
183
184
if log .IsEnabledFor (logging .DEBUG ) {
@@ -186,17 +187,16 @@ func (c *Cli) get(uri string) (*http.Response, error) {
186
187
log .Debugf ("%s" , logBuffer )
187
188
}
188
189
189
- if resp , err : = c .makeRequest (req ); err != nil {
190
+ if resp , err = c .makeRequest (req ); err != nil {
190
191
return nil , err
191
- } else {
192
- if resp .StatusCode == 401 {
193
- if err := c .CmdLogin (); err != nil {
194
- return nil , err
195
- }
196
- return c .makeRequest (req )
192
+ }
193
+ if resp .StatusCode == 401 {
194
+ if err := c .CmdLogin (); err != nil {
195
+ return nil , err
197
196
}
198
- return resp , err
197
+ return c . makeRequest ( req )
199
198
}
199
+ return resp , err
200
200
}
201
201
202
202
func (c * Cli ) makeRequest (req * http.Request ) (resp * http.Response , err error ) {
@@ -217,18 +217,17 @@ func (c *Cli) makeRequest(req *http.Request) (resp *http.Response, err error) {
217
217
if resp , err = c .ua .Do (req ); err != nil {
218
218
log .Errorf ("Failed to %s %s: %s" , req .Method , req .URL .String (), err )
219
219
return nil , err
220
- } else {
221
- if resp .StatusCode < 200 || resp .StatusCode >= 300 && resp .StatusCode != 401 {
222
- log .Errorf ("response status: %s" , resp .Status )
223
- }
220
+ }
221
+ if resp .StatusCode < 200 || resp .StatusCode >= 300 && resp .StatusCode != 401 {
222
+ log .Errorf ("response status: %s" , resp .Status )
223
+ }
224
224
225
- runtime .SetFinalizer (resp , func (r * http.Response ) {
226
- r .Body .Close ()
227
- })
225
+ runtime .SetFinalizer (resp , func (r * http.Response ) {
226
+ r .Body .Close ()
227
+ })
228
228
229
- if _ , ok := resp .Header ["Set-Cookie" ]; ok {
230
- c .saveCookies (resp )
231
- }
229
+ if _ , ok := resp .Header ["Set-Cookie" ]; ok {
230
+ c .saveCookies (resp )
232
231
}
233
232
if log .IsEnabledFor (logging .DEBUG ) {
234
233
out , _ := httputil .DumpResponse (resp , true )
@@ -237,6 +236,7 @@ func (c *Cli) makeRequest(req *http.Request) (resp *http.Response, err error) {
237
236
return resp , nil
238
237
}
239
238
239
+ // GetTemplate will return the text/template for the given command name
240
240
func (c * Cli ) GetTemplate (name string ) string {
241
241
return c .getTemplate (name )
242
242
}
@@ -256,20 +256,21 @@ func (c *Cli) getTemplate(name string) string {
256
256
if override , ok := c .opts ["template" ].(string ); ok {
257
257
if _ , err := os .Stat (override ); err == nil {
258
258
return readFile (override )
259
- } else {
260
- if t := getLookedUpTemplate (override , all_templates [override ]); t != "" {
261
- return t
262
- }
259
+ }
260
+ if t := getLookedUpTemplate (override , allTemplates [override ]); t != "" {
261
+ return t
263
262
}
264
263
}
265
264
// create-bug etc are special, if we dont find it in the path
266
265
// then just return the create template
267
266
if strings .HasPrefix (name , "create-" ) {
268
267
return getLookedUpTemplate (name , c .getTemplate ("create" ))
269
268
}
270
- return getLookedUpTemplate (name , all_templates [name ])
269
+ return getLookedUpTemplate (name , allTemplates [name ])
271
270
}
272
271
272
+ // NoChangesFound is an error returned from when editing templates
273
+ // and no modifications were made while editing
273
274
type NoChangesFound struct {}
274
275
275
276
func (f NoChangesFound ) Error () string {
@@ -360,27 +361,27 @@ func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData m
360
361
}
361
362
362
363
edited := make (map [string ]interface {})
363
- if fh , err := ioutil .ReadFile (tmpFileName ); err != nil {
364
+ var data []byte
365
+ if data , err = ioutil .ReadFile (tmpFileName ); err != nil {
364
366
log .Errorf ("Failed to read tmpfile %s: %s" , tmpFileName , err )
365
367
if editing && promptYN ("edit again?" , true ) {
366
368
continue
367
369
}
368
370
return err
369
- } else {
370
- if err := yaml .Unmarshal (fh , & edited ); err != nil {
371
- log .Errorf ("Failed to parse YAML: %s" , err )
372
- if editing && promptYN ("edit again?" , true ) {
373
- continue
374
- }
375
- return err
371
+ }
372
+ if err := yaml .Unmarshal (data , & edited ); err != nil {
373
+ log .Errorf ("Failed to parse YAML: %s" , err )
374
+ if editing && promptYN ("edit again?" , true ) {
375
+ continue
376
376
}
377
+ return err
377
378
}
378
379
379
- if fixed , err := yamlFixup (edited ); err != nil {
380
+ var fixed interface {}
381
+ if fixed , err = yamlFixup (edited ); err != nil {
380
382
return err
381
- } else {
382
- edited = fixed .(map [string ]interface {})
383
383
}
384
+ edited = fixed .(map [string ]interface {})
384
385
385
386
// if you want to abort editing a jira issue then
386
387
// you can add the "abort: true" flag to the document
@@ -422,6 +423,7 @@ func (c *Cli) editTemplate(template string, tmpFilePrefix string, templateData m
422
423
return nil
423
424
}
424
425
426
+ // Browse will open up your default browser to the provided issue
425
427
func (c * Cli ) Browse (issue string ) error {
426
428
if val , ok := c .opts ["browse" ].(bool ); ok && val {
427
429
if runtime .GOOS == "darwin" {
@@ -433,40 +435,47 @@ func (c *Cli) Browse(issue string) error {
433
435
return nil
434
436
}
435
437
438
+ // SaveData will write out the yaml formated --saveFile file with provided data
436
439
func (c * Cli ) SaveData (data interface {}) error {
437
440
if val , ok := c .opts ["saveFile" ].(string ); ok && val != "" {
438
441
yamlWrite (val , data )
439
442
}
440
443
return nil
441
444
}
442
445
446
+ // ViewIssue will return the details for the given issue id
443
447
func (c * Cli ) ViewIssue (issue string ) (interface {}, error ) {
444
448
uri := fmt .Sprintf ("%s/rest/api/2/issue/%s" , c .endpoint , issue )
445
449
if x := c .expansions (); len (x ) > 0 {
446
450
uri = fmt .Sprintf ("%s?expand=%s" , uri , strings .Join (x , "," ))
447
451
}
448
452
449
- data , err := responseToJson (c .get (uri ))
453
+ data , err := responseToJSON (c .get (uri ))
450
454
if err != nil {
451
455
return nil , err
452
- } else {
453
- return data , nil
454
456
}
457
+ return data , nil
455
458
}
456
459
460
+ // FindIssues will return a list of issues that match the given options.
461
+ // If the "query" option is undefined it will generate a JQL query
462
+ // using any/all of the provide options: project, component, assignee,
463
+ // issuetype, watcher, reporter, sort
464
+ // Further it will restrict the fields being extracted from the jira
465
+ // response with the 'queryfields' option
457
466
func (c * Cli ) FindIssues () (interface {}, error ) {
458
467
var query string
459
468
var ok bool
460
469
// project = BAKERY and status not in (Resolved, Closed)
461
470
if query , ok = c .opts ["query" ].(string ); ! ok {
462
471
qbuff := bytes .NewBufferString ("resolution = unresolved" )
463
- if project , ok := c .opts ["project" ]; ! ok {
472
+ var project string
473
+ if project , ok = c .opts ["project" ].(string ); ! ok {
464
474
err := fmt .Errorf ("Missing required arguments, either 'query' or 'project' are required" )
465
475
log .Errorf ("%s" , err )
466
476
return nil , err
467
- } else {
468
- qbuff .WriteString (fmt .Sprintf (" AND project = '%s'" , project ))
469
477
}
478
+ qbuff .WriteString (fmt .Sprintf (" AND project = '%s'" , project ))
470
479
471
480
if component , ok := c .opts ["component" ]; ok {
472
481
qbuff .WriteString (fmt .Sprintf (" AND component = '%s'" , component ))
@@ -495,11 +504,9 @@ func (c *Cli) FindIssues() (interface{}, error) {
495
504
query = qbuff .String ()
496
505
}
497
506
498
- fields := make ( []string , 0 )
507
+ fields := []string { "summary" }
499
508
if qf , ok := c .opts ["queryfields" ].(string ); ok {
500
509
fields = strings .Split (qf , "," )
501
- } else {
502
- fields = append (fields , "summary" )
503
510
}
504
511
505
512
json , err := jsonEncode (map [string ]interface {}{
@@ -514,40 +521,42 @@ func (c *Cli) FindIssues() (interface{}, error) {
514
521
}
515
522
516
523
uri := fmt .Sprintf ("%s/rest/api/2/search" , c .endpoint )
517
- if data , err := responseToJson (c .post (uri , json )); err != nil {
524
+ var data interface {}
525
+ if data , err = responseToJSON (c .post (uri , json )); err != nil {
518
526
return nil , err
519
- } else {
520
- return data , nil
521
527
}
528
+ return data , nil
522
529
}
523
530
531
+ // GetOptString will extract the string from the Cli object options
532
+ // otherwise return the provided default
524
533
func (c * Cli ) GetOptString (optName string , dflt string ) string {
525
534
return c .getOptString (optName , dflt )
526
535
}
527
536
528
537
func (c * Cli ) getOptString (optName string , dflt string ) string {
529
538
if val , ok := c .opts [optName ].(string ); ok {
530
539
return val
531
- } else {
532
- return dflt
533
540
}
541
+ return dflt
534
542
}
535
543
544
+ // GetOptBool will extract the boolean value from the Client object options
545
+ // otherwise return the provided default\
536
546
func (c * Cli ) GetOptBool (optName string , dflt bool ) bool {
537
547
return c .getOptBool (optName , dflt )
538
548
}
539
549
540
550
func (c * Cli ) getOptBool (optName string , dflt bool ) bool {
541
551
if val , ok := c .opts [optName ].(bool ); ok {
542
552
return val
543
- } else {
544
- return dflt
545
553
}
554
+ return dflt
546
555
}
547
556
548
557
// expansions returns a comma-separated list of values for field expansion
549
558
func (c * Cli ) expansions () []string {
550
- expansions := make ( []string , 0 )
559
+ var expansions []string
551
560
if x , ok := c .opts ["expand" ].(string ); ok {
552
561
expansions = strings .Split (x , "," )
553
562
}
0 commit comments