3 '''A script to buildMoonshot potentially using a schroot for install testing.
6 from contextlib import contextmanager
7 import os, subprocess, exceptions
11 from optparse import OptionParser
12 from shutil import copy
16 # These variables can be overridden by options. If packages is not
17 # set, then it is read from the rpm_packages file
18 packages = [] # Set of packages to build
21 class CommandError(exceptions.StandardError):
24 # Centos 6.5 does not have collections.OrderedDict
25 # This implementation provides the minimal functionality of OrderedDict that we need
26 # It works here, but should not be counted on for anything else.
27 class OrderedDict(dict):
29 def __setitem__(self,k, v):
31 self.keylist.append(k)
32 return super(OrderedDict,self).__setitem__(k,v)
34 def __init__(self, *args, **kwargs):
35 super(OrderedDict,self).__init__(*args, **kwargs)
39 return map( lambda(elt): self[elt], self.keylist)
42 for k in self.keylist:
46 '.tar.gz': lambda(t): run_cmd([ 'rpmbuild', '-ta', t]),
47 '.tar.bz2': lambda(t): run_cmd([ 'rpmbuild', '-ta', t]),
49 lambda(s): run_cmd(['rpmbuild', '--define', '_sourcedir '+os.getcwd(),
55 match = re.match('^.*(\\.tar\\.gz|\\.tar\\.bz2|\\.spec)$', name)
61 # The following regexp is not quite right.
62 # One place is the rpm_packages file.
63 # The other is the directory listing.
64 # The rpm_packages file might have entries like shibboleth/xmltooling
65 # Where as the distributions directory might have xmltooling-1.5.tar.gz
66 # Two requirements for correct operation:
67 # trim_target produces unique results for everything in rpm_packages
68 # trim_target correctly trims what's in the packages file to the same
69 # thing it trims the tar file or spec file to.
72 # first lose any suffix (like -1.5.tar.gz)
73 name_parts=t.split('-')
74 if name_parts[-1][0] in string.digits:
75 name_parts=name_parts[:-1]
76 name="-".join(name_parts) # in case it had dash-separated parts
77 name="-".join(name.split("/")) # replace / with -
82 def current_directory(dir):
83 "Change the current directory as a context manager; when the context exits, return."
90 def run_cmd(args, **kwords):
91 rcode = subprocess.call( args, **kwords)
93 raise CommandError(args)
95 def command_output(args) :
96 p = subprocess.Popen(args, stdout=subprocess.PIPE)
97 output = p.communicate()
100 raise CommandError(args)
101 return output.strip()
104 return builder_by_type[find_type(package)](package)
109 '''Read in the packages file from rpm_packages
111 try: pf = file("rpm_packages")
113 print "Error: rpm_packages file not found"
115 def is_comment(line):
116 if re.match("^\\s*#", line): return False
117 if "#" in line: raise ValueError(
118 "Source package line contains a comment but not at beginning")
120 return map(lambda(x): x.rstrip(),
121 filter(is_comment, pf.readlines()))
126 opt.usage = "%prog [options] distributions_dir [packages]"
127 opt.add_option('--tar-file',
129 help = 'Tar up resulting packages in given tar file',
131 (options, args) = opt.parse_args()
132 tar_file = options.tar_file
133 if tar_file is not None:
134 tar_file = os.path.join(os.getcwd(), tar_file)
136 print "Distributions directory required"
140 if len(packages) == 0: packages = read_packages()
141 package_order = OrderedDict()
143 package_order[trim_target(t)] = None
145 for t in os.listdir(dist_dir):
146 target_type = find_type(t)
147 if target_type is None: continue
148 trimmed = trim_target(t)
149 if target_type == ".spec":
150 package_order[trimmed] = t
152 # Replace None but nothing else
153 if not package_order.get(trimmed): package_order[trimmed] = t
158 run_cmd([ 'rm', '-rf',
159 os.path.expanduser("~/rpmbuild")])
160 run_cmd([ 'rpmdev-setuptree'])
161 for f in os.listdir("rpm-sources"):
162 copy("rpm-sources/" + f, dist_dir)
164 with current_directory(dist_dir):
165 for t in package_order.values():
166 if t is None: continue
168 if tar_file is not None:
169 with current_directory(os.path.expanduser("~/rpmbuild")):
170 run_cmd(['tar', '-cf', tar_file,
171 './RPMS', './SRPMS'])
173 except CommandError as c:
174 print "Error:" + str(c.args)