17db96d56Sopenharmony_ci"""distutils.command.bdist_rpm 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciImplements the Distutils 'bdist_rpm' command (create RPM source and binary 47db96d56Sopenharmony_cidistributions).""" 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ciimport subprocess, sys, os 77db96d56Sopenharmony_cifrom distutils.core import Command 87db96d56Sopenharmony_cifrom distutils.debug import DEBUG 97db96d56Sopenharmony_cifrom distutils.file_util import write_file 107db96d56Sopenharmony_cifrom distutils.errors import * 117db96d56Sopenharmony_cifrom distutils.sysconfig import get_python_version 127db96d56Sopenharmony_cifrom distutils import log 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ciclass bdist_rpm(Command): 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci description = "create an RPM distribution" 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci user_options = [ 197db96d56Sopenharmony_ci ('bdist-base=', None, 207db96d56Sopenharmony_ci "base directory for creating built distributions"), 217db96d56Sopenharmony_ci ('rpm-base=', None, 227db96d56Sopenharmony_ci "base directory for creating RPMs (defaults to \"rpm\" under " 237db96d56Sopenharmony_ci "--bdist-base; must be specified for RPM 2)"), 247db96d56Sopenharmony_ci ('dist-dir=', 'd', 257db96d56Sopenharmony_ci "directory to put final RPM files in " 267db96d56Sopenharmony_ci "(and .spec files if --spec-only)"), 277db96d56Sopenharmony_ci ('python=', None, 287db96d56Sopenharmony_ci "path to Python interpreter to hard-code in the .spec file " 297db96d56Sopenharmony_ci "(default: \"python\")"), 307db96d56Sopenharmony_ci ('fix-python', None, 317db96d56Sopenharmony_ci "hard-code the exact path to the current Python interpreter in " 327db96d56Sopenharmony_ci "the .spec file"), 337db96d56Sopenharmony_ci ('spec-only', None, 347db96d56Sopenharmony_ci "only regenerate spec file"), 357db96d56Sopenharmony_ci ('source-only', None, 367db96d56Sopenharmony_ci "only generate source RPM"), 377db96d56Sopenharmony_ci ('binary-only', None, 387db96d56Sopenharmony_ci "only generate binary RPM"), 397db96d56Sopenharmony_ci ('use-bzip2', None, 407db96d56Sopenharmony_ci "use bzip2 instead of gzip to create source distribution"), 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci # More meta-data: too RPM-specific to put in the setup script, 437db96d56Sopenharmony_ci # but needs to go in the .spec file -- so we make these options 447db96d56Sopenharmony_ci # to "bdist_rpm". The idea is that packagers would put this 457db96d56Sopenharmony_ci # info in setup.cfg, although they are of course free to 467db96d56Sopenharmony_ci # supply it on the command line. 477db96d56Sopenharmony_ci ('distribution-name=', None, 487db96d56Sopenharmony_ci "name of the (Linux) distribution to which this " 497db96d56Sopenharmony_ci "RPM applies (*not* the name of the module distribution!)"), 507db96d56Sopenharmony_ci ('group=', None, 517db96d56Sopenharmony_ci "package classification [default: \"Development/Libraries\"]"), 527db96d56Sopenharmony_ci ('release=', None, 537db96d56Sopenharmony_ci "RPM release number"), 547db96d56Sopenharmony_ci ('serial=', None, 557db96d56Sopenharmony_ci "RPM serial number"), 567db96d56Sopenharmony_ci ('vendor=', None, 577db96d56Sopenharmony_ci "RPM \"vendor\" (eg. \"Joe Blow <joe@example.com>\") " 587db96d56Sopenharmony_ci "[default: maintainer or author from setup script]"), 597db96d56Sopenharmony_ci ('packager=', None, 607db96d56Sopenharmony_ci "RPM packager (eg. \"Jane Doe <jane@example.net>\") " 617db96d56Sopenharmony_ci "[default: vendor]"), 627db96d56Sopenharmony_ci ('doc-files=', None, 637db96d56Sopenharmony_ci "list of documentation files (space or comma-separated)"), 647db96d56Sopenharmony_ci ('changelog=', None, 657db96d56Sopenharmony_ci "RPM changelog"), 667db96d56Sopenharmony_ci ('icon=', None, 677db96d56Sopenharmony_ci "name of icon file"), 687db96d56Sopenharmony_ci ('provides=', None, 697db96d56Sopenharmony_ci "capabilities provided by this package"), 707db96d56Sopenharmony_ci ('requires=', None, 717db96d56Sopenharmony_ci "capabilities required by this package"), 727db96d56Sopenharmony_ci ('conflicts=', None, 737db96d56Sopenharmony_ci "capabilities which conflict with this package"), 747db96d56Sopenharmony_ci ('build-requires=', None, 757db96d56Sopenharmony_ci "capabilities required to build this package"), 767db96d56Sopenharmony_ci ('obsoletes=', None, 777db96d56Sopenharmony_ci "capabilities made obsolete by this package"), 787db96d56Sopenharmony_ci ('no-autoreq', None, 797db96d56Sopenharmony_ci "do not automatically calculate dependencies"), 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci # Actions to take when building RPM 827db96d56Sopenharmony_ci ('keep-temp', 'k', 837db96d56Sopenharmony_ci "don't clean up RPM build directory"), 847db96d56Sopenharmony_ci ('no-keep-temp', None, 857db96d56Sopenharmony_ci "clean up RPM build directory [default]"), 867db96d56Sopenharmony_ci ('use-rpm-opt-flags', None, 877db96d56Sopenharmony_ci "compile with RPM_OPT_FLAGS when building from source RPM"), 887db96d56Sopenharmony_ci ('no-rpm-opt-flags', None, 897db96d56Sopenharmony_ci "do not pass any RPM CFLAGS to compiler"), 907db96d56Sopenharmony_ci ('rpm3-mode', None, 917db96d56Sopenharmony_ci "RPM 3 compatibility mode (default)"), 927db96d56Sopenharmony_ci ('rpm2-mode', None, 937db96d56Sopenharmony_ci "RPM 2 compatibility mode"), 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci # Add the hooks necessary for specifying custom scripts 967db96d56Sopenharmony_ci ('prep-script=', None, 977db96d56Sopenharmony_ci "Specify a script for the PREP phase of RPM building"), 987db96d56Sopenharmony_ci ('build-script=', None, 997db96d56Sopenharmony_ci "Specify a script for the BUILD phase of RPM building"), 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci ('pre-install=', None, 1027db96d56Sopenharmony_ci "Specify a script for the pre-INSTALL phase of RPM building"), 1037db96d56Sopenharmony_ci ('install-script=', None, 1047db96d56Sopenharmony_ci "Specify a script for the INSTALL phase of RPM building"), 1057db96d56Sopenharmony_ci ('post-install=', None, 1067db96d56Sopenharmony_ci "Specify a script for the post-INSTALL phase of RPM building"), 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci ('pre-uninstall=', None, 1097db96d56Sopenharmony_ci "Specify a script for the pre-UNINSTALL phase of RPM building"), 1107db96d56Sopenharmony_ci ('post-uninstall=', None, 1117db96d56Sopenharmony_ci "Specify a script for the post-UNINSTALL phase of RPM building"), 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ci ('clean-script=', None, 1147db96d56Sopenharmony_ci "Specify a script for the CLEAN phase of RPM building"), 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci ('verify-script=', None, 1177db96d56Sopenharmony_ci "Specify a script for the VERIFY phase of the RPM build"), 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci # Allow a packager to explicitly force an architecture 1207db96d56Sopenharmony_ci ('force-arch=', None, 1217db96d56Sopenharmony_ci "Force an architecture onto the RPM build process"), 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci ('quiet', 'q', 1247db96d56Sopenharmony_ci "Run the INSTALL phase of RPM building in quiet mode"), 1257db96d56Sopenharmony_ci ] 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode', 1287db96d56Sopenharmony_ci 'no-autoreq', 'quiet'] 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci negative_opt = {'no-keep-temp': 'keep-temp', 1317db96d56Sopenharmony_ci 'no-rpm-opt-flags': 'use-rpm-opt-flags', 1327db96d56Sopenharmony_ci 'rpm2-mode': 'rpm3-mode'} 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci def initialize_options(self): 1367db96d56Sopenharmony_ci self.bdist_base = None 1377db96d56Sopenharmony_ci self.rpm_base = None 1387db96d56Sopenharmony_ci self.dist_dir = None 1397db96d56Sopenharmony_ci self.python = None 1407db96d56Sopenharmony_ci self.fix_python = None 1417db96d56Sopenharmony_ci self.spec_only = None 1427db96d56Sopenharmony_ci self.binary_only = None 1437db96d56Sopenharmony_ci self.source_only = None 1447db96d56Sopenharmony_ci self.use_bzip2 = None 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci self.distribution_name = None 1477db96d56Sopenharmony_ci self.group = None 1487db96d56Sopenharmony_ci self.release = None 1497db96d56Sopenharmony_ci self.serial = None 1507db96d56Sopenharmony_ci self.vendor = None 1517db96d56Sopenharmony_ci self.packager = None 1527db96d56Sopenharmony_ci self.doc_files = None 1537db96d56Sopenharmony_ci self.changelog = None 1547db96d56Sopenharmony_ci self.icon = None 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci self.prep_script = None 1577db96d56Sopenharmony_ci self.build_script = None 1587db96d56Sopenharmony_ci self.install_script = None 1597db96d56Sopenharmony_ci self.clean_script = None 1607db96d56Sopenharmony_ci self.verify_script = None 1617db96d56Sopenharmony_ci self.pre_install = None 1627db96d56Sopenharmony_ci self.post_install = None 1637db96d56Sopenharmony_ci self.pre_uninstall = None 1647db96d56Sopenharmony_ci self.post_uninstall = None 1657db96d56Sopenharmony_ci self.prep = None 1667db96d56Sopenharmony_ci self.provides = None 1677db96d56Sopenharmony_ci self.requires = None 1687db96d56Sopenharmony_ci self.conflicts = None 1697db96d56Sopenharmony_ci self.build_requires = None 1707db96d56Sopenharmony_ci self.obsoletes = None 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ci self.keep_temp = 0 1737db96d56Sopenharmony_ci self.use_rpm_opt_flags = 1 1747db96d56Sopenharmony_ci self.rpm3_mode = 1 1757db96d56Sopenharmony_ci self.no_autoreq = 0 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci self.force_arch = None 1787db96d56Sopenharmony_ci self.quiet = 0 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci def finalize_options(self): 1817db96d56Sopenharmony_ci self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) 1827db96d56Sopenharmony_ci if self.rpm_base is None: 1837db96d56Sopenharmony_ci if not self.rpm3_mode: 1847db96d56Sopenharmony_ci raise DistutilsOptionError( 1857db96d56Sopenharmony_ci "you must specify --rpm-base in RPM 2 mode") 1867db96d56Sopenharmony_ci self.rpm_base = os.path.join(self.bdist_base, "rpm") 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci if self.python is None: 1897db96d56Sopenharmony_ci if self.fix_python: 1907db96d56Sopenharmony_ci self.python = sys.executable 1917db96d56Sopenharmony_ci else: 1927db96d56Sopenharmony_ci self.python = "python3" 1937db96d56Sopenharmony_ci elif self.fix_python: 1947db96d56Sopenharmony_ci raise DistutilsOptionError( 1957db96d56Sopenharmony_ci "--python and --fix-python are mutually exclusive options") 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci if os.name != 'posix': 1987db96d56Sopenharmony_ci raise DistutilsPlatformError("don't know how to create RPM " 1997db96d56Sopenharmony_ci "distributions on platform %s" % os.name) 2007db96d56Sopenharmony_ci if self.binary_only and self.source_only: 2017db96d56Sopenharmony_ci raise DistutilsOptionError( 2027db96d56Sopenharmony_ci "cannot supply both '--source-only' and '--binary-only'") 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci # don't pass CFLAGS to pure python distributions 2057db96d56Sopenharmony_ci if not self.distribution.has_ext_modules(): 2067db96d56Sopenharmony_ci self.use_rpm_opt_flags = 0 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) 2097db96d56Sopenharmony_ci self.finalize_package_data() 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci def finalize_package_data(self): 2127db96d56Sopenharmony_ci self.ensure_string('group', "Development/Libraries") 2137db96d56Sopenharmony_ci self.ensure_string('vendor', 2147db96d56Sopenharmony_ci "%s <%s>" % (self.distribution.get_contact(), 2157db96d56Sopenharmony_ci self.distribution.get_contact_email())) 2167db96d56Sopenharmony_ci self.ensure_string('packager') 2177db96d56Sopenharmony_ci self.ensure_string_list('doc_files') 2187db96d56Sopenharmony_ci if isinstance(self.doc_files, list): 2197db96d56Sopenharmony_ci for readme in ('README', 'README.txt'): 2207db96d56Sopenharmony_ci if os.path.exists(readme) and readme not in self.doc_files: 2217db96d56Sopenharmony_ci self.doc_files.append(readme) 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci self.ensure_string('release', "1") 2247db96d56Sopenharmony_ci self.ensure_string('serial') # should it be an int? 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci self.ensure_string('distribution_name') 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci self.ensure_string('changelog') 2297db96d56Sopenharmony_ci # Format changelog correctly 2307db96d56Sopenharmony_ci self.changelog = self._format_changelog(self.changelog) 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci self.ensure_filename('icon') 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci self.ensure_filename('prep_script') 2357db96d56Sopenharmony_ci self.ensure_filename('build_script') 2367db96d56Sopenharmony_ci self.ensure_filename('install_script') 2377db96d56Sopenharmony_ci self.ensure_filename('clean_script') 2387db96d56Sopenharmony_ci self.ensure_filename('verify_script') 2397db96d56Sopenharmony_ci self.ensure_filename('pre_install') 2407db96d56Sopenharmony_ci self.ensure_filename('post_install') 2417db96d56Sopenharmony_ci self.ensure_filename('pre_uninstall') 2427db96d56Sopenharmony_ci self.ensure_filename('post_uninstall') 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci # XXX don't forget we punted on summaries and descriptions -- they 2457db96d56Sopenharmony_ci # should be handled here eventually! 2467db96d56Sopenharmony_ci 2477db96d56Sopenharmony_ci # Now *this* is some meta-data that belongs in the setup script... 2487db96d56Sopenharmony_ci self.ensure_string_list('provides') 2497db96d56Sopenharmony_ci self.ensure_string_list('requires') 2507db96d56Sopenharmony_ci self.ensure_string_list('conflicts') 2517db96d56Sopenharmony_ci self.ensure_string_list('build_requires') 2527db96d56Sopenharmony_ci self.ensure_string_list('obsoletes') 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ci self.ensure_string('force_arch') 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci def run(self): 2577db96d56Sopenharmony_ci if DEBUG: 2587db96d56Sopenharmony_ci print("before _get_package_data():") 2597db96d56Sopenharmony_ci print("vendor =", self.vendor) 2607db96d56Sopenharmony_ci print("packager =", self.packager) 2617db96d56Sopenharmony_ci print("doc_files =", self.doc_files) 2627db96d56Sopenharmony_ci print("changelog =", self.changelog) 2637db96d56Sopenharmony_ci 2647db96d56Sopenharmony_ci # make directories 2657db96d56Sopenharmony_ci if self.spec_only: 2667db96d56Sopenharmony_ci spec_dir = self.dist_dir 2677db96d56Sopenharmony_ci self.mkpath(spec_dir) 2687db96d56Sopenharmony_ci else: 2697db96d56Sopenharmony_ci rpm_dir = {} 2707db96d56Sopenharmony_ci for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): 2717db96d56Sopenharmony_ci rpm_dir[d] = os.path.join(self.rpm_base, d) 2727db96d56Sopenharmony_ci self.mkpath(rpm_dir[d]) 2737db96d56Sopenharmony_ci spec_dir = rpm_dir['SPECS'] 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci # Spec file goes into 'dist_dir' if '--spec-only specified', 2767db96d56Sopenharmony_ci # build/rpm.<plat> otherwise. 2777db96d56Sopenharmony_ci spec_path = os.path.join(spec_dir, 2787db96d56Sopenharmony_ci "%s.spec" % self.distribution.get_name()) 2797db96d56Sopenharmony_ci self.execute(write_file, 2807db96d56Sopenharmony_ci (spec_path, 2817db96d56Sopenharmony_ci self._make_spec_file()), 2827db96d56Sopenharmony_ci "writing '%s'" % spec_path) 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci if self.spec_only: # stop if requested 2857db96d56Sopenharmony_ci return 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci # Make a source distribution and copy to SOURCES directory with 2887db96d56Sopenharmony_ci # optional icon. 2897db96d56Sopenharmony_ci saved_dist_files = self.distribution.dist_files[:] 2907db96d56Sopenharmony_ci sdist = self.reinitialize_command('sdist') 2917db96d56Sopenharmony_ci if self.use_bzip2: 2927db96d56Sopenharmony_ci sdist.formats = ['bztar'] 2937db96d56Sopenharmony_ci else: 2947db96d56Sopenharmony_ci sdist.formats = ['gztar'] 2957db96d56Sopenharmony_ci self.run_command('sdist') 2967db96d56Sopenharmony_ci self.distribution.dist_files = saved_dist_files 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci source = sdist.get_archive_files()[0] 2997db96d56Sopenharmony_ci source_dir = rpm_dir['SOURCES'] 3007db96d56Sopenharmony_ci self.copy_file(source, source_dir) 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ci if self.icon: 3037db96d56Sopenharmony_ci if os.path.exists(self.icon): 3047db96d56Sopenharmony_ci self.copy_file(self.icon, source_dir) 3057db96d56Sopenharmony_ci else: 3067db96d56Sopenharmony_ci raise DistutilsFileError( 3077db96d56Sopenharmony_ci "icon file '%s' does not exist" % self.icon) 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_ci # build package 3107db96d56Sopenharmony_ci log.info("building RPMs") 3117db96d56Sopenharmony_ci rpm_cmd = ['rpmbuild'] 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci if self.source_only: # what kind of RPMs? 3147db96d56Sopenharmony_ci rpm_cmd.append('-bs') 3157db96d56Sopenharmony_ci elif self.binary_only: 3167db96d56Sopenharmony_ci rpm_cmd.append('-bb') 3177db96d56Sopenharmony_ci else: 3187db96d56Sopenharmony_ci rpm_cmd.append('-ba') 3197db96d56Sopenharmony_ci rpm_cmd.extend(['--define', '__python %s' % self.python]) 3207db96d56Sopenharmony_ci if self.rpm3_mode: 3217db96d56Sopenharmony_ci rpm_cmd.extend(['--define', 3227db96d56Sopenharmony_ci '_topdir %s' % os.path.abspath(self.rpm_base)]) 3237db96d56Sopenharmony_ci if not self.keep_temp: 3247db96d56Sopenharmony_ci rpm_cmd.append('--clean') 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci if self.quiet: 3277db96d56Sopenharmony_ci rpm_cmd.append('--quiet') 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci rpm_cmd.append(spec_path) 3307db96d56Sopenharmony_ci # Determine the binary rpm names that should be built out of this spec 3317db96d56Sopenharmony_ci # file 3327db96d56Sopenharmony_ci # Note that some of these may not be really built (if the file 3337db96d56Sopenharmony_ci # list is empty) 3347db96d56Sopenharmony_ci nvr_string = "%{name}-%{version}-%{release}" 3357db96d56Sopenharmony_ci src_rpm = nvr_string + ".src.rpm" 3367db96d56Sopenharmony_ci non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm" 3377db96d56Sopenharmony_ci q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % ( 3387db96d56Sopenharmony_ci src_rpm, non_src_rpm, spec_path) 3397db96d56Sopenharmony_ci 3407db96d56Sopenharmony_ci out = os.popen(q_cmd) 3417db96d56Sopenharmony_ci try: 3427db96d56Sopenharmony_ci binary_rpms = [] 3437db96d56Sopenharmony_ci source_rpm = None 3447db96d56Sopenharmony_ci while True: 3457db96d56Sopenharmony_ci line = out.readline() 3467db96d56Sopenharmony_ci if not line: 3477db96d56Sopenharmony_ci break 3487db96d56Sopenharmony_ci l = line.strip().split() 3497db96d56Sopenharmony_ci assert(len(l) == 2) 3507db96d56Sopenharmony_ci binary_rpms.append(l[1]) 3517db96d56Sopenharmony_ci # The source rpm is named after the first entry in the spec file 3527db96d56Sopenharmony_ci if source_rpm is None: 3537db96d56Sopenharmony_ci source_rpm = l[0] 3547db96d56Sopenharmony_ci 3557db96d56Sopenharmony_ci status = out.close() 3567db96d56Sopenharmony_ci if status: 3577db96d56Sopenharmony_ci raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd)) 3587db96d56Sopenharmony_ci 3597db96d56Sopenharmony_ci finally: 3607db96d56Sopenharmony_ci out.close() 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci self.spawn(rpm_cmd) 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci if not self.dry_run: 3657db96d56Sopenharmony_ci if self.distribution.has_ext_modules(): 3667db96d56Sopenharmony_ci pyversion = get_python_version() 3677db96d56Sopenharmony_ci else: 3687db96d56Sopenharmony_ci pyversion = 'any' 3697db96d56Sopenharmony_ci 3707db96d56Sopenharmony_ci if not self.binary_only: 3717db96d56Sopenharmony_ci srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) 3727db96d56Sopenharmony_ci assert(os.path.exists(srpm)) 3737db96d56Sopenharmony_ci self.move_file(srpm, self.dist_dir) 3747db96d56Sopenharmony_ci filename = os.path.join(self.dist_dir, source_rpm) 3757db96d56Sopenharmony_ci self.distribution.dist_files.append( 3767db96d56Sopenharmony_ci ('bdist_rpm', pyversion, filename)) 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci if not self.source_only: 3797db96d56Sopenharmony_ci for rpm in binary_rpms: 3807db96d56Sopenharmony_ci rpm = os.path.join(rpm_dir['RPMS'], rpm) 3817db96d56Sopenharmony_ci if os.path.exists(rpm): 3827db96d56Sopenharmony_ci self.move_file(rpm, self.dist_dir) 3837db96d56Sopenharmony_ci filename = os.path.join(self.dist_dir, 3847db96d56Sopenharmony_ci os.path.basename(rpm)) 3857db96d56Sopenharmony_ci self.distribution.dist_files.append( 3867db96d56Sopenharmony_ci ('bdist_rpm', pyversion, filename)) 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci def _dist_path(self, path): 3897db96d56Sopenharmony_ci return os.path.join(self.dist_dir, os.path.basename(path)) 3907db96d56Sopenharmony_ci 3917db96d56Sopenharmony_ci def _make_spec_file(self): 3927db96d56Sopenharmony_ci """Generate the text of an RPM spec file and return it as a 3937db96d56Sopenharmony_ci list of strings (one per line). 3947db96d56Sopenharmony_ci """ 3957db96d56Sopenharmony_ci # definitions and headers 3967db96d56Sopenharmony_ci spec_file = [ 3977db96d56Sopenharmony_ci '%define name ' + self.distribution.get_name(), 3987db96d56Sopenharmony_ci '%define version ' + self.distribution.get_version().replace('-','_'), 3997db96d56Sopenharmony_ci '%define unmangled_version ' + self.distribution.get_version(), 4007db96d56Sopenharmony_ci '%define release ' + self.release.replace('-','_'), 4017db96d56Sopenharmony_ci '', 4027db96d56Sopenharmony_ci 'Summary: ' + self.distribution.get_description(), 4037db96d56Sopenharmony_ci ] 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci # Workaround for #14443 which affects some RPM based systems such as 4067db96d56Sopenharmony_ci # RHEL6 (and probably derivatives) 4077db96d56Sopenharmony_ci vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}') 4087db96d56Sopenharmony_ci # Generate a potential replacement value for __os_install_post (whilst 4097db96d56Sopenharmony_ci # normalizing the whitespace to simplify the test for whether the 4107db96d56Sopenharmony_ci # invocation of brp-python-bytecompile passes in __python): 4117db96d56Sopenharmony_ci vendor_hook = '\n'.join([' %s \\' % line.strip() 4127db96d56Sopenharmony_ci for line in vendor_hook.splitlines()]) 4137db96d56Sopenharmony_ci problem = "brp-python-bytecompile \\\n" 4147db96d56Sopenharmony_ci fixed = "brp-python-bytecompile %{__python} \\\n" 4157db96d56Sopenharmony_ci fixed_hook = vendor_hook.replace(problem, fixed) 4167db96d56Sopenharmony_ci if fixed_hook != vendor_hook: 4177db96d56Sopenharmony_ci spec_file.append('# Workaround for http://bugs.python.org/issue14443') 4187db96d56Sopenharmony_ci spec_file.append('%define __os_install_post ' + fixed_hook + '\n') 4197db96d56Sopenharmony_ci 4207db96d56Sopenharmony_ci # put locale summaries into spec file 4217db96d56Sopenharmony_ci # XXX not supported for now (hard to put a dictionary 4227db96d56Sopenharmony_ci # in a config file -- arg!) 4237db96d56Sopenharmony_ci #for locale in self.summaries.keys(): 4247db96d56Sopenharmony_ci # spec_file.append('Summary(%s): %s' % (locale, 4257db96d56Sopenharmony_ci # self.summaries[locale])) 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci spec_file.extend([ 4287db96d56Sopenharmony_ci 'Name: %{name}', 4297db96d56Sopenharmony_ci 'Version: %{version}', 4307db96d56Sopenharmony_ci 'Release: %{release}',]) 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_ci # XXX yuck! this filename is available from the "sdist" command, 4337db96d56Sopenharmony_ci # but only after it has run: and we create the spec file before 4347db96d56Sopenharmony_ci # running "sdist", in case of --spec-only. 4357db96d56Sopenharmony_ci if self.use_bzip2: 4367db96d56Sopenharmony_ci spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2') 4377db96d56Sopenharmony_ci else: 4387db96d56Sopenharmony_ci spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz') 4397db96d56Sopenharmony_ci 4407db96d56Sopenharmony_ci spec_file.extend([ 4417db96d56Sopenharmony_ci 'License: ' + self.distribution.get_license(), 4427db96d56Sopenharmony_ci 'Group: ' + self.group, 4437db96d56Sopenharmony_ci 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot', 4447db96d56Sopenharmony_ci 'Prefix: %{_prefix}', ]) 4457db96d56Sopenharmony_ci 4467db96d56Sopenharmony_ci if not self.force_arch: 4477db96d56Sopenharmony_ci # noarch if no extension modules 4487db96d56Sopenharmony_ci if not self.distribution.has_ext_modules(): 4497db96d56Sopenharmony_ci spec_file.append('BuildArch: noarch') 4507db96d56Sopenharmony_ci else: 4517db96d56Sopenharmony_ci spec_file.append( 'BuildArch: %s' % self.force_arch ) 4527db96d56Sopenharmony_ci 4537db96d56Sopenharmony_ci for field in ('Vendor', 4547db96d56Sopenharmony_ci 'Packager', 4557db96d56Sopenharmony_ci 'Provides', 4567db96d56Sopenharmony_ci 'Requires', 4577db96d56Sopenharmony_ci 'Conflicts', 4587db96d56Sopenharmony_ci 'Obsoletes', 4597db96d56Sopenharmony_ci ): 4607db96d56Sopenharmony_ci val = getattr(self, field.lower()) 4617db96d56Sopenharmony_ci if isinstance(val, list): 4627db96d56Sopenharmony_ci spec_file.append('%s: %s' % (field, ' '.join(val))) 4637db96d56Sopenharmony_ci elif val is not None: 4647db96d56Sopenharmony_ci spec_file.append('%s: %s' % (field, val)) 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_ci if self.distribution.get_url() != 'UNKNOWN': 4687db96d56Sopenharmony_ci spec_file.append('Url: ' + self.distribution.get_url()) 4697db96d56Sopenharmony_ci 4707db96d56Sopenharmony_ci if self.distribution_name: 4717db96d56Sopenharmony_ci spec_file.append('Distribution: ' + self.distribution_name) 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci if self.build_requires: 4747db96d56Sopenharmony_ci spec_file.append('BuildRequires: ' + 4757db96d56Sopenharmony_ci ' '.join(self.build_requires)) 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ci if self.icon: 4787db96d56Sopenharmony_ci spec_file.append('Icon: ' + os.path.basename(self.icon)) 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_ci if self.no_autoreq: 4817db96d56Sopenharmony_ci spec_file.append('AutoReq: 0') 4827db96d56Sopenharmony_ci 4837db96d56Sopenharmony_ci spec_file.extend([ 4847db96d56Sopenharmony_ci '', 4857db96d56Sopenharmony_ci '%description', 4867db96d56Sopenharmony_ci self.distribution.get_long_description() 4877db96d56Sopenharmony_ci ]) 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_ci # put locale descriptions into spec file 4907db96d56Sopenharmony_ci # XXX again, suppressed because config file syntax doesn't 4917db96d56Sopenharmony_ci # easily support this ;-( 4927db96d56Sopenharmony_ci #for locale in self.descriptions.keys(): 4937db96d56Sopenharmony_ci # spec_file.extend([ 4947db96d56Sopenharmony_ci # '', 4957db96d56Sopenharmony_ci # '%description -l ' + locale, 4967db96d56Sopenharmony_ci # self.descriptions[locale], 4977db96d56Sopenharmony_ci # ]) 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ci # rpm scripts 5007db96d56Sopenharmony_ci # figure out default build script 5017db96d56Sopenharmony_ci def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0])) 5027db96d56Sopenharmony_ci def_build = "%s build" % def_setup_call 5037db96d56Sopenharmony_ci if self.use_rpm_opt_flags: 5047db96d56Sopenharmony_ci def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build 5057db96d56Sopenharmony_ci 5067db96d56Sopenharmony_ci # insert contents of files 5077db96d56Sopenharmony_ci 5087db96d56Sopenharmony_ci # XXX this is kind of misleading: user-supplied options are files 5097db96d56Sopenharmony_ci # that we open and interpolate into the spec file, but the defaults 5107db96d56Sopenharmony_ci # are just text that we drop in as-is. Hmmm. 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_ci install_cmd = ('%s install -O1 --root=$RPM_BUILD_ROOT ' 5137db96d56Sopenharmony_ci '--record=INSTALLED_FILES') % def_setup_call 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci script_options = [ 5167db96d56Sopenharmony_ci ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"), 5177db96d56Sopenharmony_ci ('build', 'build_script', def_build), 5187db96d56Sopenharmony_ci ('install', 'install_script', install_cmd), 5197db96d56Sopenharmony_ci ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), 5207db96d56Sopenharmony_ci ('verifyscript', 'verify_script', None), 5217db96d56Sopenharmony_ci ('pre', 'pre_install', None), 5227db96d56Sopenharmony_ci ('post', 'post_install', None), 5237db96d56Sopenharmony_ci ('preun', 'pre_uninstall', None), 5247db96d56Sopenharmony_ci ('postun', 'post_uninstall', None), 5257db96d56Sopenharmony_ci ] 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci for (rpm_opt, attr, default) in script_options: 5287db96d56Sopenharmony_ci # Insert contents of file referred to, if no file is referred to 5297db96d56Sopenharmony_ci # use 'default' as contents of script 5307db96d56Sopenharmony_ci val = getattr(self, attr) 5317db96d56Sopenharmony_ci if val or default: 5327db96d56Sopenharmony_ci spec_file.extend([ 5337db96d56Sopenharmony_ci '', 5347db96d56Sopenharmony_ci '%' + rpm_opt,]) 5357db96d56Sopenharmony_ci if val: 5367db96d56Sopenharmony_ci with open(val) as f: 5377db96d56Sopenharmony_ci spec_file.extend(f.read().split('\n')) 5387db96d56Sopenharmony_ci else: 5397db96d56Sopenharmony_ci spec_file.append(default) 5407db96d56Sopenharmony_ci 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci # files section 5437db96d56Sopenharmony_ci spec_file.extend([ 5447db96d56Sopenharmony_ci '', 5457db96d56Sopenharmony_ci '%files -f INSTALLED_FILES', 5467db96d56Sopenharmony_ci '%defattr(-,root,root)', 5477db96d56Sopenharmony_ci ]) 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci if self.doc_files: 5507db96d56Sopenharmony_ci spec_file.append('%doc ' + ' '.join(self.doc_files)) 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_ci if self.changelog: 5537db96d56Sopenharmony_ci spec_file.extend([ 5547db96d56Sopenharmony_ci '', 5557db96d56Sopenharmony_ci '%changelog',]) 5567db96d56Sopenharmony_ci spec_file.extend(self.changelog) 5577db96d56Sopenharmony_ci 5587db96d56Sopenharmony_ci return spec_file 5597db96d56Sopenharmony_ci 5607db96d56Sopenharmony_ci def _format_changelog(self, changelog): 5617db96d56Sopenharmony_ci """Format the changelog correctly and convert it to a list of strings 5627db96d56Sopenharmony_ci """ 5637db96d56Sopenharmony_ci if not changelog: 5647db96d56Sopenharmony_ci return changelog 5657db96d56Sopenharmony_ci new_changelog = [] 5667db96d56Sopenharmony_ci for line in changelog.strip().split('\n'): 5677db96d56Sopenharmony_ci line = line.strip() 5687db96d56Sopenharmony_ci if line[0] == '*': 5697db96d56Sopenharmony_ci new_changelog.extend(['', line]) 5707db96d56Sopenharmony_ci elif line[0] == '-': 5717db96d56Sopenharmony_ci new_changelog.append(line) 5727db96d56Sopenharmony_ci else: 5737db96d56Sopenharmony_ci new_changelog.append(' ' + line) 5747db96d56Sopenharmony_ci 5757db96d56Sopenharmony_ci # strip trailing newline inserted by first changelog entry 5767db96d56Sopenharmony_ci if not new_changelog[0]: 5777db96d56Sopenharmony_ci del new_changelog[0] 5787db96d56Sopenharmony_ci 5797db96d56Sopenharmony_ci return new_changelog 580