shiftzilla 0.2.26 → 0.2.31

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
  SHA256:
3
- metadata.gz: cecae2d90020a501778d287e70fa660c766e91c5acb9f14fdffa6a80c86260ed
4
- data.tar.gz: 5c31148722ce6bf81823b23a7188ff9e0779337059c728fa0f3fc1203c02b99a
3
+ metadata.gz: 31c2e44b571b53ef99faa54d3c5e6b54e4557143fe9f40f70bc45b4124872892
4
+ data.tar.gz: 9354388b6fc4a651aa283db031af0c29073b2e78094982c0e08a9f2f7ce6f672
5
5
  SHA512:
6
- metadata.gz: d5f74bf58dee2608735e0724402990d207314e7e5009b66acc33caaabe06c8aa8e05dd1fa5a11ee8d0e4308d4c45371b3e54a4dbb73d71d8a65a2307d8baa113
7
- data.tar.gz: 061fc2bc9251a635dd19392e13f68dd2c357fada8c54a543ec4d40320ff1bbea272d12055243a66e7314acd62fe2bde15a094f5f785d402a78064b069c7224b1
6
+ metadata.gz: 213b09d6780afa354c2d7e020ac369432c01a20fdeab2229c87f542084df504204a7410732edd1b49325e82b997fa54852991fabff391adac5eb39eca69997b3
7
+ data.tar.gz: b4fdff84e4f84291a1c832777ba872a52a88479bbdc427c8c7122490f8b6d5f8bfe837e053fe5dd44ffa981e4ce3b00d5cd69082d861c8d3a91f9d1e3ae05daf
@@ -66,6 +66,7 @@ EOF
66
66
  opt :quiet, "For cron use; don't print anything to STDOUT.", :default => false
67
67
  opt :cfgpath, "Specify a config file for shiftzilla to use.", :default => "#{DEFAULT_DIR}/shiftzilla_cfg.yaml"
68
68
  opt :dbpath, "Specify a database file location for shiftzilla to use.", :default => "#{DEFAULT_DIR}/shiftzilla.sqlite"
69
+ opt :groups, "Enable group aggregation table on main page", :default => false
69
70
  end
70
71
  when 'purge'
71
72
  Optimist::options do
@@ -1,37 +1,37 @@
1
1
  module Shiftzilla
2
2
  class Bug
3
- attr_reader :id, :first_seen, :last_seen, :beta_blocker, :test_blocker, :ops_blocker, :online_blocker, :owner, :component, :pm_score, :cust_cases, :tgt_release, :summary, :status
3
+ attr_reader :id, :first_seen, :last_seen, :blocker_plus, :blocker_unknown, :test_blocker, :ops_blocker, :owner, :component, :pm_score, :cust_cases, :tgt_release, :summary, :status
4
4
 
5
5
  def initialize(bzid,binfo)
6
- @id = bzid
7
- @first_seen = binfo[:snapdate]
8
- @last_seen = binfo[:snapdate]
9
- @beta_blocker = binfo[:beta_blocker]
10
- @test_blocker = binfo[:test_blocker]
11
- @ops_blocker = binfo[:ops_blocker]
12
- @online_blocker = binfo[:online_blocker]
13
- @owner = binfo[:owner]
14
- @summary = binfo[:summary]
15
- @status = binfo[:status]
16
- @component = binfo[:component]
17
- @pm_score = binfo[:pm_score]
18
- @cust_cases = binfo[:cust_cases]
19
- @tgt_release = binfo[:tgt_release]
6
+ @id = bzid
7
+ @first_seen = binfo[:snapdate]
8
+ @last_seen = binfo[:snapdate]
9
+ @blocker_plus = binfo[:blocker_plus]
10
+ @blocker_unknown = binfo[:blocker_unknown]
11
+ @test_blocker = binfo[:test_blocker]
12
+ @ops_blocker = binfo[:ops_blocker]
13
+ @owner = binfo[:owner]
14
+ @summary = binfo[:summary]
15
+ @status = binfo[:status]
16
+ @component = binfo[:component]
17
+ @pm_score = binfo[:pm_score]
18
+ @cust_cases = binfo[:cust_cases]
19
+ @tgt_release = binfo[:tgt_release]
20
20
  end
21
21
 
22
22
  def update(binfo)
23
- @last_seen = binfo[:snapdate]
24
- @beta_blocker = binfo[:beta_blocker]
25
- @test_blocker = binfo[:test_blocker]
26
- @ops_blocker = binfo[:ops_blocker]
27
- @online_blocker = binfo[:online_blocker]
28
- @owner = binfo[:owner]
29
- @summary = binfo[:summary]
30
- @status = binfo[:status]
31
- @component = binfo[:component]
32
- @pm_score = binfo[:pm_score]
33
- @cust_cases = binfo[:cust_cases]
34
- @tgt_release = binfo[:tgt_release]
23
+ @last_seen = binfo[:snapdate]
24
+ @blocker_plus = binfo[:blocker_plus]
25
+ @blocker_unknown = binfo[:blocker_unknown]
26
+ @test_blocker = binfo[:test_blocker]
27
+ @ops_blocker = binfo[:ops_blocker]
28
+ @owner = binfo[:owner]
29
+ @summary = binfo[:summary]
30
+ @status = binfo[:status]
31
+ @component = binfo[:component]
32
+ @pm_score = binfo[:pm_score]
33
+ @cust_cases = binfo[:cust_cases]
34
+ @tgt_release = binfo[:tgt_release]
35
35
  end
36
36
 
37
37
  def age
@@ -66,4 +66,4 @@ module Shiftzilla
66
66
  val.to_f.to_s == val.to_s || val.to_i.to_s == val.to_s
67
67
  end
68
68
  end
69
- end
69
+ end
@@ -22,6 +22,7 @@ module Shiftzilla
22
22
  cfg_file['Teams'].each do |team|
23
23
  @teams << Shiftzilla::Team.new(team,group_map)
24
24
  end
25
+ set_group_components
25
26
  cfg_file['Sources'].each do |sid,sinfo|
26
27
  @sources << Shiftzilla::Source.new(sid,sinfo)
27
28
  end
@@ -50,6 +51,10 @@ module Shiftzilla
50
51
  @teams.select{ |t| t.name == tname }[0]
51
52
  end
52
53
 
54
+ def group(gname)
55
+ @groups.select{ |g| g.id == gname[0] }[0]
56
+ end
57
+
53
58
  def add_ad_hoc_team(tinfo)
54
59
  @teams << Shiftzilla::Team.new(tinfo,{},true)
55
60
  end
@@ -95,5 +100,18 @@ module Shiftzilla
95
100
  boundaries
96
101
  end
97
102
  end
103
+
104
+ def set_group_components
105
+ @groups.each do |g|
106
+ components = []
107
+ @teams.each do |t|
108
+ if t.group and (t.group.id == g.id)
109
+ components += t.components
110
+ end
111
+ end
112
+ g.set_components(components)
113
+ end
114
+ end
115
+
98
116
  end
99
117
  end
@@ -113,7 +113,7 @@ module Shiftzilla
113
113
  org_data = Shiftzilla::OrgData.new(shiftzilla_config)
114
114
  org_data.populate_releases
115
115
  org_data.build_series
116
- org_data.generate_reports
116
+ org_data.generate_reports(options[:groups])
117
117
  if options[:local_preview]
118
118
  org_data.show_local_reports
119
119
  else
@@ -1,10 +1,16 @@
1
1
  module Shiftzilla
2
2
  class Group
3
- attr_reader :id, :lead
3
+ attr_reader :name, :id, :lead, :components
4
4
 
5
5
  def initialize(ginfo)
6
- @id = ginfo['id']
7
- @lead = ginfo['lead']
6
+ @name = "Group " + ginfo['id']
7
+ @id = ginfo['id']
8
+ @lead = ginfo['lead']
8
9
  end
10
+
11
+ def set_components(component_list)
12
+ @components ||= component_list
13
+ end
14
+
9
15
  end
10
- end
16
+ end
@@ -249,6 +249,8 @@ module Shiftzilla
249
249
  errors << "Team at index #{list_idx} is missing the 'name' key."
250
250
  elsif not valid_config_string?(team['name'])
251
251
  errors << "Team at index #{list_idx} has a nil or zero-length 'name'."
252
+ elsif team['name'].start_with?("Group")
253
+ errors << "Team at index #{list_idx} begins with the string 'Group'."
252
254
  else
253
255
  tnm = team['name']
254
256
  if seen_tnms.has_key?(tnm)
@@ -329,10 +331,14 @@ module Shiftzilla
329
331
  if not milestones.has_key?(ms)
330
332
  errors << "Release at index #{list_idx} is missing the '#{ms}' milestone."
331
333
  else
334
+ if milestones[ms] == 'today' or !!(milestones[ms] =~ /today[+-]\d+[dwms]/)
335
+ # Matches the variable date format
336
+ next
337
+ end
332
338
  ms_date = milestones[ms].split('-')
333
339
  if ms_date.length == 3 and ms_date[0].length == 4 and ms_date[1].length == 2 and ms_date[2].length == 2
334
340
  else
335
- errors << "Release at index #{list_idx}: milestone '#{ms}' is not formatted correctly (YYYY-MM-DD)."
341
+ errors << "Release at index #{list_idx}: milestone '#{ms}' is not formatted correctly - (YYYY-MM-DD) or (today[+-]X[dwms])."
336
342
  end
337
343
  end
338
344
  end
@@ -1,9 +1,14 @@
1
+ require 'date'
2
+
1
3
  module Shiftzilla
2
4
  class Milestone
3
5
  def initialize(mtxt)
4
6
  @date = nil
5
7
  @stamp = ''
6
- unless (mtxt.nil? or mtxt == '')
8
+ if mtxt.start_with?('today')
9
+ @date = variable_date(mtxt)
10
+ @stamp = @date.strftime('%Y-%m-%d')
11
+ elsif not (mtxt.nil? or mtxt == '')
7
12
  @date = Date.parse(mtxt)
8
13
  @stamp = mtxt
9
14
  end
@@ -16,5 +21,42 @@ module Shiftzilla
16
21
  def stamp
17
22
  @stamp
18
23
  end
24
+
25
+ private
26
+
27
+ def variable_date(d)
28
+ # Takes a variable date string and returns the appropriate date object
29
+ # Variable dates of the form today[+,-]#[d,w,m,s]
30
+ today = Date.today
31
+
32
+ if d.length < 8
33
+ return today
34
+ end
35
+
36
+ operation = d[5]
37
+ val = d[6..-2].to_i
38
+ unit = d[-1]
39
+ days = 0
40
+
41
+ # Convert to days for simple addition
42
+ case unit
43
+ when 'd'
44
+ days = val
45
+ when 'w'
46
+ days = 7*val
47
+ when 'm'
48
+ days = 30*val
49
+ when 's' # Sprints
50
+ days = 21*val
51
+ else
52
+ days = val
53
+ end
54
+
55
+ if operation == '-'
56
+ days = days * -1
57
+ end
58
+
59
+ return today+days
60
+ end
19
61
  end
20
62
  end
@@ -1,5 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'json'
3
+ require 'uri'
3
4
  require 'shiftzilla/bug'
4
5
  require 'shiftzilla/helpers'
5
6
  require 'shiftzilla/team_data'
@@ -13,6 +14,8 @@ module Shiftzilla
13
14
  def initialize(config)
14
15
  @config = config
15
16
  @teams = config.teams
17
+ @groups = config.groups
18
+ @group_teams = []
16
19
  @releases = config.releases
17
20
  @tmp_dir = Shiftzilla::Helpers.tmp_dir
18
21
  @org_data = { '_overall' => Shiftzilla::TeamData.new('_overall',config) }
@@ -38,57 +41,71 @@ module Shiftzilla
38
41
 
39
42
  # TODO: REMOVE BUSINESS LOGIC EMBEDDED IN CODE
40
43
  if comp == 'Security' and keyw.include?('Unconfirmed')
41
- puts "NB: This report has a hardcoded exclusion of 'Security' component bugs with the 'Unconfirmed' keyword."
44
+ # This report has a hardcoded exclusion of 'Security' component bugs with the 'Unconfirmed' keyword."
42
45
  next
43
46
  end
44
47
 
45
48
  # Package up bug data
46
49
  binfo = {
47
- :snapdate => snapdate,
48
- :beta_blocker => keyw.include?('BetaBlocker'),
49
- :test_blocker => keyw.include?('TestBlocker'),
50
- :ops_blocker => keyw.include?('OpsBlocker'),
51
- :online_blocker => keyw.include?('OnlineStarter'),
52
- :owner => owns,
53
- :summary => summ,
54
- :status => stat,
55
- :component => comp,
56
- :pm_score => pmsc,
57
- :cust_cases => (cust == 1),
58
- :tgt_release => tgtr,
50
+ :snapdate => snapdate,
51
+ :blocker_plus => keyw.include?('blocker+'),
52
+ :blocker_unknown => keyw.include?('blocker?'),
53
+ :test_blocker => keyw.include?('TestBlocker'),
54
+ :ops_blocker => keyw.include?('ServiceDeliveryBlocker'),
55
+ :owner => owns,
56
+ :summary => summ,
57
+ :status => stat,
58
+ :component => comp,
59
+ :pm_score => pmsc,
60
+ :cust_cases => (cust == 1),
61
+ :tgt_release => tgtr,
59
62
  }
60
63
 
61
64
  tgt_release = @config.release_by_target(tgtr)
62
65
  all_release = @config.release('All')
63
66
 
64
67
  # If this component isn't mapped to a team, stub out a fake team.
65
- tname = comp_map.has_key?(comp) ? comp_map[comp] : "(?) #{comp}"
68
+ tname = team_comp_map.has_key?(comp) ? team_comp_map[comp] : "(?) #{comp}"
66
69
  unless @org_data.has_key?(tname)
67
70
  @config.add_ad_hoc_team({ 'name' => tname, 'components' => [comp] })
68
71
  @org_data[tname] = Shiftzilla::TeamData.new(tname)
69
72
  end
70
73
 
74
+ # Generate TeamData objects for each group
75
+ gname = group_comp_map.has_key?(comp) ? group_comp_map[comp] : nil
76
+ if not gname.nil? and not @org_data.has_key?(gname)
77
+ @org_data[gname] = Shiftzilla::TeamData.new(gname)
78
+ end
79
+
71
80
  team_rdata = tgt_release.nil? ? nil : @org_data[tname].get_release_data(tgt_release)
72
81
  team_adata = @org_data[tname].get_release_data(all_release)
73
82
  over_rdata = tgt_release.nil? ? nil : @org_data['_overall'].get_release_data(tgt_release)
74
83
  over_adata = @org_data['_overall'].get_release_data(all_release)
84
+ unless gname.nil?
85
+ group_rdata = tgt_release.nil? ? nil : @org_data[gname].get_release_data(tgt_release)
86
+ group_adata = @org_data[gname].get_release_data(all_release)
87
+ else
88
+ group_rdata = nil
89
+ group_adata = nil
90
+ end
75
91
 
76
92
  # Do some bean counting
77
- [over_rdata,team_rdata,over_adata,team_adata].each do |group|
78
- next if group.nil?
79
- snapdata = group.get_snapdata(snapshot)
80
- if group.first_snap.nil?
81
- group.first_snap = snapshot
82
- group.first_snapdate = snapdate
93
+ [over_rdata,team_rdata,over_adata,team_adata,group_rdata,group_adata].each do |grouping|
94
+ next if grouping.nil?
95
+ snapdata = grouping.get_snapdata(snapshot)
96
+ if grouping.first_snap.nil?
97
+ grouping.first_snap = snapshot
98
+ grouping.first_snapdate = snapdate
83
99
  end
84
- group.latest_snap = snapshot
85
- group.latest_snapdate = snapdate
100
+ grouping.latest_snap = snapshot
101
+ grouping.latest_snapdate = snapdate
86
102
 
87
- bug = group.add_or_update_bug(bzid,binfo)
103
+ bug = grouping.add_or_update_bug(bzid,binfo)
88
104
 
89
105
  # Add info to the snapshot
90
106
  snapdata.bug_ids << bzid
91
- if bug.beta_blocker or bug.test_blocker or bug.ops_blocker or bug.online_blocker
107
+ # Only the blocker+ flag counts as a blocker for snapshots
108
+ if bug.blocker_plus
92
109
  snapdata.tb_ids << bzid
93
110
  end
94
111
  if bug.cust_cases
@@ -131,6 +148,18 @@ module Shiftzilla
131
148
  end
132
149
  end
133
150
  end
151
+
152
+ # Create a "team" for each group here
153
+ @groups.each do |g|
154
+ ginfo = {
155
+ 'name' => g.name,
156
+ 'lead' => g.lead,
157
+ 'group' => g.id,
158
+ 'components' => g.components,
159
+ }
160
+ @group_teams << Shiftzilla::Team.new(ginfo, {g.id => g})
161
+ end
162
+
134
163
  @all_teams = @teams.map{ |t| t.name }.concat(@org_data.keys).uniq
135
164
  @ordered_teams = ['_overall'].concat(@all_teams.select{ |t| t != '_overall'}.sort)
136
165
  end
@@ -159,6 +188,7 @@ module Shiftzilla
159
188
  :tname => tdata.title,
160
189
  :file => tdata.file,
161
190
  :releases => {},
191
+ :is_group => (not @group_teams.detect{|g| g.name == tdata.title}.nil?),
162
192
  }
163
193
 
164
194
  @releases.each do |release|
@@ -182,9 +212,11 @@ module Shiftzilla
182
212
  end
183
213
  end
184
214
 
185
- def generate_reports
215
+ def generate_reports(include_groups)
186
216
  build_time = timestamp
187
217
  all_release = @config.release('All')
218
+ redirects = {}
219
+
188
220
  @ordered_teams.each do |tname|
189
221
  tinfo = @config.team(tname)
190
222
  tdata = @org_data[tname]
@@ -200,8 +232,22 @@ module Shiftzilla
200
232
  :releases => [],
201
233
  :latest_snapshot => latest_snapshot,
202
234
  :all_bugs => [],
235
+ :include_groups => include_groups,
236
+ :is_group => false,
203
237
  }
204
238
 
239
+ # Check if this is actually a group "team"
240
+ group_match = @group_teams.detect{|g| g.name == tname}
241
+ if not group_match.nil?
242
+ team_pinfo[:tinfo] = group_match
243
+ team_pinfo[:is_group] = true
244
+ elsif not tinfo.nil?
245
+ # Generate component -> team redirects
246
+ tinfo.components.each do |component|
247
+ redirects[component] = tdata.file
248
+ end
249
+ end
250
+
205
251
  @releases.each do |release|
206
252
  rname = release.name
207
253
  rdata = tdata.has_release_data?(release) ? tdata.get_release_data(release) : nil
@@ -245,7 +291,7 @@ module Shiftzilla
245
291
  :data => rdata.series[:closed_bugs],
246
292
  },
247
293
  ]),
248
- :blockers => chartify('Test / Ops Blockers',rdata.series[:date],[
294
+ :blockers => chartify('Blockers',rdata.series[:date],[
249
295
  {
250
296
  :label => 'Total',
251
297
  :data => rdata.series[:total_tb],
@@ -270,6 +316,24 @@ module Shiftzilla
270
316
  team_page = haml_engine.render(Object.new,team_pinfo)
271
317
  File.write(File.join(@tmp_dir,tdata.file), team_page)
272
318
  end
319
+
320
+ # Create component->team redirects
321
+ redirects.each do |component, team_file|
322
+ redirect_html = <<-HTML
323
+ <!DOCTYPE html>
324
+ <html>
325
+ <head>
326
+ <meta http-equiv="Refresh" content="0; url=#{team_file}" />
327
+ </head>
328
+ <body>
329
+ <p>Redirecting to <a href="#{team_file}">team page</a>...</p>
330
+ </body>
331
+ </html>
332
+ HTML
333
+ File.write(File.join(@tmp_dir, "component_#{component}.html"), redirect_html)
334
+ end
335
+
336
+
273
337
  # Copy flot library to build area
274
338
  jsdir = File.join(@tmp_dir,'js')
275
339
  Dir.mkdir(jsdir)
@@ -294,18 +358,33 @@ module Shiftzilla
294
358
 
295
359
  private
296
360
 
297
- def comp_map
298
- @comp_map ||= begin
299
- comp_map = {}
361
+ def team_comp_map
362
+ @team_comp_map ||= begin
363
+ team_comp_map = {}
300
364
  @teams.each do |team|
301
365
  team.components.each do |comp|
302
- comp_map[comp] = team.name
366
+ team_comp_map[comp] = team.name
303
367
  end
304
368
  end
305
- comp_map
369
+ team_comp_map
306
370
  end
307
371
  end
308
372
 
373
+ # Creates group component mapping
374
+ def group_comp_map
375
+ @group_comp_map ||= begin
376
+ group_comp_map = {}
377
+ @groups.each do |group|
378
+ group.components.each do |comp|
379
+ group_comp_map[comp] = group.name
380
+ end
381
+ end
382
+ group_comp_map
383
+ end
384
+ end
385
+
386
+
387
+
309
388
  def chartify(title,dates,series)
310
389
  modulo = label_modulo(dates.length)
311
390
  tlist = []
@@ -349,4 +428,4 @@ module Shiftzilla
349
428
  end
350
429
  end
351
430
  end
352
- end
431
+ end
@@ -25,7 +25,9 @@ module Shiftzilla
25
25
  output_format = @fields.map{ |fld| "%{#{fld.to_s}}" }.join("\x1F")
26
26
  table_fields = @fields.map{ |fld| "\"#{field_map[fld]}\"" }.join(',')
27
27
  insert_frame = @fields.map{ |fld| '?' }.join(', ')
28
- bz_command = "bugzilla query --savedsearch #{@search} --savedsearch-sharer-id=#{@sharer} --outputformat='#{output_format}||EOR'"
28
+ # Also grabs the flags to check for the blocker flag, this is dropped before inserting into the db
29
+ bz_command = "bugzilla query --savedsearch #{@search} --savedsearch-sharer-id=#{@sharer} --outputformat='#{output_format}\x1F%{flags}flags||EOR'"
30
+
29
31
  bz_csv = `#{bz_command}`
30
32
  retrieved = []
31
33
  bz_csv.split("||EOR\n").each do |row|
@@ -47,6 +49,28 @@ module Shiftzilla
47
49
  values[@external_bugs_idx] = 0
48
50
  end
49
51
  end
52
+
53
+ # Check for blocker+ flag and stub it as a keyword
54
+ if not values[-1].nil? and values[-1].include?("blocker+")
55
+ keyword_idx = @fields.index(:keywords)
56
+ if not values[keyword_idx]
57
+ values[keyword_idx] = "blocker+"
58
+ else
59
+ values[keyword_idx] = values[keyword_idx] + ",blocker+"
60
+ end
61
+ end
62
+ # Check for blocker? flag and stub it as a keyword
63
+ if not values[-1].nil? and values[-1].include?("blocker?")
64
+ keyword_idx = @fields.index(:keywords)
65
+ if not values[keyword_idx]
66
+ values[keyword_idx] = "blocker?"
67
+ else
68
+ values[keyword_idx] = values[keyword_idx] + ",blocker?"
69
+ end
70
+ end
71
+
72
+ # Remove flags, which is always the final value
73
+ values = values[0...-2]
50
74
  retrieved << values
51
75
  end
52
76
  puts "Retrieved #{retrieved.length} rows"
@@ -1,3 +1,3 @@
1
1
  module Shiftzilla
2
- VERSION = "0.2.26"
2
+ VERSION = "0.2.31"
3
3
  end
@@ -6,8 +6,8 @@ require 'shiftzilla/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "shiftzilla"
8
8
  spec.version = Shiftzilla::VERSION
9
- spec.authors = ["N. Harrison Ripps"]
10
- spec.email = ["nhr@redhat.com"]
9
+ spec.authors = ["N. Harrison Ripps","Rory Thrasher"]
10
+ spec.email = ["nhr@redhat.com","rthrashe@redhat.com"]
11
11
  spec.summary = %q{Shiftzilla is a tool for providing historical reports based on Bugzilla data}
12
12
  spec.description = spec.summary
13
13
  spec.homepage = "http://github.com/nhr/shiftzilla"
@@ -45,11 +45,12 @@
45
45
  - if tname != '_overall' and not tinfo.nil? and not tinfo.ad_hoc?
46
46
  %h5 Team Info
47
47
  %ul
48
- %li= "Team Lead: #{tinfo.lead}"
48
+ - unless is_group
49
+ %li= "Team Lead: #{tinfo.lead}"
49
50
  - if not tinfo.group.nil? and not tinfo.group.lead.nil?
50
51
  %li= "Group Lead: #{tinfo.group.lead}"
51
52
  - if tinfo.components.length > 0
52
- %li= "BZ Component(s): #{tinfo.components.join(', ')}"
53
+ %li= "BZ Component(s): " + tinfo.components.map{ |c| "<a href='component_#{c}.html'>#{c}</a>"}.join(', ')
53
54
  %h5= "#{tdisp} Summary"
54
55
  %table.table.table-hover.table-sm
55
56
  %tr
@@ -69,7 +70,7 @@
69
70
  - releases.each do |r|
70
71
  %td.text-right= r[:bug_avg_age]
71
72
  %tr
72
- %td Avg. Test Blocker Age
73
+ %td Avg. Blocker Age
73
74
  - releases.each do |r|
74
75
  %td.text-right= r[:tb_avg_age]
75
76
  %tr
@@ -81,7 +82,7 @@
81
82
  - releases.each do |r|
82
83
  %td.text-right= r[:snapdata].closed_bugs
83
84
  %tr
84
- %td Test / Ops Blockers
85
+ %td Blockers
85
86
  - releases.each do |r|
86
87
  %td.text-right= r[:snapdata].total_tb
87
88
  %tr
@@ -92,6 +93,26 @@
92
93
  %td Closed Blockers Yesterday
93
94
  - releases.each do |r|
94
95
  %td.text-right= r[:snapdata].closed_tb
96
+
97
+ - if tname == '_overall' and include_groups
98
+ %h5 Totals By Group
99
+ %table.table.table-hover.table-sm
100
+ %tr
101
+ %td Group
102
+ - releases.each do |r|
103
+ %td.text-right= r[:release].name
104
+ - team_files.each do |tm|
105
+ - unless tm[:is_group]
106
+ - next
107
+ %tr
108
+ %td
109
+ - if tm[:tname] == tdisp
110
+ = tdisp
111
+ - else
112
+ %a{ :href => tm[:file] }= tm[:tname]
113
+ - releases.each do |r|
114
+ %td.text-right= tm[:releases][r[:release].name]
115
+
95
116
  - if tname == '_overall'
96
117
  %h5 Totals By Team
97
118
  %table.table.table-hover.table-sm
@@ -100,6 +121,8 @@
100
121
  - releases.each do |r|
101
122
  %td.text-right= r[:release].name
102
123
  - team_files.each do |tm|
124
+ - if tm[:is_group]
125
+ - next
103
126
  %tr
104
127
  %td
105
128
  - if tm[:tname] == tdisp
@@ -130,7 +153,7 @@
130
153
  %thead
131
154
  %tr
132
155
  %th
133
- %abbr{ :title => 'Beta Blocker, Test Blocker, Ops Blocker, or Online Blocker?' } Blocker
156
+ %abbr{ :title => 'Blocker flags and keywords' } Blocker
134
157
  %th
135
158
  %abbr{ :title => 'See https://mojo.redhat.com/docs/DOC-1159309' } PM
136
159
  %th
@@ -146,10 +169,10 @@
146
169
  - all_bugs.each do |b|
147
170
  %tr
148
171
  %td
149
- = b.beta_blocker ? "<span class='badge badge-info'>&#946;eta</span>" : ''
150
- = b.test_blocker ? "<span class='badge badge-danger'>Test</span>" : ''
151
- = b.ops_blocker ? "<span class='badge badge-dark'>Ops</span>" : ''
152
- = b.online_blocker ? "<span class='badge badge-warning'>Online</span>" : ''
172
+ = b.blocker_plus ? "<span class='badge badge-danger'>&#914;locker+</span>" : ''
173
+ = b.blocker_unknown ? "<span class='badge badge-info'>blocker?</span>" : ''
174
+ = b.test_blocker ? "<span class='badge badge-warning'>Test</span>" : ''
175
+ = b.ops_blocker ? "<span class='badge badge-dark'>SD</span>" : ''
153
176
  %td= b.pm_score
154
177
  %td= b.cust_cases ? "<span class='badge badge-warning'>CC</span>" : ''
155
178
  %td(data-order="#{b.semver}")= b.tgt_release
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shiftzilla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.26
4
+ version: 0.2.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - N. Harrison Ripps
8
+ - Rory Thrasher
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2019-03-19 00:00:00.000000000 Z
12
+ date: 2020-11-02 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
@@ -156,6 +157,7 @@ description: Shiftzilla is a tool for providing historical reports based on Bugz
156
157
  data
157
158
  email:
158
159
  - nhr@redhat.com
160
+ - rthrashe@redhat.com
159
161
  executables:
160
162
  - shiftzilla
161
163
  extensions: []
@@ -182,7 +184,7 @@ files:
182
184
  - lib/shiftzilla/version.rb
183
185
  - shiftzilla.gemspec
184
186
  - shiftzilla.sql.tmpl
185
- - shiftzilla_cfg.yml.tmpl
187
+ - shiftzilla_cfg.yaml.tmpl
186
188
  - template.haml
187
189
  - vendor/flot/jquery.flot.min.js
188
190
  homepage: http://github.com/nhr/shiftzilla
@@ -204,7 +206,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
206
  - !ruby/object:Gem::Version
205
207
  version: '0'
206
208
  requirements: []
207
- rubygems_version: 3.0.1
209
+ rubyforge_project:
210
+ rubygems_version: 2.7.7
208
211
  signing_key:
209
212
  specification_version: 4
210
213
  summary: Shiftzilla is a tool for providing historical reports based on Bugzilla data