Gentoo Archives: gentoo-commits

From: Christian Ruppert <idl0r@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/qa-scripts:master commit in: package.mask/
Date: Tue, 29 Mar 2011 18:10:50
Message-Id: 135ac4fa58ecae468339885b34317545b46f8b8c.idl0r@gentoo
1 commit: 135ac4fa58ecae468339885b34317545b46f8b8c
2 Author: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
3 AuthorDate: Tue Mar 29 18:10:25 2011 +0000
4 Commit: Christian Ruppert <idl0r <AT> gentoo <DOT> org>
5 CommitDate: Tue Mar 29 18:10:25 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/qa-scripts.git;a=commit;h=135ac4fa
7
8 Add mask_check.py
9
10 ---
11 package.mask/README | 1 +
12 package.mask/mask_check.py | 354 ++++++++++++++++++++++++++++++++++++++++++++
13 2 files changed, 355 insertions(+), 0 deletions(-)
14
15 diff --git a/package.mask/README b/package.mask/README
16 new file mode 100644
17 index 0000000..73fdcbb
18 --- /dev/null
19 +++ b/package.mask/README
20 @@ -0,0 +1 @@
21 +5 0 * * * python ~/gentoo/mask_check.py $(find /usr/portage/profiles -type f -name '*.mask') > ~/public_html/gentoo/invalid-mask.txt
22
23 diff --git a/package.mask/mask_check.py b/package.mask/mask_check.py
24 new file mode 100644
25 index 0000000..78e5511
26 --- /dev/null
27 +++ b/package.mask/mask_check.py
28 @@ -0,0 +1,354 @@
29 +#!/usr/bin/env python
30 +# Copyright 1999-2011 Gentoo Foundation
31 +# Distributed under the terms of the GNU General Public License v2
32 +
33 +# python mask_check.py $(find /usr/portage/profiles -type f -name '*.mask' -not -regex '.*/prefix/.*')
34 +
35 +import re
36 +
37 +from lxml import etree
38 +from os.path import join, isfile, isdir, basename
39 +from os import listdir
40 +from sys import stderr, argv
41 +from time import strftime, gmtime
42 +
43 +from portage import settings
44 +from portage.versions import pkgsplit, vercmp
45 +
46 +OPERATORS = (">", "=", "<", "~")
47 +
48 +def strip_atoms(pkg):
49 + while pkg.startswith( OPERATORS ) and len(pkg) > 1:
50 + pkg = pkg[1:]
51 + while pkg.endswith( ("*", ".") ):
52 + pkg = pkg[0:-1]
53 +
54 + # strip slots
55 + if pkg.find(":") != -1:
56 + pkg = pkg[0:pkg.find(":")]
57 + return pkg
58 +
59 +# Deprecated
60 +def strip_atoms2(pkg):
61 + while pkg.startswith( OPERATORS ) and len(pkg) > 1:
62 + pkg = pkg[1:]
63 + while pkg.endswith( "*" ):
64 + pkg = pkg[0:-1]
65 +
66 + return pkg
67 +
68 +def pkgcmp_atom(pkgdir, pkg):
69 + ebuilds = []
70 +
71 + for ent in listdir(pkgdir):
72 + if ent.endswith(".ebuild"):
73 + ebuilds.append(ent)
74 +
75 + ppkg = basename(strip_atoms(pkg))
76 +
77 + # test
78 + ppkg2 = basename(strip_atoms2(pkg))
79 + if ppkg != ppkg2:
80 + print >> stderr, "PPKG: %s" % ppkg
81 + print >> stderr, "PPKG2: %s" % ppkg2
82 +
83 + revre = re.compile( ("^" + re.escape(ppkg) + "(-r\d+)?.ebuild$") )
84 +
85 +# print "DBG: checking for %s" % pkg
86 +# print "DBG: Got %i ebuilds:" % len(ebuilds)
87 +# print ebuilds
88 +
89 + for ebuild in ebuilds:
90 + # workaround? for - prefix
91 + if pkg.startswith( "-" ):
92 + pkg = pkg[1:]
93 +
94 + if pkg.startswith( ("=", "~") ):
95 + if pkg.startswith("~"):
96 + if revre.match(ebuild):
97 +# print "DBG: revmatch '%s' '%s'" % (pkg, ebuild)
98 + return 1
99 + else:
100 +# print "DBG: revmatch continue"
101 + continue
102 + if pkg.endswith("*"):
103 + if ebuild.startswith(ppkg):
104 +# print "DBG: startswith '%s' '%s'" % (pkg, ebuild)
105 + return 1
106 + else:
107 +# print "DBG: startswith continue"
108 + continue
109 + else:
110 + if ebuild == (ppkg + ".ebuild"):
111 +# print "DBG: '%s' == '%s'" % (ppkg, ppkg)
112 + return 1
113 + else:
114 +# print "DBG: == continue"
115 + continue
116 +
117 + if pkg.startswith( (">=", ">", "<=", "<") ):
118 + plain = strip_atoms(pkg)
119 +
120 + mypkg = pkgsplit(plain)
121 + ourpkg = pkgsplit(ebuild.rstrip(".ebuild"))
122 +
123 + mypkgv = mypkg[1]
124 + if mypkg[2] != "r0":
125 + mypkgv = mypkgv + "-" + mypkg[2]
126 +
127 + ourpkgv = ourpkg[1]
128 + if ourpkg[2] != "r0":
129 + ourpkgv = ourpkgv + "-" + ourpkg[2]
130 +
131 +# print "MYPKGV:", mypkgv, "OURPKGV:", ourpkgv, "RESULT 'vercmp('%s', '%s'): %i" % (mypkgv, ourpkgv, vercmp(mypkgv, ourpkgv))
132 +
133 + if pkg.startswith(">="):
134 + if vercmp(mypkgv, ourpkgv) <= 0:
135 +# print "HIT: '%s' >= '%s'" % (ourpkg, mypkg)
136 + return 1
137 + else:
138 +# print ">= continue"
139 + continue
140 + if pkg.startswith(">") and not pkg.startswith(">="):
141 + if vercmp(mypkgv, ourpkgv) < 0:
142 +# print "HIT: '%s' > '%s'" % (ourpkg, mypkg)
143 + return 1
144 + else:
145 +# print "> continue"
146 + continue
147 + if pkg.startswith("<="):
148 + if vercmp(mypkgv, ourpkgv) >= 0:
149 +# print "HIT: '%s' <= '%s'" % (ourpkg, mypkg)
150 + return 1
151 + else:
152 +# print "<= continue"
153 + continue
154 + if pkg.startswith("<") and not pkg.startswith("<="):
155 + if vercmp(mypkgv, ourpkgv) > 0:
156 +# print "HIT: '%s' < '%s'" % (ourpkg, mypkg)
157 + return 1
158 + else:
159 +# print "< continue"
160 + continue
161 +
162 +# print "Nothing found... '%s' is invalid" % pkg
163 + return 0
164 +
165 +def check_locuse(portdir, pkg, invalid):
166 + locuse = []
167 +
168 + ppkg = pkgsplit(strip_atoms(pkg))
169 +
170 + if ppkg:
171 + ppkg = ppkg[0]
172 + else:
173 + ppkg = strip_atoms(pkg)
174 +
175 + metadata = join(portdir, ppkg, "metadata.xml")
176 +
177 + tree = etree.parse(metadata)
178 + root = tree.getroot()
179 + for elem in root:
180 + if elem.tag == "use":
181 + for use in elem:
182 + locuse.append(use.get("name"))
183 +
184 + # create a _NEW_ list
185 + oldinvalid = [foo for foo in invalid]
186 + for iuse in oldinvalid:
187 + if iuse in locuse:
188 + invalid.remove(iuse)
189 +
190 + return invalid
191 +
192 +def check_use(portdir, line):
193 + # use.desc
194 + # <flag> - <description>
195 + usedescs = [join(portdir, "profiles/use.desc")]
196 + globuse = []
197 + invalid = []
198 + useflags = []
199 +
200 + for useflag in line.split(" ")[1:]:
201 + # get a rid of malformed stuff e.g.:
202 + # app-text/enchant zemberek
203 + if len(useflag) > 0:
204 + if useflag.startswith("-"):
205 + useflag = useflag[1:]
206 + useflags.append(useflag)
207 +
208 + pkg = line.split(" ")[0]
209 +
210 + # Add other description file
211 + for entry in listdir(join(portdir, "profiles/desc")):
212 + entry = join(portdir, "profiles/desc", entry)
213 + if isfile(entry) and entry.endswith(".desc"):
214 + usedescs.append(entry)
215 +
216 + for usedesc_f in usedescs:
217 + usedesc_fd = open(usedesc_f, "r")
218 +
219 + for line in usedesc_fd:
220 + line = line.rstrip()
221 + line = line.replace("\t", " ")
222 +
223 + if len(line) == 0:
224 + continue
225 +
226 + while line[0].isspace():
227 + if len(line) > 1:
228 + line = line[1:]
229 + else:
230 + break
231 +
232 + if line.startswith("#"):
233 + continue
234 + _flag = line.split(" - ")[0]
235 +
236 + if usedesc_f == join(portdir, "profiles/use.desc"):
237 + globuse.append(line.split(" - ")[0])
238 + else:
239 + _flag = "%s_%s" % (basename(usedesc_f).replace(".desc", ""), _flag)
240 + globuse.append(_flag)
241 +# print "GLOB: ", _flag
242 +
243 + usedesc_fd.close()
244 +
245 +# print globuse
246 +# exit(1)
247 +
248 + for flag in useflags:
249 + if not flag in globuse:
250 + # nothing found
251 + invalid.append(flag)
252 +# print "Add useflag %s" %flag
253 +
254 + # check metadata.xml
255 + if invalid:
256 + invalid = check_locuse(portdir, pkg, invalid)
257 +
258 +
259 +# print portdir, pkg, useflags
260 +# print globuse
261 +
262 + if invalid:
263 + return (pkg, invalid)
264 + else:
265 + return None
266 +
267 +# <cat>/<pkg> <use> ...
268 +def check_pkg(portdir, line):
269 +# print "PKGM1:", line
270 + pkgm = line.split(" ")[0]
271 +# print "PKGM2:", pkgm
272 +# print "DBG:", line.split(" ")
273 +
274 + if pkgm.startswith("-"):
275 + pkgm = pkgm[1:]
276 +
277 + if pkgm.startswith(OPERATORS):
278 + pkg = []
279 +# print "DBG1: %s" % pkgm
280 + plain_pkg = strip_atoms(pkgm)
281 +# print "DBG2: %s" % plain_pkg
282 +
283 + pkg = pkgsplit(plain_pkg)
284 + if not pkg:
285 + print >> stderr, "Error encountered during pkgsplit(), please contact idl0r@g.o including the whole output!"
286 + print >> stderr, "1: %s; 2: %s" % (pkgm, plain_pkg)
287 + return 0
288 +
289 + plain_pkg = strip_atoms(pkg[0])
290 +
291 + if not isdir(join(portdir, plain_pkg)):
292 + return 0
293 +
294 + if not pkgcmp_atom(join(portdir, plain_pkg), pkgm):
295 + return 0
296 +
297 + return 1
298 + else:
299 + if pkgm.find(":") != -1:
300 + pkgm = strip_atoms(pkgm)
301 + if isdir(join(portdir, pkgm)):
302 + return 1
303 + else:
304 + return 0
305 +
306 + return 0
307 +
308 +def get_timestamp():
309 + timestamp_f = join(settings["PORTDIR"], "metadata/timestamp.chk")
310 + timestamp = open(timestamp_f).readline().rstrip()
311 + if len(timestamp) < 1:
312 + return "Unknown"
313 +
314 + return timestamp
315 +
316 +def obsolete_pmask(portdir = None, package_mask=None):
317 + invalid_entries = []
318 +
319 + if not portdir:
320 + portdir = settings["PORTDIR"]
321 +
322 + if not package_mask:
323 + package_mask = join(portdir, "profiles/package.mask")
324 +
325 + pmask = open(package_mask, "r")
326 +
327 + for line in pmask:
328 + line = line.rstrip()
329 +
330 + if len(line) == 0:
331 + continue
332 +
333 + while line[0].isspace():
334 + if len(line) > 1:
335 + line = line[1:]
336 + else:
337 + break
338 +
339 + if line.startswith("#"):
340 + continue
341 +
342 + # Skip sys-freebsd
343 + if line.find("sys-freebsd") != -1:
344 + continue
345 +
346 + line = line.replace("\t", " ")
347 +
348 + # don't check useflags with check_pkg
349 + if line.find("/") != -1 and not check_pkg(portdir, line):
350 +# print "Add whole entry: '%s'" % line
351 + invalid_entries.append(line)
352 + else:
353 + invalid_use = check_use(portdir, line)
354 + if invalid_use:
355 +# print "Add useflags: '%s %s'" % (invalid_use[0], invalid_use[1])
356 + invalid_entries.append(invalid_use)
357 +
358 + pmask.close()
359 +
360 + if invalid_entries:
361 + print "Found %i invalid/obsolete entries in %s:" % (len(invalid_entries), package_mask)
362 + for invalid in invalid_entries:
363 + if isinstance(invalid, tuple):
364 + print invalid[0], invalid[1]
365 + else:
366 + print invalid
367 + print ""
368 +
369 +if __name__ == "__main__":
370 + print "A list of invalid/obsolete package.mask entries in gentoo-x86, see bug 105016"
371 + print "Generated on: %s (autogenerated at: 0 0 * * *)" % strftime( "%a %b %d %H:%M:%S %Z %Y", gmtime() )
372 + print "Timestamp of tree: %s" % get_timestamp()
373 + print "NOTE: if a package is listed as <category>/<package> <flag> ..."
374 + print " or <category>/<package> then the whole entry is invalid/obsolete."
375 + print "NOTE: if a package is listed as <category>/<package> [ <flag>, ... ] then the listed useflags are invalid."
376 + print ""
377 +
378 + if len(argv) > 1:
379 + for _pmask in argv[1:]:
380 + obsolete_pmask(package_mask=_pmask)
381 + else:
382 + obsolete_pmask()