lita-jira 0.3.1 → 0.4.0

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