ruby-jira-cli 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +47 -0
  3. data/bin/jira +26 -0
  4. data/lib/jira/api.rb +76 -0
  5. data/lib/jira/auth_api.rb +11 -0
  6. data/lib/jira/command.rb +60 -0
  7. data/lib/jira/commands/all.rb +72 -0
  8. data/lib/jira/commands/assign.rb +65 -0
  9. data/lib/jira/commands/attachments.rb +45 -0
  10. data/lib/jira/commands/checkout.rb +87 -0
  11. data/lib/jira/commands/comment/add.rb +52 -0
  12. data/lib/jira/commands/comment/delete.rb +80 -0
  13. data/lib/jira/commands/comment/list.rb +72 -0
  14. data/lib/jira/commands/comment/update.rb +88 -0
  15. data/lib/jira/commands/comment.rb +14 -0
  16. data/lib/jira/commands/delete.rb +92 -0
  17. data/lib/jira/commands/describe.rb +64 -0
  18. data/lib/jira/commands/install.rb +121 -0
  19. data/lib/jira/commands/link.rb +94 -0
  20. data/lib/jira/commands/log/add.rb +52 -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/log.rb +13 -0
  25. data/lib/jira/commands/new.rb +174 -0
  26. data/lib/jira/commands/rename.rb +53 -0
  27. data/lib/jira/commands/sprint.rb +109 -0
  28. data/lib/jira/commands/tickets.rb +55 -0
  29. data/lib/jira/commands/transition.rb +97 -0
  30. data/lib/jira/commands/version.rb +10 -0
  31. data/lib/jira/commands/vote/add.rb +43 -0
  32. data/lib/jira/commands/vote/delete.rb +46 -0
  33. data/lib/jira/commands/vote/list.rb +59 -0
  34. data/lib/jira/commands/vote.rb +12 -0
  35. data/lib/jira/commands/watch/add.rb +43 -0
  36. data/lib/jira/commands/watch/delete.rb +46 -0
  37. data/lib/jira/commands/watch/list.rb +59 -0
  38. data/lib/jira/commands/watch.rb +12 -0
  39. data/lib/jira/constants.rb +7 -0
  40. data/lib/jira/core.rb +101 -0
  41. data/lib/jira/exceptions.rb +3 -0
  42. data/lib/jira/format.rb +78 -0
  43. data/lib/jira/sprint_api.rb +33 -0
  44. data/lib/jira.rb +19 -0
  45. metadata +202 -0
@@ -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
+ 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
@@ -0,0 +1,12 @@
1
+ require 'jira/commands/vote/add'
2
+ require 'jira/commands/vote/delete'
3
+ require 'jira/commands/vote/list'
4
+
5
+ module Jira
6
+ class CLI < Thor
7
+
8
+ desc 'vote <command>', 'Commands for voting operations in JIRA'
9
+ subcommand 'vote', Vote
10
+
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ module Jira
2
+ class Watch < Thor
3
+
4
+ desc 'add', 'Watch the input ticket'
5
+ def add(ticket=Jira::Core.ticket)
6
+ Command::Watch::Add.new(ticket).run
7
+ end
8
+
9
+ end
10
+
11
+ module Command
12
+ module Watch
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}/watchers",
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 "Now watching ticket #{ticket}" }
34
+ end
35
+
36
+ def on_failure
37
+ ->{ puts "No watch." }
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ module Jira
2
+ class Watch < Thor
3
+
4
+ desc 'delete', 'Stop watching the input ticket'
5
+ def delete(ticket=Jira::Core.ticket)
6
+ Command::Watch::Delete.new(ticket).run
7
+ end
8
+
9
+ end
10
+
11
+ module Command
12
+ module Watch
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}/watchers?username=#{Jira::Core.username}"
33
+ end
34
+
35
+ def on_success
36
+ ->{ puts "Stopped watching ticket #{ticket}" }
37
+ end
38
+
39
+ def on_failure
40
+ ->{ puts "Did not stop watching ticket." }
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,59 @@
1
+ module Jira
2
+ class Watch < Thor
3
+
4
+ desc 'list', 'Lists the watchers of the input ticket'
5
+ def list(ticket=Jira::Core.ticket)
6
+ Command::Watch::List.new(ticket).run
7
+ end
8
+
9
+ end
10
+
11
+ module Command
12
+ module Watch
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 watchers.nil?
24
+ return if no_watchers?
25
+
26
+ watchers.each do |watcher|
27
+ self.watcher = watcher
28
+ display_watcher
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ attr_accessor :watcher
35
+
36
+ def no_watchers?
37
+ if watchers.count == 0
38
+ puts "Ticket #{ticket} has no watchers."
39
+ return true
40
+ end
41
+ false
42
+ end
43
+
44
+ def display_watcher
45
+ puts "[#{watchers.index(watcher).to_s.rjust(2)}] #{display_name}"
46
+ end
47
+
48
+ def display_name
49
+ Jira::Format.user(watcher['displayName'])
50
+ end
51
+
52
+ def watchers
53
+ @watchers ||= api.get("issue/#{ticket}/watchers")['watchers']
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ require 'jira/commands/watch/add'
2
+ require 'jira/commands/watch/delete'
3
+ require 'jira/commands/watch/list'
4
+
5
+ module Jira
6
+ class CLI < Thor
7
+
8
+ desc 'watch <command>', 'Commands for watching tickets in JIRA'
9
+ subcommand 'watch', Watch
10
+
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jira
4
+
5
+ VERSION = '0.0.3'.freeze
6
+
7
+ end
data/lib/jira/core.rb ADDED
@@ -0,0 +1,101 @@
1
+ module Jira
2
+ class Core
3
+ class << self
4
+
5
+ #
6
+ # @return [String] JIRA project endpoint
7
+ #
8
+ def url
9
+ @url ||= ENV['JIRA_URL'] || config[:global]['url']
10
+ end
11
+
12
+ #
13
+ # @return [String] JIRA username
14
+ #
15
+ def username
16
+ @username ||= ENV['JIRA_USERNAME'] || config[:global]['username']
17
+ end
18
+
19
+ #
20
+ # @return [String] JIRA password
21
+ #
22
+ def password
23
+ @password ||= ENV['JIRA_PASSWORD'] || config[:global]['password']
24
+ end
25
+
26
+ #
27
+ # @return [String] JIRA token
28
+ #
29
+ def token
30
+ @token ||= ENV['JIRA_TOKEN'] || config[:global]['token']
31
+ end
32
+
33
+ #
34
+ # @return [Hash] JIRA cookie
35
+ #
36
+ def cookie
37
+ return {} if config[:cookie].nil? || config[:cookie].empty?
38
+ { name: config[:cookie]['name'], value: config[:cookie]['value'] }
39
+ end
40
+
41
+ #
42
+ # @return [String] default ticket is the current branch
43
+ #
44
+ def ticket
45
+ `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip
46
+ end
47
+
48
+ #
49
+ # Determines whether or not the input ticket matches the expected JIRA
50
+ # ticketing syntax. Outputs a warning that the input ticket isn't a valid
51
+ # ticket.
52
+ #
53
+ # @param ticket [String] input ticket name
54
+ # @param verbose [Boolean] verbose output of the ticket warning
55
+ #
56
+ # @return [Boolean] whether input string matches JIRA ticket syntax
57
+ #
58
+ def ticket?(ticket, verbose=true)
59
+ !!ticket.to_s[/^[a-zA-Z]+-[0-9]+$/] and return true
60
+ if verbose
61
+ puts "#{Jira::Format.ticket(ticket)} is not a valid JIRA ticket."
62
+ end
63
+ false
64
+ end
65
+
66
+ ### Relevant Paths
67
+
68
+ #
69
+ # @return [String] path to .jira-cli file
70
+ #
71
+ def cli_path
72
+ @cli_path ||= root_path + "/.jira-cli"
73
+ end
74
+
75
+ #
76
+ # @return [String] path to .jira-rescue-cookie file
77
+ #
78
+ def rescue_cookie_path
79
+ @rescue_cookie_path ||= root_path + "/.jira-rescue-cookie"
80
+ end
81
+
82
+ def config
83
+ @config ||= (
84
+ raise InstallationException unless File.exist?(cli_path)
85
+ IniFile.load(cli_path, comment: '#', encoding: 'UTF-8')
86
+ )
87
+ end
88
+
89
+ private
90
+
91
+ def root_path
92
+ @root_path ||= (
93
+ root_path = `git rev-parse --show-toplevel 2>/dev/null`.strip
94
+ raise GitException if root_path.empty?
95
+ root_path
96
+ )
97
+ end
98
+
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,3 @@
1
+ class InstallationException < StandardError; end
2
+ class GitException < StandardError; end
3
+ class UnauthorizedException < StandardError; end
@@ -0,0 +1,78 @@
1
+ module Jira
2
+ class Format
3
+ class << self
4
+
5
+ def star
6
+ "#{Thor::Shell::Color::BOLD}"\
7
+ "#{Thor::Shell::Color::YELLOW}"\
8
+ "*"\
9
+ "#{Thor::Shell::Color::CLEAR}"
10
+ end
11
+
12
+ def ticket(ticket)
13
+ "#{Thor::Shell::Color::RED}"\
14
+ "#{ticket}"\
15
+ "#{Thor::Shell::Color::CLEAR}"
16
+ end
17
+
18
+ def status(status)
19
+ "["\
20
+ "#{Thor::Shell::Color::BLUE}"\
21
+ "#{status}"\
22
+ "#{Thor::Shell::Color::CLEAR}"\
23
+ "]"
24
+ end
25
+
26
+ def summary(summary)
27
+ "#{Thor::Shell::Color::BOLD}"\
28
+ "#{Thor::Shell::Color::WHITE}"\
29
+ "#{summary}"\
30
+ "#{Thor::Shell::Color::CLEAR}"
31
+ end
32
+
33
+ def user(user)
34
+ "#{Thor::Shell::Color::MAGENTA}"\
35
+ "#{user}"\
36
+ "#{Thor::Shell::Color::CLEAR}"
37
+ end
38
+
39
+ def time(time)
40
+ "#{Thor::Shell::Color::BLUE}"\
41
+ "#{time.strftime('%l:%M%P on %b %d, %Y').strip}"\
42
+ "#{Thor::Shell::Color::CLEAR}"
43
+ end
44
+
45
+ def comment(comment)
46
+ comment = self.wrap(comment)
47
+ comment.gsub!(/\[~[a-z]+\]/, '[[[\0]]]')
48
+ comment.gsub!(
49
+ '[[[[~',
50
+ "#{Thor::Shell::Color::BOLD}"\
51
+ "#{Thor::Shell::Color::WHITE}"\
52
+ "("\
53
+ "#{Thor::Shell::Color::MAGENTA}"\
54
+ "@"
55
+ )
56
+ comment.gsub!(
57
+ ']]]]',
58
+ "#{Thor::Shell::Color::WHITE}"\
59
+ ")"\
60
+ "#{Thor::Shell::Color::CLEAR}"
61
+ )
62
+ comment
63
+ end
64
+
65
+ def wrap(text)
66
+ width = 80
67
+ text.split("\n").collect do |line|
68
+ if line.length > width
69
+ line.gsub(/(.{1,#{width}})(\s+|$)/, "\\1\n").strip
70
+ else
71
+ line
72
+ end
73
+ end * "\n"
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,33 @@
1
+ module Jira
2
+ class SprintAPI < API
3
+
4
+ def sprint(rapid_view_id, sprint_id)
5
+ params = {
6
+ rapidViewId: rapid_view_id,
7
+ sprintId: sprint_id
8
+ }
9
+ json = get('rapid/charts/sprintreport', params: params) || {}
10
+ return json if json['errorMessages'].nil?
11
+ {}
12
+ end
13
+
14
+ def sprints(rapid_view_id)
15
+ json = get("sprintquery/#{rapid_view_id}")
16
+ return json if json['errorMessages'].nil?
17
+ {}
18
+ end
19
+
20
+ def rapid_views
21
+ json = get("rapidview")
22
+ return json['views'] if json['errorMessages'].nil?
23
+ []
24
+ end
25
+
26
+ protected
27
+
28
+ def endpoint
29
+ "#{Jira::Core.url}/rest/greenhopper/latest"
30
+ end
31
+
32
+ end
33
+ end
data/lib/jira.rb ADDED
@@ -0,0 +1,19 @@
1
+ # external dependencies
2
+ require 'thor'
3
+ require 'tty-table'
4
+ require 'inifile'
5
+ require 'tty-prompt'
6
+ require 'json'
7
+ require 'faraday'
8
+ require 'faraday_middleware'
9
+ # internal dependencies
10
+ require 'jira/exceptions'
11
+ require 'jira/constants'
12
+ require 'jira/command'
13
+ require 'jira/format'
14
+
15
+ module Jira
16
+ class CLI < Thor
17
+
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,202 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-jira-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Alex Myers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.14'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.0
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.9.0
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.0
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 0.9.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: faraday_middleware
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.10.0
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.10.0
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: 0.10.0
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 0.10.0
67
+ - !ruby/object:Gem::Dependency
68
+ name: tty-prompt
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: 0.3.0
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 0.3.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 0.3.0
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 0.3.0
87
+ - !ruby/object:Gem::Dependency
88
+ name: tty-table
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: 0.4.0
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 0.4.0
97
+ type: :runtime
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.4.0
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 0.4.0
107
+ - !ruby/object:Gem::Dependency
108
+ name: inifile
109
+ requirement: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - "~>"
112
+ - !ruby/object:Gem::Version
113
+ version: 2.0.2
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 2.0.2
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 2.0.2
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 2.0.2
127
+ description: Ruby CLI managing git-based JIRA workflows
128
+ email: dev.alex.myers@gmail.com
129
+ executables:
130
+ - jira
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - README.md
135
+ - bin/jira
136
+ - lib/jira.rb
137
+ - lib/jira/api.rb
138
+ - lib/jira/auth_api.rb
139
+ - lib/jira/command.rb
140
+ - lib/jira/commands/all.rb
141
+ - lib/jira/commands/assign.rb
142
+ - lib/jira/commands/attachments.rb
143
+ - lib/jira/commands/checkout.rb
144
+ - lib/jira/commands/comment.rb
145
+ - lib/jira/commands/comment/add.rb
146
+ - lib/jira/commands/comment/delete.rb
147
+ - lib/jira/commands/comment/list.rb
148
+ - lib/jira/commands/comment/update.rb
149
+ - lib/jira/commands/delete.rb
150
+ - lib/jira/commands/describe.rb
151
+ - lib/jira/commands/install.rb
152
+ - lib/jira/commands/link.rb
153
+ - lib/jira/commands/log.rb
154
+ - lib/jira/commands/log/add.rb
155
+ - lib/jira/commands/log/delete.rb
156
+ - lib/jira/commands/log/list.rb
157
+ - lib/jira/commands/log/update.rb
158
+ - lib/jira/commands/new.rb
159
+ - lib/jira/commands/rename.rb
160
+ - lib/jira/commands/sprint.rb
161
+ - lib/jira/commands/tickets.rb
162
+ - lib/jira/commands/transition.rb
163
+ - lib/jira/commands/version.rb
164
+ - lib/jira/commands/vote.rb
165
+ - lib/jira/commands/vote/add.rb
166
+ - lib/jira/commands/vote/delete.rb
167
+ - lib/jira/commands/vote/list.rb
168
+ - lib/jira/commands/watch.rb
169
+ - lib/jira/commands/watch/add.rb
170
+ - lib/jira/commands/watch/delete.rb
171
+ - lib/jira/commands/watch/list.rb
172
+ - lib/jira/constants.rb
173
+ - lib/jira/core.rb
174
+ - lib/jira/exceptions.rb
175
+ - lib/jira/format.rb
176
+ - lib/jira/sprint_api.rb
177
+ homepage: https://github.com/ajmyers01/jira-cli
178
+ licenses:
179
+ - MIT
180
+ metadata: {}
181
+ post_install_message:
182
+ rdoc_options: []
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ required_rubygems_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ requirements: []
196
+ rubyforge_project:
197
+ rubygems_version: 2.4.8
198
+ signing_key:
199
+ specification_version: 4
200
+ summary: JIRA CLI
201
+ test_files: []
202
+ has_rdoc: