Gentoo Archives: gentoo-commits

From: "Paweł Hajdan" <phajdan.jr@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/arch-tools:master commit in: /
Date: Mon, 21 Nov 2011 08:35:12
Message-Id: 6f2f2e0dde5c8a1f593fe523e8e72b6eeff5cbb9.phajdan.jr@gentoo
1 commit: 6f2f2e0dde5c8a1f593fe523e8e72b6eeff5cbb9
2 Author: Pawel Hajdan, Jr <phajdan.jr <AT> gentoo <DOT> org>
3 AuthorDate: Mon Nov 21 08:34:19 2011 +0000
4 Commit: Paweł Hajdan <phajdan.jr <AT> gentoo <DOT> org>
5 CommitDate: Mon Nov 21 08:34:19 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/arch-tools.git;a=commit;h=6f2f2e0d
7
8 Automated finding candidates for stabilization.
9
10 ---
11 stabilization-candidates.py | 122 +++++++++++++++++++++++++++++++++++++++++++
12 1 files changed, 122 insertions(+), 0 deletions(-)
13
14 diff --git a/stabilization-candidates.py b/stabilization-candidates.py
15 new file mode 100755
16 index 0000000..5d0c3f8
17 --- /dev/null
18 +++ b/stabilization-candidates.py
19 @@ -0,0 +1,122 @@
20 +#!/usr/bin/env python
21 +# Copyright 2011 Gentoo Foundation
22 +# Distributed under the terms of the GNU General Public License v2
23 +
24 +import datetime
25 +import optparse
26 +import os.path
27 +import re
28 +import subprocess
29 +
30 +import bugz.bugzilla
31 +from portage.package.ebuild.getmaskingstatus import getmaskingstatus
32 +from portage.xml.metadata import MetaDataXML
33 +import portage.versions
34 +
35 +class MyBugz(bugz.bugzilla.Bugz):
36 + def get_input(self, prompt):
37 + return raw_input(prompt)
38 +
39 +if __name__ == "__main__":
40 + parser = optparse.OptionParser()
41 + parser.add_option("--arch", dest="arch", action="append", help="Gentoo arch to use, e.g. x86, amd64, ... Can be passed multiple times.")
42 + parser.add_option("--days", dest="days", type=int, default=30, help="Number of days in the tree after stabilization is possible.")
43 + parser.add_option("--repo", dest="repo", help="Path to portage CVS repository")
44 + parser.add_option("--category", dest="category", help="Portage category filter (default is all categories)")
45 +
46 + (options, args) = parser.parse_args()
47 + if not options.arch:
48 + parser.error("--arch option is required")
49 + if not options.repo:
50 + parser.error("--repo option is required")
51 + if args:
52 + parser.error("unrecognized command-line args")
53 +
54 + url = 'https://bugs.gentoo.org'
55 + print 'You may be prompted for your Gentoo Bugzilla username and password (%s).' % url
56 + bugzilla = MyBugz(url)
57 + bugzilla.auth()
58 +
59 + now = datetime.datetime.now()
60 + for cp in portage.portdb.cp_all():
61 + if options.category and not cp.startswith(options.category + "/"):
62 + continue
63 + best_stable = portage.versions.best(portage.portdb.match(cp))
64 + if not best_stable:
65 + continue
66 + candidates = []
67 + for cpv in portage.portdb.cp_list(cp):
68 + # Only consider higher versions than best stable.
69 + if portage.versions.pkgcmp(portage.versions.pkgsplit(cpv), portage.versions.pkgsplit(best_stable)) != 1:
70 + continue
71 +
72 + # Eliminate alpha, beta, pre, rc, and so on packages.
73 + is_unstable = False
74 + for suffix in portage.versions.endversion_keys:
75 + if ("_" + suffix) in portage.versions.pkgsplit(cpv)[1]:
76 + is_unstable = True
77 + break
78 + if is_unstable:
79 + continue
80 +
81 + # Eliminate hard masked packages among others.
82 + if getmaskingstatus(cpv) not in [[u'~%s keyword' % arch] for arch in options.arch]:
83 + continue
84 +
85 + pv = portage.versions.catsplit(cpv)[1]
86 + with open(os.path.join(options.repo, cp, 'ChangeLog')) as changelog_file:
87 + regex = '\*%s \((.*)\)' % re.escape(pv)
88 + match = re.search(regex, changelog_file.read())
89 + if not match:
90 + continue
91 + changelog_date = datetime.datetime.strptime(match.group(1), '%d %b %Y')
92 + if now - changelog_date < datetime.timedelta(days=options.days):
93 + continue
94 +
95 + candidates.append(cpv)
96 + if not candidates:
97 + continue
98 + candidates.sort(key=portage.versions.cpv_sort_key())
99 + print '\t\tWorking on %s. Candidates: %s' % (cp, ', '.join(candidates))
100 + candidates.reverse()
101 + best_candidate = None
102 + cvs_path = os.path.join(options.repo, cp)
103 + for candidate in candidates:
104 + ebuild_name = portage.versions.catsplit(candidate)[1] + ".ebuild"
105 + ebuild_path = os.path.join(cvs_path, ebuild_name)
106 + manifest_path = os.path.join(cvs_path, 'Manifest')
107 + original_contents = open(ebuild_path).read()
108 + manifest_contents = open(manifest_path).read()
109 + try:
110 + for arch in options.arch:
111 + subprocess.check_output(["ekeyword", arch, ebuild_name], cwd=cvs_path)
112 + subprocess.check_output(["repoman", "manifest"], cwd=cvs_path)
113 + subprocess.check_output(["repoman", "full"], cwd=cvs_path)
114 + except subprocess.CalledProcessError:
115 + continue
116 + finally:
117 + f = open(ebuild_path, "w")
118 + f.write(original_contents)
119 + f.close()
120 + f = open(manifest_path, "w")
121 + f.write(manifest_contents)
122 + f.close()
123 + best_candidate = candidate
124 + break
125 + if best_candidate:
126 + # Do not risk trying to stabilize a package with known bugs.
127 + bugs = bugzilla.search(cp, status=None)
128 + if bugs:
129 + continue
130 +
131 + # Protection against filing a stabilization bug twice.
132 + bugs = bugzilla.search(best_candidate)
133 + if bugs:
134 + continue
135 +
136 + metadata = MetaDataXML(os.path.join(cvs_path, 'metadata.xml'), '/usr/portage/metadata/herds.xml')
137 +
138 + # Spam protection (strip @ and domain name).
139 + maintainer_string = re.sub('@[^\s]*', '', metadata.format_maintainer_string())
140 +
141 + print (cp, best_stable, best_candidate, maintainer_string)