jira-cli 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/jira.rb +0 -14
- data/lib/jira/api.rb +51 -82
- data/lib/jira/command.rb +36 -0
- data/lib/jira/commands/all.rb +75 -0
- data/lib/jira/commands/assign.rb +53 -7
- data/lib/jira/commands/attachments.rb +27 -4
- data/lib/jira/commands/comment.rb +3 -3
- data/lib/jira/commands/delete.rb +81 -27
- data/lib/jira/commands/describe.rb +51 -68
- data/lib/jira/commands/install.rb +54 -16
- data/lib/jira/commands/link.rb +68 -38
- data/lib/jira/commands/log.rb +4 -4
- data/lib/jira/commands/new.rb +137 -79
- data/lib/jira/commands/rename.rb +44 -10
- data/lib/jira/commands/sprint.rb +80 -0
- data/lib/jira/commands/tickets.rb +28 -4
- data/lib/jira/commands/transition.rb +60 -24
- data/lib/jira/commands/vote.rb +89 -16
- data/lib/jira/commands/watch.rb +90 -16
- data/lib/jira/constants.rb +1 -1
- data/lib/jira/core.rb +25 -53
- data/lib/jira/legacy_api.rb +102 -0
- data/lib/jira/mixins.rb +4 -8
- data/lib/jira/sprint_api.rb +49 -0
- metadata +69 -11
- data/lib/jira/io.rb +0 -17
data/lib/jira/commands/rename.rb
CHANGED
@@ -1,19 +1,53 @@
|
|
1
|
+
require_relative '../command'
|
2
|
+
|
1
3
|
module Jira
|
2
4
|
class CLI < Thor
|
3
5
|
|
4
6
|
desc "rename", "Updates the summary of the input ticket"
|
5
7
|
def rename(ticket=Jira::Core.ticket)
|
6
|
-
|
7
|
-
summary = self.io.ask("New ticket summary?")
|
8
|
-
if !summary.strip.empty?
|
9
|
-
params = { fields: { summary: summary } }
|
10
|
-
self.api.put("issue/#{ticket}", params) do |json|
|
11
|
-
puts "Successfully updated ticket #{ticket}'s summary."
|
12
|
-
end
|
13
|
-
else
|
14
|
-
puts "No change made to ticket #{ticket}."
|
15
|
-
end
|
8
|
+
Command::Rename.new(ticket).run
|
16
9
|
end
|
17
10
|
|
18
11
|
end
|
12
|
+
|
13
|
+
module Command
|
14
|
+
class Rename < Base
|
15
|
+
|
16
|
+
attr_accessor :ticket
|
17
|
+
|
18
|
+
def initialize(ticket)
|
19
|
+
self.ticket = ticket
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
return if ticket.empty?
|
24
|
+
return if summary.empty?
|
25
|
+
api.patch "issue/#{ticket}",
|
26
|
+
params: params,
|
27
|
+
success: on_success,
|
28
|
+
failure: on_failure
|
29
|
+
end
|
30
|
+
|
31
|
+
def params
|
32
|
+
{
|
33
|
+
fields: {
|
34
|
+
summary: summary
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_success
|
40
|
+
->{ puts "Successfully updated ticket #{ticket}'s summary." }
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_failure
|
44
|
+
->{ puts "No change made to ticket #{ticket}." }
|
45
|
+
end
|
46
|
+
|
47
|
+
def summary
|
48
|
+
@summary ||= io.ask("New summary for ticket #{ticket}:")
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
19
53
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../command'
|
2
|
+
|
3
|
+
module Jira
|
4
|
+
class CLI < Thor
|
5
|
+
|
6
|
+
desc "sprint", "Lists sprint info"
|
7
|
+
def sprint
|
8
|
+
Command::Sprint.new.run
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
module Command
|
14
|
+
class Sprint < Base
|
15
|
+
|
16
|
+
def run
|
17
|
+
return if rapid_view.empty?
|
18
|
+
return if no_sprints?
|
19
|
+
return if sprint.empty?
|
20
|
+
render_table(
|
21
|
+
[ 'Sprint', 'State' ],
|
22
|
+
[ [ info['sprint']['name'], info['sprint']['state'] ] ]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def no_sprints?
|
29
|
+
if sprints.empty?
|
30
|
+
puts "The #{rapid_view['name']} board has no sprints."
|
31
|
+
return true
|
32
|
+
end
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
|
36
|
+
def info
|
37
|
+
@info ||= sprint_api.sprint(rapid_view['id'], sprint['id'])
|
38
|
+
end
|
39
|
+
|
40
|
+
def sprint
|
41
|
+
@sprint ||= sprints[
|
42
|
+
io.select("Select a sprint:", sprints.keys[-10..-1])
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
def sprints
|
47
|
+
@sprints ||= (
|
48
|
+
sprints = {}
|
49
|
+
sprint_api.sprints(rapid_view['id'])['sprints'].each do |sprint|
|
50
|
+
sprints[sprint['name']] = {
|
51
|
+
'id' => sprint['id'],
|
52
|
+
'name' => sprint['name']
|
53
|
+
}
|
54
|
+
end
|
55
|
+
sprints
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def rapid_view
|
60
|
+
@rapid_view ||= rapid_views[
|
61
|
+
io.select("Select a rapid view:", rapid_views.keys)
|
62
|
+
]
|
63
|
+
end
|
64
|
+
|
65
|
+
def rapid_views
|
66
|
+
@rapid_views ||= (
|
67
|
+
rapid_views = {}
|
68
|
+
sprint_api.rapid_views.each do |rapid_view|
|
69
|
+
rapid_views[rapid_view['name']] = {
|
70
|
+
'id' => rapid_view['id'],
|
71
|
+
'name' => rapid_view['name']
|
72
|
+
}
|
73
|
+
end
|
74
|
+
rapid_views
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,11 +1,29 @@
|
|
1
|
+
require_relative '../command'
|
2
|
+
|
1
3
|
module Jira
|
2
4
|
class CLI < Thor
|
3
5
|
|
4
6
|
desc "tickets", "List the tickets of the input username"
|
5
7
|
def tickets(username=Jira::Core.username)
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
Command::Tickets.new(username).run
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Command
|
13
|
+
class Tickets < Base
|
14
|
+
|
15
|
+
attr_accessor :username
|
16
|
+
|
17
|
+
def initialize(username)
|
18
|
+
self.username = username
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return if username.empty?
|
23
|
+
return if metadata.empty?
|
24
|
+
|
25
|
+
issues = metadata['issues']
|
26
|
+
if !issues.nil? and issues.count > 0
|
9
27
|
issues.each do |issue|
|
10
28
|
ticket = issue['key']
|
11
29
|
|
@@ -16,7 +34,13 @@ module Jira
|
|
16
34
|
puts "There are no tickets for username #{username}."
|
17
35
|
end
|
18
36
|
end
|
19
|
-
end
|
20
37
|
|
38
|
+
private
|
39
|
+
|
40
|
+
def metadata
|
41
|
+
@metadata ||= api.get("search?jql=assignee=#{username}")
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
21
45
|
end
|
22
46
|
end
|
@@ -1,36 +1,72 @@
|
|
1
|
+
require_relative '../command'
|
2
|
+
|
1
3
|
module Jira
|
2
4
|
class CLI < Thor
|
3
5
|
|
4
6
|
desc "transition", "Transitions the input ticket to the next state"
|
5
7
|
def transition(ticket=Jira::Core.ticket)
|
6
|
-
|
7
|
-
options = {}
|
8
|
-
json['transitions'].each do |transition|
|
9
|
-
options[transition['to']['name']] = transition['id']
|
10
|
-
end
|
11
|
-
options['Cancel'] = nil
|
12
|
-
|
13
|
-
choice = self.io.choose(
|
14
|
-
"Transition #{Jira::Format.ticket(ticket)} to",
|
15
|
-
options.keys
|
16
|
-
)
|
17
|
-
if options[choice].nil?
|
18
|
-
puts "No transition was performed on #{ticket}."
|
19
|
-
else
|
20
|
-
self.api_transition(ticket, options[choice], choice)
|
21
|
-
end
|
22
|
-
end
|
8
|
+
Command::Transition.new(ticket).run
|
23
9
|
end
|
24
10
|
|
25
|
-
|
11
|
+
end
|
12
|
+
|
13
|
+
module Command
|
14
|
+
class Transition < Base
|
15
|
+
|
16
|
+
attr_accessor :ticket
|
17
|
+
|
18
|
+
def initialize(ticket)
|
19
|
+
self.ticket = ticket
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
return if ticket.empty?
|
24
|
+
return if metadata.empty?
|
25
|
+
return if transition.empty?
|
26
|
+
api.post "issue/#{ticket}/transitions",
|
27
|
+
params: params,
|
28
|
+
success: on_success,
|
29
|
+
failure: on_failure
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def params
|
35
|
+
{ transition: { id: transition } }
|
36
|
+
end
|
26
37
|
|
27
|
-
def
|
28
|
-
|
29
|
-
self.api.post("issue/#{ticket}/transitions", params) do |json|
|
30
|
-
puts "Successfully performed transition (#{description}) "\
|
31
|
-
"on ticket #{ticket}."
|
32
|
-
end
|
38
|
+
def on_success
|
39
|
+
->{ puts "Transitioned ticket #{ticket} to #{transition_name}." }
|
33
40
|
end
|
34
41
|
|
42
|
+
def on_failure
|
43
|
+
->{ puts "Failed to transition ticket #{ticket}." }
|
44
|
+
end
|
45
|
+
|
46
|
+
def transition_name
|
47
|
+
transitions.invert[transition]
|
48
|
+
end
|
49
|
+
|
50
|
+
def transition
|
51
|
+
@transition ||= transitions[
|
52
|
+
io.select("Transition #{ticket} to:", transitions.keys)
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
def transitions
|
57
|
+
@transitions ||= (
|
58
|
+
transitions = {}
|
59
|
+
metadata['transitions'].each do |transition|
|
60
|
+
transitions[transition['to']['name']] = transition['id']
|
61
|
+
end
|
62
|
+
transitions
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
def metadata
|
67
|
+
@metadata ||= api.get("issue/#{ticket}/transitions")
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
35
71
|
end
|
36
72
|
end
|
data/lib/jira/commands/vote.rb
CHANGED
@@ -1,20 +1,69 @@
|
|
1
|
+
require_relative '../command'
|
2
|
+
|
1
3
|
module Jira
|
2
4
|
class CLI < Thor
|
3
5
|
|
4
6
|
desc "vote", "Vote against the input ticket"
|
5
7
|
def vote(ticket=Jira::Core.ticket)
|
6
|
-
|
7
|
-
puts "Successfully voted against ticket #{ticket}"
|
8
|
-
return
|
9
|
-
end
|
10
|
-
puts "No vote."
|
8
|
+
Command::Vote.new(ticket).run
|
11
9
|
end
|
12
10
|
|
13
11
|
desc "votes", "List the votes of the input ticket"
|
14
12
|
def votes(ticket=Jira::Core.ticket)
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
18
67
|
voters.each do |voter|
|
19
68
|
displayName = voter['displayName']
|
20
69
|
|
@@ -25,17 +74,41 @@ module Jira
|
|
25
74
|
puts "There are no votes on ticket #{ticket}."
|
26
75
|
end
|
27
76
|
end
|
28
|
-
end
|
29
77
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
puts "Successfully unvoted against ticket #{ticket}"
|
35
|
-
return
|
78
|
+
private
|
79
|
+
|
80
|
+
def metadata
|
81
|
+
@metadata ||= api.get("issue/#{ticket}/votes")
|
36
82
|
end
|
37
|
-
puts "No unvote."
|
38
83
|
end
|
39
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
|
40
113
|
end
|
41
114
|
end
|
data/lib/jira/commands/watch.rb
CHANGED
@@ -1,20 +1,70 @@
|
|
1
|
+
require_relative '../command'
|
2
|
+
|
1
3
|
module Jira
|
2
4
|
class CLI < Thor
|
3
5
|
|
4
6
|
desc "watch", "Watch against the input ticket"
|
5
7
|
def watch(ticket=Jira::Core.ticket)
|
6
|
-
|
7
|
-
puts "Successfully watched against ticket #{ticket}"
|
8
|
-
return
|
9
|
-
end
|
10
|
-
puts "No watch."
|
8
|
+
Command::Watch.new(ticket).run
|
11
9
|
end
|
12
10
|
|
13
11
|
desc "watchers", "List the watchers of the input ticket"
|
14
12
|
def watchers(ticket=Jira::Core.ticket)
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
Command::Watchers.new(ticket).run
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "unwatch", "Unwatch against the input ticket"
|
17
|
+
def unwatch(ticket=Jira::Core.ticket)
|
18
|
+
Command::Unwatch.new(ticket).run
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
module Command
|
24
|
+
class Watch < 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}/watchers",
|
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 "Now watching ticket #{ticket}" }
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_failure
|
48
|
+
->{ puts "No watch." }
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
class Watchers < Base
|
55
|
+
|
56
|
+
attr_accessor :ticket
|
57
|
+
|
58
|
+
def initialize(ticket)
|
59
|
+
self.ticket = ticket
|
60
|
+
end
|
61
|
+
|
62
|
+
def run
|
63
|
+
return if ticket.empty?
|
64
|
+
return if metadata.empty?
|
65
|
+
|
66
|
+
watchers = metadata['watchers']
|
67
|
+
if !watchers.nil? and watchers.count > 0
|
18
68
|
watchers.each do |watcher|
|
19
69
|
displayName = watcher['displayName']
|
20
70
|
|
@@ -25,17 +75,41 @@ module Jira
|
|
25
75
|
puts "There are no watchers on ticket #{ticket}."
|
26
76
|
end
|
27
77
|
end
|
28
|
-
end
|
29
78
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
puts "Successfully unwatched against ticket #{ticket}"
|
35
|
-
return
|
79
|
+
private
|
80
|
+
|
81
|
+
def metadata
|
82
|
+
@metadata ||= api.get("issue/#{ticket}/watchers")
|
36
83
|
end
|
37
|
-
puts "No unwatch."
|
38
84
|
end
|
39
85
|
|
86
|
+
class Unwatch < Base
|
87
|
+
|
88
|
+
attr_accessor :ticket
|
89
|
+
|
90
|
+
def initialize(ticket)
|
91
|
+
self.ticket = ticket
|
92
|
+
end
|
93
|
+
|
94
|
+
def run
|
95
|
+
return if ticket.empty?
|
96
|
+
|
97
|
+
username = Jira::Core.username
|
98
|
+
api.delete "issue/#{ticket}/watchers?username=#{username}",
|
99
|
+
success: on_success,
|
100
|
+
failure: on_failure
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def on_success
|
106
|
+
->{ puts "Stopped watching ticket #{ticket}" }
|
107
|
+
end
|
108
|
+
|
109
|
+
def on_failure
|
110
|
+
->{ puts "No unwatch." }
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
40
114
|
end
|
41
115
|
end
|