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