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.
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