NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

bdist_rpm.py (15531B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\command\bdist_rpm.py
      2 __revision__ = '$Id: bdist_rpm.py 87602 2011-01-01 04:24:26Z richard.tew $'
      3 import sys
      4 import os
      5 import string
      6 from distutils.core import Command
      7 from distutils.debug import DEBUG
      8 from distutils.file_util import write_file
      9 from distutils.errors import DistutilsOptionError, DistutilsPlatformError, DistutilsFileError, DistutilsExecError
     10 from distutils import log
     11 
     12 class bdist_rpm(Command):
     13     description = 'create an RPM distribution'
     14     user_options = [('bdist-base=', None, 'base directory for creating built distributions'),
     15      ('rpm-base=', None, 'base directory for creating RPMs (defaults to "rpm" under --bdist-base; must be specified for RPM 2)'),
     16      ('dist-dir=', 'd', 'directory to put final RPM files in (and .spec files if --spec-only)'),
     17      ('python=', None, 'path to Python interpreter to hard-code in the .spec file (default: "python")'),
     18      ('fix-python', None, 'hard-code the exact path to the current Python interpreter in the .spec file'),
     19      ('spec-only', None, 'only regenerate spec file'),
     20      ('source-only', None, 'only generate source RPM'),
     21      ('binary-only', None, 'only generate binary RPM'),
     22      ('use-bzip2', None, 'use bzip2 instead of gzip to create source distribution'),
     23      ('distribution-name=', None, 'name of the (Linux) distribution to which this RPM applies (*not* the name of the module distribution!)'),
     24      ('group=', None, 'package classification [default: "Development/Libraries"]'),
     25      ('release=', None, 'RPM release number'),
     26      ('serial=', None, 'RPM serial number'),
     27      ('vendor=', None, 'RPM "vendor" (eg. "Joe Blow <joe@example.com>") [default: maintainer or author from setup script]'),
     28      ('packager=', None, 'RPM packager (eg. "Jane Doe <jane@example.net>")[default: vendor]'),
     29      ('doc-files=', None, 'list of documentation files (space or comma-separated)'),
     30      ('changelog=', None, 'RPM changelog'),
     31      ('icon=', None, 'name of icon file'),
     32      ('provides=', None, 'capabilities provided by this package'),
     33      ('requires=', None, 'capabilities required by this package'),
     34      ('conflicts=', None, 'capabilities which conflict with this package'),
     35      ('build-requires=', None, 'capabilities required to build this package'),
     36      ('obsoletes=', None, 'capabilities made obsolete by this package'),
     37      ('no-autoreq', None, 'do not automatically calculate dependencies'),
     38      ('keep-temp', 'k', "don't clean up RPM build directory"),
     39      ('no-keep-temp', None, 'clean up RPM build directory [default]'),
     40      ('use-rpm-opt-flags', None, 'compile with RPM_OPT_FLAGS when building from source RPM'),
     41      ('no-rpm-opt-flags', None, 'do not pass any RPM CFLAGS to compiler'),
     42      ('rpm3-mode', None, 'RPM 3 compatibility mode (default)'),
     43      ('rpm2-mode', None, 'RPM 2 compatibility mode'),
     44      ('prep-script=', None, 'Specify a script for the PREP phase of RPM building'),
     45      ('build-script=', None, 'Specify a script for the BUILD phase of RPM building'),
     46      ('pre-install=', None, 'Specify a script for the pre-INSTALL phase of RPM building'),
     47      ('install-script=', None, 'Specify a script for the INSTALL phase of RPM building'),
     48      ('post-install=', None, 'Specify a script for the post-INSTALL phase of RPM building'),
     49      ('pre-uninstall=', None, 'Specify a script for the pre-UNINSTALL phase of RPM building'),
     50      ('post-uninstall=', None, 'Specify a script for the post-UNINSTALL phase of RPM building'),
     51      ('clean-script=', None, 'Specify a script for the CLEAN phase of RPM building'),
     52      ('verify-script=', None, 'Specify a script for the VERIFY phase of the RPM build'),
     53      ('force-arch=', None, 'Force an architecture onto the RPM build process'),
     54      ('quiet', 'q', 'Run the INSTALL phase of RPM building in quiet mode')]
     55     boolean_options = ['keep-temp',
     56      'use-rpm-opt-flags',
     57      'rpm3-mode',
     58      'no-autoreq',
     59      'quiet']
     60     negative_opt = {'no-keep-temp': 'keep-temp',
     61      'no-rpm-opt-flags': 'use-rpm-opt-flags',
     62      'rpm2-mode': 'rpm3-mode'}
     63 
     64     def initialize_options(self):
     65         self.bdist_base = None
     66         self.rpm_base = None
     67         self.dist_dir = None
     68         self.python = None
     69         self.fix_python = None
     70         self.spec_only = None
     71         self.binary_only = None
     72         self.source_only = None
     73         self.use_bzip2 = None
     74         self.distribution_name = None
     75         self.group = None
     76         self.release = None
     77         self.serial = None
     78         self.vendor = None
     79         self.packager = None
     80         self.doc_files = None
     81         self.changelog = None
     82         self.icon = None
     83         self.prep_script = None
     84         self.build_script = None
     85         self.install_script = None
     86         self.clean_script = None
     87         self.verify_script = None
     88         self.pre_install = None
     89         self.post_install = None
     90         self.pre_uninstall = None
     91         self.post_uninstall = None
     92         self.prep = None
     93         self.provides = None
     94         self.requires = None
     95         self.conflicts = None
     96         self.build_requires = None
     97         self.obsoletes = None
     98         self.keep_temp = 0
     99         self.use_rpm_opt_flags = 1
    100         self.rpm3_mode = 1
    101         self.no_autoreq = 0
    102         self.force_arch = None
    103         self.quiet = 0
    104 
    105     def finalize_options(self):
    106         self.set_undefined_options('bdist', ('bdist_base', 'bdist_base'))
    107         if self.rpm_base is None:
    108             if not self.rpm3_mode:
    109                 raise DistutilsOptionError, 'you must specify --rpm-base in RPM 2 mode'
    110             self.rpm_base = os.path.join(self.bdist_base, 'rpm')
    111         if self.python is None:
    112             if self.fix_python:
    113                 self.python = sys.executable
    114             else:
    115                 self.python = 'python'
    116         elif self.fix_python:
    117             raise DistutilsOptionError, '--python and --fix-python are mutually exclusive options'
    118         if os.name != 'posix':
    119             raise DistutilsPlatformError, "don't know how to create RPM distributions on platform %s" % os.name
    120         if self.binary_only and self.source_only:
    121             raise DistutilsOptionError, "cannot supply both '--source-only' and '--binary-only'"
    122         if not self.distribution.has_ext_modules():
    123             self.use_rpm_opt_flags = 0
    124         self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
    125         self.finalize_package_data()
    126 
    127     def finalize_package_data(self):
    128         self.ensure_string('group', 'Development/Libraries')
    129         self.ensure_string('vendor', '%s <%s>' % (self.distribution.get_contact(), self.distribution.get_contact_email()))
    130         self.ensure_string('packager')
    131         self.ensure_string_list('doc_files')
    132         if isinstance(self.doc_files, list):
    133             for readme in ('README', 'README.txt'):
    134                 if os.path.exists(readme) and readme not in self.doc_files:
    135                     self.doc_files.append(readme)
    136 
    137         self.ensure_string('release', '1')
    138         self.ensure_string('serial')
    139         self.ensure_string('distribution_name')
    140         self.ensure_string('changelog')
    141         self.changelog = self._format_changelog(self.changelog)
    142         self.ensure_filename('icon')
    143         self.ensure_filename('prep_script')
    144         self.ensure_filename('build_script')
    145         self.ensure_filename('install_script')
    146         self.ensure_filename('clean_script')
    147         self.ensure_filename('verify_script')
    148         self.ensure_filename('pre_install')
    149         self.ensure_filename('post_install')
    150         self.ensure_filename('pre_uninstall')
    151         self.ensure_filename('post_uninstall')
    152         self.ensure_string_list('provides')
    153         self.ensure_string_list('requires')
    154         self.ensure_string_list('conflicts')
    155         self.ensure_string_list('build_requires')
    156         self.ensure_string_list('obsoletes')
    157         self.ensure_string('force_arch')
    158 
    159     def run(self):
    160         if DEBUG:
    161             print 'before _get_package_data():'
    162             print 'vendor =', self.vendor
    163             print 'packager =', self.packager
    164             print 'doc_files =', self.doc_files
    165             print 'changelog =', self.changelog
    166         if self.spec_only:
    167             spec_dir = self.dist_dir
    168             self.mkpath(spec_dir)
    169         else:
    170             rpm_dir = {}
    171             for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'):
    172                 rpm_dir[d] = os.path.join(self.rpm_base, d)
    173                 self.mkpath(rpm_dir[d])
    174 
    175             spec_dir = rpm_dir['SPECS']
    176         spec_path = os.path.join(spec_dir, '%s.spec' % self.distribution.get_name())
    177         self.execute(write_file, (spec_path, self._make_spec_file()), "writing '%s'" % spec_path)
    178         if self.spec_only:
    179             return
    180         saved_dist_files = self.distribution.dist_files[:]
    181         sdist = self.reinitialize_command('sdist')
    182         if self.use_bzip2:
    183             sdist.formats = ['bztar']
    184         else:
    185             sdist.formats = ['gztar']
    186         self.run_command('sdist')
    187         self.distribution.dist_files = saved_dist_files
    188         source = sdist.get_archive_files()[0]
    189         source_dir = rpm_dir['SOURCES']
    190         self.copy_file(source, source_dir)
    191         if self.icon:
    192             if os.path.exists(self.icon):
    193                 self.copy_file(self.icon, source_dir)
    194             else:
    195                 raise DistutilsFileError, "icon file '%s' does not exist" % self.icon
    196         log.info('building RPMs')
    197         rpm_cmd = ['rpm']
    198         if os.path.exists('/usr/bin/rpmbuild') or os.path.exists('/bin/rpmbuild'):
    199             rpm_cmd = ['rpmbuild']
    200         if self.source_only:
    201             rpm_cmd.append('-bs')
    202         elif self.binary_only:
    203             rpm_cmd.append('-bb')
    204         else:
    205             rpm_cmd.append('-ba')
    206         if self.rpm3_mode:
    207             rpm_cmd.extend(['--define', '_topdir %s' % os.path.abspath(self.rpm_base)])
    208         if not self.keep_temp:
    209             rpm_cmd.append('--clean')
    210         if self.quiet:
    211             rpm_cmd.append('--quiet')
    212         rpm_cmd.append(spec_path)
    213         nvr_string = '%{name}-%{version}-%{release}'
    214         src_rpm = nvr_string + '.src.rpm'
    215         non_src_rpm = '%{arch}/' + nvr_string + '.%{arch}.rpm'
    216         q_cmd = "rpm -q --qf '%s %s\\n' --specfile '%s'" % (src_rpm, non_src_rpm, spec_path)
    217         out = os.popen(q_cmd)
    218         try:
    219             binary_rpms = []
    220             source_rpm = None
    221             while 1:
    222                 line = out.readline()
    223                 if not line:
    224                     break
    225                 l = string.split(string.strip(line))
    226                 binary_rpms.append(l[1])
    227                 if source_rpm is None:
    228                     source_rpm = l[0]
    229 
    230             status = out.close()
    231             if status:
    232                 raise DistutilsExecError('Failed to execute: %s' % repr(q_cmd))
    233         finally:
    234             out.close()
    235 
    236         self.spawn(rpm_cmd)
    237         if not self.dry_run:
    238             if not self.binary_only:
    239                 srpm = os.path.join(rpm_dir['SRPMS'], source_rpm)
    240                 self.move_file(srpm, self.dist_dir)
    241             if not self.source_only:
    242                 for rpm in binary_rpms:
    243                     rpm = os.path.join(rpm_dir['RPMS'], rpm)
    244                     if os.path.exists(rpm):
    245                         self.move_file(rpm, self.dist_dir)
    246 
    247     def _dist_path(self, path):
    248         return os.path.join(self.dist_dir, os.path.basename(path))
    249 
    250     def _make_spec_file(self):
    251         spec_file = ['%define name ' + self.distribution.get_name(),
    252          '%define version ' + self.distribution.get_version().replace('-', '_'),
    253          '%define unmangled_version ' + self.distribution.get_version(),
    254          '%define release ' + self.release.replace('-', '_'),
    255          '',
    256          'Summary: ' + self.distribution.get_description()]
    257         spec_file.extend(['Name: %{name}', 'Version: %{version}', 'Release: %{release}'])
    258         if self.use_bzip2:
    259             spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2')
    260         else:
    261             spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz')
    262         spec_file.extend(['License: ' + self.distribution.get_license(),
    263          'Group: ' + self.group,
    264          'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot',
    265          'Prefix: %{_prefix}'])
    266         if not self.force_arch:
    267             if not self.distribution.has_ext_modules():
    268                 spec_file.append('BuildArch: noarch')
    269         else:
    270             spec_file.append('BuildArch: %s' % self.force_arch)
    271         for field in ('Vendor', 'Packager', 'Provides', 'Requires', 'Conflicts', 'Obsoletes'):
    272             val = getattr(self, string.lower(field))
    273             if isinstance(val, list):
    274                 spec_file.append('%s: %s' % (field, string.join(val)))
    275             elif val is not None:
    276                 spec_file.append('%s: %s' % (field, val))
    277 
    278         if self.distribution.get_url() != 'UNKNOWN':
    279             spec_file.append('Url: ' + self.distribution.get_url())
    280         if self.distribution_name:
    281             spec_file.append('Distribution: ' + self.distribution_name)
    282         if self.build_requires:
    283             spec_file.append('BuildRequires: ' + string.join(self.build_requires))
    284         if self.icon:
    285             spec_file.append('Icon: ' + os.path.basename(self.icon))
    286         if self.no_autoreq:
    287             spec_file.append('AutoReq: 0')
    288         spec_file.extend(['', '%description', self.distribution.get_long_description()])
    289         def_setup_call = '%s %s' % (self.python, os.path.basename(sys.argv[0]))
    290         def_build = '%s build' % def_setup_call
    291         if self.use_rpm_opt_flags:
    292             def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build
    293         install_cmd = '%s install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES' % def_setup_call
    294         script_options = [('prep', 'prep_script', '%setup -n %{name}-%{unmangled_version}'),
    295          ('build', 'build_script', def_build),
    296          ('install', 'install_script', install_cmd),
    297          ('clean', 'clean_script', 'rm -rf $RPM_BUILD_ROOT'),
    298          ('verifyscript', 'verify_script', None),
    299          ('pre', 'pre_install', None),
    300          ('post', 'post_install', None),
    301          ('preun', 'pre_uninstall', None),
    302          ('postun', 'post_uninstall', None)]
    303         for rpm_opt, attr, default in script_options:
    304             val = getattr(self, attr)
    305             if val or default:
    306                 spec_file.extend(['', '%' + rpm_opt])
    307                 if val:
    308                     spec_file.extend(string.split(open(val, 'r').read(), '\n'))
    309                 else:
    310                     spec_file.append(default)
    311 
    312         spec_file.extend(['', '%files -f INSTALLED_FILES', '%defattr(-,root,root)'])
    313         if self.doc_files:
    314             spec_file.append('%doc ' + string.join(self.doc_files))
    315         if self.changelog:
    316             spec_file.extend(['', '%changelog'])
    317             spec_file.extend(self.changelog)
    318         return spec_file
    319 
    320     def _format_changelog(self, changelog):
    321         if not changelog:
    322             return changelog
    323         new_changelog = []
    324         for line in string.split(string.strip(changelog), '\n'):
    325             line = string.strip(line)
    326             if line[0] == '*':
    327                 new_changelog.extend(['', line])
    328             elif line[0] == '-':
    329                 new_changelog.append(line)
    330             else:
    331                 new_changelog.append('  ' + line)
    332 
    333         if not new_changelog[0]:
    334             del new_changelog[0]
    335         return new_changelog