summaryrefslogtreecommitdiff
blob: 8414f44c1d82140fcddb447b34ca31fddf514b77 (plain)
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
#!/usr/bin/env python
# Copyright 2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import itertools
import optparse
import os
import re
import subprocess
import sys

import portage.versions

BUG_REGEX = re.compile("[Bb]ug #?(\d+)")

def print_and_log(message, log):
	try:
		print message
		log.write(message)
	finally:
		log.flush()

def run_command(args, cwd, log):
	try:
		log.write("Running %r in %s...\n" % (args, cwd))
		cmd  = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
		output = cmd.communicate()[0]
		log.write("Finished with exit code %d\n" % cmd.returncode)
		log.write(output)
		return (cmd.returncode, output)
	finally:
		log.flush()

if __name__ == "__main__":
	parser = optparse.OptionParser()
	parser.add_option("--arch", dest="arch", help="Gentoo arch to use, e.g. x86, amd64, ...")
	parser.add_option("-i", "--input", dest="input_filename", default="package.keywords", help="Input filename for generated package.keywords file [default=%default]")
	parser.add_option("--repo", dest="repo", help="Path to portage CVS repository")
	parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False)

	(options, args) = parser.parse_args()
	if not options.arch:
		parser.error("--arch option is required")
	if not options.input_filename:
		parser.error("--input option is required")
	if not options.repo:
		parser.error("--repo option is required")
	if args:
		parser.error("unrecognized command-line args")
	
	with open(options.input_filename, "r") as input_file:
		stabilization_list = []
		bug_id = -1
		for line in input_file:
			if line == "\n":
				continue

			if line.startswith("#"):
				match = BUG_REGEX.search(line, re.IGNORECASE)
				if not match:
					print 'Ignoring comment line [%s]...' % line
					continue
				else:
					bug_id = int(match.group(1))
				continue

			if bug_id == -1:
				print 'Could not recognize bug id'
				sys.exit(1)

			if not line.endswith("\n"):
				line += "\n"
			cpv = line[1:-1]
			p = portage.versions.catsplit(cpv)[1]
			pn = portage.versions.pkgsplit(cpv)[0]
			ebuild_name = p + ".ebuild"
			stabilization_list.append((pn, ebuild_name, bug_id))

		# Sanity check.
		success = True
		for pn, ebuild_name, bug_id in stabilization_list:
			ebuild_path = os.path.join(options.repo, pn, ebuild_name)
			if not os.path.exists(ebuild_path):
				print '%s: file does not exist' % ebuild_path
				success = False
		if not success:
			print 'Sanity check failed. Please make sure your CVS repo is up to date (cvs up).'
			sys.exit(1)

		with open('batch-stabilize.log', 'w') as log_file:
			for pn, ebuild_name, bug_id in stabilization_list:
				commit_message = "%s stable wrt bug #%d" % (options.arch, bug_id)
				cvs_path = os.path.join(options.repo, pn)
				print_and_log('Working in %s...' % cvs_path, log_file)
				if run_command(["cvs", "up"], cvs_path, log_file)[0] != 0:
					print '!!! cvs up failed'
					sys.exit(1)
				if run_command(["ekeyword", options.arch, ebuild_name], cvs_path, log_file)[0] != 0:
					print '!!! ekeyword failed'
					sys.exit(1)
				return_code, output = run_command(["cvs", "diff"], cvs_path, log_file)
				# It seems that cvs diff returns 1 if there are differences.
				if return_code == 0 and not output:
					print_and_log('Seems already keyworded, skipping.', log_file)
					continue
				if run_command(["echangelog", commit_message], cvs_path, log_file)[0] != 0:
					print '!!! ekeyword failed'
					sys.exit(1)
				if run_command(["repoman", "manifest"], cvs_path, log_file)[0] != 0:
					print '!!! repoman manifest failed'
					sys.exit(1)
				if run_command(["repoman", "full"], cvs_path, log_file)[0] != 0:
					print '!!! repoman full failed'
					sys.exit(1)
				if run_command(["repoman", "commit", "-m", commit_message], cvs_path, log_file)[0] != 0:
					print '!!! repoman full failed'
					sys.exit(1)