jira-cli 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|