jira-cli 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -28
  3. data/bin/jira +3 -1
  4. data/lib/jira.rb +12 -6
  5. data/lib/jira/api.rb +10 -5
  6. data/lib/jira/auth_api.rb +11 -0
  7. data/lib/jira/command.rb +21 -1
  8. data/lib/jira/commands/all.rb +2 -2
  9. data/lib/jira/commands/assign.rb +2 -2
  10. data/lib/jira/commands/comment.rb +8 -98
  11. data/lib/jira/commands/comment/add.rb +46 -0
  12. data/lib/jira/commands/comment/delete.rb +80 -0
  13. data/lib/jira/commands/comment/list.rb +69 -0
  14. data/lib/jira/commands/comment/update.rb +88 -0
  15. data/lib/jira/commands/delete.rb +0 -2
  16. data/lib/jira/commands/describe.rb +0 -2
  17. data/lib/jira/commands/install.rb +39 -17
  18. data/lib/jira/commands/link.rb +4 -3
  19. data/lib/jira/commands/log.rb +7 -72
  20. data/lib/jira/commands/log/add.rb +50 -0
  21. data/lib/jira/commands/log/delete.rb +80 -0
  22. data/lib/jira/commands/log/list.rb +69 -0
  23. data/lib/jira/commands/log/update.rb +89 -0
  24. data/lib/jira/commands/new.rb +4 -6
  25. data/lib/jira/commands/rename.rb +0 -2
  26. data/lib/jira/commands/sprint.rb +3 -3
  27. data/lib/jira/commands/tickets.rb +0 -2
  28. data/lib/jira/commands/transition.rb +0 -2
  29. data/lib/jira/commands/vote.rb +5 -107
  30. data/lib/jira/commands/vote/add.rb +43 -0
  31. data/lib/jira/commands/vote/delete.rb +46 -0
  32. data/lib/jira/commands/vote/list.rb +59 -0
  33. data/lib/jira/commands/watch.rb +5 -108
  34. data/lib/jira/commands/watch/add.rb +43 -0
  35. data/lib/jira/commands/watch/delete.rb +46 -0
  36. data/lib/jira/commands/watch/list.rb +59 -0
  37. data/lib/jira/constants.rb +1 -1
  38. data/lib/jira/core.rb +9 -1
  39. data/lib/jira/sprint_api.rb +2 -18
  40. metadata +17 -5
  41. data/lib/jira/commands/commit.rb +0 -14
  42. data/lib/jira/legacy_api.rb +0 -102
  43. 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
@@ -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
- 'id' => component['id']
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
 
@@ -1,5 +1,3 @@
1
- require_relative '../command'
2
-
3
1
  module Jira
4
2
  class CLI < Thor
5
3
 
@@ -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:", rapid_views.keys)
61
+ io.select("Select a rapid view:", keys)
62
62
  ]
63
63
  end
64
64
 
@@ -1,5 +1,3 @@
1
- require_relative '../command'
2
-
3
1
  module Jira
4
2
  class CLI < Thor
5
3
 
@@ -1,5 +1,3 @@
1
- require_relative '../command'
2
-
3
1
  module Jira
4
2
  class CLI < Thor
5
3
 
@@ -1,114 +1,12 @@
1
- require_relative '../command'
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 "vote", "Vote against the input ticket"
7
- def vote(ticket=Jira::Core.ticket)
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