| 1 | #!/usr/bin/env python |
|---|
| 2 | |
|---|
| 3 | import glob |
|---|
| 4 | import logging |
|---|
| 5 | import os |
|---|
| 6 | import re |
|---|
| 7 | import shutil |
|---|
| 8 | try: |
|---|
| 9 | import subprocess |
|---|
| 10 | except ImportError: |
|---|
| 11 | from fake_subprocess import subprocess |
|---|
| 12 | import sys |
|---|
| 13 | |
|---|
| 14 | redhat_latest_version = 6 |
|---|
| 15 | fedora_latest_version = 14 |
|---|
| 16 | |
|---|
| 17 | script = sys.argv[0] |
|---|
| 18 | script = os.path.abspath(script) |
|---|
| 19 | src_dir = os.path.dirname(script) |
|---|
| 20 | os.chdir(src_dir) |
|---|
| 21 | |
|---|
| 22 | logging.getLogger().setLevel(logging.INFO) |
|---|
| 23 | log_dir = os.path.join(src_dir, "logs") |
|---|
| 24 | rpm_dir = os.path.join(src_dir, "rpms") |
|---|
| 25 | srpm_dir = os.path.join(src_dir, "srpms") |
|---|
| 26 | tmp_dir = os.path.join(src_dir, "tmp") |
|---|
| 27 | rpmbuild_dir = os.path.join(os.getenv("HOME"), "rpmbuild") |
|---|
| 28 | |
|---|
| 29 | distro_order = [] |
|---|
| 30 | distro_download_urls = {} |
|---|
| 31 | fedora_version = None |
|---|
| 32 | if os.path.exists('/etc/redhat-release') and not os.path.exists('/etc/fedora-release'): |
|---|
| 33 | version = open('/etc/redhat-release').read().split(" ")[2] |
|---|
| 34 | if version == "Enterprise": # Naming standard changed in RHEL 6 |
|---|
| 35 | version = open('/etc/redhat-release').read().split(" ")[6] |
|---|
| 36 | if "." in version: |
|---|
| 37 | version = version.split(".")[0] |
|---|
| 38 | version = int(version) |
|---|
| 39 | if version > redhat_latest_version: |
|---|
| 40 | logging.error("Version of RedHat is %d, which is greater than latest supported version %d" % (version ,redhat_latest_version)) |
|---|
| 41 | sys.exit(1) |
|---|
| 42 | distro_order = [str(v) for v in range(version, redhat_latest_version+1)] |
|---|
| 43 | download_urls = ["ftp://ftp.is.co.za/mirror/centos/$distro_version/os/SRPMS/"] |
|---|
| 44 | for d in distro_order: |
|---|
| 45 | distro_download_urls[d] = download_urls |
|---|
| 46 | if version < 6: |
|---|
| 47 | fedora_version = 6 |
|---|
| 48 | else: |
|---|
| 49 | fedora_version = 14 |
|---|
| 50 | elif os.path.exists('/etc/fedora-release'): |
|---|
| 51 | version = open('/etc/fedora-release').read().split(" ") |
|---|
| 52 | for part in version: |
|---|
| 53 | if "." in part: |
|---|
| 54 | part = part.split(".")[0] |
|---|
| 55 | if part.isdigit(): |
|---|
| 56 | version = int(part) |
|---|
| 57 | break |
|---|
| 58 | if not isinstance(version, int): |
|---|
| 59 | raise RuntimeError("Could not extract version from release %r" % version) |
|---|
| 60 | fedora_version = version |
|---|
| 61 | if fedora_version: |
|---|
| 62 | if fedora_version > fedora_latest_version: |
|---|
| 63 | logging.error("Version of Fedora is %d, which is greater than latest supported version %d" % (fedora_version ,fedora_latest_version)) |
|---|
| 64 | sys.exit(1) |
|---|
| 65 | f_distro_order = [str(v) for v in range(fedora_version, fedora_latest_version+1)] |
|---|
| 66 | distro_order.extend(f_distro_order) |
|---|
| 67 | for d in f_distro_order: |
|---|
| 68 | if int(d) >= 12: |
|---|
| 69 | distro_download_urls[d] = ["ftp://mirrors.kernel.org/fedora/releases/$distro_version/Everything/source/SRPMS/", |
|---|
| 70 | "ftp://mirrors.kernel.org/fedora/updates/$distro_version/SRPMS/", |
|---|
| 71 | "ftp://mirrors.kernel.org/fedora/updates/$distro_version/SRPMS.newkey/"] |
|---|
| 72 | else: |
|---|
| 73 | distro_download_urls[d] = ["ftp://archive.kernel.org/fedora-archive/fedora/linux/releases/$distro_version/Everything/source/SRPMS", |
|---|
| 74 | "ftp://archive.kernel.org/fedora-archive/fedora/linux/updates/$distro_version/SRPMS/", |
|---|
| 75 | "ftp://archive.kernel.org/fedora-archive/fedora/linux/updates/$distro_version/SRPMS.newkey/"] |
|---|
| 76 | |
|---|
| 77 | packages = sys.argv[1:] |
|---|
| 78 | if not packages: |
|---|
| 79 | packages = [line.strip() for line in open(os.path.join(src_dir, "requirements-srpm"), "r").readlines() if line.strip()] |
|---|
| 80 | |
|---|
| 81 | def ensure_dir(dirname): |
|---|
| 82 | if not os.path.exists(dirname): |
|---|
| 83 | os.mkdir(dirname) |
|---|
| 84 | |
|---|
| 85 | ensure_dir(srpm_dir) |
|---|
| 86 | ensure_dir(rpm_dir) |
|---|
| 87 | ensure_dir(log_dir) |
|---|
| 88 | |
|---|
| 89 | os.chdir(srpm_dir) |
|---|
| 90 | if sys.version_info[0] == 2 and sys.version_info[1] < 5: |
|---|
| 91 | if os.path.exists('/etc/redhat-release') and not os.path.exists('/etc/fedora-release'): |
|---|
| 92 | quote_defines = version < 5 |
|---|
| 93 | else: |
|---|
| 94 | quote_defines = False |
|---|
| 95 | no_name_change = False |
|---|
| 96 | try_install = False |
|---|
| 97 | replace_python = True |
|---|
| 98 | python_exe = subprocess.Popen(["which", "python"+os.environ["PYTHON_SUFFIX"]], stdout=subprocess.PIPE).communicate()[0].replace("\n","") |
|---|
| 99 | if quote_defines: |
|---|
| 100 | rpmdefines = ["--define",'"__python %s"' % (python_exe)] |
|---|
| 101 | else: |
|---|
| 102 | rpmdefines = ["--define",'__python %s' % (python_exe)] |
|---|
| 103 | python_version = os.environ["PYTHON_VERSION"] |
|---|
| 104 | else: |
|---|
| 105 | no_name_change = True |
|---|
| 106 | try_install = True |
|---|
| 107 | replace_python = False |
|---|
| 108 | python_exe = subprocess.Popen(["which", "python"], stdout=subprocess.PIPE).communicate()[0].replace("\n","") |
|---|
| 109 | rpmdefines = [] |
|---|
| 110 | python_version = "%d.%d" % (sys.version_info[0], sys.version_info[1]) |
|---|
| 111 | quote_defines = False |
|---|
| 112 | |
|---|
| 113 | # If this is CentOS < 5 or equivalent, blas-devel=blas, lapack-devel=lapack and gcc-gfortran=gcc4-gfortran |
|---|
| 114 | old_fortran = version < 5 |
|---|
| 115 | # If this is < Fedora 8, python-setuptools-devel = python-setuptools |
|---|
| 116 | old_python_setuptools = version < 8 |
|---|
| 117 | old_x11 = version < 5 |
|---|
| 118 | python_suffix = os.environ.get("PYTHON_SUFFIX","") |
|---|
| 119 | python_suffix2 = os.environ.get("PYTHON_SUFFIX2","") |
|---|
| 120 | |
|---|
| 121 | REQUIREMENT_PARSER = re.compile("([^<=>]*)([<=>]+.*)?") |
|---|
| 122 | |
|---|
| 123 | def fix_package_name(package_name, force_version_marker=False): |
|---|
| 124 | """Fixes the package name to refer to python $PYTHON_SUFFIX - if the force_version_marker argument is True, $PYTHON_SUFFIX2 will be appended if no other method is found""" |
|---|
| 125 | # Replace the word python, but not python followed by a variable, as we don't know the purpose of the variable |
|---|
| 126 | if package_name == "Distutils": |
|---|
| 127 | return None |
|---|
| 128 | elif no_name_change: |
|---|
| 129 | return package_name |
|---|
| 130 | elif package_name == "tkinter": |
|---|
| 131 | return "tkinter"+python_suffix |
|---|
| 132 | elif re.match(r".*\bpython\b[^%]", package_name) or package_name.endswith("python"): |
|---|
| 133 | return re.sub(r"\bpython\b","python"+python_suffix,package_name) |
|---|
| 134 | elif re.match(r".*\bpython2\b[^%]", package_name) or package_name.endswith("python2"): |
|---|
| 135 | return re.sub(r"\bpython2\b","python"+python_suffix,package_name) |
|---|
| 136 | elif package_name.endswith("py"): |
|---|
| 137 | return package_name + python_suffix |
|---|
| 138 | elif package_name in ["protobuf", "cairo"]: |
|---|
| 139 | # we'll manually change the protobuf-python package, but not the rest |
|---|
| 140 | return package_name |
|---|
| 141 | elif old_x11 and re.match(r".*\blibX(11|render)-devel\b", package_name): |
|---|
| 142 | return re.sub(r"\blibX(11|render)-devel\b","xorg-x11-devel",package_name) |
|---|
| 143 | elif package_name.startswith("py"): |
|---|
| 144 | if package_name.endswith("-devel"): |
|---|
| 145 | return package_name.replace("-devel",python_suffix2+"-devel") |
|---|
| 146 | if package_name.endswith("-doc"): |
|---|
| 147 | return package_name.replace("-doc",python_suffix2+"-doc") |
|---|
| 148 | if package_name.endswith("-codegen"): |
|---|
| 149 | return package_name.replace("-codegen",python_suffix2+"-codegen") |
|---|
| 150 | return package_name + python_suffix2 |
|---|
| 151 | elif force_version_marker: |
|---|
| 152 | return package_name + python_suffix2 |
|---|
| 153 | return package_name |
|---|
| 154 | |
|---|
| 155 | not_found_packages = [] |
|---|
| 156 | failed_builds = [] |
|---|
| 157 | |
|---|
| 158 | for p in packages: |
|---|
| 159 | min_p_version = None |
|---|
| 160 | min_package_version = 0 |
|---|
| 161 | if ">=" in p: |
|---|
| 162 | p, min_p_version = p.split(">=") |
|---|
| 163 | min_p_version = min_p_version.strip() |
|---|
| 164 | if "-" in min_p_version: |
|---|
| 165 | min_p_version, min_package_version = min_p_version.split("-") |
|---|
| 166 | min_package_version = int(min_package_version) |
|---|
| 167 | min_p_version = [int(m) for m in min_p_version.split(".")] |
|---|
| 168 | p = p.strip() |
|---|
| 169 | new_p = fix_package_name(p, True) |
|---|
| 170 | existing_packages = glob.glob("../rpms/%s-*.rpm" % new_p) |
|---|
| 171 | if existing_packages: |
|---|
| 172 | logging.info("Not building %s because of existing packages %r" % (p, existing_packages)) |
|---|
| 173 | continue |
|---|
| 174 | logfile = open(os.path.join(log_dir, "%s-fetch-srpm.log" % (p,)), "w") |
|---|
| 175 | if try_install: |
|---|
| 176 | if subprocess.Popen(["yum","info",p], stdout=subprocess.PIPE).communicate()[0] != "": |
|---|
| 177 | subprocess.call(["yum","install","-y",p], stdout=logfile, stderr=logfile) |
|---|
| 178 | continue |
|---|
| 179 | # Check for existence of a built package |
|---|
| 180 | for distro_version in distro_order: |
|---|
| 181 | print ("downloading %s from %s" % (p, distro_version)) |
|---|
| 182 | # TODO: use yumdownloader to get mirroring etc - turns out to be tricky |
|---|
| 183 | # yumdownloader -c yum/yum-fedora-$distro_version.conf --source -e fedora-source --destdir=$HOME/Packaging/centuryegg/srpms $p |
|---|
| 184 | for parent_url in distro_download_urls[distro_version]: |
|---|
| 185 | url = "%s/%s-*.src.rpm" % (parent_url.replace("$distro_version", distro_version), p) |
|---|
| 186 | print ("trying %s" % (url,)) |
|---|
| 187 | subprocess.call(["wget", "-c", url], stdout=logfile, stderr=logfile) |
|---|
| 188 | srpms = glob.glob("%s*.src.rpm" % (p,)) |
|---|
| 189 | for s in srpms[:]: |
|---|
| 190 | if "*" in s: |
|---|
| 191 | srpms.remove(s) |
|---|
| 192 | elif not re.match("^%s-[0-9]" % p, s): |
|---|
| 193 | srpms.remove(s) |
|---|
| 194 | elif min_p_version: |
|---|
| 195 | s_version = s.replace(p,"") |
|---|
| 196 | s_package_version = s_version.split("-")[2].split(".")[0] |
|---|
| 197 | s_version = s_version.split("-")[1] |
|---|
| 198 | sd_version = [] |
|---|
| 199 | for sd_p in re.split("[^0-9]",s_version): |
|---|
| 200 | if sd_p.isdigit(): |
|---|
| 201 | sd_version.append(int(sd_p)) |
|---|
| 202 | s_version = sd_version |
|---|
| 203 | for n, v in enumerate(min_p_version): |
|---|
| 204 | if n > len(s_version): |
|---|
| 205 | srpms.remove(s) |
|---|
| 206 | break |
|---|
| 207 | elif v > s_version[n]: |
|---|
| 208 | srpms.remove(s) |
|---|
| 209 | break |
|---|
| 210 | elif v == s_version[n] and min_package_version > int(s_package_version): |
|---|
| 211 | srpms.remove(s) |
|---|
| 212 | break |
|---|
| 213 | elif v < s_version[n]: |
|---|
| 214 | break |
|---|
| 215 | if srpms: |
|---|
| 216 | break |
|---|
| 217 | src_rpm_files = srpms |
|---|
| 218 | src_rpm_files.sort() |
|---|
| 219 | if not src_rpm_files: |
|---|
| 220 | print ("could not find source rpm for %s" % (p,)) |
|---|
| 221 | not_found_packages.append(p) |
|---|
| 222 | continue |
|---|
| 223 | src_rpm = src_rpm_files[-1] |
|---|
| 224 | subprocess.call(["rpm", "-ivh", "--nomd5", src_rpm]) |
|---|
| 225 | specfile_name = os.path.join(rpmbuild_dir, "SPECS", "%s.spec" % (p,)) |
|---|
| 226 | if not os.path.exists(specfile_name): |
|---|
| 227 | # Try strip version number off |
|---|
| 228 | specfile_name = os.path.join(rpmbuild_dir, "SPECS", "%s.spec" % (p[:-1],)) |
|---|
| 229 | new_specfile_name = "%s.spec" % (new_p,) |
|---|
| 230 | lines = open(specfile_name, "r").readlines() |
|---|
| 231 | specfile = open(new_specfile_name, "w") |
|---|
| 232 | requirements = "" |
|---|
| 233 | package_name = "" |
|---|
| 234 | defines = {} |
|---|
| 235 | if p == "python-sqlalchemy" and version <= 4: |
|---|
| 236 | # In RedHat 4, strip off the first 8 lines - boolean logic old rpmtools can't handle |
|---|
| 237 | lines = [lines[1]] + lines[8:] |
|---|
| 238 | for line in lines: |
|---|
| 239 | if line.startswith("%define"): |
|---|
| 240 | key, value = line.replace("%define", "", 1).strip().split(" ", 1) |
|---|
| 241 | defines[key] = value |
|---|
| 242 | if line.startswith("%setup"): |
|---|
| 243 | if "-n" not in line: |
|---|
| 244 | line = line.rstrip("\n") + " -n %{name}-%{version}\n" |
|---|
| 245 | if replace_python and "python " in line and "with_python" not in line: |
|---|
| 246 | line = line.replace("/usr/bin/python ","%{__python} ").replace("python ", "%{__python} ") |
|---|
| 247 | line_parts = line.split() |
|---|
| 248 | if "install" in line_parts: |
|---|
| 249 | if not "-O1" in line_parts: |
|---|
| 250 | line = line.replace("install", "install -O1", 1) |
|---|
| 251 | if ">=" in line_parts: |
|---|
| 252 | line = " ".join(line_parts[:line_parts.index(">=")]) |
|---|
| 253 | if replace_python and "python -c " in line: |
|---|
| 254 | line = line.replace("python -c ", "%{__python} -c ") |
|---|
| 255 | # HACK for python-imaging and numpy - we always use setuptools, as sure as eggs is eggs: |
|---|
| 256 | if line.startswith("%if") and "%{?fedora}" in line and ">=" in line: |
|---|
| 257 | line = '%if "eggs" == "eggs"\n' |
|---|
| 258 | if replace_python and re.compile("^%(package|description|files).*").match(line) and "python" in line: |
|---|
| 259 | line = re.sub(r"\bpython\b", "python"+python_suffix, line) |
|---|
| 260 | if re.compile("^(Name|Provides|Requires|BuildRequires|BuildPre).*").match(line): |
|---|
| 261 | if line.startswith("Name:"): |
|---|
| 262 | package_name = line.replace("Name:", "", 1).strip() |
|---|
| 263 | new_package_name = fix_package_name(package_name, True) |
|---|
| 264 | if package_name != new_package_name: |
|---|
| 265 | line = line.replace(package_name, new_package_name) |
|---|
| 266 | line += "\n%%define name %s\n" % (package_name,) |
|---|
| 267 | elif line.startswith("Require") and "python-abi" in line: |
|---|
| 268 | # We take care of abi considerations, and this just confuses things |
|---|
| 269 | continue |
|---|
| 270 | elif replace_python and line.startswith("Build") and "pygtk2" in line: |
|---|
| 271 | # We don't compile with pygtk2 or tk support when replacing python - it conflicts too complicatedly |
|---|
| 272 | continue |
|---|
| 273 | else: |
|---|
| 274 | new_words = [] |
|---|
| 275 | for word in line.split(): |
|---|
| 276 | if word.endswith(","): |
|---|
| 277 | new_word = fix_package_name(word[:-1]) |
|---|
| 278 | if new_word: |
|---|
| 279 | new_word += "," |
|---|
| 280 | else: |
|---|
| 281 | new_word = fix_package_name(word) |
|---|
| 282 | if new_word: |
|---|
| 283 | new_words.append(new_word) |
|---|
| 284 | line = " ".join(new_words) + "\n" |
|---|
| 285 | if line.startswith("Build"): |
|---|
| 286 | if old_fortran: |
|---|
| 287 | line = line.replace("lapack-devel","lapack").replace("blas-devel","blas").replace("gcc-gfortran","gcc4-gfortran") |
|---|
| 288 | if old_python_setuptools: |
|---|
| 289 | line = line.replace("setuptools-devel","setuptools") |
|---|
| 290 | requirements += " " + line[line.find(":")+1:] |
|---|
| 291 | elif line.startswith("Require"): |
|---|
| 292 | line = line.replace("%{name}", new_package_name) |
|---|
| 293 | # monkey-patch, we should have better ways for this |
|---|
| 294 | if line.startswith("%build") and package_name in ["pygtk2","pycairo", "pygobject2"]: |
|---|
| 295 | line += "export PYTHON=%{__python}\n" |
|---|
| 296 | if package_name == "python-matplotlib" and line.startswith(r"%{__python} setup.py build"): |
|---|
| 297 | specfile.write("sed -i -e 's/gtk = True/gtk = False/' -e 's/tkagg = True/tkagg = False/' -e 's/GTKAgg/Agg/' setup.cfg\n") |
|---|
| 298 | if line.startswith("%build") and package_name == "python-ldap": |
|---|
| 299 | specfile.write('sed -ie "/OPT_X_TLS_CRL\(CHECK\|_NONE\|_PEER\|_ALL\)/d" Modules/constants.c\n') |
|---|
| 300 | if line.startswith("%{python_sitelib}") and package_name == "pyparsing" and line.rstrip().endswith(".py"): |
|---|
| 301 | specfile.write("%%{python_sitelib}/%s-*-py%s.egg-info\n" % (package_name, python_version)) |
|---|
| 302 | if line.startswith("%{python_sitelib}") and package_name in ["pytz", "python-dateutil"]: |
|---|
| 303 | specfile.write("%%{python_sitelib}/%s-*-py%s.egg-info\n" % (package_name.replace("-","_"), python_version)) |
|---|
| 304 | if line.startswith("%{python_sitearch}") and package_name == "numpy": |
|---|
| 305 | specfile.write("%%{python_sitearch}/numpy-*-py%s.egg-info\n" % python_version) |
|---|
| 306 | if line.startswith("%{python_sitearch}") and package_name == "python-numarray": |
|---|
| 307 | specfile.write("%%{python_sitearch}/numarray-*-py%s.egg-info\n" % python_version) |
|---|
| 308 | if line.startswith('%if "%{fedora}" > "8"') and package_name == "python-xlrd": |
|---|
| 309 | # This is checking setuptools version, but we're using a modern one |
|---|
| 310 | line = line.replace("%{fedora}","9") |
|---|
| 311 | if line.startswith("%{python_sitearch}") and package_name == "python-imaging" and (line.rstrip().endswith(".py") or line.rstrip().endswith(".py*")): |
|---|
| 312 | specfile.write("%%{python_sitearch}/PIL/PIL-*-py%s.egg-info\n" % python_version) |
|---|
| 313 | # Redhat 5 and below version of python-imaging don't include this file |
|---|
| 314 | # FIXME: We should automatically get the retrieved package version to do this (the relevant version change is 1.1.5 -> 1.1.6) |
|---|
| 315 | if version > 5: |
|---|
| 316 | specfile.write("%%{python_sitearch}/pysane-*-py%s.egg-info\n" % python_version) |
|---|
| 317 | if "_tkagg.so" in line and package_name == "python-matplotlib": |
|---|
| 318 | if line.startswith("%exclude"): |
|---|
| 319 | specfile.write("%%{python_sitearch}/matplotlib-*-py%s.egg-info\n" % python_version) |
|---|
| 320 | continue |
|---|
| 321 | if "_xmlplus" in line and package_name == "PyXML" and version > 4: |
|---|
| 322 | specfile.write("%%{_libdir}/python%%pyver/site-packages/%s-*-py%s.egg-info\n" % (package_name, python_version)) |
|---|
| 323 | if "_bindir" in line and package_name == "PyXML": |
|---|
| 324 | line = "%exclude "+line |
|---|
| 325 | if line.startswith("%{python_sitearch}") and package_name == "python-crypto" and (line.rstrip().endswith(".py") or line.rstrip().endswith("Crypto/*.py*")): |
|---|
| 326 | specfile.write("%%{python_sitearch}/pycrypto-*-py%s.egg-info\n" % python_version) |
|---|
| 327 | if package_name == "python-nose" and "nosetests-2.6" in line: |
|---|
| 328 | line = line.replace("2.6",os.environ["MIN_PYTHON_VERSION"]) |
|---|
| 329 | if "with_python3 1" in line: |
|---|
| 330 | line = line.replace("with_python3 1","with_python3 0") |
|---|
| 331 | if package_name == "pyparsing" and line.startswith("%{python3_sitelib}"): |
|---|
| 332 | continue |
|---|
| 333 | if package_name == "python-sqlite2" and line.startswith("%dir %{python_sitearch}"): |
|---|
| 334 | specfile.write("%%{python_sitearch}/pysqlite-*-py%s.egg-info\n" % python_version) |
|---|
| 335 | if package_name == "protobuf" and "py2.5" in line: |
|---|
| 336 | line = line.replace("py2.5", "py%s" % python_version) |
|---|
| 337 | if version <= 4 and package_name == "python-sqlalchemy" and "filter_setup" in line or "filter_provides" in line: |
|---|
| 338 | continue |
|---|
| 339 | specfile.write(line) |
|---|
| 340 | specfile.close() |
|---|
| 341 | log_filename = os.path.join(log_dir, "%s-build-srpm.log" % (p,)) |
|---|
| 342 | logfile = open(log_filename, "w") |
|---|
| 343 | if requirements.strip(): |
|---|
| 344 | # TODO: split the requirements up, without splitting version requirements |
|---|
| 345 | requirements = requirements.replace(",", " ") |
|---|
| 346 | requirement_parts = [part for part in requirements.split() if part] |
|---|
| 347 | requirements = [] |
|---|
| 348 | for part in requirement_parts: |
|---|
| 349 | if part[:1].isalpha(): |
|---|
| 350 | requirements.append(" ") |
|---|
| 351 | if "%{" in part: |
|---|
| 352 | part = subprocess.Popen(["rpmbuild", "--nodeps", "-E", part, new_specfile_name], stdout=subprocess.PIPE).communicate()[0] |
|---|
| 353 | for key in re.compile("%{([^}]*)}").findall(part): |
|---|
| 354 | if key in defines: |
|---|
| 355 | part = part.replace("%%{%s}" % (key,), defines[key]) |
|---|
| 356 | requirements.append(part) |
|---|
| 357 | requirements = "".join(requirements).strip().split() |
|---|
| 358 | requirement_names = [] |
|---|
| 359 | for part in requirements: |
|---|
| 360 | m = REQUIREMENT_PARSER.match(part) |
|---|
| 361 | if m: |
|---|
| 362 | requirement_names.append(m.group(1)) |
|---|
| 363 | else: |
|---|
| 364 | requirement_names.append(part) |
|---|
| 365 | for package in requirement_names[:]: |
|---|
| 366 | if subprocess.Popen(["rpm","-qa",package], stdout=subprocess.PIPE).communicate()[0]: |
|---|
| 367 | print "Requirement %s already installed" % package |
|---|
| 368 | requirement_names.remove(package) |
|---|
| 369 | build_reqs = [] |
|---|
| 370 | print "resolving requirements:", requirements, " - searching without conditions as ", requirement_names |
|---|
| 371 | for line in subprocess.Popen(["yum", "resolvedep"] + requirement_names, stdout=subprocess.PIPE).communicate()[0].splitlines(): |
|---|
| 372 | if " " in line: |
|---|
| 373 | continue |
|---|
| 374 | build_reqs.append(line) |
|---|
| 375 | if build_reqs: |
|---|
| 376 | retcode = subprocess.call(["sudo", "yum", "install", "-y"] + build_reqs) |
|---|
| 377 | if p == "protobuf": |
|---|
| 378 | if quote_defines: |
|---|
| 379 | rpmdefines.extend(["--define", '"_without_java 1"']) |
|---|
| 380 | rpmdefines.extend(["--define", '"_without_gtest 1"']) |
|---|
| 381 | rpmdefines.extend(["--define", '"_without_python 0"']) |
|---|
| 382 | else: |
|---|
| 383 | rpmdefines.extend(["--define", "_without_java 1"]) |
|---|
| 384 | rpmdefines.extend(["--define", "_without_gtest 1"]) |
|---|
| 385 | rpmdefines.extend(["--define", '_without_python 0']) |
|---|
| 386 | print "Build arguments: ",["rpmbuild"]+rpmdefines+["-ba",new_specfile_name] |
|---|
| 387 | retcode = subprocess.call(["rpmbuild"] + rpmdefines + ["-ba", new_specfile_name], stdout=logfile, stderr=logfile) |
|---|
| 388 | if retcode: |
|---|
| 389 | logging.warning("Error building source package for %s: tail of log file follows" % (p,)) |
|---|
| 390 | print "".join(open(log_filename, "rb").readlines()[-10:]) |
|---|
| 391 | failed_builds.append(p) |
|---|
| 392 | continue |
|---|
| 393 | rpm_arch = subprocess.Popen(["rpmbuild", "-E", "%{_arch}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].strip() |
|---|
| 394 | rpmarch_dir = os.path.join(rpmbuild_dir, "RPMS", rpm_arch) |
|---|
| 395 | rpmnoarch_dir = os.path.join(rpmbuild_dir, "RPMS", "noarch") |
|---|
| 396 | if os.path.exists(rpmarch_dir): |
|---|
| 397 | for rpm_filename in [filename for filename in os.listdir(rpmarch_dir) if filename.startswith(new_p) and filename.endswith(".rpm")]: |
|---|
| 398 | logging.info("Copying built %s" % (rpm_filename,)) |
|---|
| 399 | shutil.copyfile(os.path.join(rpmarch_dir, rpm_filename), os.path.join(rpm_dir, rpm_filename)) |
|---|
| 400 | if os.path.exists(rpmnoarch_dir): |
|---|
| 401 | for rpm_filename in [filename for filename in os.listdir(rpmnoarch_dir) if filename.startswith(new_p) and filename.endswith(".rpm")]: |
|---|
| 402 | logging.info("Copying built %s" % (rpm_filename,)) |
|---|
| 403 | shutil.copyfile(os.path.join(rpmnoarch_dir, rpm_filename), os.path.join(rpm_dir, rpm_filename)) |
|---|
| 404 | |
|---|
| 405 | if not_found_packages: |
|---|
| 406 | sys.stderr.write("Packages not found: %s\n" % ",".join(not_found_packages)) |
|---|
| 407 | if failed_builds: |
|---|
| 408 | sys.stderr.write("Packages failed to build: %s\n" % ",".join(failed_builds)) |
|---|
| 409 | if not_found_packages or failed_builds: |
|---|
| 410 | sys.exit(1) |
|---|
| 411 | |
|---|