import os, subprocess, exceptions
import re
import sys
+import string
from optparse import OptionParser
from shutil import copy
# These variables can be overridden by options. If packages is not
# set, then it is read from the rpm_packages file
packages = [] # Set of packages to build
+tar_file = None
class CommandError(exceptions.StandardError):
pass
-def is_tarball(name):
- return re.match('^.*\\.tar\\.gz', name)
-
-def trim_tarball(t):
- match = re.match('([^/-]*/)?([^-/]+)', t)
- return match.group(2)
+# Centos 6.5 does not have collections.OrderedDict
+# This implementation provides the minimal functionality of OrderedDict that we need
+# It works here, but should not be counted on for anything else.
+class OrderedDict(dict):
+
+ def __setitem__(self,k, v):
+ if k not in self:
+ self.keylist.append(k)
+ return super(OrderedDict,self).__setitem__(k,v)
+
+ def __init__(self, *args, **kwargs):
+ super(OrderedDict,self).__init__(*args, **kwargs)
+ self.keylist = []
+
+ def values(self):
+ return map( lambda(elt): self[elt], self.keylist)
+
+ def iteritems(self):
+ for k in self.keylist:
+ yield (k, self[k])
+
+builder_by_type = {
+ '.tar.gz': lambda(t): run_cmd([ 'rpmbuild', '-ta', t]),
+ '.tar.bz2': lambda(t): run_cmd([ 'rpmbuild', '-ta', t]),
+ '.spec':
+ lambda(s): run_cmd(['rpmbuild', '--define', '_sourcedir '+os.getcwd(),
+ '-ba', s]),
+ }
+
+
+def find_type(name):
+ match = re.match('^.*(\\.tar\\.gz|\\.tar\\.bz2|\\.spec)$', name)
+ if match:
+ return match.group(1)
+ else: return None
+
+
+# The following regexp is not quite right.
+# One place is the rpm_packages file.
+# The other is the directory listing.
+# The rpm_packages file might have entries like shibboleth/xmltooling
+# Where as the distributions directory might have xmltooling-1.5.tar.gz
+# Two requirements for correct operation:
+# trim_target produces unique results for everything in rpm_packages
+# trim_target correctly trims what's in the packages file to the same
+# thing it trims the tar file or spec file to.
+#
+def trim_target(t):
+ # first lose any suffix (like -1.5.tar.gz)
+ name_parts=t.split('-')
+ if name_parts[-1][0] in string.digits:
+ name_parts=name_parts[:-1]
+ name="-".join(name_parts) # in case it had dash-separated parts
+ name="-".join(name.split("/")) # replace / with -
+ return name
+
@contextmanager
def current_directory(dir):
"Change the current directory as a context manager; when the context exits, return."
return output.strip()
def build(package):
- run_cmd(['rpmbuild', '-ta', package])
+ return builder_by_type[find_type(package)](package)
# main program
opt = OptionParser()
opt.usage = "%prog [options] distributions_dir [packages]"
+opt.add_option('--tar-file',
+ dest='tar_file',
+ help = 'Tar up resulting packages in given tar file',
+ default = None)
(options, args) = opt.parse_args()
+tar_file = options.tar_file
+if tar_file is not None:
+ tar_file = os.path.join(os.getcwd(), tar_file)
if len(args) == 0:
print "Distributions directory required"
exit(1)
dist_dir = args[0]
packages = args[1:]
-
if len(packages) == 0: packages = read_packages()
-package_order = {}
-count = 0
-tarballs = filter(is_tarball, os.listdir(dist_dir))
+package_order = OrderedDict()
for t in packages:
- package_order[trim_tarball(t)] = count
- count += 1
-
+ package_order[trim_target(t)] = None
+
+for t in os.listdir(dist_dir):
+ target_type = find_type(t)
+ if target_type is None: continue
+ trimmed = trim_target(t)
+ if target_type == ".spec":
+ package_order[trimmed] = t
+ else:
+ # Replace None but nothing else
+ if not package_order.get(trimmed): package_order[trimmed] = t
os.umask(022)
try:
+ run_cmd([ 'rm', '-rf',
+ os.path.expanduser("~/rpmbuild")])
+ run_cmd([ 'rpmdev-setuptree'])
+ for f in os.listdir("rpm-sources"):
+ copy("rpm-sources/" + f, dist_dir)
+
with current_directory(dist_dir):
- tarballs.sort (key = lambda x: package_order[trim_tarball(x)])
- for t in tarballs:
+ for t in package_order.values():
+ if t is None: continue
build(t)
+ if tar_file is not None:
+ with current_directory(os.path.expanduser("~/rpmbuild")):
+ run_cmd(['tar', '-cf', tar_file,
+ './RPMS', './SRPMS'])
+
except CommandError as c:
print "Error:" + str(c.args)
exit(1)