lita-jira 0.3.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ec792cf09935ca050ad43f9267251831c2c0e551
4
+ data.tar.gz: 2e5658bc5ed997068470279c7fb6eaf51acfb20a
5
+ SHA512:
6
+ metadata.gz: cd93b6be7fe4d14ec6dc2d4f0862c63db299d9340bf64901ec58d1b2f03bd1fbf9073bbf1d27ed69865b2fbe1e273acce65d21890f12250333105fccea68343e
7
+ data.tar.gz: 3622a99a077d3c7784aa0cebfea90c5ff277eb5fa74baaa3e8ea28e40e50588630b219581cce1d16b6e747d4e08985acd70ebebc87bef362fa400fa0568d5c8b
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.swp
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ ClassLength:
2
+ Max: 400
3
+
4
+ CyclomaticComplexity:
5
+ Max: 10
6
+
7
+ Documentation:
8
+ Enabled: false
9
+
10
+ FileName:
11
+ Enabled: false
12
+
13
+ LineLength:
14
+ Max: 130
15
+
16
+ MethodLength:
17
+ Max: 30
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script: bundle exec rake
5
+ before_install:
6
+ - gem update --system
7
+ services:
8
+ - redis-server
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,9 @@
1
+ Pull requests are awesome! Pull requests with tests are even more awesome!
2
+
3
+ ## Quick steps
4
+
5
+ 1. Fork the repo.
6
+ 2. Run the tests: `bundle && rake`
7
+ 3. Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, it needs a test!
8
+ 4. Make the test pass.
9
+ 5. Push to your fork and submit a pull request.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'jira-ruby', require: 'jira'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014 Eric Sigler
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # lita-jira
2
+
3
+ [![Build Status](https://img.shields.io/travis/esigler/lita-jira/master.svg)](https://travis-ci.org/esigler/lita-jira)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://tldrlegal.com/license/mit-license)
5
+ [![RubyGems :: RMuh Gem Version](http://img.shields.io/gem/v/lita-jira.svg)](https://rubygems.org/gems/lita-jira)
6
+ [![Coveralls Coverage](https://img.shields.io/coveralls/esigler/lita-jira/master.svg)](https://coveralls.io/r/esigler/lita-jira)
7
+ [![Code Climate](https://img.shields.io/codeclimate/github/esigler/lita-jira.svg)](https://codeclimate.com/github/esigler/lita-jira)
8
+ [![Gemnasium](https://img.shields.io/gemnasium/esigler/lita-jira.svg)](https://gemnasium.com/esigler/lita-jira)
9
+
10
+ JIRA (https://www.atlassian.com/software/jira) [handler](https://github.com/jimmycuadra/lita) for creating, updating issues.
11
+
12
+ ## Installation
13
+
14
+ Add lita-jira to your Lita instance's Gemfile:
15
+
16
+ ``` ruby
17
+ gem "lita-jira"
18
+ ```
19
+
20
+ ## Configuration
21
+
22
+ Add the following variables to your lita config file:
23
+
24
+ ```
25
+ config.handlers.jira.username = 'your_jira_username'
26
+ config.handlers.jira.password = 'a_password'
27
+ config.handlers.jira.site = 'https://your.jira.instance.example.com/'
28
+ config.handlers.jira.context = '' # If your instance is in a /subdirectory, put that here
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ### Shortcuts
34
+
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>
66
+ ```
67
+
68
+ ### Search
69
+
70
+ ```
71
+ jira search "<text>" - Search for <text> across all of JIRA
72
+ jira search <project ID> "<text>" - Search for <text> within the scope of <project ID>
73
+ ```
74
+
75
+ ### Misc
76
+
77
+ ```
78
+ jira identify <email address> - Associate your chat user with your email address
79
+ jira forget - Remove your chat user / email association
80
+ 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
+ ```
84
+
85
+ ## License
86
+
87
+ [MIT](http://opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new(:rubocop)
7
+
8
+ task default: [:spec, :rubocop]
@@ -0,0 +1,420 @@
1
+ module Lita
2
+ module Handlers
3
+ class Jira < Handler
4
+ PROJECT_PATTERN = '[a-zA-Z0-9]{1,10}'
5
+ ISSUE_PATTERN = "#{PROJECT_PATTERN}-[0-9]{1,5}"
6
+
7
+ route(
8
+ /^todo\s(.*)$/,
9
+ :todo,
10
+ command: true,
11
+ help: {
12
+ t('help.todo.syntax') => t('help.todo.desc')
13
+ }
14
+ )
15
+
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
+ )
24
+
25
+ route(
26
+ /^jira\sissue\sassignee\s(#{ISSUE_PATTERN})\s(.+)$/,
27
+ :issue_assignee_set,
28
+ command: true,
29
+ help: {
30
+ t('help.issue.assignee_set.syntax') => t('help.issue.assignee_set.syntax')
31
+ }
32
+ )
33
+
34
+ route(
35
+ /^jira\sissue\sattachments\s(#{ISSUE_PATTERN})$/,
36
+ :issue_attachments_list,
37
+ command: true,
38
+ 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')
198
+ }
199
+ )
200
+
201
+ 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,
236
+ command: true,
237
+ help: {
238
+ 'jira <issue ID>' => 'Shows summary for <issue ID>'
239
+ }
240
+ )
241
+
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
+ )
399
+ end
400
+
401
+ def fetch_issue(key)
402
+ j_client.Issue.find(key)
403
+ rescue JIRA::HTTPError
404
+ Lita.logger.error('JIRA HTTPError')
405
+ nil
406
+ end
407
+
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)
415
+ end
416
+ end
417
+
418
+ Lita.register_handler(Jira)
419
+ end
420
+ end
data/lib/lita-jira.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'lita'
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join('..', '..', 'locales', '*.yml'), __FILE__
5
+ )]
6
+
7
+ require 'lita/handlers/jira'
8
+
9
+ require 'jira'
data/lita-jira.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'lita-jira'
3
+ spec.version = '0.3.1'
4
+ spec.authors = ['Eric Sigler']
5
+ spec.email = ['me@esigler.com']
6
+ spec.description = 'A Lita handler for interacting with a JIRA ticket tracker.'
7
+ spec.summary = 'A Lita handler for interacting with a JIRA ticket tracker.'
8
+ spec.homepage = 'https://github.com/esigler/lita-jira'
9
+ spec.license = 'MIT'
10
+ spec.metadata = { 'lita_plugin_type' => 'handler' }
11
+
12
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
13
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
15
+ spec.require_paths = ['lib']
16
+
17
+ spec.add_runtime_dependency 'lita', '>= 3.0'
18
+ spec.add_runtime_dependency 'jira-ruby', '>= 0.1.8'
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.3'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'rspec', '>= 3.0.0.beta2'
23
+ spec.add_development_dependency 'simplecov'
24
+ spec.add_development_dependency 'coveralls'
25
+ spec.add_development_dependency 'rubocop'
26
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,41 @@
1
+ en:
2
+ lita:
3
+ handlers:
4
+ jira:
5
+ error:
6
+ not_implemented: Not implemented yet.
7
+ request: Error fetching JIRA issue
8
+ 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>
40
+ issue:
41
+ details: "%{key}: %{summary}, assigned to: %{assigned}, priority: %{priority}, status: %{status}"
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lita::Handlers::Jira, lita_handler: true do
4
+ let(:open_issue) do
5
+ double(summary: 'Some summary text',
6
+ assignee: double(displayName: 'A Person'),
7
+ priority: double(name: 'P0'),
8
+ status: double(name: 'In Progress'),
9
+ key: 'XYZ-987')
10
+ end
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)
15
+ end
16
+
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
53
+
54
+ it 'sets site to nil' do
55
+ expect(Lita.config.handlers.jira.site).to be_nil
56
+ end
57
+
58
+ it 'sets context to nil' do
59
+ expect(Lita.config.handlers.jira.context).to be_nil
60
+ end
61
+ end
62
+
63
+ describe '#issue_summary' do
64
+ it 'with valid issue ID shows summary' do
65
+ grab_issue_request('XYZ-987', open_issue)
66
+ send_command('jira XYZ-987')
67
+ expect(replies.last).to eq('XYZ-987: Some summary text')
68
+ end
69
+
70
+ it 'without valid issue ID shows an error' do
71
+ grab_issue_request('XYZ-987', nil)
72
+ send_command('jira XYZ-987')
73
+ expect(replies.last).to eq('Error fetching JIRA issue')
74
+ end
75
+ end
76
+
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')
81
+ expect(replies.last).to eq('XYZ-987: Some summary text, assigned to: ' \
82
+ 'A Person, priority: P0, status: In Progress')
83
+ end
84
+
85
+ it 'without valid issue ID shows an error' do
86
+ grab_issue_request('XYZ-987', nil)
87
+ send_command('jira XYZ-987 details')
88
+ expect(replies.last).to eq('Error fetching JIRA issue')
89
+ end
90
+ end
91
+
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
189
+
190
+ describe '#default_priority' do
191
+ end
192
+ end
@@ -0,0 +1,10 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4
+ SimpleCov::Formatter::HTMLFormatter,
5
+ Coveralls::SimpleCov::Formatter
6
+ ]
7
+ SimpleCov.start { add_filter '/spec/' }
8
+
9
+ require 'lita-jira'
10
+ require 'lita/rspec'
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-jira
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Eric Sigler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jira-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.8
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.8
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0.beta2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0.beta2
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: coveralls
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: A Lita handler for interacting with a JIRA ticket tracker.
126
+ email:
127
+ - me@esigler.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rubocop.yml"
134
+ - ".travis.yml"
135
+ - CONTRIBUTING.md
136
+ - Gemfile
137
+ - LICENSE
138
+ - README.md
139
+ - Rakefile
140
+ - lib/lita-jira.rb
141
+ - lib/lita/handlers/jira.rb
142
+ - lita-jira.gemspec
143
+ - locales/en.yml
144
+ - spec/lita/handlers/jira_spec.rb
145
+ - spec/spec_helper.rb
146
+ homepage: https://github.com/esigler/lita-jira
147
+ licenses:
148
+ - MIT
149
+ metadata:
150
+ lita_plugin_type: handler
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 2.2.2
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: A Lita handler for interacting with a JIRA ticket tracker.
171
+ test_files:
172
+ - spec/lita/handlers/jira_spec.rb
173
+ - spec/spec_helper.rb