19
19
from collections import defaultdict, OrderedDict
24
25
from urllib.request import urlopen
27
29
from jinja2 import Environment, FileSystemLoader
31
34
loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__)) + '/templates'),
123
126
def get_subscribers_json(packages, subscribers_json):
124
127
if subscribers_json is None:
125
j = urlopen("http://people.canonical.com/~ubuntu-archive/package-team-mapping.json")
128
j = urlopen("https://ubuntu-archive-team.ubuntu.com/package-team-mapping.json")
127
130
j = open(subscribers_json, 'rb')
188
191
waiting = attr.ib(default=None) # [(source_package_name, arches)]
189
192
data = attr.ib(default=None) # data for package_in_proposed
190
193
unsatdepends = attr.ib(default=None) # [string]
194
unsatbuilddep = attr.ib(default=None) # [string]
195
brokenbin = attr.ib(default=None) # [string]
196
componentmismatch = attr.ib(default=None) # [string]
192
198
_age = attr.ib(default=None)
235
244
print("fetching yaml")
236
245
if args.excuses_yaml:
237
yaml_text = open(args.excuses_yaml).read()
246
if args.excuses_yaml.endswith('.xz'):
247
yaml_text = lzma.open(args.excuses_yaml)
249
yaml_text = open(args.excuses_yaml)
239
yaml_text = urlopen("https://people.canonical.com/~ubuntu-archive/proposed-migration/update_excuses.yaml").read()
252
yaml_text = lzma.open(urlopen("https://ubuntu-archive-team.ubuntu.com/proposed-migration/update_excuses.yaml.xz"))
253
except urllib.error.HTTPError as e:
254
print("Reading fallback yaml (%s)" % e)
255
yaml_text = urlopen("https://ubuntu-archive-team.ubuntu.com/proposed-migration/update_excuses.yaml")
240
256
print("parsing yaml")
241
257
# The CSafeLoader is ten times faster than the regular one
242
258
excuses = yaml.load(yaml_text, Loader=yaml.CSafeLoader)
248
264
# Missing component means main
249
265
if item.get('component', 'main') not in components:
251
prob = Problem(kind='package-in-proposed', data=item, package_in_proposed=source_package_name)
267
prob = Problem(kind='package-in-proposed', data=defaultdict(dict, item), package_in_proposed=source_package_name)
252
268
in_proposed_packages[source_package_name] = prob
253
269
prob.regressions = []
254
270
prob.waiting = []
271
prob.componentmismatch = []
272
# The verdict entries are not items to list on the report
273
for policy in ['autopkgtest', 'update-excuse', 'block-bugs']:
275
del item['policy_info'][policy]['verdict']
255
278
if 'autopkgtest' in item['reason']:
256
279
for package, results in sorted(item['policy_info']['autopkgtest'].items()):
269
292
prob.regressions.append(regr)
271
294
prob.waiting.append((package + ": " + ", ".join(wait_arches)))
295
if 'depends' in item['reason']:
296
for l in item['excuses']:
297
if 'cannot depend on' in l:
298
prob.componentmismatch.append(l)
272
299
if 'dependencies' in item and 'unsatisfiable-dependencies' in item['dependencies']:
273
300
unsatd = defaultdict(list)
274
301
for arch, packages in item['dependencies']['unsatisfiable-dependencies'].items():
275
302
for p in packages:
276
303
unsatd[p].append(arch)
277
304
prob.unsatdepends = ['{}: {}'.format(p, ', '.join(sorted(arches))) for p, arches in sorted(unsatd.items())]
305
if 'policy_info' in item:
306
if 'build-depends' in item['policy_info'] and 'unsatisfiable-arch-build-depends' in item['policy_info']['build-depends']:
307
unsatdbd = defaultdict(list)
308
for arch, packages in item['policy_info']['build-depends']['unsatisfiable-arch-build-depends'].items():
310
unsatdbd[p].append(arch)
311
prob.unsatbuilddep = ['{}: {}'.format(p, ', '.join(sorted(arches))) for p, arches in sorted(unsatdbd.items())]
279
313
package_to_problems = defaultdict(list)
281
315
for problem in in_proposed_packages.values():
282
package_to_problems[problem.package_in_proposed].append(problem)
316
# nautilus/riscv64 -> nautilus
317
pkg = problem.package_in_proposed.split('/')[0]
318
package_to_problems[pkg].append(problem)
283
319
for regression in problem.regressions:
284
320
if regression.blocking not in in_proposed_packages:
307
343
subscribers = get_subscribers_json(set(package_to_problems), args.subscribers_json)
308
344
for p in set(package_to_problems):
309
if p not in subscribers:
345
pkg = p.split('/')[0]
346
if pkg not in subscribers:
310
347
subscribers[p] = ['unknown']
312
349
all_teams = set()
330
367
all_teams=all_teams,
331
368
team_to_problems=team_to_problems,
332
369
team_to_attn_count=team_to_attn_count,
333
now=excuses["generated-date"].strftime("%Y.%m.%d %H:%M:%S")))
370
now=excuses["generated-date"].strftime("%Y.%m.%d %H:%M:%S") + ' ' + time.localtime().tm_zone))
334
371
if args.yaml_output:
335
372
team_to_problem_data = {}
336
373
for t, ps in team_to_problems.items():