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 |