opsask 2.0.0 → 2.0.1

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: d841e29ac173b8f44d7a5ff45c7d1e8d4de825aa
4
- data.tar.gz: 76c7c5466e88f24c2d6568bc5f76a3e36aff536a
3
+ metadata.gz: cbff03a2754db23e2c4924d402c479430b57eae0
4
+ data.tar.gz: 34b9c28797098d3329167157effee3421fde796e
5
5
  SHA512:
6
- metadata.gz: 5966bee1cc2398ee5f0be1452c6386cd17d10c64ff306671559b1f344143f355edfb319dc10b0505cfcbd0883c7565aa1a05e14f350479dd1451b905fbfd72fe
7
- data.tar.gz: 2fd73ba9fb5cc48f741f0a65daf5a487b1bbdc90fae73410326f949e868ddf15df422849e186c4d0d5d1e79e3d0f9a939952814bc703909caa72418dc87b8a2a
6
+ metadata.gz: 67de8c2f12b86598b6a6d1c6f3a33033bcbcf945710d4b09a456d4bd953dc99a7aabeacc1017a706668e337a51220d6ec9ca94ad0f80d2caf76e852b6db1e3fc
7
+ data.tar.gz: 9a3d53f75530f62ecdf57d64e6ed6bf578d9fe57c43dea8d5b742b1d84a608037e73e54b09a7710524d9ed172c99e9c07b9d2663005b5aecca9fa018000f2ef0
data/.gitignore CHANGED
@@ -12,3 +12,4 @@ pkg
12
12
  .DS_Store
13
13
  config.json
14
14
  .bundle
15
+ .yardoc
data/Gemfile.lock CHANGED
@@ -3,9 +3,9 @@ PATH
3
3
  specs:
4
4
  opsask (2.0.0)
5
5
  curb (~> 0.8)
6
- jira-ruby (~> 0.1)
7
6
  rack (~> 1)
8
7
  rack-flash3 (~> 1)
8
+ sclemmer-jira-ruby (~> 0.1)
9
9
  sinatra (~> 1.4)
10
10
  sinatra-partial (~> 0.4)
11
11
  thin (~> 1)
@@ -14,7 +14,7 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- activesupport (4.1.7)
17
+ activesupport (4.1.8)
18
18
  i18n (~> 0.6, >= 0.6.9)
19
19
  json (~> 1.7, >= 1.7.7)
20
20
  minitest (~> 5.1)
@@ -25,9 +25,6 @@ GEM
25
25
  daemons (1.1.9)
26
26
  eventmachine (1.0.3)
27
27
  i18n (0.6.11)
28
- jira-ruby (0.1.11)
29
- activesupport (~> 4.1.4)
30
- oauth (~> 0.4.7)
31
28
  json (1.8.1)
32
29
  method_source (0.8.2)
33
30
  minitest (5.4.3)
@@ -43,6 +40,9 @@ GEM
43
40
  rack
44
41
  rake (10.3.2)
45
42
  rubygems-tasks (0.2.4)
43
+ sclemmer-jira-ruby (0.1.12)
44
+ activesupport (~> 4.1.4)
45
+ oauth (~> 0.4.7)
46
46
  sinatra (1.4.5)
47
47
  rack (~> 1.4)
48
48
  rack-protection (~> 1.4)
@@ -60,7 +60,7 @@ GEM
60
60
  tzinfo (1.2.2)
61
61
  thread_safe (~> 0.1)
62
62
  version (1.0.0)
63
- yard (0.8.7.4)
63
+ yard (0.8.7.6)
64
64
 
65
65
  PLATFORMS
66
66
  ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 2.0.1
data/lib/opsask/app.rb CHANGED
@@ -55,18 +55,41 @@ module OpsAsk
55
55
  end
56
56
 
57
57
  get '/sprint/:sprint_num' do
58
- erb :agile, locals: {
59
- asks: asks_in_sprint(params[:sprint_num]),
60
- sprint: get_sprint(params[:sprint_num]),
58
+ num = params[:sprint_num]
59
+ sprint = get_sprint(num)
60
+ id = sprint['id']
61
+ erb :stats, locals: {
62
+ sprint: sprint,
63
+ ask_stats: stats_for(
64
+ asks_in_sprint(num),
65
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "labels in (Sprint#{num}) AND resolution is not EMPTY"}",
66
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "labels in (Sprint#{num}) AND resolution is EMPTY"}"
67
+ ),
68
+ sprint_stats: stats_for(
69
+ items_in_sprint(num),
70
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "sprint = #{id} AND resolution is not EMPTY"}",
71
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "sprint = #{id} AND resolution is EMPTY"}"
72
+ ),
61
73
  untracked_jiras: untracked_issues,
62
74
  stragglers: straggling_issues
63
75
  }
64
76
  end
65
77
 
66
- get '/agile' do
67
- erb :agile, locals: {
68
- asks: asks_in_current_sprint,
69
- sprint: current_sprint([]),
78
+ get '/sprint' do
79
+ num = current_sprint_num
80
+ id = current_sprint_id
81
+ erb :stats, locals: {
82
+ sprint: current_sprint,
83
+ ask_stats: stats_for(
84
+ asks_in_current_sprint,
85
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "labels in (Sprint#{num}) AND resolution is not EMPTY"}",
86
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "labels in (Sprint#{num}) AND resolution is EMPTY"}"
87
+ ),
88
+ sprint_stats: stats_for(
89
+ items_in_current_sprint,
90
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "sprint = #{id} AND resolution is not EMPTY"}",
91
+ "#{settings.config[:jira_url]}/issues/?jql=#{URI::escape "sprint = #{id} AND resolution is EMPTY"}"
92
+ ),
70
93
  untracked_jiras: untracked_issues,
71
94
  stragglers: straggling_issues
72
95
  }
@@ -216,14 +239,68 @@ module OpsAsk
216
239
  return date
217
240
  end
218
241
 
242
+ def stats_for issues, resolved_link, unresolved_link
243
+ return {} unless logged_in?
244
+ return {} unless issues
245
+
246
+ resolved_issues, unresolved_issues = [], []
247
+
248
+ issues.map! do |i|
249
+ key = i['key']
250
+ status = i['fields']['status']['name']
251
+ resolution = i['fields']['resolution']['name'] rescue nil
252
+ points = i['fields']['customfield_10002'].to_i
253
+
254
+ issue = {
255
+ key: key,
256
+ status: status,
257
+ resolution: resolution,
258
+ points: points
259
+ }
260
+
261
+ if resolution.nil?
262
+ unresolved_issues << issue
263
+ else
264
+ resolved_issues << issue
265
+ end
266
+ end
267
+
268
+ {
269
+ resolved: {
270
+ number: resolved_issues.size,
271
+ points: resolved_issues.map { |i| i[:points] }.reduce(0, :+),
272
+ link: resolved_link
273
+ },
274
+ unresolved: {
275
+ number: unresolved_issues.size,
276
+ points: unresolved_issues.map { |i| i[:points] }.reduce(0, :+),
277
+ link: unresolved_link
278
+ }
279
+ }
280
+ end
281
+
282
+ def items_in_current_sprint
283
+ items_in_sprint current_sprint_num
284
+ end
285
+
286
+ def items_in_sprint num
287
+ return [] unless logged_in?
288
+ issues = []
289
+ id = get_sprint(num)['id']
290
+ @jira_client.Issue.jql("sprint = #{id}", max_results: 500).each do |i|
291
+ issues << i.attrs
292
+ end
293
+ return issues
294
+ end
295
+
219
296
  def asks_in_current_sprint
220
- # TODO
297
+ asks_in_sprint current_sprint_num
221
298
  end
222
299
 
223
300
  def asks_in_sprint num
224
301
  return [] unless logged_in?
225
302
  issues = []
226
- @jira_client.Issue.jql("project = #{settings.config[:project_name]} AND labels in (OpsAsk) and labels in (Sprint#{num})").each do |i|
303
+ @jira_client.Issue.jql("labels in (Sprint#{num})", max_results: 500).each do |i|
227
304
  issues << i.attrs
228
305
  end
229
306
  return issues
@@ -279,6 +356,14 @@ module OpsAsk
279
356
  sprint.nil? ? nil : sprint['name'].gsub(/\s+/, '')
280
357
  end
281
358
 
359
+ def current_sprint_num sprint=current_sprint
360
+ sprint.nil? ? nil : sprint['name'].gsub(/\D+/, '')
361
+ end
362
+
363
+ def current_sprint_id sprint=current_sprint
364
+ sprint.nil? ? nil : sprint['id']
365
+ end
366
+
282
367
  def current_sprint keys=[ 'sprintsData', 'sprints', 0 ]
283
368
  url = "#{settings.config[:jira_url]}/rest/greenhopper/1.0/xboard/work/allData.json?rapidViewId=#{settings.config[:agile_board]}"
284
369
  curl_request = Curl::Easy.http_get(url) do |curl|
@@ -294,11 +379,12 @@ module OpsAsk
294
379
  begin
295
380
  data = JSON::parse(raw_response)
296
381
  keys.each { |k| data = data[k] }
297
- return data
382
+ return data unless data.nil?
298
383
  rescue
299
384
  $stderr.puts "Failed to parse response from JIRA: #{raw_response}"
300
385
  end
301
- return nil
386
+
387
+ return sprints.last
302
388
  end
303
389
 
304
390
  def today offset=0
@@ -324,9 +410,9 @@ module OpsAsk
324
410
  def jiras_for date
325
411
  return [] unless logged_in?
326
412
  unless ops?
327
- return @jira_client.Issue.jql("due = #{date} AND project = #{settings.config[:project_name]} AND type != Change AND labels not in (OpsOnly)")
413
+ return @jira_client.Issue.jql("due = #{date} AND project = #{settings.config[:project_name]} AND type != Change AND labels not in (OpsOnly)", max_results: 100)
328
414
  end
329
- return @jira_client.Issue.jql("due = #{date} AND project = #{settings.config[:project_name]} AND type != Change")
415
+ return @jira_client.Issue.jql("due = #{date} AND project = #{settings.config[:project_name]} AND type != Change", max_results: 100)
330
416
  end
331
417
 
332
418
  def jira_count_for date
@@ -462,7 +548,7 @@ module OpsAsk
462
548
  "resolution = unresolved",
463
549
  "assignee = denimcores"
464
550
  ].join(' AND ')
465
- @jira_client.Issue.jql(constraints).sort_by do |jira|
551
+ @jira_client.Issue.jql(constraints, max_results: 100).sort_by do |jira|
466
552
  sorting_key_for(jira)
467
553
  end.reverse
468
554
  end
@@ -476,7 +562,7 @@ module OpsAsk
476
562
  "resolution = unresolved",
477
563
  "assignee != denimcores"
478
564
  ].join(' AND ')
479
- @jira_client.Issue.jql(constraints).sort_by do |jira|
565
+ @jira_client.Issue.jql(constraints, max_results: 100).sort_by do |jira|
480
566
  sorting_key_for(jira)
481
567
  end.reverse
482
568
  end
data/opsask.gemspec CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |s|
18
18
  s.add_runtime_dependency 'curb', '~> 0.8'
19
19
  s.add_runtime_dependency 'rack', '~> 1'
20
20
  s.add_runtime_dependency 'sinatra', '~> 1.4'
21
- s.add_runtime_dependency 'jira-ruby', '~> 0.1'
22
21
  s.add_runtime_dependency 'rack-flash3', '~> 1'
23
22
  s.add_runtime_dependency 'sinatra-partial', '~> 0.4'
23
+ s.add_runtime_dependency 'sclemmer-jira-ruby', '~> 0.1'
24
24
 
25
25
  s.files = `git ls-files`.split("\n")
26
26
  s.test_files = `git ls-files -- test/*`.split("\n")
data/public/css/style.css CHANGED
@@ -149,4 +149,42 @@ p.ops-queues-are-full {
149
149
  input[type="checkbox"] + label {
150
150
  color: #bbb;
151
151
  margin-left: 0.2em;
152
+ }
153
+
154
+ #stats h2 {
155
+ text-align: center;
156
+ }
157
+
158
+ .stats .stat {
159
+ padding-top: 2em;
160
+ padding-bottom: 2em;
161
+ background-color: #333;
162
+ text-align: center;
163
+ }
164
+
165
+ .stat.resolved {
166
+ color: #fff;
167
+ background-color: #5da423;
168
+ margin-top: 0.75em;
169
+ }
170
+
171
+ .stat.unresolved {
172
+ color: #000;
173
+ background-color: #ff005c;
174
+ margin-top: 2em;
175
+ }
176
+
177
+ .stat .number {
178
+ font-size: 1.25em;
179
+ font-weight: bold;
180
+ }
181
+
182
+ .stat .points {
183
+ padding-top: 0.5em;
184
+ }
185
+
186
+ .stat .about {
187
+ font-size: 1.5em;
188
+ padding-top: 0.75em;
189
+ font-weight: bold;
152
190
  }
data/views/stats.erb ADDED
@@ -0,0 +1,42 @@
1
+ <div class="row" id="stats">
2
+ <div class="small-10 columns">
3
+ <div class="small-5 small-offset-2 columns">
4
+ <h2>OpsAsk</h2>
5
+ <div class="stats">
6
+ <a href="<%= ask_stats[:resolved][:link] rescue '#' %>" target="_blank">
7
+ <div class="stat resolved">
8
+ <div class="issues"><span class="number"><%= ask_stats[:resolved][:number] rescue 0 %></span> issues</div>
9
+ <div class="points"><span class="number"><%= ask_stats[:resolved][:points] rescue 0 %></span> points</div>
10
+ <div class="about">Resolved</div>
11
+ </div>
12
+ </a>
13
+ <a href="<%= ask_stats[:unresolved][:link] rescue '#' %>" target="_blank">
14
+ <div class="stat unresolved">
15
+ <div class="issues"><span class="number"><%= ask_stats[:unresolved][:number] rescue 0 %></span> issues</div>
16
+ <div class="points"><span class="number"><%= ask_stats[:unresolved][:points] rescue 0 %></span> points</div>
17
+ <div class="about">Unresolved</div>
18
+ </div>
19
+ </a>
20
+ </div>
21
+ </div>
22
+ <div class="small-5 columns">
23
+ <h2><%= sprint['name'] %></h2>
24
+ <div class="stats">
25
+ <a href="<%= sprint_stats[:resolved][:link] rescue '#' %>" target="_blank">
26
+ <div class="stat resolved">
27
+ <div class="issues"><span class="number"><%= sprint_stats[:resolved][:number] rescue 0 %></span> issues</div>
28
+ <div class="points"><span class="number"><%= sprint_stats[:resolved][:points] rescue 0 %></span> points</div>
29
+ <div class="about">Resolved</div>
30
+ </div>
31
+ </a>
32
+ <a href="<%= sprint_stats[:unresolved][:link] rescue '#' %>" target="_blank">
33
+ <div class="stat unresolved">
34
+ <div class="issues"><span class="number"><%= sprint_stats[:unresolved][:number] rescue 0 %></span> issues</div>
35
+ <div class="points"><span class="number"><%= sprint_stats[:unresolved][:points] rescue 0 %></span> points</div>
36
+ <div class="about">Unresolved</div>
37
+ </div>
38
+ </a>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opsask
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Clemmer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2014-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -81,47 +81,47 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.4'
83
83
  - !ruby/object:Gem::Dependency
84
- name: jira-ruby
84
+ name: rack-flash3
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.1'
89
+ version: '1'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.1'
96
+ version: '1'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rack-flash3
98
+ name: sinatra-partial
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '1'
103
+ version: '0.4'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '1'
110
+ version: '0.4'
111
111
  - !ruby/object:Gem::Dependency
112
- name: sinatra-partial
112
+ name: sclemmer-jira-ruby
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.4'
117
+ version: '0.1'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.4'
124
+ version: '0.1'
125
125
  description: Ask Ops for stuff.
126
126
  email: sczizzo@gmail.com
127
127
  executables:
@@ -130,10 +130,6 @@ extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
132
  - ".gitignore"
133
- - ".yardoc/checksums"
134
- - ".yardoc/object_types"
135
- - ".yardoc/objects/root.dat"
136
- - ".yardoc/proxy_types"
137
133
  - Gemfile
138
134
  - Gemfile.lock
139
135
  - LICENSE
@@ -184,10 +180,10 @@ files:
184
180
  - views/_flash.erb
185
181
  - views/_form.erb
186
182
  - views/_queue.erb
187
- - views/agile.erb
188
183
  - views/glance.erb
189
184
  - views/index.erb
190
185
  - views/layout.erb
186
+ - views/stats.erb
191
187
  - views/stragglers.erb
192
188
  - views/untracked.erb
193
189
  homepage: http://git.ops.bluejeans.com/inf/opsask
data/.yardoc/checksums DELETED
@@ -1,4 +0,0 @@
1
- lib/opsask.rb 26167cfdc95bfa320a4682e865fad3fd4294de49
2
- lib/opsask/app.rb 09e478d4a4a125c5309674b63c524744ba2eef23
3
- lib/opsask/main.rb 42451dbc69a564cc5b7a5398924a9191982bd75e
4
- lib/opsask/metadata.rb dd8e240fb7495b0fb35668a8c3625bab7775bc8d
data/.yardoc/object_types DELETED
Binary file
Binary file
data/.yardoc/proxy_types DELETED
Binary file
data/views/agile.erb DELETED
@@ -1,6 +0,0 @@
1
- <div class="row" id="asks">
2
- <h2><%= JSON::pretty_generate(asks) %></h2>
3
- </div>
4
- <div class="row" id="sprint">
5
- <h2><%= JSON::pretty_generate(sprint) %></h2>
6
- </div>