jira-cli 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -28
- data/bin/jira +3 -1
- data/lib/jira.rb +12 -6
- data/lib/jira/api.rb +10 -5
- data/lib/jira/auth_api.rb +11 -0
- data/lib/jira/command.rb +21 -1
- data/lib/jira/commands/all.rb +2 -2
- data/lib/jira/commands/assign.rb +2 -2
- data/lib/jira/commands/comment.rb +8 -98
- data/lib/jira/commands/comment/add.rb +46 -0
- data/lib/jira/commands/comment/delete.rb +80 -0
- data/lib/jira/commands/comment/list.rb +69 -0
- data/lib/jira/commands/comment/update.rb +88 -0
- data/lib/jira/commands/delete.rb +0 -2
- data/lib/jira/commands/describe.rb +0 -2
- data/lib/jira/commands/install.rb +39 -17
- data/lib/jira/commands/link.rb +4 -3
- data/lib/jira/commands/log.rb +7 -72
- data/lib/jira/commands/log/add.rb +50 -0
- data/lib/jira/commands/log/delete.rb +80 -0
- data/lib/jira/commands/log/list.rb +69 -0
- data/lib/jira/commands/log/update.rb +89 -0
- data/lib/jira/commands/new.rb +4 -6
- data/lib/jira/commands/rename.rb +0 -2
- data/lib/jira/commands/sprint.rb +3 -3
- data/lib/jira/commands/tickets.rb +0 -2
- data/lib/jira/commands/transition.rb +0 -2
- data/lib/jira/commands/vote.rb +5 -107
- data/lib/jira/commands/vote/add.rb +43 -0
- data/lib/jira/commands/vote/delete.rb +46 -0
- data/lib/jira/commands/vote/list.rb +59 -0
- data/lib/jira/commands/watch.rb +5 -108
- data/lib/jira/commands/watch/add.rb +43 -0
- data/lib/jira/commands/watch/delete.rb +46 -0
- data/lib/jira/commands/watch/list.rb +59 -0
- data/lib/jira/constants.rb +1 -1
- data/lib/jira/core.rb +9 -1
- data/lib/jira/sprint_api.rb +2 -18
- metadata +17 -5
- data/lib/jira/commands/commit.rb +0 -14
- data/lib/jira/legacy_api.rb +0 -102
- data/lib/jira/mixins.rb +0 -56
@@ -0,0 +1,69 @@
|
|
1
|
+
module Jira
|
2
|
+
class Log < Thor
|
3
|
+
|
4
|
+
desc 'list', 'Lists work logged on the input ticket'
|
5
|
+
def list(ticket=Jira::Core.ticket)
|
6
|
+
Command::Log::List.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Log
|
13
|
+
class List < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket=Jira::Core.ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
if logs.empty?
|
23
|
+
puts "Ticket #{ticket} has no work logged."
|
24
|
+
return
|
25
|
+
end
|
26
|
+
render_table(header, rows)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_accessor :log
|
32
|
+
|
33
|
+
def header
|
34
|
+
[ 'Author', 'Updated At', 'Time Spent' ]
|
35
|
+
end
|
36
|
+
|
37
|
+
def rows
|
38
|
+
rows = []
|
39
|
+
logs.each do |log|
|
40
|
+
self.log = log
|
41
|
+
rows << row
|
42
|
+
end
|
43
|
+
rows
|
44
|
+
end
|
45
|
+
|
46
|
+
def row
|
47
|
+
[ author, updated_at, time_spent ]
|
48
|
+
end
|
49
|
+
|
50
|
+
def author
|
51
|
+
log['updateAuthor']['displayName']
|
52
|
+
end
|
53
|
+
|
54
|
+
def updated_at
|
55
|
+
Jira::Format.time(Time.parse(log['updated']))
|
56
|
+
end
|
57
|
+
|
58
|
+
def time_spent
|
59
|
+
log['timeSpent']
|
60
|
+
end
|
61
|
+
|
62
|
+
def logs
|
63
|
+
@logs ||= api.get("issue/#{ticket}/worklog")['worklogs']
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Jira
|
2
|
+
class Log < Thor
|
3
|
+
|
4
|
+
desc 'update', 'Updates work logged on the input ticket'
|
5
|
+
def update(ticket=Jira::Core.ticket)
|
6
|
+
Command::Log::Update.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Log
|
13
|
+
class Update < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket=Jira::Core.ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return unless logs?
|
23
|
+
api.patch endpoint,
|
24
|
+
params: params,
|
25
|
+
success: on_success,
|
26
|
+
failure: on_failure
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def params
|
32
|
+
{ timeSpent: updated_time_spent }
|
33
|
+
end
|
34
|
+
|
35
|
+
def updated_time_spent
|
36
|
+
io.ask('Updated time spent?')
|
37
|
+
end
|
38
|
+
|
39
|
+
def logs?
|
40
|
+
if json.empty?
|
41
|
+
puts "Ticket #{ticket} has no work logged."
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def endpoint
|
48
|
+
"issue/#{ticket}/worklog/#{to_update['id']}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_success
|
52
|
+
->{ puts "Successfully updated #{to_update['timeSpent']}." }
|
53
|
+
end
|
54
|
+
|
55
|
+
def on_failure
|
56
|
+
->{ puts "No logged work updated." }
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_update
|
60
|
+
@to_delete ||= logs[
|
61
|
+
io.select("Select a worklog to update:", logs.keys)
|
62
|
+
]
|
63
|
+
end
|
64
|
+
|
65
|
+
def logs
|
66
|
+
@logs ||= (
|
67
|
+
logs = {}
|
68
|
+
json.each do |log|
|
69
|
+
logs[description_for(log)] = log
|
70
|
+
end
|
71
|
+
logs
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def description_for(log)
|
76
|
+
author = log['updateAuthor']['displayName']
|
77
|
+
updated_at = Jira::Format.time(Time.parse(log['updated']))
|
78
|
+
time_spent = log['timeSpent']
|
79
|
+
"#{author} @ #{updated_at}: #{time_spent}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def json
|
83
|
+
@json ||= api.get("issue/#{ticket}/worklog")['worklogs']
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/jira/commands/new.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative '../command'
|
2
|
-
|
3
1
|
module Jira
|
4
2
|
class CLI < Thor
|
5
3
|
|
@@ -108,11 +106,11 @@ module Jira
|
|
108
106
|
@components ||= (
|
109
107
|
components = {}
|
110
108
|
project_metadata['components'].each do |component|
|
111
|
-
components[component['name']] = {
|
112
|
-
|
113
|
-
|
109
|
+
components[component['name']] = { 'id' => component['id'] }
|
110
|
+
end
|
111
|
+
unless components.empty?
|
112
|
+
io.multi_select("Select component(s):", components)
|
114
113
|
end
|
115
|
-
io.multi_select("Select component(s):", components) unless components.empty?
|
116
114
|
)
|
117
115
|
end
|
118
116
|
|
data/lib/jira/commands/rename.rb
CHANGED
data/lib/jira/commands/sprint.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative '../command'
|
2
|
-
|
3
1
|
module Jira
|
4
2
|
class CLI < Thor
|
5
3
|
|
@@ -57,8 +55,10 @@ module Jira
|
|
57
55
|
end
|
58
56
|
|
59
57
|
def rapid_view
|
58
|
+
keys = rapid_views.keys
|
59
|
+
return '' if keys.empty?
|
60
60
|
@rapid_view ||= rapid_views[
|
61
|
-
io.select("Select a rapid view:",
|
61
|
+
io.select("Select a rapid view:", keys)
|
62
62
|
]
|
63
63
|
end
|
64
64
|
|
data/lib/jira/commands/vote.rb
CHANGED
@@ -1,114 +1,12 @@
|
|
1
|
-
|
1
|
+
require 'jira/commands/vote/add'
|
2
|
+
require 'jira/commands/vote/delete'
|
3
|
+
require 'jira/commands/vote/list'
|
2
4
|
|
3
5
|
module Jira
|
4
6
|
class CLI < Thor
|
5
7
|
|
6
|
-
desc
|
7
|
-
|
8
|
-
Command::Vote.new(ticket).run
|
9
|
-
end
|
8
|
+
desc 'vote <command>', 'Commands for voting operations in JIRA'
|
9
|
+
subcommand 'vote', Vote
|
10
10
|
|
11
|
-
desc "votes", "List the votes of the input ticket"
|
12
|
-
def votes(ticket=Jira::Core.ticket)
|
13
|
-
Command::Votes.new(ticket).run
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "unvote", "Unvote against the input ticket"
|
17
|
-
def unvote(ticket=Jira::Core.ticket)
|
18
|
-
Command::Unvote.new(ticket).run
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
module Command
|
24
|
-
class Vote < Base
|
25
|
-
|
26
|
-
attr_accessor :ticket
|
27
|
-
|
28
|
-
def initialize(ticket)
|
29
|
-
self.ticket = ticket
|
30
|
-
end
|
31
|
-
|
32
|
-
def run
|
33
|
-
return if ticket.empty?
|
34
|
-
|
35
|
-
api.post "issue/#{ticket}/votes",
|
36
|
-
params: Jira::Core.username,
|
37
|
-
success: on_success,
|
38
|
-
failure: on_failure
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def on_success
|
44
|
-
->{ puts "Successfully added vote to ticket #{ticket}" }
|
45
|
-
end
|
46
|
-
|
47
|
-
def on_failure
|
48
|
-
->{ puts "No vote." }
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
class Votes < Base
|
54
|
-
|
55
|
-
attr_accessor :ticket
|
56
|
-
|
57
|
-
def initialize(ticket)
|
58
|
-
self.ticket = ticket
|
59
|
-
end
|
60
|
-
|
61
|
-
def run
|
62
|
-
return if ticket.empty?
|
63
|
-
return if metadata.empty?
|
64
|
-
|
65
|
-
voters = metadata['voters']
|
66
|
-
if !voters.nil? and voters.count > 0
|
67
|
-
voters.each do |voter|
|
68
|
-
displayName = voter['displayName']
|
69
|
-
|
70
|
-
printf "[%2d]", voters.index(voter)
|
71
|
-
puts " #{Jira::Format.user(displayName)}"
|
72
|
-
end
|
73
|
-
else
|
74
|
-
puts "There are no votes on ticket #{ticket}."
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def metadata
|
81
|
-
@metadata ||= api.get("issue/#{ticket}/votes")
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
class Unvote < Base
|
86
|
-
|
87
|
-
attr_accessor :ticket
|
88
|
-
|
89
|
-
def initialize(ticket)
|
90
|
-
self.ticket = ticket
|
91
|
-
end
|
92
|
-
|
93
|
-
def run
|
94
|
-
return if ticket.empty?
|
95
|
-
|
96
|
-
username = Jira::Core.username
|
97
|
-
api.delete "issue/#{ticket}/votes?username=#{username}",
|
98
|
-
success: on_success,
|
99
|
-
failure: on_failure
|
100
|
-
end
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
def on_success
|
105
|
-
->{ puts "Successfully removed vote from ticket #{ticket}" }
|
106
|
-
end
|
107
|
-
|
108
|
-
def on_failure
|
109
|
-
->{ puts "No unvote." }
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
11
|
end
|
114
12
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Jira
|
2
|
+
class Vote < Thor
|
3
|
+
|
4
|
+
desc 'add', 'Vote for the input ticket'
|
5
|
+
def add(ticket=Jira::Core.ticket)
|
6
|
+
Command::Vote::Add.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Vote
|
13
|
+
class Add < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return if ticket.empty?
|
23
|
+
|
24
|
+
api.post "issue/#{ticket}/votes",
|
25
|
+
params: "\"#{Jira::Core.username}\"",
|
26
|
+
success: on_success,
|
27
|
+
failure: on_failure
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def on_success
|
33
|
+
->{ puts "Successfully voted for ticket #{ticket}" }
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_failure
|
37
|
+
->{ puts "No vote cast." }
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Jira
|
2
|
+
class Vote < Thor
|
3
|
+
|
4
|
+
desc 'delete', 'Delete vote for the input ticket'
|
5
|
+
def delete(ticket=Jira::Core.ticket)
|
6
|
+
Command::Vote::Delete.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Vote
|
13
|
+
class Delete < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return if ticket.empty?
|
23
|
+
|
24
|
+
api.delete endpoint,
|
25
|
+
success: on_success,
|
26
|
+
failure: on_failure
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def endpoint
|
32
|
+
"issue/#{ticket}/votes?username=#{Jira::Core.username}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_success
|
36
|
+
->{ puts "Successfully removed vote from ticket #{ticket}" }
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_failure
|
40
|
+
->{ puts "No unvote." }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Jira
|
2
|
+
class Vote < Thor
|
3
|
+
|
4
|
+
desc 'list', "List the votes on the input ticket"
|
5
|
+
def list(ticket=Jira::Core.ticket)
|
6
|
+
Command::Vote::List.new(ticket).run
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Command
|
12
|
+
module Vote
|
13
|
+
class List < Base
|
14
|
+
|
15
|
+
attr_accessor :ticket
|
16
|
+
|
17
|
+
def initialize(ticket)
|
18
|
+
self.ticket = ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return if ticket.empty?
|
23
|
+
return if voters.nil?
|
24
|
+
return if no_voters?
|
25
|
+
|
26
|
+
voters.each do |voter|
|
27
|
+
self.voter = voter
|
28
|
+
display_voter
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_accessor :voter
|
35
|
+
|
36
|
+
def display_voter
|
37
|
+
puts "[#{voters.index(voter).to_s.rjust(2)}] #{display_name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def display_name
|
41
|
+
Jira::Format.user(voter['displayName'])
|
42
|
+
end
|
43
|
+
|
44
|
+
def no_voters?
|
45
|
+
if voters.count == 0
|
46
|
+
puts "There are no votes on ticket #{ticket}."
|
47
|
+
return true
|
48
|
+
end
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
def voters
|
53
|
+
@voters ||= api.get("issue/#{ticket}/votes")['voters']
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|