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 +4 -4
- data/bin/shiftzilla +1 -0
- data/lib/shiftzilla/bug.rb +28 -28
- data/lib/shiftzilla/config.rb +18 -0
- data/lib/shiftzilla/engine.rb +1 -1
- data/lib/shiftzilla/group.rb +10 -4
- data/lib/shiftzilla/helpers.rb +7 -1
- data/lib/shiftzilla/milestone.rb +43 -1
- data/lib/shiftzilla/org_data.rb +111 -32
- data/lib/shiftzilla/source.rb +25 -1
- data/lib/shiftzilla/version.rb +1 -1
- data/shiftzilla.gemspec +2 -2
- data/{shiftzilla_cfg.yml.tmpl → shiftzilla_cfg.yaml.tmpl} +0 -0
- data/template.haml +32 -9
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31c2e44b571b53ef99faa54d3c5e6b54e4557143fe9f40f70bc45b4124872892
|
4
|
+
data.tar.gz: 9354388b6fc4a651aa283db031af0c29073b2e78094982c0e08a9f2f7ce6f672
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 213b09d6780afa354c2d7e020ac369432c01a20fdeab2229c87f542084df504204a7410732edd1b49325e82b997fa54852991fabff391adac5eb39eca69997b3
|
7
|
+
data.tar.gz: b4fdff84e4f84291a1c832777ba872a52a88479bbdc427c8c7122490f8b6d5f8bfe837e053fe5dd44ffa981e4ce3b00d5cd69082d861c8d3a91f9d1e3ae05daf
|
data/bin/shiftzilla
CHANGED
@@ -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
|
data/lib/shiftzilla/bug.rb
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
module Shiftzilla
|
2
2
|
class Bug
|
3
|
-
attr_reader :id, :first_seen, :last_seen, :
|
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
|
7
|
-
@first_seen
|
8
|
-
@last_seen
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@owner
|
14
|
-
@summary
|
15
|
-
@status
|
16
|
-
@component
|
17
|
-
@pm_score
|
18
|
-
@cust_cases
|
19
|
-
@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
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@owner
|
29
|
-
@summary
|
30
|
-
@status
|
31
|
-
@component
|
32
|
-
@pm_score
|
33
|
-
@cust_cases
|
34
|
-
@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
|
data/lib/shiftzilla/config.rb
CHANGED
@@ -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
|
data/lib/shiftzilla/engine.rb
CHANGED
@@ -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
|
data/lib/shiftzilla/group.rb
CHANGED
@@ -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
|
-
@
|
7
|
-
@
|
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
|
data/lib/shiftzilla/helpers.rb
CHANGED
@@ -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
|
data/lib/shiftzilla/milestone.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/shiftzilla/org_data.rb
CHANGED
@@ -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
|
-
|
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
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:owner
|
53
|
-
:summary
|
54
|
-
:status
|
55
|
-
:component
|
56
|
-
:pm_score
|
57
|
-
:cust_cases
|
58
|
-
:tgt_release
|
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 =
|
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 |
|
78
|
-
next if
|
79
|
-
snapdata =
|
80
|
-
if
|
81
|
-
|
82
|
-
|
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
|
-
|
85
|
-
|
100
|
+
grouping.latest_snap = snapshot
|
101
|
+
grouping.latest_snapdate = snapdate
|
86
102
|
|
87
|
-
bug =
|
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
|
-
|
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('
|
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
|
298
|
-
@
|
299
|
-
|
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
|
-
|
366
|
+
team_comp_map[comp] = team.name
|
303
367
|
end
|
304
368
|
end
|
305
|
-
|
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
|
data/lib/shiftzilla/source.rb
CHANGED
@@ -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
|
-
|
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"
|
data/lib/shiftzilla/version.rb
CHANGED
data/shiftzilla.gemspec
CHANGED
@@ -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"
|
File without changes
|
data/template.haml
CHANGED
@@ -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
|
-
|
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):
|
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.
|
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
|
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 => '
|
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.
|
150
|
-
= b.
|
151
|
-
= b.
|
152
|
-
= b.
|
172
|
+
= b.blocker_plus ? "<span class='badge badge-danger'>Β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.
|
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:
|
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.
|
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
|
-
|
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
|