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)
71 def current_directory(dir):
72 "Change the current directory as a context manager; when the context exits, return."
79 def run_cmd(args, **kwords):
80 rcode = subprocess.call( args, **kwords)
82 raise CommandError(args)
84 def command_output(args) :
85 p = subprocess.Popen(args, stdout=subprocess.PIPE)
86 output = p.communicate()
89 raise CommandError(args)
93 return builder_by_type[find_type(package)](package)
98 '''Read in the packages file from rpm_packages
100 try: pf = file("rpm_packages")
102 print "Error: rpm_packages file not found"
104 def is_comment(line):
105 if re.match("^\\s*#", line): return False
106 if "#" in line: raise ValueError(
107 "Source package line contains a comment but not at beginning")
109 return map(lambda(x): x.rstrip(),
110 filter(is_comment, pf.readlines()))
115 opt.usage = "%prog [options] distributions_dir [packages]"
116 opt.add_option('--tar-file',
118 help = 'Tar up resulting packages in given tar file',
120 (options, args) = opt.parse_args()
121 tar_file = options.tar_file
122 if tar_file is not None:
123 tar_file = os.path.join(os.getcwd(), tar_file)
125 print "Distributions directory required"
129 if len(packages) == 0: packages = read_packages()
130 package_order = OrderedDict()
132 package_order[trim_target(t)] = None
134 for t in os.listdir(dist_dir):
135 target_type = find_type(t)
136 if target_type is None: continue
137 trimmed = trim_target(t)
138 if target_type == ".spec":
139 package_order[trimmed] = t
141 if trimmed not in package_order: package_order[trimmed] = t
148 run_cmd([ 'rm', '-rf',
149 os.path.expanduser("~/rpmbuild")])
150 run_cmd([ 'rpmdev-setuptree'])
151 for f in os.listdir("rpm-sources"):
152 copy("rpm-sources/" + f, dist_dir)
154 with current_directory(dist_dir):
155 for t in package_order.values():
156 if t is None: continue
158 if tar_file is not None:
159 with current_directory(os.path.expanduser("~/rpmbuild")):
160 run_cmd(['tar', '-cf', tar_file,
161 './RPMS', './SRPMS'])
163 except CommandError as c:
164 print "Error:" + str(c.args)