lita-jira 0.3.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec792cf09935ca050ad43f9267251831c2c0e551
4
- data.tar.gz: 2e5658bc5ed997068470279c7fb6eaf51acfb20a
3
+ metadata.gz: 90dd09ba21f516a5e3ba14b4e508a701e3ba49e6
4
+ data.tar.gz: 5425fa36b10399c2d7be59ae6a853e7058a4aac2
5
5
  SHA512:
6
- metadata.gz: cd93b6be7fe4d14ec6dc2d4f0862c63db299d9340bf64901ec58d1b2f03bd1fbf9073bbf1d27ed69865b2fbe1e273acce65d21890f12250333105fccea68343e
7
- data.tar.gz: 3622a99a077d3c7784aa0cebfea90c5ff277eb5fa74baaa3e8ea28e40e50588630b219581cce1d16b6e747d4e08985acd70ebebc87bef362fa400fa0568d5c8b
6
+ metadata.gz: bbff8e22a6e47173002f04d361f55ab1a1bf7cd783a56bc00d4564db07dccb1bc500237ed016e8087fe3a96ea153cda28cb02b78a165fc6a7fe07c91884b611e
7
+ data.tar.gz: dca962c74e1fce373a8c127f330e0fa42ad99cf03a7053693aa1d5d52163dcf39fb8fe56e7a19a5df2eca8b350df0c0ff0f1ad3e4d72a99af607e6fcf986d7a9
data/.gitignore CHANGED
@@ -16,4 +16,3 @@ spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
- *.swp
data/.rubocop.yml CHANGED
@@ -1,17 +1,6 @@
1
- ClassLength:
2
- Max: 400
3
-
4
- CyclomaticComplexity:
5
- Max: 10
6
-
7
- Documentation:
8
- Enabled: false
9
-
10
1
  FileName:
11
- Enabled: false
2
+ Exclude:
3
+ - lib/lita-jira.rb
12
4
 
13
5
  LineLength:
14
6
  Max: 130
15
-
16
- MethodLength:
17
- Max: 30
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
3
+ - 2.1
4
4
  script: bundle exec rake
5
5
  before_install:
6
6
  - gem update --system
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![Code Climate](https://img.shields.io/codeclimate/github/esigler/lita-jira.svg)](https://codeclimate.com/github/esigler/lita-jira)
8
8
  [![Gemnasium](https://img.shields.io/gemnasium/esigler/lita-jira.svg)](https://gemnasium.com/esigler/lita-jira)
9
9
 
10
- JIRA (https://www.atlassian.com/software/jira) [handler](https://github.com/jimmycuadra/lita) for creating, updating issues.
10
+ A [JIRA](https://www.atlassian.com/software/jira) plugin for [Lita](https://github.com/jimmycuadra/lita).
11
11
 
12
12
  ## Installation
13
13
 
@@ -33,36 +33,11 @@ config.handlers.jira.context = '' # If your instance is in a /subdirectory, put
33
33
  ### Shortcuts
34
34
 
35
35
  ```
36
- todo <summary> - Creates an issue with your default priority and project settings, assigned to yourself
37
- ```
38
-
39
- ### Issues
40
-
41
- ```
42
- jira issue assignee <issue ID> - Shows assignee of <issue ID>
43
- jira issue assignee <issue ID> <email address> - Sets <email address> as the assignee
44
- jira issue attachments <issue ID> - Shows all attachments for <issue ID>
45
- jira issue attachments <issue ID> <URL> - Adds <URL> as an attachment on <issue ID>
46
- jira issue comments <issue ID> - Shows all comments for <issue ID>
47
- jira issue comments <issue ID> <text> - Adds <text> as a comment on <issue ID>
48
- jira issue details <issue ID> - Shows all details for <issue ID>
49
- jira issue issuetype <issue ID> - Shows the Issue Type of <issue ID>
50
- jira issue issuetype <issue ID> <issuetype ID> - Sets the Issue Type of <issue ID> to <issuetype ID>
51
- jira issue new <project ID> <args> - Creates a new issue in <project ID> with <args> (args is any name:"value" pair, such as summary:"Some text")
52
- jira issue notify <issue ID> - Shows who is notified when <issue ID> is changed
53
- jira issue notify <issue ID> <email address> - Adds <email address> to notification list for <issue ID>
54
- jira issue priority <issue ID> - Shows priority of <issue ID>
55
- jira issue priority <issue ID> <new priority> - Sets <new priority> of <issue ID>
56
- jira issue summary <issue ID> - Shows summary of <issue ID>
57
- jira issue summary <issue ID> <text> - Sets summary of <issue ID> to <text>
58
- jira issue watchers <issue ID> - Shows watchers of <issue ID>
59
- jira issue watchers <issue ID> <email address> - Adds <email address> to watchers list for <issue ID>
60
- ```
61
-
62
- ### Issue Types
63
-
64
- ```
65
- jira issuetype list <project ID> - List all issuetypes for <project ID>
36
+ todo <project> "<subject>" ["<summary>"] - Creates an issue in <project> with <subject> and optionally <summary>
37
+ jira <issue> - Shows a short summary <issue>
38
+ jira details <issue> - Shows all details about <issue>
39
+ jira assign <user> to <issue> - Assigns <user> to <issue>, <user> can be a 'Full Name' or a '@mentionname'
40
+ jira comment on <issue> <comment text> - Adds <comment text> to <issue>
66
41
  ```
67
42
 
68
43
  ### Search
@@ -78,8 +53,6 @@ jira search <project ID> "<text>" - Search for <text> within the scope of <proje
78
53
  jira identify <email address> - Associate your chat user with your email address
79
54
  jira forget - Remove your chat user / email association
80
55
  jira whoami - Show your chat user / email association
81
- jira default project <project ID> - Set your default project ID to <project ID>
82
- jira default priority <priority> - Set your default priority to <priority>
83
56
  ```
84
57
 
85
58
  ## License
@@ -0,0 +1,21 @@
1
+ # Helper functions for lita-jira
2
+ module JiraHelper
3
+ # Issues
4
+ module Issue
5
+ def fetch_issue(key)
6
+ client.Issue.find(key)
7
+ rescue
8
+ log.error('JIRA HTTPError')
9
+ nil
10
+ end
11
+
12
+ def format_issue(issue)
13
+ t('issue.details',
14
+ key: issue.key,
15
+ summary: issue.summary,
16
+ assigned: issue.assignee.displayName,
17
+ priority: issue.priority.name,
18
+ status: issue.status.name)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ # Helper functions for lita-jira
2
+ module JiraHelper
3
+ # Misc
4
+ module Misc
5
+ def client
6
+ JIRA::Client.new(
7
+ username: config.username,
8
+ password: config.password,
9
+ site: config.site,
10
+ context_path: config.context,
11
+ auth_type: :basic
12
+ )
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ # Helper functions for lita-jira
2
+ module JiraHelper
3
+ # Regular expressions
4
+ module Regex
5
+ PROJECT_PATTERN = /(?<project>[a-zA-Z0-9]{1,10})/
6
+ ISSUE_PATTERN = /(?<issue>#{PROJECT_PATTERN}-[0-9]{1,5}+)/
7
+ EMAIL_PATTERN = /(?<email>[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+)/i
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ # Helper functions for lita-jira
2
+ module JiraHelper
3
+ # Utility helpers
4
+ module Utility
5
+ def get_email(user)
6
+ return nil unless user_stored?(user)
7
+ redis.get(normalize_user(user))
8
+ end
9
+
10
+ def user_stored?(user)
11
+ redis.exists(normalize_user(user))
12
+ end
13
+
14
+ def store_user!(user, email)
15
+ return false if user_stored?(user)
16
+ redis.set(normalize_user(user), email)
17
+ end
18
+
19
+ def delete_user!(user)
20
+ return false unless user_stored?(user)
21
+ redis.del(normalize_user(user))
22
+ end
23
+
24
+ def normalize_user(user)
25
+ "user_#{user.id}"
26
+ end
27
+ end
28
+ end
@@ -1,417 +1,65 @@
1
+ # lita-jira plugin
1
2
  module Lita
3
+ # Because we can.
2
4
  module Handlers
5
+ # Main handler
3
6
  class Jira < Handler
4
- PROJECT_PATTERN = '[a-zA-Z0-9]{1,10}'
5
- ISSUE_PATTERN = "#{PROJECT_PATTERN}-[0-9]{1,5}"
7
+ namespace 'Jira'
6
8
 
7
- route(
8
- /^todo\s(.*)$/,
9
- :todo,
10
- command: true,
11
- help: {
12
- t('help.todo.syntax') => t('help.todo.desc')
13
- }
14
- )
9
+ config :username, required: true
10
+ config :password, required: true
11
+ config :site, required: true
12
+ config :context, required: true
15
13
 
16
- route(
17
- /^jira\sissue\sassignee\s(#{ISSUE_PATTERN})$/,
18
- :issue_assignee_list,
19
- command: true,
20
- help: {
21
- t('help.issue.assignee_list.syntax') => t('help.issue.assignee_list.desc')
22
- }
23
- )
14
+ include ::JiraHelper::Issue
15
+ include ::JiraHelper::Misc
16
+ include ::JiraHelper::Regex
24
17
 
25
18
  route(
26
- /^jira\sissue\sassignee\s(#{ISSUE_PATTERN})\s(.+)$/,
27
- :issue_assignee_set,
19
+ /^jira\s#{ISSUE_PATTERN}$/,
20
+ :summary,
28
21
  command: true,
29
22
  help: {
30
- t('help.issue.assignee_set.syntax') => t('help.issue.assignee_set.syntax')
23
+ t('help.summary.syntax') => t('help.summary.desc')
31
24
  }
32
25
  )
33
26
 
34
27
  route(
35
- /^jira\sissue\sattachments\s(#{ISSUE_PATTERN})$/,
36
- :issue_attachments_list,
28
+ /^jira\sdetails\s#{ISSUE_PATTERN}$/,
29
+ :details,
37
30
  command: true,
38
31
  help: {
39
- t('help.issue.attachments_list.syntax') => t('help.issue.attachments_list.desc')
40
- }
41
- )
42
-
43
- route(
44
- /^jira\sissue\sattachments\s(#{ISSUE_PATTERN})\s(.+)$/,
45
- :issue_attachments_set,
46
- command: true,
47
- help: {
48
- t('help.issue.attachments_set.syntax') => t('help.issue.attachments_set.desc')
49
- }
50
- )
51
-
52
- route(
53
- /^jira\sissue\scomments\s(#{ISSUE_PATTERN})$/,
54
- :issue_comments_list,
55
- command: true,
56
- help: {
57
- t('help.issue.comments_list.syntax') => t('help.issue.comments_list.desc')
58
- }
59
- )
60
-
61
- route(
62
- /^jira\sissue\scomments\s(#{ISSUE_PATTERN})\s(.+)$/,
63
- :issue_comments_add,
64
- command: true,
65
- help: {
66
- t('help.issue.comments_set.syntax') => t('help.issue.comments_set.desc')
67
- }
68
- )
69
-
70
- route(
71
- /^jira\sissue\sdetails\s(#{ISSUE_PATTERN})$/,
72
- :issue_details,
73
- command: true,
74
- help: {
75
- t('help.issue.details.syntax') => t('help.issue.details.desc')
76
- }
77
- )
78
-
79
- route(
80
- /^jira\sissue\sissuetype\s(#{ISSUE_PATTERN})$/,
81
- :issue_issuetype_list,
82
- command: true,
83
- help: {
84
- t('help.issue.issuetype_list.syntax') => t('help.issue.issuetype_list.desc')
85
- }
86
- )
87
-
88
- route(
89
- /^jira\sissue\sissuetype\s(#{ISSUE_PATTERN})\s(\d+)$/,
90
- :issue_issuetype_set,
91
- command: true,
92
- help: {
93
- t('help.issue.issuetype_set.syntax') => t('help.issue.issuetype_set.desc')
94
- }
95
- )
96
-
97
- route(
98
- /^jira\sissue\snew\s(#{PROJECT_PATTERN})\s(.+)$/,
99
- :issue_new,
100
- help: {
101
- t('help.issue.new.syntax') => t('help.issue.new.desc')
102
- }
103
- )
104
-
105
- route(
106
- /^jira\sissue\snotify\s(#{ISSUE_PATTERN})$/,
107
- :issue_notify_list,
108
- help: {
109
- t('help.issue.notify_list.syntax') => t('help.issue.notify_list.desc')
110
- }
111
- )
112
-
113
- route(
114
- /^jira\sissue\snotify\s(#{ISSUE_PATTERN})\s(.+)$/,
115
- :issue_notify_set,
116
- help: {
117
- t('help.issue.notify_set.syntax') => t('help.issue.notify_set.desc')
118
- }
119
- )
120
-
121
- route(
122
- /^jira\sissue\spriority\s(#{ISSUE_PATTERN})$/,
123
- :issue_priority_list,
124
- help: {
125
- t('help.issue.priority_list.syntax') => t('help.issue.priority_list.desc')
126
- }
127
- )
128
-
129
- route(
130
- /^jira\sissue\spriority\s(#{ISSUE_PATTERN})\s(\d+)$/,
131
- :issue_priority_set,
132
- help: {
133
- t('help.issue.priority_set.syntax') => t('help.issue.priority_set.desc')
134
- }
135
- )
136
-
137
- route(
138
- /^jira\sissue\ssummary\s(#{ISSUE_PATTERN})$/,
139
- :issue_summary_list,
140
- help: {
141
- t('help.issue.summary_list.syntax') => t('help.issue.summary_list.desc')
142
- }
143
- )
144
-
145
- route(
146
- /^jira\sissue\ssummary\s(#{ISSUE_PATTERN})\s(.+)$/,
147
- :issue_summary_set,
148
- help: {
149
- t('help.issue.summary_set.syntax') => t('help.issue.summary_set.desc')
150
- }
151
- )
152
-
153
- route(
154
- /^jira\sissue\swatchers\s(#{ISSUE_PATTERN})$/,
155
- :issue_watchers_list,
156
- help: {
157
- t('help.issue.watchers_list.syntax') => t('help.issue.watchers_list.desc')
158
- }
159
- )
160
-
161
- route(
162
- /^jira\sissue\swatchers\s(#{ISSUE_PATTERN})\s(.+)$/,
163
- :issue_watchers_set,
164
- help: {
165
- t('help.issue.watchers_set.syntax') => t('help.issue.watchers_set.desc')
166
- }
167
- )
168
-
169
- route(
170
- /^jira\sissuetype\slist\s(#{PROJECT_PATTERN})$/,
171
- :issuetype_list,
172
- help: {
173
- t('help.issuetype.list.syntax') => t('help.issuetype.list.desc')
174
- }
175
- )
176
-
177
- route(
178
- /^jira\ssearch\s(.+)$/,
179
- :search_full,
180
- help: {
181
- t('help.search.full.syntax') => t('help.search.full.desc')
182
- }
183
- )
184
-
185
- route(
186
- /^jira\ssearch\s(#{PROJECT_PATTERN})\s(.+)$/,
187
- :search_project,
188
- help: {
189
- t('help.search.project.syntax') => t('help.search.project.desc')
190
- }
191
- )
192
-
193
- route(
194
- /^jira\sidentify\s(.+)$/,
195
- :identify,
196
- help: {
197
- t('help.identify.syntax') => t('help.identify.desc')
32
+ t('help.details.syntax') => t('help.details.desc')
198
33
  }
199
34
  )
200
35
 
201
36
  route(
202
- /^jira\sforget$/,
203
- :forget,
204
- help: {
205
- t('help.forget.syntax') => t('help.forget.desc')
206
- }
207
- )
208
-
209
- route(
210
- /^jira\swhoami$/,
211
- :whoami,
212
- help: {
213
- t('help.whoami.syntax') => t('help.whoami.desc')
214
- }
215
- )
216
-
217
- route(
218
- /^jira\sdefault\sproject\s(#{PROJECT_PATTERN})$/,
219
- :default_project,
220
- help: {
221
- t('help.default.project.syntax') => t('help.default.project.desc')
222
- }
223
- )
224
-
225
- route(
226
- /^jira\sdefault\spriority\s(\d+)$/,
227
- :default_priority,
228
- help: {
229
- t('help.default.priority.syntax') => t('help.default.priority.desc')
230
- }
231
- )
232
-
233
- route(
234
- /^jira\s(#{ISSUE_PATTERN})$/,
235
- :issue_summary,
37
+ /^jira\scomment\son\s#{ISSUE_PATTERN}\s"(?<comment>.+)"$/,
38
+ :comment,
236
39
  command: true,
237
40
  help: {
238
- 'jira <issue ID>' => 'Shows summary for <issue ID>'
41
+ t('help.comment.syntax') => t('help.comment.desc')
239
42
  }
240
43
  )
241
44
 
242
- route(
243
- /^jira\s(#{ISSUE_PATTERN})\sdetails$/,
244
- :issue_details,
245
- command: true,
246
- help: {
247
- 'jira <issue ID> details' => 'Shows detailed information for <issue ID>' }
248
- )
249
-
250
- def self.default_config(config)
251
- config.username = nil
252
- config.password = nil
253
- config.site = nil
254
- config.context = nil
255
- end
256
-
257
- def issue_summary(response)
258
- key = response.matches[0][0]
259
- issue = fetch_issue(key)
260
- if issue
261
- response.reply("#{key}: #{issue.summary}")
262
- else
263
- response.reply(t('error.request'))
264
- end
265
- end
266
-
267
- def issue_details(response)
268
- key = response.matches[0][0]
269
- issue = fetch_issue(key)
270
- if issue
271
- response.reply(format_issue(issue))
272
- else
273
- response.reply(t('error.request'))
274
- end
275
- end
276
-
277
- def todo(response)
278
- response.reply(t('error.not_implemented'))
279
- end
280
-
281
- def issue_assignee_list(response)
282
- response.reply(t('error.not_implemented'))
283
- end
284
-
285
- def issue_assignee_set(response)
286
- response.reply(t('error.not_implemented'))
287
- end
288
-
289
- def issue_attachments_list(response)
290
- response.reply(t('error.not_implemented'))
291
- end
292
-
293
- def issue_attachments_set(response)
294
- response.reply(t('error.not_implemented'))
295
- end
296
-
297
- def issue_comments_list(response)
298
- response.reply(t('error.not_implemented'))
299
- end
300
-
301
- def issue_comments_add(response)
302
- response.reply(t('error.not_implemented'))
303
- end
304
-
305
- def issue_issuetype_list(response)
306
- response.reply(t('error.not_implemented'))
307
- end
308
-
309
- def issue_issuetype_set(response)
310
- response.reply(t('error.not_implemented'))
311
- end
312
-
313
- def issue_new(response)
314
- response.reply(t('error.not_implemented'))
315
- end
316
-
317
- def issue_notify_list(response)
318
- response.reply(t('error.not_implemented'))
319
- end
320
-
321
- def issue_notify_set(response)
322
- response.reply(t('error.not_implemented'))
323
- end
324
-
325
- def issue_priority_list(response)
326
- response.reply(t('error.not_implemented'))
327
- end
328
-
329
- def issue_priority_set(response)
330
- response.reply(t('error.not_implemented'))
331
- end
332
-
333
- def issue_summary_list(response)
334
- response.reply(t('error.not_implemented'))
335
- end
336
-
337
- def issue_summary_set(response)
338
- response.reply(t('error.not_implemented'))
339
- end
340
-
341
- def issue_watchers_list(response)
342
- response.reply(t('error.not_implemented'))
343
- end
344
-
345
- def issue_watchers_set(response)
346
- response.reply(t('error.not_implemented'))
347
- end
348
-
349
- def issuetype_list(response)
350
- response.reply(t('error.not_implemented'))
351
- end
352
-
353
- def search_full(response)
354
- response.reply(t('error.not_implemented'))
355
- end
356
-
357
- def search_project(response)
358
- response.reply(t('error.not_implemented'))
359
- end
360
-
361
- def identify(response)
362
- response.reply(t('error.not_implemented'))
363
- end
364
-
365
- def forget(response)
366
- response.reply(t('error.not_implemented'))
367
- end
368
-
369
- def whoami(response)
370
- response.reply(t('error.not_implemented'))
371
- end
372
-
373
- def default_project(response)
374
- response.reply(t('error.not_implemented'))
375
- end
376
-
377
- def default_priority(response)
378
- response.reply(t('error.not_implemented'))
379
- end
380
-
381
- private
382
-
383
- def j_client
384
- if Lita.config.handlers.jira.username.nil? ||
385
- Lita.config.handlers.jira.password.nil? ||
386
- Lita.config.handlers.jira.site.nil? ||
387
- Lita.config.handlers.jira.context.nil?
388
- Lita.logger.error('Missing config for JIRA')
389
- fail 'Missing config'
390
- end
391
-
392
- JIRA::Client.new(
393
- username: Lita.config.handlers.jira.username,
394
- password: Lita.config.handlers.jira.password,
395
- site: Lita.config.handlers.jira.site,
396
- context_path: Lita.config.handlers.jira.context,
397
- auth_type: :basic
398
- )
45
+ def summary(response)
46
+ issue = fetch_issue(response.match_data['issue'])
47
+ return response.reply(t('error.request')) unless issue
48
+ response.reply("#{issue.key}: #{issue.summary}")
399
49
  end
400
50
 
401
- def fetch_issue(key)
402
- j_client.Issue.find(key)
403
- rescue JIRA::HTTPError
404
- Lita.logger.error('JIRA HTTPError')
405
- nil
51
+ def details(response)
52
+ issue = fetch_issue(response.match_data['issue'])
53
+ return response.reply(t('error.request')) unless issue
54
+ response.reply(format_issue(issue))
406
55
  end
407
56
 
408
- def format_issue(issue)
409
- t('issue.details',
410
- key: issue.key,
411
- summary: issue.summary,
412
- assigned: issue.assignee.displayName,
413
- priority: issue.priority.name,
414
- status: issue.status.name)
57
+ def comment(response)
58
+ issue = fetch_issue(response.match_data['issue'])
59
+ return response.reply(t('error.request')) unless issue
60
+ comment = issue.comments.build
61
+ comment.save!(body: response.match_data['comment'])
62
+ response.reply(t('comment.added', issue: issue.key))
415
63
  end
416
64
  end
417
65
 
@@ -0,0 +1,62 @@
1
+ # lita-jira plugin
2
+ module Lita
3
+ # Because we can.
4
+ module Handlers
5
+ # Utilities
6
+ class JiraUtility < Handler
7
+ namespace 'Jira'
8
+
9
+ include ::JiraHelper::Issue
10
+ include ::JiraHelper::Misc
11
+ include ::JiraHelper::Regex
12
+ include ::JiraHelper::Utility
13
+
14
+ route(
15
+ /^jira\sidentify\s#{EMAIL_PATTERN}$/,
16
+ :identify,
17
+ command: true,
18
+ help: {
19
+ t('help.identify.syntax') => t('help.identify.desc')
20
+ }
21
+ )
22
+
23
+ route(
24
+ /^jira\sforget$/,
25
+ :forget,
26
+ command: true,
27
+ help: {
28
+ t('help.forget.syntax') => t('help.forget.desc')
29
+ }
30
+ )
31
+
32
+ route(
33
+ /^jira\swhoami$/,
34
+ :whoami,
35
+ command: true,
36
+ help: {
37
+ t('help.whoami.syntax') => t('help.whoami.desc')
38
+ }
39
+ )
40
+
41
+ def identify(response)
42
+ email = response.match_data['email']
43
+ return response.reply(t('error.already_identified', email: get_email(response.user))) if user_stored?(response.user)
44
+ store_user!(response.user, email)
45
+ response.reply(t('identify.stored', email: email))
46
+ end
47
+
48
+ def forget(response)
49
+ return response.reply(t('error.not_identified')) unless user_stored?(response.user)
50
+ delete_user!(response.user)
51
+ response.reply(t('identify.deleted'))
52
+ end
53
+
54
+ def whoami(response)
55
+ return response.reply(t('error.not_identified')) unless user_stored?(response.user)
56
+ response.reply(t('identify.email', email: get_email(response.user)))
57
+ end
58
+
59
+ Lita.register_handler(JiraUtility)
60
+ end
61
+ end
62
+ end
data/lib/lita-jira.rb CHANGED
@@ -4,6 +4,12 @@ Lita.load_locales Dir[File.expand_path(
4
4
  File.join('..', '..', 'locales', '*.yml'), __FILE__
5
5
  )]
6
6
 
7
- require 'lita/handlers/jira'
8
-
9
7
  require 'jira'
8
+
9
+ require 'jirahelper/issue'
10
+ require 'jirahelper/misc'
11
+ require 'jirahelper/regex'
12
+ require 'jirahelper/utility'
13
+
14
+ require 'lita/handlers/jira_utility'
15
+ require 'lita/handlers/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.1'
3
+ spec.version = '0.4.0'
4
4
  spec.authors = ['Eric Sigler']
5
5
  spec.email = ['me@esigler.com']
6
6
  spec.description = 'A Lita handler for interacting with a JIRA ticket tracker.'
@@ -14,12 +14,12 @@ Gem::Specification.new do |spec|
14
14
  spec.test_files = spec.files.grep(/^(test|spec|features)\//)
15
15
  spec.require_paths = ['lib']
16
16
 
17
- spec.add_runtime_dependency 'lita', '>= 3.0'
17
+ spec.add_runtime_dependency 'lita', '>= 4.0'
18
18
  spec.add_runtime_dependency 'jira-ruby', '>= 0.1.8'
19
19
 
20
20
  spec.add_development_dependency 'bundler', '~> 1.3'
21
21
  spec.add_development_dependency 'rake'
22
- spec.add_development_dependency 'rspec', '>= 3.0.0.beta2'
22
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
23
23
  spec.add_development_dependency 'simplecov'
24
24
  spec.add_development_dependency 'coveralls'
25
25
  spec.add_development_dependency 'rubocop'
data/locales/en.yml CHANGED
@@ -3,39 +3,33 @@ en:
3
3
  handlers:
4
4
  jira:
5
5
  error:
6
- not_implemented: Not implemented yet.
6
+ already_identified: "You are already identified as %{email}"
7
+ not_identified: You do not have an email address on record
7
8
  request: Error fetching JIRA issue
8
9
  help:
9
- todo:
10
- syntax: todo <summary>
11
- desc: Creates an issue with your default priority and project settings, assigned to yourself
12
- issue:
13
- assignee_list:
14
- syntax: jira issue assignee <issue ID>
15
- desc: Shows assignee of <issue ID>
16
- assignee_set:
17
- syntax: jira issue assignee <issue ID> <email address>
18
- desc: Sets <email address> as the assignee
19
- attachments_list:
20
- syntax: jira issue attachments <issue ID>
21
- desc: Shows all attachments for <issue ID>
22
- attachments_set:
23
- syntax: jira issue attachments <issue ID> <URL>
24
- desc: Adds <URL> as an attachment on <issue ID>
25
- comments_list:
26
- syntax: jira issue comments <issue ID>
27
- desc: Shows all comments for <issue ID>
28
- comments_set:
29
- syntax: jira issue comments <issue ID> <text>
30
- desc: Adds <text> as a comment on <issue ID>
31
- details:
32
- syntax: jira issue details <issue ID>
33
- desc: Shows all details for <issue ID>
34
- issuetype_list:
35
- syntax: jira issue issuetype <issue ID>
36
- desc: Shows the Issue Type of <issue ID>
37
- issuetype_set:
38
- syntax: jira issue issuetype <issue ID> <issuetype ID>
39
- desc: Sets the Issue Type of <issue ID> to <issuetype ID>
10
+ identify:
11
+ syntax: jira identify <email address>
12
+ desc: Associate your chat user with your email address
13
+ forget:
14
+ syntax: jira forget
15
+ desc: Remove your chat user / email association
16
+ whoami:
17
+ syntax: jira whoami
18
+ desc: Show your chat user / email association
19
+ comment:
20
+ syntax:
21
+ desc:
22
+ details:
23
+ syntax: jira details <issue>
24
+ desc: Shows detailed information for <issue>
25
+ summary:
26
+ syntax: jira <issue>
27
+ desc: Shows summary for <issue>
28
+ identify:
29
+ stored: "You have been identified as %{email} to JIRA"
30
+ deleted: You have been de-identified from JIRA
31
+ email: "You are identified with JIRA as %{email}"
40
32
  issue:
41
- details: "%{key}: %{summary}, assigned to: %{assigned}, priority: %{priority}, status: %{status}"
33
+ details: "%{key}: %{summary}, assigned to: %{assigned}, priority: %{priority}, status: %{status}"
34
+ comment:
35
+ added: "Comment added to %{issue}"
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Lita::Handlers::Jira, lita_handler: true do
4
- let(:open_issue) do
4
+ let(:basic_issue) do
5
5
  double(summary: 'Some summary text',
6
6
  assignee: double(displayName: 'A Person'),
7
7
  priority: double(name: 'P0'),
@@ -9,184 +9,71 @@ describe Lita::Handlers::Jira, lita_handler: true do
9
9
  key: 'XYZ-987')
10
10
  end
11
11
 
12
- def grab_issue_request(key, issue)
13
- allow_any_instance_of(Lita::Handlers::Jira).to \
14
- receive(:fetch_issue).with(key).and_return(issue)
12
+ let(:open_issue) do
13
+ r = double
14
+ expect(r).to receive_message_chain('Issue.find') { basic_issue }
15
+ r
15
16
  end
16
17
 
17
- it { routes_command('todo some text').to(:todo) }
18
- it { routes_command('jira issue assignee ABC-123').to(:issue_assignee_list) }
19
- it { routes_command('jira issue assignee ABC-123 foo@example.com').to(:issue_assignee_set) }
20
- it { routes_command('jira issue attachments ABC-123').to(:issue_attachments_list) }
21
- it { routes_command('jira issue attachments ABC-123 http://example.com').to(:issue_attachments_set) }
22
- it { routes_command('jira issue comments ABC-123').to(:issue_comments_list) }
23
- it { routes_command('jira issue comments ABC-123 Some text').to(:issue_comments_add) }
24
- it { routes_command('jira issue details ABC-123').to(:issue_details) }
25
- it { routes_command('jira issue issuetype ABC-123').to(:issue_issuetype_list) }
26
- it { routes_command('jira issue issuetype ABC-123 4').to(:issue_issuetype_set) }
27
- it { routes_command('jira issue new ABC some:thing').to(:issue_new) }
28
- it { routes_command('jira issue notify ABC-123').to(:issue_notify_list) }
29
- it { routes_command('jira issue notify ABC-123 foo@example.com').to(:issue_notify_set) }
30
- it { routes_command('jira issue priority ABC-123').to(:issue_priority_list) }
31
- it { routes_command('jira issue priority ABC-123 9').to(:issue_priority_set) }
32
- it { routes_command('jira issue summary ABC-123').to(:issue_summary_list) }
33
- it { routes_command('jira issue summary ABC-123 Some text!').to(:issue_summary_set) }
34
- it { routes_command('jira issue watchers ABC-123').to(:issue_watchers_list) }
35
- it { routes_command('jira issue watchers ABC-123 foo@example.com').to(:issue_watchers_set) }
36
- it { routes_command('jira issuetype list ABC').to(:issuetype_list) }
37
- it { routes_command('jira search Some text').to(:search_full) }
38
- it { routes_command('jira search ABC Some text').to(:search_project) }
39
- it { routes_command('jira identify foo@example.com').to(:identify) }
40
- it { routes_command('jira forget').to(:forget) }
41
- it { routes_command('jira whoami').to(:whoami) }
42
- it { routes_command('jira default project ABC').to(:default_project) }
43
- it { routes_command('jira default priority 9').to(:default_priority) }
44
-
45
- describe '.default_config' do
46
- it 'sets username to nil' do
47
- expect(Lita.config.handlers.jira.username).to be_nil
48
- end
49
-
50
- it 'sets password to nil' do
51
- expect(Lita.config.handlers.jira.password).to be_nil
52
- end
18
+ let(:failed_find) do
19
+ r = double
20
+ expect(r).to receive_message_chain('Issue.find').and_throw(JIRA::HTTPError)
21
+ r
22
+ end
53
23
 
54
- it 'sets site to nil' do
55
- expect(Lita.config.handlers.jira.site).to be_nil
56
- end
24
+ let(:comment_issue) do
25
+ r = double
26
+ expect(r).to receive_message_chain('Issue.find') { basic_issue }
27
+ expect(r).to receive_message_chain('Issue.find.comments.build.save!') { basic_issue }
28
+ r
29
+ end
57
30
 
58
- it 'sets context to nil' do
59
- expect(Lita.config.handlers.jira.context).to be_nil
60
- end
31
+ it do
32
+ is_expected.to route_command('jira ABC-123')
33
+ is_expected.to route_command('jira details ABC-123')
34
+ is_expected.to route_command('jira comment on ABC-123 "You just need a cat"')
61
35
  end
62
36
 
63
- describe '#issue_summary' do
64
- it 'with valid issue ID shows summary' do
65
- grab_issue_request('XYZ-987', open_issue)
37
+ describe '#summary' do
38
+ it 'shows summary with a valid issue' do
39
+ grab_request(open_issue)
66
40
  send_command('jira XYZ-987')
67
41
  expect(replies.last).to eq('XYZ-987: Some summary text')
68
42
  end
69
43
 
70
- it 'without valid issue ID shows an error' do
71
- grab_issue_request('XYZ-987', nil)
44
+ it 'warns the user when the issue is not valid' do
45
+ grab_request(failed_find)
72
46
  send_command('jira XYZ-987')
73
47
  expect(replies.last).to eq('Error fetching JIRA issue')
74
48
  end
75
49
  end
76
50
 
77
- describe '#issue_details' do
78
- it 'with valid issue ID shows details' do
79
- grab_issue_request('XYZ-987', open_issue)
80
- send_command('jira XYZ-987 details')
51
+ describe '#details' do
52
+ it 'shows details with a valid issue' do
53
+ grab_request(open_issue)
54
+ send_command('jira details XYZ-987')
81
55
  expect(replies.last).to eq('XYZ-987: Some summary text, assigned to: ' \
82
56
  'A Person, priority: P0, status: In Progress')
83
57
  end
84
58
 
85
- it 'without valid issue ID shows an error' do
86
- grab_issue_request('XYZ-987', nil)
87
- send_command('jira XYZ-987 details')
59
+ it 'warns the user when the issue is not valid' do
60
+ grab_request(failed_find)
61
+ send_command('jira details XYZ-987')
88
62
  expect(replies.last).to eq('Error fetching JIRA issue')
89
63
  end
90
64
  end
91
65
 
92
- describe '#todo' do
93
- end
94
-
95
- describe '#issue_assignee_list' do
96
- it 'with valid issue ID shows the current assignees'
97
-
98
- it 'without valid issue ID shows an error'
99
- end
100
-
101
- describe '#issue_assignee_set' do
102
- it 'with valid issue ID sets an assignee'
103
-
104
- it 'without valid issue ID shows an error'
105
- end
106
-
107
- describe '#issue_attachments_list' do
108
- it 'with valid issue ID shows the current attachments'
109
-
110
- it 'without valid issue ID shows an error'
111
- end
112
-
113
- describe '#issue_attachments_set' do
114
- it 'without valid issue ID shows an error'
115
- end
116
-
117
- describe '#issue_comments_list' do
118
- it 'without valid issue ID shows an error'
119
- end
120
-
121
- describe '#issue_comments_add' do
122
- it 'without valid issue ID shows an error'
123
- end
124
-
125
- describe '#issue_issuetype_list' do
126
- it 'without valid issue ID shows an error'
127
- end
128
-
129
- describe '#issue_issuetype_set' do
130
- it 'without valid issue ID shows an error'
131
- end
132
-
133
- describe '#issue_new' do
134
- end
135
-
136
- describe '#issue_notify_list' do
137
- it 'without valid issue ID shows an error'
138
- end
139
-
140
- describe '#issue_notify_set' do
141
- it 'without valid issue ID shows an error'
142
- end
143
-
144
- describe '#issue_priority_list' do
145
- it 'without valid issue ID shows an error'
146
- end
147
-
148
- describe '#issue_priority_set' do
149
- it 'without valid issue ID shows an error'
150
- end
151
-
152
- describe '#issue_summary_list' do
153
- it 'without valid issue ID shows an error'
154
- end
155
-
156
- describe '#issue_summary_set' do
157
- it 'without valid issue ID shows an error'
158
- end
159
-
160
- describe '#issue_watchers_list' do
161
- it 'without valid issue ID shows an error'
162
- end
163
-
164
- describe '#issue_watchers_set' do
165
- it 'without valid issue ID shows an error'
166
- end
167
-
168
- describe '#issuetype_list' do
169
- it 'without valid issuetype shows an error'
170
- end
171
-
172
- describe '#search_full' do
173
- end
174
-
175
- describe '#search_project' do
176
- end
177
-
178
- describe '#identify' do
179
- end
180
-
181
- describe '#forget' do
182
- end
183
-
184
- describe '#whoami' do
185
- end
186
-
187
- describe '#default_project' do
188
- end
66
+ describe '#comment' do
67
+ it 'updates the comment with a valid issue and comment text' do
68
+ grab_request(comment_issue)
69
+ send_command('jira comment on XYZ-987 "Testing"')
70
+ expect(replies.last).to eq('Comment added to XYZ-987')
71
+ end
189
72
 
190
- describe '#default_priority' do
73
+ it 'warns the user when the issue is not valid' do
74
+ grab_request(failed_find)
75
+ send_command('jira comment on XYZ-987 "Testing"')
76
+ expect(replies.last).to eq('Error fetching JIRA issue')
77
+ end
191
78
  end
192
79
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lita::Handlers::JiraUtility, lita_handler: true do
4
+ it do
5
+ is_expected.to route_command('jira identify user@example.com').to(:identify)
6
+ is_expected.to route_command('jira forget').to(:forget)
7
+ is_expected.to route_command('jira whoami').to(:whoami)
8
+ end
9
+
10
+ describe '#identify' do
11
+ it 'remembers the user if they do not already have an email address stored' do
12
+ send_command('jira identify user@example.com')
13
+ expect(replies.last).to eq('You have been identified as user@example.com to JIRA')
14
+ end
15
+
16
+ it 'warns the user if they have already stored an email address' do
17
+ send_command('jira identify user@example.com')
18
+ send_command('jira identify otheruser@example.com')
19
+ expect(replies.last).to eq('You are already identified as user@example.com')
20
+ end
21
+ end
22
+
23
+ describe '#forget' do
24
+ it 'forgets the user if they have an email address stored' do
25
+ send_command('jira identify user@example.com')
26
+ send_command('jira forget')
27
+ expect(replies.last).to eq('You have been de-identified from JIRA')
28
+ end
29
+
30
+ it 'warns the user if they did not have a stored email address' do
31
+ send_command('jira forget')
32
+ expect(replies.last).to eq('You do not have an email address on record')
33
+ end
34
+ end
35
+
36
+ describe '#whoami' do
37
+ it 'shows the current stored email address if one exists' do
38
+ send_command('jira identify user@example.com')
39
+ send_command('jira whoami')
40
+ expect(replies.last).to eq('You are identified with JIRA as user@example.com')
41
+ end
42
+
43
+ it 'warns the user if there is no stored address' do
44
+ send_command('jira whoami')
45
+ expect(replies.last).to eq('You do not have an email address on record')
46
+ end
47
+ end
48
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,3 +8,16 @@ SimpleCov.start { add_filter '/spec/' }
8
8
 
9
9
  require 'lita-jira'
10
10
  require 'lita/rspec'
11
+
12
+ Lita.version_3_compatibility_mode = false
13
+
14
+ RSpec.configure do |config|
15
+ config.before do
16
+ registry.register_handler(Lita::Handlers::Jira)
17
+ registry.register_handler(Lita::Handlers::JiraUtility)
18
+ end
19
+ end
20
+
21
+ def grab_request(result)
22
+ expect(JIRA::Client).to receive(:new) { result }
23
+ 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.3.1
4
+ version: 0.4.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: 2014-10-23 00:00:00.000000000 Z
11
+ date: 2014-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lita
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '4.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '4.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: jira-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 3.0.0.beta2
75
+ version: 3.0.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: 3.0.0.beta2
82
+ version: 3.0.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -137,11 +137,17 @@ files:
137
137
  - LICENSE
138
138
  - README.md
139
139
  - Rakefile
140
+ - lib/jirahelper/issue.rb
141
+ - lib/jirahelper/misc.rb
142
+ - lib/jirahelper/regex.rb
143
+ - lib/jirahelper/utility.rb
140
144
  - lib/lita-jira.rb
141
145
  - lib/lita/handlers/jira.rb
146
+ - lib/lita/handlers/jira_utility.rb
142
147
  - lita-jira.gemspec
143
148
  - locales/en.yml
144
149
  - spec/lita/handlers/jira_spec.rb
150
+ - spec/lita/handlers/jira_utility_spec.rb
145
151
  - spec/spec_helper.rb
146
152
  homepage: https://github.com/esigler/lita-jira
147
153
  licenses:
@@ -170,4 +176,5 @@ specification_version: 4
170
176
  summary: A Lita handler for interacting with a JIRA ticket tracker.
171
177
  test_files:
172
178
  - spec/lita/handlers/jira_spec.rb
179
+ - spec/lita/handlers/jira_utility_spec.rb
173
180
  - spec/spec_helper.rb