3 '''A script to buildMoonshot potentially using a schroot for install testing.
6 from contextlib import contextmanager
7 import os, subprocess, exceptions
10 from optparse import OptionParser
11 from shutil import copy
15 # These variables can be overridden by options. If packages is not
16 # set, then it is read from the rpm_packages file
17 packages = [] # Set of packages to build
20 class CommandError(exceptions.StandardError):
23 # Centos 6.5 does not have collections.OrderedDict
24 # This implementation provides the minimal functionality of OrderedDict that we need
25 # It works here, but should not be counted on for anything else.
26 class OrderedDict(dict):
28 def __setitem__(self,k, v):
30 self.keylist.append(k)
31 return super(OrderedDict,self).__setitem__(k,v)
33 def __init__(self, *args, **kwargs):
34 super(OrderedDict,self).__init__(*args, **kwargs)
38 return map( lambda(elt): self[elt], self.keylist)
41 '.tar.gz': lambda(t): run_cmd([ 'rpmbuild', '-ta', t]),
43 lambda(s): run_cmd(['rpmbuild', '--define', '_sourcedir '+os.getcwd(),
49 match = re.match('^.*(\\.tar\\.gz|\\.spec)$', name)
55 # The following regexp is not quite right.
56 # One place is the rpm_packages file.
57 # The other is the directory listing.
58 # The rpm_packages file might have entries like shibboleth/xmltooling
59 # Where as the distributions directory might have xmltooling-1.5.tar.gz
60 # Two requirements for correct operation:
61 # trim_target produces unique results for everything in rpm_packages
62 # trim_target correctly trims what's in the packages file to the same
63 # thing it trims the tar file or spec file to.
66 match = re.match('([^/-]*/)?([^-/]+)', t)
67 if match is None: return ""
72 def current_directory(dir):
73 "Change the current directory as a context manager; when the context exits, return."
80 def run_cmd(args, **kwords):
81 rcode = subprocess.call( args, **kwords)
83 raise CommandError(args)
85 def command_output(args) :
86 p = subprocess.Popen(args, stdout=subprocess.PIPE)
87 output = p.communicate()
90 raise CommandError(args)
94 return builder_by_type[find_type(package)](package)
99 '''Read in the packages file from rpm_packages
101 try: pf = file("rpm_packages")
103 print "Error: rpm_packages file not found"
105 def is_comment(line):
106 if re.match("^\\s*#", line): return False
107 if "#" in line: raise ValueError(
108 "Source package line contains a comment but not at beginning")
110 return map(lambda(x): x.rstrip(),
111 filter(is_comment, pf.readlines()))
116 opt.usage = "%prog [options] distributions_dir [packages]"
117 opt.add_option('--tar-file',
119 help = 'Tar up resulting packages in given tar file',
121 (options, args) = opt.parse_args()
122 tar_file = options.tar_file
123 if tar_file is not None:
124 tar_file = os.path.join(os.getcwd(), tar_file)
126 print "Distributions directory required"
130 if len(packages) == 0: packages = read_packages()
131 package_order = OrderedDict()
133 package_order[trim_target(t)] = None
135 for t in os.listdir(dist_dir):
136 target_type = find_type(t)
137 if target_type is None: continue
138 trimmed = trim_target(t)
139 if target_type == ".spec":
140 package_order[trimmed] = t
142 # Replace None but nothing else
143 if not package_order.get(trimmed): package_order[trimmed] = t
150 run_cmd([ 'rm', '-rf',
151 os.path.expanduser("~/rpmbuild")])
152 run_cmd([ 'rpmdev-setuptree'])
153 for f in os.listdir("rpm-sources"):
154 copy("rpm-sources/" + f, dist_dir)
156 with current_directory(dist_dir):
157 for t in package_order.values():
158 if t is None: continue
160 if tar_file is not None:
161 with current_directory(os.path.expanduser("~/rpmbuild")):
162 run_cmd(['tar', '-cf', tar_file,
163 './RPMS', './SRPMS'])
165 except CommandError as c:
166 print "Error:" + str(c.args)