ruby-jira-cli 0.0.3

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 (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: