Gentoo Archives: gentoo-portage-dev

From: Chris Reffett <creffett@g.o>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [PATCH 1/2] Split output for repoman checks into file and message
Date: Wed, 19 Feb 2014 18:10:34
Message-Id: 1392833405-1622-2-git-send-email-creffett@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH 0/2] Refactor repoman QA handling by Chris Reffett
1 This wraps the output of emerge checks so that a list of length 1-2 is
2 generated. The first element is the file, the second element (optional)
3 is a more descriptive error message. This change will help us eventually
4 introduce more machine-readable output formats.
5 ---
6 bin/repoman | 232 +++++++++++++++++++++++------------------------
7 pym/repoman/utilities.py | 18 +++-
8 2 files changed, 128 insertions(+), 122 deletions(-)
9
10 diff --git a/bin/repoman b/bin/repoman
11 index 888892b..3d5dde4 100755
12 --- a/bin/repoman
13 +++ b/bin/repoman
14 @@ -1402,7 +1402,7 @@ for x in effective_scanlist:
15 repoman_settings['PORTAGE_QUIET'] = '1'
16 if not portage.digestcheck([], repoman_settings, strict=1):
17 stats["manifest.bad"] += 1
18 - fails["manifest.bad"].append(os.path.join(x, 'Manifest'))
19 + fails["manifest.bad"].append([os.path.join(x, 'Manifest')])
20 repoman_settings.pop('PORTAGE_QUIET', None)
21
22 if options.mode == 'manifest-check':
23 @@ -1416,7 +1416,7 @@ for x in effective_scanlist:
24 if (y in no_exec or y.endswith(".ebuild")) and \
25 stat.S_IMODE(os.stat(os.path.join(checkdir, y)).st_mode) & 0o111:
26 stats["file.executable"] += 1
27 - fails["file.executable"].append(os.path.join(checkdir, y))
28 + fails["file.executable"].append([os.path.join(checkdir, y)])
29 if y.endswith(".ebuild"):
30 pf = y[:-7]
31 ebuildlist.append(pf)
32 @@ -1426,17 +1426,17 @@ for x in effective_scanlist:
33 except KeyError:
34 allvalid = False
35 stats["ebuild.syntax"] += 1
36 - fails["ebuild.syntax"].append(os.path.join(x, y))
37 + fails["ebuild.syntax"].append([os.path.join(x, y)])
38 continue
39 except IOError:
40 allvalid = False
41 stats["ebuild.output"] += 1
42 - fails["ebuild.output"].append(os.path.join(x, y))
43 + fails["ebuild.output"].append([os.path.join(x, y)])
44 continue
45 if not portage.eapi_is_supported(myaux["EAPI"]):
46 allvalid = False
47 stats["EAPI.unsupported"] += 1
48 - fails["EAPI.unsupported"].append(os.path.join(x, y))
49 + fails["EAPI.unsupported"].append([os.path.join(x, y)])
50 continue
51 pkgs[pf] = Package(cpv=cpv, metadata=myaux,
52 root_config=root_config, type_name="ebuild")
53 @@ -1468,8 +1468,8 @@ for x in effective_scanlist:
54 index = -1
55 if index != -1:
56 stats["file.name"] += 1
57 - fails["file.name"].append("%s/%s: char '%s'" % \
58 - (checkdir, y, y[index]))
59 + fails["file.name"].append(["%s/%s" % (checkdir, y),
60 + "char '%s'" % y[index]])
61
62 if not (y in ("ChangeLog", "metadata.xml") or y.endswith(".ebuild")):
63 continue
64 @@ -1488,7 +1488,8 @@ for x in effective_scanlist:
65 line += l2
66 if l2 != 0:
67 s = s[s.rfind("\n") + 1:]
68 - fails["file.UTF8"].append("%s/%s: line %i, just after: '%s'" % (checkdir, y, line, s))
69 + fails["file.UTF8"].append(["%s/%s" % (checkdir, y),
70 + "line %i, just after: '%s'" % (line, s)])
71 finally:
72 if f is not None:
73 f.close()
74 @@ -1503,8 +1504,8 @@ for x in effective_scanlist:
75 for l in myf:
76 if l[:-1][-7:] == ".ebuild":
77 stats["ebuild.notadded"] += 1
78 - fails["ebuild.notadded"].append(
79 - os.path.join(x, os.path.basename(l[:-1])))
80 + fails["ebuild.notadded"].append([
81 + os.path.join(x, os.path.basename(l[:-1]))])
82 myf.close()
83
84 if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded:
85 @@ -1556,7 +1557,7 @@ for x in effective_scanlist:
86 except IOError:
87 if vcs == "cvs":
88 stats["CVS/Entries.IO_error"] += 1
89 - fails["CVS/Entries.IO_error"].append(checkdir + "/CVS/Entries")
90 + fails["CVS/Entries.IO_error"].append([checkdir + "/CVS/Entries"])
91 else:
92 raise
93 continue
94 @@ -1581,8 +1582,8 @@ for x in effective_scanlist:
95 pass
96 else:
97 stats["SRC_URI.syntax"] += 1
98 - fails["SRC_URI.syntax"].append(
99 - "%s.ebuild SRC_URI: %s" % (mykey, e))
100 + fails["SRC_URI.syntax"].append([
101 + "%s.ebuild" % mykey, "SRC_URI: %s" % e])
102 del fetchlist_dict
103 if not src_uri_error:
104 # This test can produce false positives if SRC_URI could not
105 @@ -1594,11 +1595,11 @@ for x in effective_scanlist:
106 for entry in mydigests:
107 if entry not in myfiles_all:
108 stats["digest.unused"] += 1
109 - fails["digest.unused"].append(checkdir + "::" + entry)
110 + fails["digest.unused"].append([checkdir + "::" + entry])
111 for entry in myfiles_all:
112 if entry not in mydigests:
113 stats["digest.missing"] += 1
114 - fails["digest.missing"].append(checkdir + "::" + entry)
115 + fails["digest.missing"].append([checkdir + "::" + entry])
116 del myfiles_all
117
118 if os.path.exists(checkdir + "/files"):
119 @@ -1630,10 +1631,12 @@ for x in effective_scanlist:
120 # 20 KiB and 60 KiB causes a warning, while file size over 60 KiB causes an error.
121 elif mystat.st_size > 61440:
122 stats["file.size.fatal"] += 1
123 - fails["file.size.fatal"].append("(" + str(mystat.st_size//1024) + " KiB) " + x + "/files/" + y)
124 + fails["file.size.fatal"].append([x + "/files/" + y,
125 + "(" + str(mystat.st_size//1024) + " KiB)"])
126 elif mystat.st_size > 20480:
127 stats["file.size"] += 1
128 - fails["file.size"].append("(" + str(mystat.st_size//1024) + " KiB) " + x + "/files/" + y)
129 + fails["file.size"].append([x + "/files/" + y,
130 + "(" + str(mystat.st_size//1024) + " KiB)"])
131
132 index = repo_config.find_invalid_path_char(y)
133 if index != -1:
134 @@ -1646,19 +1649,19 @@ for x in effective_scanlist:
135 index = -1
136 if index != -1:
137 stats["file.name"] += 1
138 - fails["file.name"].append("%s/files/%s: char '%s'" % \
139 - (checkdir, y, y[index]))
140 + fails["file.name"].append(["%s/files/%s" % (checkdir, y),
141 + "char '%s'" % y[index]])
142 del mydigests
143
144 if check_changelog and "ChangeLog" not in checkdirlist:
145 stats["changelog.missing"] += 1
146 - fails["changelog.missing"].append(x + "/ChangeLog")
147 + fails["changelog.missing"].append([x + "/ChangeLog"])
148
149 musedict = {}
150 # metadata.xml file check
151 if "metadata.xml" not in checkdirlist:
152 stats["metadata.missing"] += 1
153 - fails["metadata.missing"].append(x + "/metadata.xml")
154 + fails["metadata.missing"].append([x + "/metadata.xml"])
155 # metadata.xml parse check
156 else:
157 metadata_bad = False
158 @@ -1674,7 +1677,7 @@ for x in effective_scanlist:
159 except (ExpatError, SyntaxError, EnvironmentError) as e:
160 metadata_bad = True
161 stats["metadata.bad"] += 1
162 - fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
163 + fails["metadata.bad"].append(["%s/metadata.xml" % x, e])
164 del e
165 else:
166 if not hasattr(xml_parser, 'parser') or \
167 @@ -1685,9 +1688,9 @@ for x in effective_scanlist:
168 else:
169 if "XML_DECLARATION" not in xml_info:
170 stats["metadata.bad"] += 1
171 - fails["metadata.bad"].append("%s/metadata.xml: "
172 + fails["metadata.bad"].append(["%s/metadata.xml" % x,
173 "xml declaration is missing on first line, "
174 - "should be '%s'" % (x, metadata_xml_declaration))
175 + "should be '%s'" % metadata_xml_declaration])
176 else:
177 xml_version, xml_encoding, xml_standalone = \
178 xml_info["XML_DECLARATION"]
179 @@ -1698,15 +1701,15 @@ for x in effective_scanlist:
180 encoding_problem = "but it is undefined"
181 else:
182 encoding_problem = "not '%s'" % xml_encoding
183 - fails["metadata.bad"].append("%s/metadata.xml: "
184 + fails["metadata.bad"].append(["%s/metadata.xml" % x,
185 "xml declaration encoding should be '%s', %s" %
186 - (x, metadata_xml_encoding, encoding_problem))
187 + (metadata_xml_encoding, encoding_problem)])
188
189 if "DOCTYPE" not in xml_info:
190 metadata_bad = True
191 stats["metadata.bad"] += 1
192 - fails["metadata.bad"].append("%s/metadata.xml: %s" % (x,
193 - "DOCTYPE is missing"))
194 + fails["metadata.bad"].append(["%s/metadata.xml" % x,
195 + "DOCTYPE is missing"])
196 else:
197 doctype_name, doctype_system, doctype_pubid = \
198 xml_info["DOCTYPE"]
199 @@ -1716,15 +1719,15 @@ for x in effective_scanlist:
200 system_problem = "but it is undefined"
201 else:
202 system_problem = "not '%s'" % doctype_system
203 - fails["metadata.bad"].append("%s/metadata.xml: "
204 + fails["metadata.bad"].append(["%s/metadata.xml" % x,
205 "DOCTYPE: SYSTEM should refer to '%s', %s" %
206 - (x, metadata_dtd_uri, system_problem))
207 + (metadata_dtd_uri, system_problem)])
208
209 if doctype_name != metadata_doctype_name:
210 stats["metadata.bad"] += 1
211 - fails["metadata.bad"].append("%s/metadata.xml: "
212 + fails["metadata.bad"].append(["%s/metadata.xml" % x,
213 "DOCTYPE: name should be '%s', not '%s'" %
214 - (x, metadata_doctype_name, doctype_name))
215 + (metadata_doctype_name, doctype_name)])
216
217 # load USE flags from metadata.xml
218 try:
219 @@ -1732,7 +1735,7 @@ for x in effective_scanlist:
220 except portage.exception.ParseError as e:
221 metadata_bad = True
222 stats["metadata.bad"] += 1
223 - fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
224 + fails["metadata.bad"].append(["%s/metadata.xml" % x, e])
225 else:
226 for atom in chain(*musedict.values()):
227 if atom is None:
228 @@ -1741,14 +1744,14 @@ for x in effective_scanlist:
229 atom = Atom(atom)
230 except InvalidAtom as e:
231 stats["metadata.bad"] += 1
232 - fails["metadata.bad"].append(
233 - "%s/metadata.xml: Invalid atom: %s" % (x, e))
234 + fails["metadata.bad"].append([
235 + "%s/metadata.xml" % x, "Invalid atom: %s" % e])
236 else:
237 if atom.cp != x:
238 stats["metadata.bad"] += 1
239 - fails["metadata.bad"].append(
240 - ("%s/metadata.xml: Atom contains "
241 - "unexpected cat/pn: %s") % (x, atom))
242 + fails["metadata.bad"].append([
243 + "%s/metadata.xml" % x, "Atom contains "
244 + "unexpected cat/pn: %s" % atom])
245
246 # Run other metadata.xml checkers
247 try:
248 @@ -1756,7 +1759,7 @@ for x in effective_scanlist:
249 except (utilities.UnknownHerdsError, ) as e:
250 metadata_bad = True
251 stats["metadata.bad"] += 1
252 - fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
253 + fails["metadata.bad"].append(["%s/metadata.xml" %x, e])
254 del e
255
256 # Only carry out if in package directory or check forced
257 @@ -1772,7 +1775,7 @@ for x in effective_scanlist:
258 for z in out.splitlines():
259 print(red("!!! ") + z)
260 stats["metadata.bad"] += 1
261 - fails["metadata.bad"].append(x + "/metadata.xml")
262 + fails["metadata.bad"].append([x + "/metadata.xml"])
263
264 del metadata_bad
265 muselist = frozenset(musedict)
266 @@ -1795,23 +1798,23 @@ for x in effective_scanlist:
267 if check_changelog and not changelog_modified \
268 and ebuild_path in new_ebuilds:
269 stats['changelog.ebuildadded'] += 1
270 - fails['changelog.ebuildadded'].append(relative_path)
271 + fails['changelog.ebuildadded'].append([relative_path])
272
273 if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded and y not in eadded:
274 # ebuild not added to vcs
275 stats["ebuild.notadded"] += 1
276 - fails["ebuild.notadded"].append(x + "/" + y + ".ebuild")
277 + fails["ebuild.notadded"].append([x + "/" + y + ".ebuild"])
278 myesplit = portage.pkgsplit(y)
279 if myesplit is None or myesplit[0] != x.split("/")[-1] \
280 or pv_toolong_re.search(myesplit[1]) \
281 or pv_toolong_re.search(myesplit[2]):
282 stats["ebuild.invalidname"] += 1
283 - fails["ebuild.invalidname"].append(x + "/" + y + ".ebuild")
284 + fails["ebuild.invalidname"].append([x + "/" + y + ".ebuild"])
285 continue
286 elif myesplit[0] != pkgdir:
287 print(pkgdir, myesplit[0])
288 stats["ebuild.namenomatch"] += 1
289 - fails["ebuild.namenomatch"].append(x + "/" + y + ".ebuild")
290 + fails["ebuild.namenomatch"].append([x + "/" + y + ".ebuild"])
291 continue
292
293 pkg = pkgs[y]
294 @@ -1821,7 +1824,7 @@ for x in effective_scanlist:
295 for k, msgs in pkg.invalid.items():
296 for msg in msgs:
297 stats[k] += 1
298 - fails[k].append("%s: %s" % (relative_path, msg))
299 + fails[k].append([relative_path, msg])
300 continue
301
302 myaux = pkg._metadata
303 @@ -1831,13 +1834,11 @@ for x in effective_scanlist:
304
305 if repo_config.eapi_is_banned(eapi):
306 stats["repo.eapi.banned"] += 1
307 - fails["repo.eapi.banned"].append(
308 - "%s: %s" % (relative_path, eapi))
309 + fails["repo.eapi.banned"].append([relative_path, eapi])
310
311 elif repo_config.eapi_is_deprecated(eapi):
312 stats["repo.eapi.deprecated"] += 1
313 - fails["repo.eapi.deprecated"].append(
314 - "%s: %s" % (relative_path, eapi))
315 + fails["repo.eapi.deprecated"].append([relative_path, eapi])
316
317 for k, v in myaux.items():
318 if not isinstance(v, basestring):
319 @@ -1845,10 +1846,9 @@ for x in effective_scanlist:
320 m = non_ascii_re.search(v)
321 if m is not None:
322 stats["variable.invalidchar"] += 1
323 - fails["variable.invalidchar"].append(
324 - ("%s: %s variable contains non-ASCII " + \
325 - "character at position %s") % \
326 - (relative_path, k, m.start() + 1))
327 + fails["variable.invalidchar"].append([
328 + relative_path, "%s variable contains non-ASCII " +
329 + "character at position %s" % (k, m.start() + 1)])
330
331 if not src_uri_error:
332 # Check that URIs don't reference a server from thirdpartymirrors.
333 @@ -1864,13 +1864,13 @@ for x in effective_scanlist:
334
335 new_uri = "mirror://%s/%s" % (mirror_alias, uri[len(mirror):])
336 stats["SRC_URI.mirror"] += 1
337 - fails["SRC_URI.mirror"].append(
338 - "%s: '%s' found in thirdpartymirrors, use '%s'" % \
339 - (relative_path, mirror, new_uri))
340 + fails["SRC_URI.mirror"].append([
341 + relative_path, "'%s' found in thirdpartymirrors, use '%s'" % \
342 + (mirror, new_uri)])
343
344 if myaux.get("PROVIDE"):
345 stats["virtual.oldstyle"] += 1
346 - fails["virtual.oldstyle"].append(relative_path)
347 + fails["virtual.oldstyle"].append([relative_path])
348
349 for pos, missing_var in enumerate(missingvars):
350 if not myaux.get(missing_var):
351 @@ -1881,21 +1881,21 @@ for x in effective_scanlist:
352 continue
353 myqakey = missingvars[pos] + ".missing"
354 stats[myqakey] += 1
355 - fails[myqakey].append(x + "/" + y + ".ebuild")
356 + fails[myqakey].append([x + "/" + y + ".ebuild"])
357
358 if catdir == "virtual":
359 for var in ("HOMEPAGE", "LICENSE"):
360 if myaux.get(var):
361 myqakey = var + ".virtual"
362 stats[myqakey] += 1
363 - fails[myqakey].append(relative_path)
364 + fails[myqakey].append([relative_path])
365
366 # 14 is the length of DESCRIPTION=""
367 if len(myaux['DESCRIPTION']) > max_desc_len:
368 stats['DESCRIPTION.toolong'] += 1
369 - fails['DESCRIPTION.toolong'].append(
370 - "%s: DESCRIPTION is %d characters (max %d)" % \
371 - (relative_path, len(myaux['DESCRIPTION']), max_desc_len))
372 + fails['DESCRIPTION.toolong'].append([
373 + relative_path, "DESCRIPTION is %d characters (max %d)" % \
374 + (len(myaux['DESCRIPTION']), max_desc_len)])
375
376 keywords = myaux["KEYWORDS"].split()
377 stable_keywords = []
378 @@ -1908,8 +1908,8 @@ for x in effective_scanlist:
379 stable_keywords.sort()
380 stats["KEYWORDS.stable"] += 1
381 fails["KEYWORDS.stable"].append(
382 - x + "/" + y + ".ebuild added with stable keywords: %s" % \
383 - " ".join(stable_keywords))
384 + [x + "/" + y + ".ebuild", "added with stable keywords: %s" % \
385 + " ".join(stable_keywords)])
386
387 ebuild_archs = set(kw.lstrip("~") for kw in keywords \
388 if not kw.startswith("-"))
389 @@ -1921,9 +1921,8 @@ for x in effective_scanlist:
390 dropped_keywords = previous_keywords.difference(ebuild_archs)
391 if dropped_keywords:
392 stats["KEYWORDS.dropped"] += 1
393 - fails["KEYWORDS.dropped"].append(
394 - relative_path + ": %s" % \
395 - " ".join(sorted(dropped_keywords)))
396 + fails["KEYWORDS.dropped"].append([
397 + relative_path, "".join(sorted(dropped_keywords))])
398
399 slot_keywords[pkg.slot].update(ebuild_archs)
400
401 @@ -1937,7 +1936,7 @@ for x in effective_scanlist:
402 haskeyword = True
403 if not haskeyword:
404 stats["KEYWORDS.stupid"] += 1
405 - fails["KEYWORDS.stupid"].append(x + "/" + y + ".ebuild")
406 + fails["KEYWORDS.stupid"].append([x + "/" + y + ".ebuild"])
407
408 """
409 Ebuilds that inherit a "Live" eclass (darcs,subversion,git,cvs,etc..) should
410 @@ -1952,14 +1951,14 @@ for x in effective_scanlist:
411 del keyword
412 if bad_stable_keywords:
413 stats["LIVEVCS.stable"] += 1
414 - fails["LIVEVCS.stable"].append(
415 - x + "/" + y + ".ebuild with stable keywords:%s " % \
416 - bad_stable_keywords)
417 + fails["LIVEVCS.stable"].append([
418 + x + "/" + y + ".ebuild", "with stable keywords:%s " % \
419 + bad_stable_keywords])
420 del bad_stable_keywords
421
422 if keywords and not has_global_mask(pkg):
423 stats["LIVEVCS.unmasked"] += 1
424 - fails["LIVEVCS.unmasked"].append(relative_path)
425 + fails["LIVEVCS.unmasked"].append([relative_path])
426
427 if options.ignore_arches:
428 arches = [[repoman_settings["ARCH"], repoman_settings["ARCH"],
429 @@ -2024,8 +2023,8 @@ for x in effective_scanlist:
430 if runtime and \
431 "test?" in mydepstr.split():
432 stats[mytype + '.suspect'] += 1
433 - fails[mytype + '.suspect'].append(relative_path + \
434 - ": 'test?' USE conditional in %s" % mytype)
435 + fails[mytype + '.suspect'].append([relative_path,
436 + "'test?' USE conditional in %s" % mytype])
437
438 for atom in atoms:
439 if atom == "||":
440 @@ -2045,40 +2044,40 @@ for x in effective_scanlist:
441 if not is_blocker and \
442 atom.cp in suspect_virtual:
443 stats['virtual.suspect'] += 1
444 - fails['virtual.suspect'].append(
445 - relative_path +
446 - ": %s: consider using '%s' instead of '%s'" %
447 - (mytype, suspect_virtual[atom.cp], atom))
448 + fails['virtual.suspect'].append([
449 + relative_path,
450 + "consider using '%s' instead of '%s'" %
451 + (suspect_virtual[atom.cp], atom)])
452
453 if buildtime and \
454 not is_blocker and \
455 not inherited_java_eclass and \
456 atom.cp == "virtual/jdk":
457 stats['java.eclassesnotused'] += 1
458 - fails['java.eclassesnotused'].append(relative_path)
459 + fails['java.eclassesnotused'].append([relative_path])
460 elif buildtime and \
461 not is_blocker and \
462 not inherited_wxwidgets_eclass and \
463 atom.cp == "x11-libs/wxGTK":
464 stats['wxwidgets.eclassnotused'] += 1
465 - fails['wxwidgets.eclassnotused'].append(
466 - (relative_path + ": %ss on x11-libs/wxGTK"
467 - " without inheriting wxwidgets.eclass") % mytype)
468 + fails['wxwidgets.eclassnotused'].append([
469 + relative_path, "%ss on x11-libs/wxGTK"
470 + " without inheriting wxwidgets.eclass" % mytype])
471 elif runtime:
472 if not is_blocker and \
473 atom.cp in suspect_rdepend:
474 stats[mytype + '.suspect'] += 1
475 - fails[mytype + '.suspect'].append(
476 - relative_path + ": '%s'" % atom)
477 + fails[mytype + '.suspect'].append([
478 + relative_path, "'%s'" % atom])
479
480 if atom.operator == "~" and \
481 portage.versions.catpkgsplit(atom.cpv)[3] != "r0":
482 qacat = 'dependency.badtilde'
483 stats[qacat] += 1
484 - fails[qacat].append(
485 - (relative_path + ": %s uses the ~ operator"
486 + fails[qacat].append([
487 + relative_path, "%s uses the ~ operator"
488 " with a non-zero revision:" + \
489 - " '%s'") % (mytype, atom))
490 + " '%s'" % (mytype, atom)])
491
492 type_list.extend([mytype] * (len(badsyntax) - len(type_list)))
493
494 @@ -2088,7 +2087,7 @@ for x in effective_scanlist:
495 else:
496 qacat = m + ".syntax"
497 stats[qacat] += 1
498 - fails[qacat].append("%s: %s: %s" % (relative_path, m, b))
499 + fails[qacat].append([relative_path, "%s: %s" % (m, b)])
500
501 badlicsyntax = len([z for z in type_list if z == "LICENSE"])
502 badprovsyntax = len([z for z in type_list if z == "PROVIDE"])
503 @@ -2115,14 +2114,14 @@ for x in effective_scanlist:
504 if default_use and not eapi_has_iuse_defaults(eapi):
505 for myflag in default_use:
506 stats['EAPI.incompatible'] += 1
507 - fails['EAPI.incompatible'].append(
508 - (relative_path + ": IUSE defaults" + \
509 + fails['EAPI.incompatible'].append([
510 + relative_path, "IUSE defaults" + \
511 " not supported with EAPI='%s':" + \
512 - " '%s'") % (eapi, myflag))
513 + " '%s'" % (eapi, myflag)])
514
515 for mypos in range(len(myuse)):
516 stats["IUSE.invalid"] += 1
517 - fails["IUSE.invalid"].append(x + "/" + y + ".ebuild: %s" % myuse[mypos])
518 + fails["IUSE.invalid"].append([x + "/" + y + ".ebuild", myuse[mypos]])
519
520 # Check for outdated RUBY targets
521 if "ruby-ng" in inherited or "ruby-fakegem" in inherited or "ruby" in inherited:
522 @@ -2130,8 +2129,8 @@ for x in effective_scanlist:
523 if ruby_intersection:
524 for myruby in ruby_intersection:
525 stats["IUSE.rubydeprecated"] += 1
526 - fails["IUSE.rubydeprecated"].append(
527 - (relative_path + ": Deprecated ruby target: %s") % myruby)
528 + fails["IUSE.rubydeprecated"].append([
529 + relative_path, "Deprecated ruby target: %s" % myruby])
530
531 # license checks
532 if not badlicsyntax:
533 @@ -2145,10 +2144,10 @@ for x in effective_scanlist:
534 # function will remove it without removing values.
535 if lic not in liclist and lic != "||":
536 stats["LICENSE.invalid"] += 1
537 - fails["LICENSE.invalid"].append(x + "/" + y + ".ebuild: %s" % lic)
538 + fails["LICENSE.invalid"].append([x + "/" + y + ".ebuild", lic])
539 elif lic in liclist_deprecated:
540 stats["LICENSE.deprecated"] += 1
541 - fails["LICENSE.deprecated"].append("%s: %s" % (relative_path, lic))
542 + fails["LICENSE.deprecated"].append([relative_path, lic])
543
544 # keyword checks
545 myuse = myaux["KEYWORDS"].split()
546 @@ -2161,10 +2160,10 @@ for x in effective_scanlist:
547 myskey = myskey[1:]
548 if myskey not in kwlist:
549 stats["KEYWORDS.invalid"] += 1
550 - fails["KEYWORDS.invalid"].append(x + "/" + y + ".ebuild: %s" % mykey)
551 + fails["KEYWORDS.invalid"].append([x + "/" + y + ".ebuild", mykey])
552 elif myskey not in profiles:
553 stats["KEYWORDS.invalid"] += 1
554 - fails["KEYWORDS.invalid"].append(x + "/" + y + ".ebuild: %s (profile invalid)" % mykey)
555 + fails["KEYWORDS.invalid"].append([x + "/" + y + ".ebuild", "%s (profile invalid)" % mykey])
556
557 # restrict checks
558 myrestrict = None
559 @@ -2172,8 +2171,8 @@ for x in effective_scanlist:
560 myrestrict = portage.dep.use_reduce(myaux["RESTRICT"], matchall=1, flat=True)
561 except portage.exception.InvalidDependString as e:
562 stats["RESTRICT.syntax"] += 1
563 - fails["RESTRICT.syntax"].append(
564 - "%s: RESTRICT: %s" % (relative_path, e))
565 + fails["RESTRICT.syntax"].append([
566 + relative_path, "RESTRICT: %s" % e])
567 del e
568 if myrestrict:
569 myrestrict = set(myrestrict)
570 @@ -2181,22 +2180,22 @@ for x in effective_scanlist:
571 if mybadrestrict:
572 stats["RESTRICT.invalid"] += len(mybadrestrict)
573 for mybad in mybadrestrict:
574 - fails["RESTRICT.invalid"].append(x + "/" + y + ".ebuild: %s" % mybad)
575 + fails["RESTRICT.invalid"].append([x + "/" + y + ".ebuild", mybad])
576 # REQUIRED_USE check
577 required_use = myaux["REQUIRED_USE"]
578 if required_use:
579 if not eapi_has_required_use(eapi):
580 stats['EAPI.incompatible'] += 1
581 - fails['EAPI.incompatible'].append(
582 - relative_path + ": REQUIRED_USE" + \
583 - " not supported with EAPI='%s'" % (eapi,))
584 + fails['EAPI.incompatible'].append([
585 + relative_path, "REQUIRED_USE" + \
586 + " not supported with EAPI='%s'" % eapi])
587 try:
588 portage.dep.check_required_use(required_use, (),
589 pkg.iuse.is_valid_flag, eapi=eapi)
590 except portage.exception.InvalidDependString as e:
591 stats["REQUIRED_USE.syntax"] += 1
592 - fails["REQUIRED_USE.syntax"].append(
593 - "%s: REQUIRED_USE: %s" % (relative_path, e))
594 + fails["REQUIRED_USE.syntax"].append([
595 + relative_path, "REQUIRED_USE: %s" % e])
596 del e
597
598 # Syntax Checks
599 @@ -2214,7 +2213,7 @@ for x in effective_scanlist:
600 try:
601 for check_name, e in run_checks(f, pkg):
602 stats[check_name] += 1
603 - fails[check_name].append(relative_path + ': %s' % e)
604 + fails[check_name].append([relative_path, e])
605 finally:
606 f.close()
607 except UnicodeDecodeError:
608 @@ -2367,14 +2366,12 @@ for x in effective_scanlist:
609 if not atoms:
610 continue
611 stats[mykey] += 1
612 - fails[mykey].append("%s: %s: %s(%s) %s" % \
613 - (relative_path, mytype, keyword,
614 - prof, repr(atoms)))
615 + fails[mykey].append([relative_path, "%s: %s(%s) %s" % \
616 + (mytype, keyword, prof, repr(atoms))])
617 else:
618 stats[mykey] += 1
619 - fails[mykey].append("%s: %s: %s(%s) %s" % \
620 - (relative_path, mytype, keyword,
621 - prof, repr(atoms)))
622 + fails[mykey].append([relative_path, "%s: %s(%s) %s" % \
623 + (mytype, keyword, prof, repr(atoms))])
624
625 if not baddepsyntax and unknown_pkgs:
626 type_map = {}
627 @@ -2382,17 +2379,16 @@ for x in effective_scanlist:
628 type_map.setdefault(mytype, set()).add(atom)
629 for mytype, atoms in type_map.items():
630 stats["dependency.unknown"] += 1
631 - fails["dependency.unknown"].append("%s: %s: %s" %
632 - (relative_path, mytype, ", ".join(sorted(atoms))))
633 + fails["dependency.unknown"].append([relative_path, "%s: %s" %
634 + (mytype, ", ".join(sorted(atoms)))])
635
636 # check if there are unused local USE-descriptions in metadata.xml
637 # (unless there are any invalids, to avoid noise)
638 if allvalid:
639 for myflag in muselist.difference(used_useflags):
640 stats["metadata.warning"] += 1
641 - fails["metadata.warning"].append(
642 - "%s/metadata.xml: unused local USE-description: '%s'" % \
643 - (x, myflag))
644 + fails["metadata.warning"].append(["%s/metadata.xml" % x,
645 + "unused local USE-description: '%s'" % myflag])
646
647 if options.if_modified == "y" and len(effective_scanlist) < 1:
648 logging.warn("--if-modified is enabled, but no modified packages were found!")
649 diff --git a/pym/repoman/utilities.py b/pym/repoman/utilities.py
650 index aec61fe..066a357 100644
651 --- a/pym/repoman/utilities.py
652 +++ b/pym/repoman/utilities.py
653 @@ -325,8 +325,14 @@ def format_qa_output(formatter, stats, fails, dofull, dofail, options, qawarning
654 fails_list = fails[category]
655 if not full and len(fails_list) > 12:
656 fails_list = fails_list[:12]
657 - for failure in fails_list:
658 - formatter.add_literal_data(" " + failure)
659 + for entry in fails_list:
660 + # If the tuple has two entries, then the error should be filename: error
661 + if len(entry) == 2:
662 + error = "%s: %s" % (entry[0], entry[1])
663 + # Otherwise, just output the filename
664 + else:
665 + error = entry[0]
666 + formatter.add_literal_data(" " + error)
667 formatter.add_line_break()
668
669
670 @@ -370,8 +376,12 @@ def format_qa_output_column(formatter, stats, fails, dofull, dofail, options, qa
671 fails_list = fails[category]
672 if not full and len(fails_list) > 12:
673 fails_list = fails_list[:12]
674 - for failure in fails_list:
675 - formatter.add_literal_data(category + " " + failure)
676 + for entry in fails_list:
677 + if len(entry) == 2:
678 + error = "%s %s" % (entry[0], entry[1])
679 + else:
680 + error = entry[0]
681 + formatter.add_literal_data(category + " " + error)
682 formatter.add_line_break()
683
684 def editor_is_executable(editor):
685 --
686 1.8.5.3

Replies