lita-jira 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/README.md +1 -0
- data/lib/jirahelper/issue.rb +31 -2
- data/lib/lita/handlers/jira.rb +28 -0
- data/lita-jira.gemspec +8 -8
- data/locales/en.yml +7 -1
- data/spec/lita/handlers/jira_spec.rb +88 -0
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8e25e7c623d12ae007a12d829a9982e4cd282f0
|
4
|
+
data.tar.gz: 4af36f87192c00de42d16201f43e351aa3c6636d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44b1d5c7b1ab88e483d1a2a8164e7e4891a58912d285d2c39399cbce34777e3ba20b6340baa5da955662f74a6fdf9116e44a70ab0ac8321e5aa9c748360a0b0e
|
7
|
+
data.tar.gz: 0a1f45120e30e39f0e2968789d411305b31bf91b19dfda8a65590b457da93d5d194bf044e8183a43176c4c7cc5273b155d8f96e628813a9bfe8a2f79ec142b19
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -40,6 +40,7 @@ todo <project> "<subject>" ["<summary>"] - Creates an issue in <project> with <s
|
|
40
40
|
jira <issue> - Shows a short summary <issue>
|
41
41
|
jira details <issue> - Shows all details about <issue>
|
42
42
|
jira comment on <issue> <comment text> - Adds <comment text> to <issue>
|
43
|
+
jira myissues - Displays a list of issues assigned to identified user
|
43
44
|
```
|
44
45
|
|
45
46
|
### Misc
|
data/lib/jirahelper/issue.rb
CHANGED
@@ -9,6 +9,14 @@ module JiraHelper
|
|
9
9
|
nil
|
10
10
|
end
|
11
11
|
|
12
|
+
# Leverage the jira-ruby Issue.jql search feature
|
13
|
+
#
|
14
|
+
# @param [Type String] jql Valid JQL query
|
15
|
+
# @return [Type Array] 0-m JIRA Issues returned from query
|
16
|
+
def fetch_issues(jql)
|
17
|
+
client.Issue.jql(jql)
|
18
|
+
end
|
19
|
+
|
12
20
|
def fetch_project(key)
|
13
21
|
client.Project.find(key)
|
14
22
|
rescue
|
@@ -20,11 +28,20 @@ module JiraHelper
|
|
20
28
|
t('issue.details',
|
21
29
|
key: issue.key,
|
22
30
|
summary: issue.summary,
|
23
|
-
assigned: issue.assignee.displayName,
|
24
|
-
priority: issue.priority.name,
|
31
|
+
assigned: optional_issue_property('unassigned') { issue.assignee.displayName },
|
32
|
+
priority: optional_issue_property('none') { issue.priority.name },
|
25
33
|
status: issue.status.name)
|
26
34
|
end
|
27
35
|
|
36
|
+
# Enumerate issues returned from JQL query and format for response
|
37
|
+
#
|
38
|
+
# @param [Type Array] issues 1-m issues returned from JQL query
|
39
|
+
# @return [Type Array<String>] formatted issues for display to user
|
40
|
+
def format_issues(issues)
|
41
|
+
results = [t('myissues.info')]
|
42
|
+
results.concat(issues.map { |issue| format_issue(issue) })
|
43
|
+
end
|
44
|
+
|
28
45
|
def create_issue(project, subject, summary)
|
29
46
|
project = fetch_project(project)
|
30
47
|
return nil unless project
|
@@ -35,5 +52,17 @@ module JiraHelper
|
|
35
52
|
issue.fetch
|
36
53
|
issue
|
37
54
|
end
|
55
|
+
|
56
|
+
# Attempt to retrieve optional JIRA issue property value via a provided block.
|
57
|
+
# JIRA properties such as assignee and priority may not exist.
|
58
|
+
# In that case, the fallback will be used.
|
59
|
+
#
|
60
|
+
# @param [Type String] fallback A String value to use if the JIRA property value doesn't exist
|
61
|
+
# @return [Type String] fallback or returned value from yield block
|
62
|
+
def optional_issue_property(fallback = '')
|
63
|
+
yield
|
64
|
+
rescue
|
65
|
+
fallback
|
66
|
+
end
|
38
67
|
end
|
39
68
|
end
|
data/lib/lita/handlers/jira.rb
CHANGED
@@ -14,6 +14,7 @@ module Lita
|
|
14
14
|
include ::JiraHelper::Issue
|
15
15
|
include ::JiraHelper::Misc
|
16
16
|
include ::JiraHelper::Regex
|
17
|
+
include ::JiraHelper::Utility
|
17
18
|
|
18
19
|
route(
|
19
20
|
/^jira\s#{ISSUE_PATTERN}$/,
|
@@ -33,6 +34,15 @@ module Lita
|
|
33
34
|
}
|
34
35
|
)
|
35
36
|
|
37
|
+
route(
|
38
|
+
/^jira\smyissues$/,
|
39
|
+
:myissues,
|
40
|
+
command: true,
|
41
|
+
help: {
|
42
|
+
t('help.myissues.syntax') => t('help.myissues.desc')
|
43
|
+
}
|
44
|
+
)
|
45
|
+
|
36
46
|
route(
|
37
47
|
/^jira\scomment\son\s#{ISSUE_PATTERN}\s#{COMMENT_PATTERN}$/,
|
38
48
|
:comment,
|
@@ -78,6 +88,24 @@ module Lita
|
|
78
88
|
return response.reply(t('error.request')) unless issue
|
79
89
|
response.reply(t('issue.created', key: issue.key))
|
80
90
|
end
|
91
|
+
|
92
|
+
# rubocop:disable Metrics/AbcSize
|
93
|
+
def myissues(response)
|
94
|
+
return response.reply(t('error.not_identified')) unless user_stored?(response.user)
|
95
|
+
|
96
|
+
begin
|
97
|
+
issues = fetch_issues("assignee = '#{get_email(response.user)}' AND status not in (Closed)")
|
98
|
+
rescue
|
99
|
+
log.error('JIRA HTTPError')
|
100
|
+
response.reply(t('error.request'))
|
101
|
+
return
|
102
|
+
end
|
103
|
+
|
104
|
+
return response.reply(t('myissues.empty')) unless issues.size > 0
|
105
|
+
|
106
|
+
response.reply(format_issues(issues))
|
107
|
+
end
|
108
|
+
# rubocop:enable Metrics/AbcSize
|
81
109
|
end
|
82
110
|
|
83
111
|
Lita.register_handler(Jira)
|
data/lita-jira.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'lita-jira'
|
3
|
-
spec.version = '0.
|
3
|
+
spec.version = '0.6.0'
|
4
4
|
spec.authors = ['Eric Sigler']
|
5
5
|
spec.email = ['me@esigler.com']
|
6
6
|
spec.description = 'A JIRA plugin for Lita.'
|
@@ -10,17 +10,17 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.metadata = { 'lita_plugin_type' => 'handler' }
|
11
11
|
|
12
12
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
13
|
-
spec.executables = spec.files.grep(
|
14
|
-
spec.test_files = spec.files.grep(
|
13
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
14
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
15
15
|
spec.require_paths = ['lib']
|
16
16
|
|
17
17
|
spec.add_runtime_dependency 'lita', '>= 4.0'
|
18
|
-
spec.add_runtime_dependency 'jira-ruby'
|
18
|
+
spec.add_runtime_dependency 'jira-ruby'
|
19
19
|
|
20
|
-
spec.add_development_dependency 'bundler'
|
21
|
-
spec.add_development_dependency 'rake'
|
22
|
-
spec.add_development_dependency 'rspec', '>= 3.0.0'
|
23
|
-
spec.add_development_dependency 'simplecov'
|
20
|
+
spec.add_development_dependency 'bundler'
|
24
21
|
spec.add_development_dependency 'coveralls'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'rspec'
|
25
24
|
spec.add_development_dependency 'rubocop'
|
25
|
+
spec.add_development_dependency 'simplecov'
|
26
26
|
end
|
data/locales/en.yml
CHANGED
@@ -28,6 +28,9 @@ en:
|
|
28
28
|
todo:
|
29
29
|
syntax: todo <project> "<subject>" ["<summary>"]
|
30
30
|
desc: Creates an issue in <project> with <subject> and optionally <summary>
|
31
|
+
myissues:
|
32
|
+
syntax: jira myissues
|
33
|
+
desc: If identified, will display a list of issues currently assigned to you
|
31
34
|
identify:
|
32
35
|
stored: "You have been identified as %{email} to JIRA"
|
33
36
|
deleted: You have been de-identified from JIRA
|
@@ -37,4 +40,7 @@ en:
|
|
37
40
|
details: "%{key}: %{summary}, assigned to: %{assigned}, priority: %{priority}, status: %{status}"
|
38
41
|
summary: "%{key}: %{summary}"
|
39
42
|
comment:
|
40
|
-
added: "Comment added to %{issue}"
|
43
|
+
added: "Comment added to %{issue}"
|
44
|
+
myissues:
|
45
|
+
empty: "You do not have any assigned issues. Great job!"
|
46
|
+
info: "Here are issues currently assigned to you:"
|
@@ -12,6 +12,33 @@ describe Lita::Handlers::Jira, lita_handler: true do
|
|
12
12
|
result
|
13
13
|
end
|
14
14
|
|
15
|
+
let(:saved_issue_with_fewer_details) do
|
16
|
+
result = double(summary: 'Some summary text',
|
17
|
+
status: double(name: 'In Progress'),
|
18
|
+
key: 'XYZ-987')
|
19
|
+
allow(result).to receive('assignee').and_raise
|
20
|
+
allow(result).to receive('priority').and_raise
|
21
|
+
allow(result).to receive('save') { true }
|
22
|
+
allow(result).to receive('fetch') { true }
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:valid_search_results) do
|
27
|
+
result = [double(summary: 'Some summary text',
|
28
|
+
assignee: double(displayName: 'A Person'),
|
29
|
+
priority: double(name: 'P0'),
|
30
|
+
status: double(name: 'In Progress'),
|
31
|
+
key: 'XYZ-987'),
|
32
|
+
double(summary: 'Some summary text 2',
|
33
|
+
assignee: double(displayName: 'A Person 2'),
|
34
|
+
priority: double(name: 'P1'),
|
35
|
+
status: double(name: 'In Progress 2'),
|
36
|
+
key: 'XYZ-988')]
|
37
|
+
allow(result).to receive('save') { true }
|
38
|
+
allow(result).to receive('fetch') { true }
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
15
42
|
let(:saved_project) do
|
16
43
|
double(key: 'XYZ',
|
17
44
|
id: 1)
|
@@ -23,6 +50,13 @@ describe Lita::Handlers::Jira, lita_handler: true do
|
|
23
50
|
allow(issue).to receive_message_chain('Issue.find.comments.build.save!') { saved_issue }
|
24
51
|
allow(issue).to receive_message_chain('Issue.build') { saved_issue }
|
25
52
|
allow(issue).to receive_message_chain('Project.find') { saved_project }
|
53
|
+
allow(issue).to receive_message_chain('Issue.jql') { valid_search_results }
|
54
|
+
issue
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:client_with_fewer_details) do
|
58
|
+
issue = double
|
59
|
+
allow(issue).to receive_message_chain('Issue.find') { saved_issue_with_fewer_details }
|
26
60
|
issue
|
27
61
|
end
|
28
62
|
|
@@ -32,18 +66,31 @@ describe Lita::Handlers::Jira, lita_handler: true do
|
|
32
66
|
r
|
33
67
|
end
|
34
68
|
|
69
|
+
let(:failed_find_issues) do
|
70
|
+
r = double
|
71
|
+
expect(r).to receive_message_chain('Issue.jql').and_throw(JIRA::HTTPError)
|
72
|
+
r
|
73
|
+
end
|
74
|
+
|
35
75
|
let(:failed_find_project) do
|
36
76
|
r = double
|
37
77
|
expect(r).to receive_message_chain('Project.find').and_throw(JIRA::HTTPError)
|
38
78
|
r
|
39
79
|
end
|
40
80
|
|
81
|
+
let(:empty_search_result) do
|
82
|
+
r = double
|
83
|
+
expect(r).to receive_message_chain('Issue.jql') { [] }
|
84
|
+
r
|
85
|
+
end
|
86
|
+
|
41
87
|
it do
|
42
88
|
is_expected.to route_command('jira ABC-123').to(:summary)
|
43
89
|
is_expected.to route_command('jira details ABC-123').to(:details)
|
44
90
|
is_expected.to route_command('jira comment on ABC-123 "You just need a cat"').to(:comment)
|
45
91
|
is_expected.to route_command('todo ABC "summary text"').to(:todo)
|
46
92
|
is_expected.to route_command('todo ABC "summary text" "subject text"').to(:todo)
|
93
|
+
is_expected.to route_command('jira myissues').to(:myissues)
|
47
94
|
end
|
48
95
|
|
49
96
|
describe '#summary' do
|
@@ -68,6 +115,13 @@ describe Lita::Handlers::Jira, lita_handler: true do
|
|
68
115
|
'A Person, priority: P0, status: In Progress')
|
69
116
|
end
|
70
117
|
|
118
|
+
it 'shows fewer details when the property is not set' do
|
119
|
+
grab_request(client_with_fewer_details)
|
120
|
+
send_command('jira details XYZ-987')
|
121
|
+
expect(replies.last).to eq('XYZ-987: Some summary text, assigned to: ' \
|
122
|
+
'unassigned, priority: none, status: In Progress')
|
123
|
+
end
|
124
|
+
|
71
125
|
it 'warns the user when the issue is not valid' do
|
72
126
|
grab_request(failed_find_issue)
|
73
127
|
send_command('jira details XYZ-987')
|
@@ -102,4 +156,38 @@ describe Lita::Handlers::Jira, lita_handler: true do
|
|
102
156
|
expect(replies.last).to eq('Error fetching JIRA issue')
|
103
157
|
end
|
104
158
|
end
|
159
|
+
|
160
|
+
describe '#myissues' do
|
161
|
+
before { send_command('jira forget') }
|
162
|
+
context 'when not identified' do
|
163
|
+
it 'fails when user is not identified' do
|
164
|
+
send_command('jira myissues')
|
165
|
+
expect(replies.last).to eq('You do not have an email address on record')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'when identified' do
|
170
|
+
before { send_command('jira identify user@example.com') }
|
171
|
+
|
172
|
+
it 'shows default response when no results are returned' do
|
173
|
+
grab_request(empty_search_result)
|
174
|
+
send_command('jira myissues')
|
175
|
+
expect(replies.last).to eq('You do not have any assigned issues. Great job!')
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'shows results when returned' do
|
179
|
+
grab_request(valid_client)
|
180
|
+
send_command('jira myissues')
|
181
|
+
expect(replies.last).to eq(['Here are issues currently assigned to you:',
|
182
|
+
'XYZ-987: Some summary text, assigned to: A Person, priority: P0, status: In Progress',
|
183
|
+
'XYZ-988: Some summary text 2, assigned to: A Person 2, priority: P1, status: In Progress 2'])
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'shows an error when the search fails' do
|
187
|
+
grab_request(failed_find_issues)
|
188
|
+
send_command('jira myissues')
|
189
|
+
expect(replies.last).to eq('Error fetching JIRA issue')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
105
193
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-jira
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Sigler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|
@@ -30,30 +30,30 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0
|
33
|
+
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: coveralls
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,21 +67,21 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rubocop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: simplecov
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|