jira-cli 0.2.1 → 0.2.2
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.
- 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/constants.rb
CHANGED
data/lib/jira/core.rb
CHANGED
@@ -2,41 +2,39 @@ module Jira
|
|
2
2
|
class Core
|
3
3
|
class << self
|
4
4
|
|
5
|
-
#
|
6
|
-
# Memoizes url, username, and password
|
7
|
-
#
|
8
|
-
def setup
|
9
|
-
self.url
|
10
|
-
end
|
11
|
-
|
12
|
-
### Virtual Attributes
|
13
|
-
|
14
5
|
#
|
15
6
|
# @return [String] JIRA project endpoint
|
16
7
|
#
|
17
8
|
def url
|
18
|
-
@url ||= ENV['JIRA_URL'] ||
|
9
|
+
@url ||= ENV['JIRA_URL'] || config[:global]['url']
|
19
10
|
end
|
20
11
|
|
21
12
|
#
|
22
13
|
# @return [String] JIRA username
|
23
14
|
#
|
24
15
|
def username
|
25
|
-
@username ||= ENV['JIRA_USERNAME'] ||
|
16
|
+
@username ||= ENV['JIRA_USERNAME'] || config[:global]['username']
|
26
17
|
end
|
27
18
|
|
28
19
|
#
|
29
20
|
# @return [String] JIRA password
|
30
21
|
#
|
31
22
|
def password
|
32
|
-
@password ||= ENV['JIRA_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'] || self.read(self.cli_path)[:global]['token']
|
33
31
|
end
|
34
32
|
|
35
33
|
#
|
36
34
|
# @return [String] default ticket is the current branch
|
37
35
|
#
|
38
36
|
def ticket
|
39
|
-
`git rev-parse --abbrev-ref HEAD`.strip
|
37
|
+
`git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip
|
40
38
|
end
|
41
39
|
|
42
40
|
#
|
@@ -63,51 +61,25 @@ module Jira
|
|
63
61
|
# @return [String] path to .jira-cli file
|
64
62
|
#
|
65
63
|
def cli_path
|
66
|
-
@cli_path ||=
|
64
|
+
@cli_path ||= root_path + "/.jira-cli"
|
67
65
|
end
|
68
66
|
|
69
|
-
|
70
|
-
|
71
|
-
#
|
67
|
+
private
|
68
|
+
|
72
69
|
def root_path
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
@root_path ||= (
|
71
|
+
root_path = `git rev-parse --show-toplevel 2>/dev/null`.strip
|
72
|
+
raise GitException if root_path.empty?
|
73
|
+
root_path
|
74
|
+
)
|
76
75
|
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
#
|
85
|
-
def discard_memoized
|
86
|
-
@url = nil
|
87
|
-
@username = nil
|
88
|
-
@password = nil
|
89
|
-
end
|
90
|
-
|
91
|
-
#
|
92
|
-
# Validates the location and reads the contents of the input path
|
93
|
-
#
|
94
|
-
# @param path [String] path of file to read
|
95
|
-
#
|
96
|
-
# @return [Object] IniFile object of the file at the input path
|
97
|
-
#
|
98
|
-
def read(path)
|
99
|
-
self.validate_path!(path)
|
100
|
-
IniFile.load(path, { :comment => '#', :encoding => 'UTF-8' })
|
101
|
-
end
|
102
|
-
|
103
|
-
#
|
104
|
-
# Aborts command if no file at the input path exists.
|
105
|
-
#
|
106
|
-
# @param path [String] path to validate
|
107
|
-
#
|
108
|
-
def validate_path!(path)
|
109
|
-
raise InstallationException.new if !File.exists?(path)
|
110
|
-
end
|
77
|
+
def config
|
78
|
+
@config ||= (
|
79
|
+
raise InstallationException unless File.exists?(cli_path)
|
80
|
+
IniFile.load(cli_path, comment: '#', encoding: 'UTF-8')
|
81
|
+
)
|
82
|
+
end
|
111
83
|
|
112
84
|
end
|
113
85
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Jira
|
4
|
+
class LegacyAPI
|
5
|
+
|
6
|
+
TYPES = [
|
7
|
+
:rest,
|
8
|
+
:agile
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
ENDPOINTS = {
|
12
|
+
rest: 'rest/api/2',
|
13
|
+
agile: 'rest/greenhopper/latest'
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
#
|
17
|
+
# Initialize Jira::API
|
18
|
+
#
|
19
|
+
# @param type [Symbol]
|
20
|
+
#
|
21
|
+
def initialize(type)
|
22
|
+
@type = type
|
23
|
+
@client = Faraday.new
|
24
|
+
@client.basic_auth(Jira::Core.username, Jira::Core.password)
|
25
|
+
|
26
|
+
self.define_actions
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
#
|
32
|
+
# Defines the API DELETE, GET, POST, PUT interaction methods
|
33
|
+
#
|
34
|
+
def define_actions
|
35
|
+
#
|
36
|
+
# def method(path, params={})
|
37
|
+
#
|
38
|
+
# Issue an API DELETE, GET, POST, or PUT request and return parse JSON
|
39
|
+
#
|
40
|
+
# @param path [String] API path
|
41
|
+
# @param params [Hash] params to send
|
42
|
+
#
|
43
|
+
# @yield(Hash) yields to a success block
|
44
|
+
#
|
45
|
+
# @return [JSON] parased API response
|
46
|
+
#
|
47
|
+
[:delete, :get, :post, :put].each do |method|
|
48
|
+
self.class.send(:define_method, method) do |path, params=nil, verbose=true, &block|
|
49
|
+
params = params.to_json if !params.nil?
|
50
|
+
response = @client.send(
|
51
|
+
method,
|
52
|
+
self.endpoint(path),
|
53
|
+
params,
|
54
|
+
self.headers
|
55
|
+
)
|
56
|
+
json = response.body.to_s.from_json
|
57
|
+
if self.errorless?(json, verbose)
|
58
|
+
block.call(json)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# If any, outputs all API errors described by the input JSON
|
66
|
+
#
|
67
|
+
# @param json [Hash] API response JSON
|
68
|
+
# @param verbose [Boolean] true if errors should be output
|
69
|
+
#
|
70
|
+
# @return [Boolean] true if no errors exist
|
71
|
+
#
|
72
|
+
def errorless?(json, verbose=true)
|
73
|
+
errors = json['errorMessages']
|
74
|
+
if !errors.nil?
|
75
|
+
puts errors.join('. ') if verbose
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
return true
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Returns the full JIRA REST API endpoint
|
83
|
+
#
|
84
|
+
# @param path [String] API path
|
85
|
+
#
|
86
|
+
# @return [String] API endpoint
|
87
|
+
#
|
88
|
+
def endpoint(path)
|
89
|
+
"#{Jira::Core.url}/#{ENDPOINTS[@type]}/#{path}"
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Returns the default API headers
|
94
|
+
#
|
95
|
+
# @return [Hash] API headers
|
96
|
+
#
|
97
|
+
def headers
|
98
|
+
{ 'Content-Type' => 'application/json' }
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
data/lib/jira/mixins.rb
CHANGED
@@ -2,18 +2,14 @@ module Jira
|
|
2
2
|
class CLI < Thor
|
3
3
|
|
4
4
|
require 'json'
|
5
|
-
require 'faraday'
|
6
|
-
require 'inquirer'
|
7
5
|
require 'inifile'
|
6
|
+
require 'tty-prompt'
|
8
7
|
include Thor::Actions
|
9
8
|
|
10
9
|
protected
|
11
10
|
|
12
|
-
#
|
13
|
-
# @return [Highline] HighLine instance for handling input
|
14
|
-
#
|
15
11
|
def io
|
16
|
-
@io ||=
|
12
|
+
@io ||= TTY::Prompt.new
|
17
13
|
end
|
18
14
|
|
19
15
|
#
|
@@ -25,7 +21,7 @@ module Jira
|
|
25
21
|
key = "@api_#{type}"
|
26
22
|
klass = self.instance_variable_get(key)
|
27
23
|
if klass.nil?
|
28
|
-
klass = Jira::
|
24
|
+
klass = Jira::LegacyAPI.new(type)
|
29
25
|
self.instance_variable_set(key, klass)
|
30
26
|
end
|
31
27
|
return klass
|
@@ -38,7 +34,7 @@ module Jira
|
|
38
34
|
# @return index [Integer] asked type of index
|
39
35
|
#
|
40
36
|
def get_type_of_index(command, description)
|
41
|
-
response = self.io.ask("Index for #{command} to #{description}").strip
|
37
|
+
response = self.io.ask("Index for #{command} to #{description}:").strip
|
42
38
|
return -1 if response.empty?
|
43
39
|
index = response.to_i
|
44
40
|
return -1 if index < 0
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
module Jira
|
5
|
+
class SprintAPI
|
6
|
+
|
7
|
+
def sprint(rapid_view_id, sprint_id)
|
8
|
+
response = client.get(
|
9
|
+
'rapid/charts/sprintreport',
|
10
|
+
rapidViewId: rapid_view_id,
|
11
|
+
sprintId: sprint_id
|
12
|
+
)
|
13
|
+
return response.body if response.success?
|
14
|
+
{}
|
15
|
+
end
|
16
|
+
|
17
|
+
def sprints(rapid_view_id)
|
18
|
+
response = client.get("sprintquery/#{rapid_view_id}")
|
19
|
+
return response.body if response.success?
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
|
23
|
+
def rapid_views
|
24
|
+
response = client.get("rapidview")
|
25
|
+
return response.body['views'] if response.success?
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def client
|
32
|
+
@client ||= Faraday.new(endpoint) do |faraday|
|
33
|
+
faraday.request :basic_auth, Jira::Core.username, Jira::Core.password
|
34
|
+
faraday.request :json
|
35
|
+
faraday.response :json
|
36
|
+
faraday.adapter :net_http
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def endpoint
|
41
|
+
"#{Jira::Core.url}/rest/greenhopper/latest"
|
42
|
+
end
|
43
|
+
|
44
|
+
def headers
|
45
|
+
{ 'Content-Type' => 'application/json' }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jira-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Darren
|
7
|
+
- Darren Cheng
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -45,25 +45,65 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 0.9.0
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: faraday_middleware
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.
|
53
|
+
version: 0.10.0
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: 0.
|
56
|
+
version: 0.10.0
|
57
57
|
type: :runtime
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: 0.
|
63
|
+
version: 0.10.0
|
64
64
|
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: 0.
|
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
|
67
107
|
- !ruby/object:Gem::Dependency
|
68
108
|
name: inifile
|
69
109
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +124,20 @@ dependencies:
|
|
84
124
|
- - ">="
|
85
125
|
- !ruby/object:Gem::Version
|
86
126
|
version: 2.0.2
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: pry
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
87
141
|
description: CLI used to manage JIRA workflows leveraging git
|
88
142
|
email: darren@thanx.com
|
89
143
|
executables:
|
@@ -95,6 +149,8 @@ files:
|
|
95
149
|
- bin/jira
|
96
150
|
- lib/jira.rb
|
97
151
|
- lib/jira/api.rb
|
152
|
+
- lib/jira/command.rb
|
153
|
+
- lib/jira/commands/all.rb
|
98
154
|
- lib/jira/commands/assign.rb
|
99
155
|
- lib/jira/commands/attachments.rb
|
100
156
|
- lib/jira/commands/comment.rb
|
@@ -106,6 +162,7 @@ files:
|
|
106
162
|
- lib/jira/commands/log.rb
|
107
163
|
- lib/jira/commands/new.rb
|
108
164
|
- lib/jira/commands/rename.rb
|
165
|
+
- lib/jira/commands/sprint.rb
|
109
166
|
- lib/jira/commands/tickets.rb
|
110
167
|
- lib/jira/commands/transition.rb
|
111
168
|
- lib/jira/commands/version.rb
|
@@ -115,9 +172,10 @@ files:
|
|
115
172
|
- lib/jira/core.rb
|
116
173
|
- lib/jira/exceptions.rb
|
117
174
|
- lib/jira/format.rb
|
118
|
-
- lib/jira/
|
175
|
+
- lib/jira/legacy_api.rb
|
119
176
|
- lib/jira/mixins.rb
|
120
|
-
|
177
|
+
- lib/jira/sprint_api.rb
|
178
|
+
homepage: https://github.com/drn/jira-cli
|
121
179
|
licenses:
|
122
180
|
- MIT
|
123
181
|
metadata: {}
|
@@ -137,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
195
|
version: '0'
|
138
196
|
requirements: []
|
139
197
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.
|
198
|
+
rubygems_version: 2.5.1
|
141
199
|
signing_key:
|
142
200
|
specification_version: 4
|
143
201
|
summary: JIRA CLI
|