lita-rally 0.5.1 → 1.0.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: 9bbc5ed8578ec25616f170a8e30daf1815f00c84
4
- data.tar.gz: 49ff71920b01d7055f5cc6446a91877b99f8667f
3
+ metadata.gz: 7bf8834065045d16994a6bb96b410dcd800c29c7
4
+ data.tar.gz: d2784f663aaa28ed26b8467f8eed0d8bb80a08b5
5
5
  SHA512:
6
- metadata.gz: e949763e95fd0f4309532b3b2ff78f3e30bf00be4c3638bfc7a0be72b60b00874e8a1caa64cb461568e2e98236f11d593a9b1c48337d7374f9832cebadcdc102
7
- data.tar.gz: cb64a2c961a67104bf1d3e8e194ed9664e26163df98d7584c54efc9c8b3f043f90a79c7d255d9912ef4af08402cccd22c5b98de00e7d867739edfa3cbcee5688
6
+ metadata.gz: ebb35d0f3eb7fb5be0313ca808d29fbf5b36b355ac1a4610c83a5e4e5c94bcf7b9fdb2c02b356b6813fe2071fc72ab226829e582757a1e55d67700a7c07e8369
7
+ data.tar.gz: 4d41677a8c4797e5823b994af5f78e92eb5ba851361f855ca87b5e2d49d753fb7e93efb40c84c68c7fb959992c05efc1444d5efe78f308d78bb4f49aea9706be
data/README.md CHANGED
@@ -54,6 +54,21 @@ to the corresponding schedule states of the artifact. **Default:**
54
54
  }
55
55
  ```
56
56
 
57
+ ```config.handlers.rally.action_task_state_map``` - [Hash] a map of actions to
58
+ the corresponding task state of the artifact. **Default:**
59
+
60
+ ```ruby
61
+ {
62
+ 'start' => 'In-Progress',
63
+ 'pause' => 'Defined',
64
+ 'backlog' => 'Defined',
65
+ 'finish' => 'Completed',
66
+ 'accept' => 'Completed',
67
+ }
68
+ ```
69
+
70
+ ```config.handlers.rally.hipchat_token``` - [String] Hipchat token.
71
+ **Default:** nil
57
72
 
58
73
  ## Usage
59
74
 
@@ -96,6 +111,24 @@ lita rally query <type> <query_string>
96
111
 
97
112
  Execute raw Rally API query with <type> and <query_string>
98
113
 
114
+ ```
115
+ lita rally mine
116
+ ```
117
+
118
+ **(HipChat Only, require hipchat_tocken config)** Look up all Rally objects
119
+ belongs to me. (Limited to type Defect, Story, Task) Look up involves using
120
+ HipChat to determine user's e-mail. HipChat user's registered e-mail must match
121
+ Rally user registered e-mail.
122
+
123
+ ```
124
+ lita rally my <defect|defects|story|stories|task|tasks>
125
+ ```
126
+
127
+ **(HipChat Only, require hipchat_tocken config)** Look up all Rally objects
128
+ belongs to me of specific type. (Limited to type Defect, Story, Task) Look up
129
+ involves using HipChat to determine user's e-mail. HipChat user's registered
130
+ e-mail must match Rally user registered e-mail.
131
+
99
132
  ```
100
133
  lita rally <start|pause|finish|accept|backlog> <FormattedID>
101
134
  ```
@@ -83,7 +83,7 @@ module Lita
83
83
  'start' => 'Submitted',
84
84
  'pause' => 'Submitted',
85
85
  'backlog' => 'Submitted',
86
- 'finished' => 'Fixed',
86
+ 'finish' => 'Fixed',
87
87
  'accept' => 'Closed',
88
88
  }
89
89
  config :action_schedule_state_map, type: Hash, default: {
@@ -93,6 +93,14 @@ module Lita
93
93
  'accept' => 'Accepted',
94
94
  'backlog' => 'Backlog',
95
95
  }
96
+ config :action_task_state_map, type: Hash, default: {
97
+ 'start' => 'In-Progress',
98
+ 'pause' => 'Defined',
99
+ 'backlog' => 'Defined',
100
+ 'finish' => 'Completed',
101
+ 'accept' => 'Completed',
102
+ }
103
+ config :hipchat_token, type: String, default: nil
96
104
 
97
105
  route(/^rally me ([[:alpha:]]+)(\d+)/, :rally_show, command: true, help: {
98
106
  'rally me <identifier>' => 'Show me that rally object'
@@ -117,7 +125,7 @@ module Lita
117
125
  route(/^rally (start|pause|finish|accept|backlog) ([[:alpha:]]+)(\d+)/,
118
126
  :rally_mark, command: true, help: {
119
127
  'rally <start|pause|finish|accept|backlog> <formattedID>' =>
120
- 'mark issue in-progress'
128
+ 'Move issues between scheduling states'
121
129
  })
122
130
 
123
131
  route(/^rally query (\w+)\s+(.*)$/,
@@ -138,6 +146,57 @@ module Lita
138
146
  'Find defect objects in date range'
139
147
  })
140
148
 
149
+ route( /^rally mine/, :rally_find_mine, command: true, help: {
150
+ 'rally mine' =>
151
+ '(HipChat Only) Find defects/stories/tasks belongs to me'
152
+ })
153
+
154
+ route( /^rally my (defect|defects|story|stories|task|tasks)/,
155
+ :rally_find_my, command: true, help: {
156
+ 'rally my <defect|story|task>' =>
157
+ '(HipChat Only) Find defects/stories/tasks belongs to me'
158
+ })
159
+
160
+ def rally_find_my(response)
161
+ if config.hipchat_token
162
+ uuid = rally_find_user(hipchat_find_user(response.user.mention_name))
163
+
164
+ raise "Your email is not found in Rally" unless uuid
165
+
166
+ type = response.matches[0][0]
167
+
168
+ type = 'story' if type == 'stories'
169
+ type = type[0..-2] if type[-1] == 's'
170
+
171
+ response.reply(rally_find_type(type, uuid))
172
+ else
173
+ response.reply('This is a HipChat only function, please provide '\
174
+ 'hipchat_token to use this function.')
175
+ end
176
+ rescue Exception => e
177
+ response.reply("Error occured: #{e}")
178
+ end
179
+
180
+ def rally_find_mine(response)
181
+ if config.hipchat_token
182
+ uuid = rally_find_user(hipchat_find_user(response.user.mention_name))
183
+
184
+ raise "Your email is not found in Rally" unless uuid
185
+
186
+ response.reply(
187
+ %w{story defect task}.inject("") do |output,type|
188
+ output += "#{type.capitalize}:\n#{rally_find_type(type, uuid)}"
189
+ end
190
+ )
191
+
192
+ else
193
+ response.reply('This is a HipChat only function, please provide '\
194
+ 'hipchat_token to use this function.')
195
+ end
196
+ rescue Exception => e
197
+ response.reply("Error occured: #{e}")
198
+ end
199
+
141
200
  def rally_find_defect_back(response)
142
201
  field =
143
202
  response.matches[0][0] == 'created' ? 'CreationDate' : 'ClosedDate'
@@ -188,11 +247,20 @@ module Lita
188
247
  type = response.matches[0][1].downcase
189
248
  id = response.matches[0][2]
190
249
 
250
+ raise 'Only defect (DE) story (US) task (TA) are supported' unless
251
+ %{de us ta}.include?(type)
252
+
191
253
  schedule_state = config.action_schedule_state_map[action]
192
254
 
193
- state = config.action_state_map[action]
255
+ state = if type == 'ta'
256
+ config.action_task_state_map[action]
257
+ else
258
+ config.action_state_map[action]
259
+ end
194
260
 
195
- response.reply(update_object(type, id, 'ScheduleState', schedule_state))
261
+ response.reply(
262
+ update_object(type, id, 'ScheduleState', schedule_state)
263
+ ) if %{de us}.include?(type)
196
264
 
197
265
  response.reply(update_object(type, id, 'State', state))
198
266
 
@@ -200,7 +268,8 @@ module Lita
200
268
  "<br />Marked #{state} by #{response.user.name} on " \
201
269
  "#{Time.now.strftime('%Y-%m-%dT%H:%M:%S%z')}",
202
270
  append: true)
203
-
271
+ rescue Exception => e
272
+ response.reply("Error: #{e}")
204
273
  end
205
274
 
206
275
  def rally_show(response)
@@ -413,20 +482,45 @@ module Lita
413
482
  )
414
483
  end
415
484
 
416
- def rally_search(type, term, field)
485
+ def rally_find_type(type, uuid)
486
+ rally = get_rally_api
487
+
488
+ q = "(Owner.ObjectUUID = \"#{uuid}\")"
489
+ query =
490
+ case type
491
+ when 'defect'
492
+ "(#{q} AND (ScheduleState != Accepted))"
493
+ when 'story'
494
+ "(#{q} AND (ScheduleState != Accepted))"
495
+ when 'task'
496
+ "(#{q} AND (State != Completed))"
497
+ else
498
+ raise "Not a supported type: #{type}"
499
+ end
500
+
501
+ rally_search(type, query, 'raw', true)
502
+ rescue Exception => e
503
+ "Query error #{e}"
504
+ end
505
+
506
+ def rally_search(type, term, field, state = false)
417
507
  rally = get_rally_api
418
508
 
419
509
  query = RallyAPI::RallyQuery.new()
420
510
  if %w{defect defects}.include?(type)
421
511
  query.type = 'defect'
422
- else
512
+ elsif %w{story stories}.include?(type)
423
513
  query.type = 'story'
514
+ else
515
+ query.type = 'task'
424
516
  end
425
517
 
426
518
  if field == 'name'
427
519
  query.query_string = "(Name contains \"#{term}\")"
428
- else
520
+ elsif field == 'description'
429
521
  query.query_string = "(Description contains \"#{term}\")"
522
+ else
523
+ query.query_string = term
430
524
  end
431
525
 
432
526
  result = rally.find(query)
@@ -435,10 +529,44 @@ module Lita
435
529
 
436
530
  result.inject("#{result.count} results total:\n") do |o,r|
437
531
  r.read
438
- o += "#{r['FormattedID']} - #{r['Name']}\n"
532
+ o += "#{r['FormattedID']}"
533
+ o += " [#{r['ScheduleState']}]" if
534
+ state && %{defect story}.include?(type)
535
+ o += " [#{r['State']}]" if state && type == 'task'
536
+ o += " - #{r['Name']}"
537
+ o += "\n"
439
538
  end
440
539
  end
441
540
 
541
+ def get_hipchat_rest
542
+ RestClient::Resource.new(
543
+ "#{HIPCHAT}/",
544
+ headers: {
545
+ Authorization: "Bearer #{config.hipchat_token}"
546
+ }
547
+ )
548
+ end
549
+
550
+ def hipchat_find_user(mention_name)
551
+ JSON.parse(
552
+ get_hipchat_rest["user/@#{mention_name}"].get
553
+ )['email']
554
+ end
555
+
556
+ def rally_find_user(email)
557
+ rally = get_rally_api
558
+
559
+ query = RallyAPI::RallyQuery.new()
560
+ query.type = :user
561
+ query.query_string = "(EmailAddress = #{email})"
562
+
563
+ result = rally.find(query)
564
+
565
+ return nil if result.count == 0
566
+
567
+ result[0].read['ObjectUUID']
568
+ end
569
+
442
570
  end
443
571
 
444
572
  Lita.register_handler(Rally)
data/lita-rally.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'lita-rally'
3
- spec.version = '0.5.1'
3
+ spec.version = '1.0.0'
4
4
  spec.authors = ['Richard Li']
5
5
  spec.email = ['evilcat@wisewolfsolutions.com']
6
6
  spec.description = %q{Rally plugin for lita bot}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-rally
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-25 00:00:00.000000000 Z
11
+ date: 2015-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lita