Example #1
0
def check_cfg_files(cfg_files, module_name):
    """check if the configuration files actually specify something

    If config files are given, give warning if they don't contain
    information. This may indicate a wrong module name name, for
    example.
    """

    cfg = ConfigParser.SafeConfigParser()
    cfg.read(cfg_files)
    if cfg.has_section(module_name):
        section_items = cfg.items(module_name)
    else:
        section_items = []
    default_items = cfg.items('DEFAULT')

    n_items = len(section_items) + len(default_items)
    if n_items == 0:
        log.warn('configuration files were specified, but no options were '
                 'found in "%s" or "DEFAULT" sections.' % (module_name, ))
Example #2
0
def check_cfg_files(cfg_files,module_name):
    """check if the configuration files actually specify something

    If config files are given, give warning if they don't contain
    information. This may indicate a wrong module name name, for
    example.
    """

    cfg = ConfigParser.SafeConfigParser()
    cfg.read(cfg_files)
    if cfg.has_section(module_name):
        section_items = cfg.items(module_name)
    else:
        section_items = []
    default_items = cfg.items('DEFAULT')

    n_items = len(section_items) + len(default_items)
    if n_items==0:
        log.warn('configuration files were specified, but no options were '
                 'found in "%s" or "DEFAULT" sections.' % (module_name,) )
Example #3
0
 def _make_cfg_defaults(
     self,
     module_name=NotGiven,
     default_distribution=NotGiven,
     guess_maintainer=NotGiven,
 ):
     defaults = {}
     default_re = re.compile(r'^.* \(Default: (.*)\)$')
     for longopt, shortopt, description in stdeb_cfg_options:
         assert longopt.endswith('=')
         assert longopt.lower() == longopt
         key = longopt[:-1]
         matchobj = default_re.search(description)
         if matchobj is not None:
             # has a default value
             groups = matchobj.groups()
             assert len(groups) == 1
             value = groups[0]
             # A few special cases
             if value == '<source-debianized-setup-name>':
                 assert key == 'source'
                 value = source_debianize_name(module_name)
             elif value == 'python-<debianized-setup-name>':
                 assert key == 'package'
                 value = 'python-' + debianize_name(module_name)
             elif value == '<setup-maintainer-or-author>':
                 assert key == 'maintainer'
                 value = guess_maintainer
             if key == 'suite':
                 if default_distribution is not None:
                     value = default_distribution
                     log.warn('Deprecation warning: you are using the '
                              '--default-distribution option. '
                              'Switch to the --suite option.')
         else:
             # no default value
             value = ''
         defaults[key] = value
     return defaults
Example #4
0
    def run(self):
        ###############################################
        # 1. setup initial variables
        #    A. create config defaults
        module_name = self.distribution.get_name()

        if 1:
            # set default maintainer
            if (
                self.distribution.get_maintainer() != "UNKNOWN"
                and self.distribution.get_maintainer_email() != "UNKNOWN"
            ):
                guess_maintainer = "%s <%s>" % (
                    self.distribution.get_maintainer(),
                    self.distribution.get_maintainer_email(),
                )
            elif self.distribution.get_author() != "UNKNOWN" and self.distribution.get_author_email() != "UNKNOWN":
                guess_maintainer = "%s <%s>" % (self.distribution.get_author(), self.distribution.get_author_email())
            else:
                guess_maintainer = "unknown <unknown@unknown>"
        if self.default_maintainer is not None:
            log.warn(
                "Deprecation warning: you are using the "
                "--default-maintainer option. "
                "Switch to the --maintainer option."
            )
            guess_maintainer = self.default_maintainer

        #    B. find config files (if any)
        cfg_files = []
        if self.extra_cfg_file is not None:
            cfg_files.append(self.extra_cfg_file)

        use_setuptools = True
        try:
            ei_cmd = self.distribution.get_command_obj("egg_info")
        except DistutilsModuleError, err:
            use_setuptools = False
Example #5
0
 def _make_cfg_defaults(self,
                        module_name=NotGiven,
                        default_distribution=NotGiven,
                        guess_maintainer=NotGiven,
                        ):
     defaults = {}
     default_re = re.compile(r'^.* \(Default: (.*)\)$')
     for longopt,shortopt,description in stdeb_cfg_options:
         assert longopt.endswith('=')
         assert longopt.lower() == longopt
         key = longopt[:-1]
         matchobj = default_re.search( description )
         if matchobj is not None:
             # has a default value
             groups = matchobj.groups()
             assert len(groups)==1
             value = groups[0]
             # A few special cases
             if value == '<source-debianized-setup-name>':
                 assert key=='source'
                 value = source_debianize_name(module_name)
             elif value == 'python-<debianized-setup-name>':
                 assert key=='package'
                 value = 'python-' + debianize_name(module_name)
             elif value == '<setup-maintainer-or-author>':
                 assert key=='maintainer'
                 value = guess_maintainer
             if key=='suite':
                 if default_distribution is not None:
                     value = default_distribution
                     log.warn('Deprecation warning: you are using the '
                              '--default-distribution option. '
                              'Switch to the --suite option.')
         else:
             # no default value
             value = ''
         defaults[key] = value
     return defaults
Example #6
0
    def get_debinfo(self):
        ###############################################
        # 1. setup initial variables
        #    A. create config defaults
        module_name = self.distribution.get_name()

        if 1:
            # set default maintainer
            if (self.distribution.get_maintainer() != 'UNKNOWN'
                    and self.distribution.get_maintainer_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>" % (
                    self.distribution.get_maintainer(),
                    self.distribution.get_maintainer_email())
            elif (self.distribution.get_author() != 'UNKNOWN'
                  and self.distribution.get_author_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>" % (
                    self.distribution.get_author(),
                    self.distribution.get_author_email())
            else:
                guess_maintainer = "unknown <unknown@unknown>"
        if self.default_maintainer is not None:
            log.warn('Deprecation warning: you are using the '
                     '--default-maintainer option. '
                     'Switch to the --maintainer option.')
            guess_maintainer = self.default_maintainer

        #    B. find config files (if any)
        cfg_files = []
        if self.extra_cfg_file is not None:
            cfg_files.append(self.extra_cfg_file)

        use_setuptools = True
        try:
            ei_cmd = self.distribution.get_command_obj('egg_info')
        except DistutilsModuleError, err:
            use_setuptools = False
Example #7
0
    def run(self):
        debinfo = self.get_debinfo()
        if debinfo.patch_file != '' and self.patch_already_applied:
            raise RuntimeError('A patch was already applied, but another '
                               'patch is requested.')

        ###############################################
        # 2. Build source tree and rename it to be in self.dist_dir

        #    A. create source archive in new directory
        repackaged_dirname = debinfo.source+'-'+debinfo.upstream_version
        fullpath_repackaged_dirname = os.path.join(self.dist_dir,
                                                   repackaged_dirname)

        source_tarball = None
        cleanup_dirs = []

        exclude_dirs = ['.svn', '.git']
        # copy source tree
        if os.path.exists(fullpath_repackaged_dirname):
            shutil.rmtree(fullpath_repackaged_dirname)
        os.makedirs(fullpath_repackaged_dirname)
        orig_dir = os.path.abspath(os.curdir)
        for src in os.listdir(orig_dir):
            if src not in exclude_dirs+[self.dist_dir,'build','dist']:
                dst = os.path.join(fullpath_repackaged_dirname,src)
                if os.path.isdir(src):
                    shutil.copytree(src, dst, symlinks=True)
                else:
                    shutil.copy2(src, dst )
        # remove .pyc files which dpkg-source cannot package
        for root, dirs, files in os.walk(fullpath_repackaged_dirname):
            for name in files:
                if name.endswith('.pyc'):
                    fullpath = os.path.join(root,name)
                    os.unlink(fullpath)
            for name in dirs:
                if name in exclude_dirs:
                    fullpath = os.path.join(root,name)
                    shutil.rmtree(fullpath)

        if self.use_premade_distfile is not None:
        # ensure premade sdist can actually be used
            self.use_premade_distfile = os.path.abspath(self.use_premade_distfile)
            expand_dir = os.path.join(self.dist_dir,'tmp_sdist_dsc')
            cleanup_dirs.append(expand_dir)
            if os.path.exists(expand_dir):
                shutil.rmtree(expand_dir)
            if not os.path.exists(self.dist_dir):
                os.mkdir(self.dist_dir)
            os.mkdir(expand_dir)

            expand_sdist_file(self.use_premade_distfile,cwd=expand_dir)

            is_tgz=False
            if self.use_premade_distfile.lower().endswith('.tar.gz'):
                is_tgz=True

            # now the sdist package is expanded in expand_dir
            expanded_root_files = os.listdir(expand_dir)
            assert len(expanded_root_files)==1
            distname_in_premade_distfile = expanded_root_files[0]
            debianized_dirname = repackaged_dirname
            original_dirname = os.path.split(distname_in_premade_distfile)[-1]
            do_repack=False
            if is_tgz:
                source_tarball = self.use_premade_distfile
            else:
                log.warn('WARNING: .orig.tar.gz will be generated from sdist '
                         'archive ("%s") because it is not a .tar.gz file',
                         self.use_premade_distfile)
                do_repack=True

            if do_repack:
                tmp_dir = os.path.join(self.dist_dir, 'tmp_repacking_dir' )
                os.makedirs( tmp_dir )
                cleanup_dirs.append(tmp_dir)
                source_tarball = os.path.join(tmp_dir,'repacked_sdist.tar.gz')
                repack_tarball_with_debianized_dirname(self.use_premade_distfile,
                                                       source_tarball,
                                                       debianized_dirname,
                                                       original_dirname )
            if source_tarball is not None:
                # Because we deleted all .pyc files above, if the
                # original source dist has them, we will have
                # (wrongly) deleted them. So, quit loudly rather
                # than fail silently.
                for root, dirs, files in os.walk(fullpath_repackaged_dirname):
                    for name in files:
                        if name.endswith('.pyc'):
                            raise RuntimeError('original source dist cannot '
                                               'contain .pyc files')
        else:
            if 0:
                # haven't figured out why
                raise NotImplementedError("the code path is broken right now")


        ###############################################
        # 3. Find all directories

        for pkgdir in self.distribution.packages or []:
            debinfo.dirlist += ' ' + pkgdir.replace('.', '/')

        ###############################################
        # 4. Build source tree and rename it to be in self.dist_dir

        build_dsc(debinfo,
                  self.dist_dir,
                  repackaged_dirname,
                  orig_sdist=source_tarball,
                  patch_posix = self.patch_posix,
                  remove_expanded_source_dir=self.remove_expanded_source_dir,
                  )

        for rmdir in cleanup_dirs:
            shutil.rmtree(rmdir)
Example #8
0
def build_dsc(debinfo,
              dist_dir,
              repackaged_dirname,
              orig_sdist=None,
              patch_posix=0,
              remove_expanded_source_dir=0):
    """make debian source package"""
    #    A. Find new dirname and delete any pre-existing contents

    # dist_dir is usually 'deb_dist'

    # the location of the copied original source package (it was
    # re-recreated in dist_dir)
    fullpath_repackaged_dirname = os.path.join(dist_dir,repackaged_dirname)

    ###############################################
    # 1. make temporary original source tarball

    #    Note that, for the final tarball, best practices suggest
    #    using "dpkg-source -b".  See
    #    http://www.debian.org/doc/developers-reference/ch-best-pkging-practices.en.html

    # Create the name of the tarball that qualifies as the upstream
    # source. If the original was specified, we'll link to
    # it. Otherwise, we generate our own .tar.gz file from the output
    # of "python setup.py sdist" (done above) so that we avoid
    # packaging .svn directories, for example.

    repackaged_orig_tarball = ('%(source)s_%(upstream_version)s.orig.tar.gz'%
                               debinfo.__dict__)
    repackaged_orig_tarball_path = os.path.join(dist_dir,
                                                repackaged_orig_tarball)
    if orig_sdist is not None:
        if os.path.exists(repackaged_orig_tarball_path):
            os.unlink(repackaged_orig_tarball_path)
        link_func(orig_sdist,repackaged_orig_tarball_path)
    else:
        make_tarball(repackaged_orig_tarball,
                     repackaged_dirname,
                     cwd=dist_dir)

    # apply patch
    if debinfo.patch_file != '':
        apply_patch(debinfo.patch_file,
                    posix=patch_posix,
                    level=debinfo.patch_level,
                    cwd=fullpath_repackaged_dirname)

    for fname in ['Makefile','makefile']:
        if os.path.exists(os.path.join(fullpath_repackaged_dirname,fname)):
            sys.stderr.write('*'*1000 + '\n')
            sys.stderr.write('WARNING: a Makefile exists in this package. '
                             'debhelper 7 will attempt to use this rather than '
                             'setup.py to build and install the package.\n')
            sys.stderr.write('*'*1000 + '\n')


    ###############################################
    # 2. create debian/ directory and contents
    debian_dir = os.path.join(fullpath_repackaged_dirname,'debian')
    if not os.path.exists(debian_dir):
        os.mkdir(debian_dir)

    #    A. debian/changelog
    fd = open( os.path.join(debian_dir,'changelog'), mode='w')
    fd.write("""\
%(source)s (%(full_version)s) %(distname)s; urgency=low

  * source package automatically created by stdeb %(stdeb_version)s

 -- %(maintainer)s  %(date822)s\n"""%debinfo.__dict__)
    fd.close()

    #    B. debian/control
    if debinfo.uploaders:
        debinfo.uploaders = 'Uploaders: %s\n' % ', '.join(debinfo.uploaders)
    else:
        debinfo.uploaders = ''
    control = CONTROL_FILE%debinfo.__dict__
    fd = open( os.path.join(debian_dir,'control'), mode='w')
    fd.write(control)
    fd.close()

    #    C. debian/rules
    debinfo.percent_symbol = '%'
    rules = RULES_MAIN%debinfo.__dict__

    rules = rules.replace('        ','\t')
    rules_fname = os.path.join(debian_dir,'rules')
    fd = open( rules_fname, mode='w')
    fd.write(rules)
    fd.close()
    os.chmod(rules_fname,0755)

    #    D. debian/compat
    fd = open( os.path.join(debian_dir,'compat'), mode='w')
    fd.write('7\n')
    fd.close()

    #    E. debian/package.mime
    if debinfo.mime_file != '':
        if not os.path.exists(debinfo.mime_file):
            raise ValueError(
                'a MIME file was specified, but does not exist: %s'%(
                debinfo.mime_file,))
        link_func( debinfo.mime_file,
                 os.path.join(debian_dir,debinfo.package+'.mime'))
    if debinfo.shared_mime_file != '':
        if not os.path.exists(debinfo.shared_mime_file):
            raise ValueError(
                'a shared MIME file was specified, but does not exist: %s'%(
                debinfo.shared_mime_file,))
        link_func( debinfo.shared_mime_file,
                 os.path.join(debian_dir,
                              debinfo.package+'.sharedmimeinfo'))

    #    F. debian/copyright
    if debinfo.copyright_file != '':
        link_func( debinfo.copyright_file,
                 os.path.join(debian_dir,'copyright'))

    #    G. debian/<package>.preinst
    if debinfo.do_pycentral_removal_preinst:
        preinst = PREINST%debinfo.__dict__
        fd = open( os.path.join(debian_dir,'%s.preinst'%debinfo.package), mode='w')
        fd.write(preinst)
        fd.close()

    #    H. debian/<package>.install
    if len(debinfo.install_file_lines):
        fd = open( os.path.join(debian_dir,'%s.install'%debinfo.package), mode='w')
        fd.write('\n'.join(debinfo.install_file_lines)+'\n')
        fd.close()

    #    I. debian/<package>.udev
    if debinfo.udev_rules != '':
        fname = debinfo.udev_rules
        if not os.path.exists(fname):
            raise ValueError('udev rules file specified, but does not exist')
        link_func(fname,
                  os.path.join(debian_dir,'%s.udev'%debinfo.package))

    ###############################################
    # 3. unpack original source tarball

    debianized_package_dirname = fullpath_repackaged_dirname+'.debianized'
    if os.path.exists(debianized_package_dirname):
        raise RuntimeError('debianized_package_dirname exists: %s' %
                           debianized_package_dirname)
    #    A. move debianized tree away
    os.rename(fullpath_repackaged_dirname, debianized_package_dirname )
    if orig_sdist is not None:
        #    B. expand repackaged original tarball
        tmp_dir = os.path.join(dist_dir,'tmp-expand')
        os.mkdir(tmp_dir)
        try:
            expand_tarball(orig_sdist,cwd=tmp_dir)
            orig_tarball_top_contents = os.listdir(tmp_dir)

            # make sure original tarball has exactly one directory
            assert len(orig_tarball_top_contents)==1
            orig_dirname = orig_tarball_top_contents[0]
            fullpath_orig_dirname = os.path.join(tmp_dir,orig_dirname)

            #    C. move original repackaged tree to .orig
            target = fullpath_repackaged_dirname+'.orig'
            if os.path.exists(target):
                # here from previous invocation, probably
                shutil.rmtree(target)
            os.rename(fullpath_orig_dirname,target)

        finally:
            shutil.rmtree(tmp_dir)

    if 1:
        # check versions of debhelper and python-support
        debhelper_version_str = get_version_str('debhelper')
        if len(debhelper_version_str)==0:
            log.warn('This version of stdeb requires debhelper >= %s, but you '
                     'do not have debhelper installed. '
                     'Could not check compatibility.'%DH_MIN_VERS)
        else:
            if not dpkg_compare_versions(
                debhelper_version_str, 'ge', DH_MIN_VERS ):
                log.warn('This version of stdeb requires debhelper >= %s. '
                         'Use stdeb 0.3.x to generate source packages '
                         'compatible with older versions of debhelper.'%(
                    DH_MIN_VERS,))

        pysupport_version_str = get_version_str('python-support')
        if len(pysupport_version_str)==0:
            log.warn('This version of stdeb requires python-support >= %s, '
                     'but you do not have python-support installed. '
                     'Could not check compatibility.'%PYSUPPORT_MIN_VERS)
        else:
            if not dpkg_compare_versions(
                pysupport_version_str, 'ge', PYSUPPORT_MIN_VERS ):
                log.warn('This version of stdeb requires python-support >= %s. '
                         'Use stdeb 0.3.x to generate source packages '
                         'compatible with older versions of python-support.'%(
                    PYSUPPORT_MIN_VERS,))

    #    D. restore debianized tree
    os.rename(fullpath_repackaged_dirname+'.debianized',
              fullpath_repackaged_dirname)

    #    Re-generate tarball using best practices see
    #    http://www.debian.org/doc/developers-reference/ch-best-pkging-practices.en.html
    #    call "dpkg-source -b new_dirname orig_dirname"
    log.info('CALLING dpkg-source -b %s %s (in dir %s)'%(
        repackaged_dirname,
        repackaged_orig_tarball,
        dist_dir))

    dpkg_source('-b',repackaged_dirname,
                repackaged_orig_tarball,
                cwd=dist_dir)

    if 1:
        shutil.rmtree(fullpath_repackaged_dirname)

    if not remove_expanded_source_dir:
        # expand the debian source package
        dsc_name = debinfo.source + '_' + debinfo.dsc_version + '.dsc'
        dpkg_source('-x',dsc_name,
                    cwd=dist_dir)
Example #9
0
    def __init__(self,
                 cfg_files=NotGiven,
                 module_name=NotGiven,
                 default_distribution=NotGiven,
                 default_maintainer=NotGiven,
                 upstream_version=NotGiven,
                 egg_module_name=NotGiven,
                 has_ext_modules=NotGiven,
                 description=NotGiven,
                 long_description=NotGiven,
                 patch_file=None,
                 patch_level=None,
                 install_requires=None,
                 setup_requires=None,
                 debian_version=None,
                 workaround_548392=None,
                 have_script_entry_points = None,
                 pycentral_backwards_compatibility=None,
                 ):
        if cfg_files is NotGiven: raise ValueError("cfg_files must be supplied")
        if module_name is NotGiven: raise ValueError(
            "module_name must be supplied")
        if default_distribution is NotGiven: raise ValueError(
            "default_distribution must be supplied")
        if default_maintainer is NotGiven: raise ValueError(
            "default_maintainer must be supplied")
        if upstream_version is NotGiven: raise ValueError(
            "upstream_version must be supplied")
        if has_ext_modules is NotGiven: raise ValueError(
            "has_ext_modules must be supplied")
        if description is NotGiven: raise ValueError(
            "description must be supplied")
        if long_description is NotGiven: raise ValueError(
            "long_description must be supplied")

        cfg_defaults = self._make_cfg_defaults(
            module_name=module_name,
            default_distribution=default_distribution,
            default_maintainer=default_maintainer,
            )

        cfg = ConfigParser.SafeConfigParser(cfg_defaults)
        cfg.read(cfg_files)

        self.stdeb_version = __stdeb_version__
        self.module_name = module_name
        self.source = parse_val(cfg,module_name,'Source')
        self.package = parse_val(cfg,module_name,'Package')
        forced_upstream_version = parse_val(cfg,module_name,
                                            'Forced-Upstream-Version')
        if forced_upstream_version == '':
            upstream_version_prefix = parse_val(cfg,module_name,
                                                'Upstream-Version-Prefix')
            upstream_version_suffix = parse_val(cfg,module_name,
                                                'Upstream-Version-Suffix')
            self.upstream_version = (upstream_version_prefix+
                                        debianize_version(upstream_version)+
                                        upstream_version_suffix)
        else:
            if (debianize_version(forced_upstream_version) !=
                forced_upstream_version):
                raise ValueError('forced upstream version ("%s") not a '
                                 'Debian-compatible version (e.g. "%s")'%(
                    forced_upstream_version,
                    debianize_version(forced_upstream_version)))
            self.upstream_version = forced_upstream_version
        self.egg_module_name = egg_module_name
        self.epoch = parse_val(cfg,module_name,'Epoch')
        if self.epoch != '' and not self.epoch.endswith(':'):
            self.epoch = self.epoch + ':'
        self.packaging_version = parse_val(cfg,module_name,'Debian-Version')
        if debian_version is not None:
            # command-line arg overrides file
            self.packaging_version = debian_version
        self.dsc_version = '%s-%s'%(
            self.upstream_version,
            self.packaging_version)
        self.full_version = '%s%s-%s'%(
            self.epoch,
            self.upstream_version,
            self.packaging_version)
        self.distname = parse_val(cfg,module_name,'Distribution')
        self.maintainer = ', '.join(parse_vals(cfg,module_name,'Maintainer'))
        self.uploaders = parse_vals(cfg,module_name,'Uploaders')
        self.date822 = get_date_822()

        build_deps = ['python-setuptools (>= 0.6b3)']
        build_deps.extend(
            get_deb_depends_from_setuptools_requires(setup_requires))

        depends = ['${python:Depends}', 'python-pkg-resources']
        need_custom_binary_target = False

        self.do_pycentral_removal_preinst = pycentral_backwards_compatibility

        if has_ext_modules:
            self.architecture = 'any'
            depends.append('${shlibs:Depends}')
            build_deps.append('python-all-dev')
        else:
            self.architecture = 'all'

        self.copyright_file = parse_val(cfg,module_name,'Copyright-File')
        self.mime_file = parse_val(cfg,module_name,'MIME-File')

        self.shared_mime_file = parse_val(cfg,module_name,'Shared-MIME-File')

        if self.mime_file == '' and self.shared_mime_file == '':
            self.dh_installmime_line = ''
        else:
            need_custom_binary_target = True
            self.dh_installmime_line = '\tdh_installmime'
            if self.architecture == 'all':
                self.dh_installmime_line += ' -i'
            else:
                self.dh_installmime_line += ' -a'

        mime_desktop_files = parse_vals(cfg,module_name,'MIME-Desktop-Files')
        if len(mime_desktop_files):
            need_custom_binary_target = True
            self.dh_desktop_line = '\tdh_desktop'
            if self.architecture == 'all':
                self.dh_desktop_line += ' -i'
            else:
                self.dh_desktop_line += ' -a'
        else:
            self.dh_desktop_line = ''

        #    E. any mime .desktop files
        self.install_file_lines = []
        for mime_desktop_file in mime_desktop_files:
            self.install_file_lines.append(
                '%s usr/share/applications'%mime_desktop_file)

        depends.extend(parse_vals(cfg,module_name,'Depends') )
        depends.extend(get_deb_depends_from_setuptools_requires(
            install_requires))
        self.depends = ', '.join(depends)

        self.description = description
        if long_description != 'UNKNOWN':
            ld2=[]
            for line in long_description.split('\n'):
                ls = line.strip()
                if len(ls):
                    ld2.append(' '+line)
                else:
                    ld2.append(' .')
            self.long_description = '\n'.join(ld2)
        else:
            self.long_description = ''

        if have_script_entry_points:
            if workaround_548392:
                build_deps.append( 'debhelper (>= %s)'%DH_MIN_VERS)
            else:
                build_deps.append( 'debhelper (>= %s)'%DH_IDEAL_VERS )
        else:
            build_deps.append( 'debhelper (>= %s)'%DH_MIN_VERS )

        build_deps.append('python-support (>= %s)'%PYSUPPORT_MIN_VERS)

        build_deps.extend( parse_vals(cfg,module_name,'Build-Depends') )
        self.build_depends = ', '.join(build_deps)

        self.suggests = ', '.join( parse_vals(cfg,module_name,'Suggests') )
        self.recommends = ', '.join( parse_vals(cfg,module_name,'Recommends') )

        self.source_stanza_extras = ''

        build_conflicts = parse_vals(cfg,module_name,'Build-Conflicts')
        if len(build_conflicts):
            self.source_stanza_extras += ('Build-Conflicts: '+
                                              ', '.join( build_conflicts )+'\n')

        self.patch_file = parse_val(cfg,module_name,'Stdeb-Patch-File')

        if patch_file is not None:
            if self.patch_file != '':
                raise RuntimeError('A patch file was specified on the command '
                                   'line and in .cfg file.')
            else:
                self.patch_file = patch_file

        self.patch_level = parse_val(cfg,module_name,'Stdeb-Patch-Level')
        if self.patch_level != '':
            if patch_level is not None:
                raise RuntimeError('A patch level was specified on the command '
                                   'line and in .cfg file.')
            else:
                self.patch_level = int(self.patch_level)
        else:
            if patch_level is not None:
                self.patch_level = patch_level
            else:
                self.patch_level = 0

        xs_python_version = parse_vals(cfg,module_name,'XS-Python-Version')
        if have_script_entry_points and workaround_548392:

            # Trap cases that might trigger Debian bug #548392 and
            # workaround. Disable this block once the bugfix has
            # become widespread and change Build-Depends: to include
            # sufficiently recent debhelper.

            if len(xs_python_version)==0:
                # No Python version specified. For now, just use default Python
                log.warn('working around Debian #548392, changing '
                         'XS-Python-Version: to \'current\'')
                xs_python_version = ['current']
            else:

                # The user specified a Python version. Check if s/he
                # specified more than one. (Specifying a single
                # version won't trigger the bug.)

                pyversions_fname = '/usr/bin/pyversions'
                assert os.path.exists(pyversions_fname)
                pyversions = load_module('pyversions',pyversions_fname)
                vstring = ', '.join(xs_python_version)
                pyversions_result = pyversions.parse_versions(vstring)
                if ('versions' in pyversions_result and
                    len(pyversions_result['versions'])>1):

                    vers = list(pyversions_result['versions'])
                    # More than one Python version specified.

                    # This is dubious as the following comparison
                    # happens at source build time, but what matters
                    # is what runs when building the binary package.

                    default_vers = pyversions.default_version(version_only=True)
                    if default_vers in vers:
                        log.warn('working around Debian #548392, changing '
                                 'XS-Python-Version: to \'current\'')
                        xs_python_version = ['current']
                    else:
                        vers.sort()
                        log.warn('working around Debian #548392, changing '
                                 'XS-Python-Version: to \'%s\''%vers[-1])
                        xs_python_version = [vers[-1]]
                elif 'all' in pyversions_result:
                    log.warn('working around Debian #548392, changing '
                             'XS-Python-Version: to \'current\'')
                    xs_python_version = ['current']

        if len(xs_python_version)!=0:
            self.source_stanza_extras += ('XS-Python-Version: '+
                                          ', '.join(xs_python_version)+'\n')
        self.package_stanza_extras = """\
XB-Python-Version: ${python:Versions}
"""

        dpkg_shlibdeps_params = parse_val(
            cfg,module_name,'dpkg-shlibdeps-params')
        if dpkg_shlibdeps_params:
            need_custom_binary_target = True
            self.dh_binary_lines = """\tdh binary --before dh_shlibdeps
\tdh_shlibdeps -a --dpkg-shlibdeps-params=%s
\tdh binary --after dh_shlibdeps"""%dpkg_shlibdeps_params

        else:
            self.dh_binary_lines = '\tdh binary'

        conflicts = parse_vals(cfg,module_name,'Conflicts')
        if len(conflicts):
            self.package_stanza_extras += ('Conflicts: '+
                                              ', '.join( conflicts )+'\n')

        provides = parse_vals(cfg,module_name,'Provides')
        provides.insert(0, 'Provides: ${python:Provides}')
        self.package_stanza_extras += ', '.join( provides  )+'\n'

        replaces = parse_vals(cfg,module_name,'Replaces')
        if len(replaces):
            self.package_stanza_extras += ('Replaces: ' +
                                              ', '.join( replaces  )+'\n')
        self.dirlist = ""

        setup_env_vars = parse_vals(cfg,module_name,'Setup-Env-Vars')
        self.exports = ""
        if len(setup_env_vars):
            self.exports += '\n'
            self.exports += '#exports specified using stdeb Setup-Env-Vars:\n'
            self.exports += '\n'.join(['export %s'%v for v in setup_env_vars])
            self.exports += '\n'
        self.udev_rules = parse_val(cfg,module_name,'Udev-Rules')

        if need_custom_binary_target:
            self.binary_target_lines = RULES_BINARY_TARGET%self.__dict__
        else:
            self.binary_target_lines = ''
Example #10
0
        if l:
            emo = E.search(l)
            assert emo, l
            dmo = D.search(l)
            assert dmo, l
            eggsndebs.add((emo.group(1), dmo.group(1)))

    for (egginfo, debname) in eggsndebs:
        pydist = pkg_resources.Distribution.from_filename(egginfo)
        try:
            dd.setdefault(
                pydist.project_name.lower(), {}).setdefault(
                pydist, set()).add(debname)
        except ValueError, le:
            log.warn("I got an error parsing a .egg-info file named \"%s\" "
                     "from Debian package \"%s\" as a pkg_resources "
                     "Distribution: %s" % (egginfo, debname, le,))
            pass

    # Now for each requirement, see if a Debian package satisfies it.
    ops = {'<':'<<','>':'>>','==':'=','<=':'<=','>=':'>='}
    for req in parsed_reqs:
        reqname = req.project_name.lower()
        gooddebs = set()
        for pydist, debs in dd.get(reqname, {}).iteritems():
            if pydist in req:
                ## log.info("I found Debian packages \"%s\" which provides "
                ##          "Python package \"%s\", version \"%s\", which "
                ##          "satisfies our version requirements: \"%s\""
                ##          % (', '.join(debs), req.project_name, ver, req)
                gooddebs |= (debs)
Example #11
0
    def run(self):
        debinfo = self.get_debinfo()
        if debinfo.patch_file != '' and self.patch_already_applied:
            raise RuntimeError('A patch was already applied, but another '
                               'patch is requested.')

        repackaged_dirname = debinfo.source + '-' + debinfo.upstream_version
        fullpath_repackaged_dirname = os.path.join(self.dist_dir,
                                                   repackaged_dirname)

        cleanup_dirs = []
        if self.use_premade_distfile is None:
            # generate original tarball
            sdist_cmd = self.distribution.get_command_obj('sdist')
            self.run_command('sdist')

            source_tarball = None
            for archive_file in sdist_cmd.get_archive_files():
                if archive_file.endswith('.tar.gz'):
                    source_tarball = archive_file

            if source_tarball is None:
                raise RuntimeError('sdist did not produce .tar.gz file')

            # make copy of source tarball in deb_dist/
            local_source_tarball = os.path.split(source_tarball)[-1]
            shutil.copy2(source_tarball, local_source_tarball)
            source_tarball = local_source_tarball
            self.use_premade_distfile = source_tarball
        else:
            source_tarball = self.use_premade_distfile

        # Copy source tree assuming that package-0.1.tar.gz contains
        # single top-level path 'package-0.1'. The contents of this
        # directory are then used.

        if os.path.exists(fullpath_repackaged_dirname):
            shutil.rmtree(fullpath_repackaged_dirname)

        tmpdir = tempfile.mkdtemp()
        expand_sdist_file(os.path.abspath(source_tarball), cwd=tmpdir)
        expanded_base_files = os.listdir(tmpdir)
        assert len(expanded_base_files) == 1
        actual_package_dirname = expanded_base_files[0]
        expected_package_dirname = debinfo.module_name + '-' + debinfo.upstream_version
        shutil.move(os.path.join(tmpdir, actual_package_dirname),
                    fullpath_repackaged_dirname)

        # ensure premade sdist can actually be used
        self.use_premade_distfile = os.path.abspath(self.use_premade_distfile)
        expand_dir = os.path.join(self.dist_dir, 'tmp_sdist_dsc')
        cleanup_dirs.append(expand_dir)
        if os.path.exists(expand_dir):
            shutil.rmtree(expand_dir)
        if not os.path.exists(self.dist_dir):
            os.mkdir(self.dist_dir)
        os.mkdir(expand_dir)

        expand_sdist_file(self.use_premade_distfile, cwd=expand_dir)

        is_tgz = False
        if self.use_premade_distfile.lower().endswith('.tar.gz'):
            is_tgz = True

        # now the sdist package is expanded in expand_dir
        expanded_root_files = os.listdir(expand_dir)
        assert len(expanded_root_files) == 1
        distname_in_premade_distfile = expanded_root_files[0]
        debianized_dirname = repackaged_dirname
        original_dirname = os.path.split(distname_in_premade_distfile)[-1]
        do_repack = False
        if is_tgz:
            source_tarball = self.use_premade_distfile
        else:
            log.warn(
                'WARNING: .orig.tar.gz will be generated from sdist '
                'archive ("%s") because it is not a .tar.gz file',
                self.use_premade_distfile)
            do_repack = True

        if do_repack:
            tmp_dir = os.path.join(self.dist_dir, 'tmp_repacking_dir')
            os.makedirs(tmp_dir)
            cleanup_dirs.append(tmp_dir)
            source_tarball = os.path.join(tmp_dir, 'repacked_sdist.tar.gz')
            repack_tarball_with_debianized_dirname(self.use_premade_distfile,
                                                   source_tarball,
                                                   debianized_dirname,
                                                   original_dirname)
        if source_tarball is not None:
            # Because we deleted all .pyc files above, if the
            # original source dist has them, we will have
            # (wrongly) deleted them. So, quit loudly rather
            # than fail silently.
            for root, dirs, files in os.walk(fullpath_repackaged_dirname):
                for name in files:
                    if name.endswith('.pyc'):
                        raise RuntimeError('original source dist cannot '
                                           'contain .pyc files')

        ###############################################
        # 3. Find all directories

        for pkgdir in self.distribution.packages or []:
            debinfo.dirlist += ' ' + pkgdir.replace('.', '/')

        ###############################################
        # 4. Build source tree and rename it to be in self.dist_dir

        build_dsc(
            debinfo,
            self.dist_dir,
            repackaged_dirname,
            orig_sdist=source_tarball,
            patch_posix=self.patch_posix,
            remove_expanded_source_dir=self.remove_expanded_source_dir,
            sign_dsc=self.sign_results,
            extend_diff_ignore=self.extend_diff_ignore,
        )

        for rmdir in cleanup_dirs:
            shutil.rmtree(rmdir)
Example #12
0
    def __init__(self,
                 cfg_files=NotGiven,
                 module_name=NotGiven,
                 default_distribution=NotGiven,
                 guess_maintainer=NotGiven,
                 upstream_version=NotGiven,
                 has_ext_modules=NotGiven,
                 description=NotGiven,
                 long_description=NotGiven,
                 patch_file=None,
                 patch_level=None,
                 install_requires=None,
                 setup_requires=None,
                 debian_version=None,
                 workaround_548392=None,
                 force_buildsystem=None,
                 have_script_entry_points = None,
                 pycentral_backwards_compatibility=None,
                 use_setuptools = False,
                 guess_conflicts_provides_replaces = False,
                 sdist_dsc_command = None,
                 ):
        if cfg_files is NotGiven: raise ValueError("cfg_files must be supplied")
        if module_name is NotGiven: raise ValueError(
            "module_name must be supplied")
        if default_distribution is NotGiven: raise ValueError(
            "default_distribution must be supplied")
        if guess_maintainer is NotGiven: raise ValueError(
            "guess_maintainer must be supplied")
        if upstream_version is NotGiven: raise ValueError(
            "upstream_version must be supplied")
        if has_ext_modules is NotGiven: raise ValueError(
            "has_ext_modules must be supplied")
        if description is NotGiven: raise ValueError(
            "description must be supplied")
        if long_description is NotGiven: raise ValueError(
            "long_description must be supplied")

        cfg_defaults = self._make_cfg_defaults(
            module_name=module_name,
            default_distribution=default_distribution,
            guess_maintainer=guess_maintainer,
            )

        if len(cfg_files):
            check_cfg_files(cfg_files,module_name)

        cfg = ConfigParser.SafeConfigParser(cfg_defaults)
        cfg.read(cfg_files)

        if sdist_dsc_command is not None:
            # Allow distutils commands to override config files (this lets
            # command line options beat file options).
            for longopt, shortopt, desc in stdeb_cfg_options:
                name = longopt[:-1]
                name = name.replace('-','_')
                value = getattr( sdist_dsc_command, name )
                if value is not None:
                    cfg.set( module_name, name, value )

        self.stdeb_version = __stdeb_version__
        self.module_name = module_name
        self.source = parse_val(cfg,module_name,'Source')
        self.package = parse_val(cfg,module_name,'Package')
        forced_upstream_version = parse_val(cfg,module_name,
                                            'Forced-Upstream-Version')
        if forced_upstream_version == '':
            upstream_version_prefix = parse_val(cfg,module_name,
                                                'Upstream-Version-Prefix')
            upstream_version_suffix = parse_val(cfg,module_name,
                                                'Upstream-Version-Suffix')
            self.upstream_version = (upstream_version_prefix+
                                        debianize_version(upstream_version)+
                                        upstream_version_suffix)
        else:
            if (debianize_version(forced_upstream_version) !=
                forced_upstream_version):
                raise ValueError('forced upstream version ("%s") not a '
                                 'Debian-compatible version (e.g. "%s")'%(
                    forced_upstream_version,
                    debianize_version(forced_upstream_version)))
            self.upstream_version = forced_upstream_version
        self.epoch = parse_val(cfg,module_name,'Epoch')
        if self.epoch != '' and not self.epoch.endswith(':'):
            self.epoch = self.epoch + ':'
        self.packaging_version = parse_val(cfg,module_name,'Debian-Version')
        if debian_version is not None:
            # command-line arg overrides file
            self.packaging_version = debian_version
        self.dsc_version = '%s-%s'%(
            self.upstream_version,
            self.packaging_version)
        self.full_version = '%s%s-%s'%(
            self.epoch,
            self.upstream_version,
            self.packaging_version)
        self.distname = parse_val(cfg,module_name,'Suite')
        self.maintainer = ', '.join(parse_vals(cfg,module_name,'Maintainer'))
        self.uploaders = parse_vals(cfg,module_name,'Uploaders')
        self.date822 = get_date_822()

        build_deps = []
        if use_setuptools:
            build_deps.append('python-setuptools (>= 0.6b3)')
	if setup_requires is not None and len(setup_requires):
            build_deps.extend(
                get_deb_depends_from_setuptools_requires(setup_requires))

        depends = ['${python:Depends}']
        need_custom_binary_target = False

        self.do_pycentral_removal_preinst = pycentral_backwards_compatibility

        if has_ext_modules:
            self.architecture = 'any'
            depends.append('${shlibs:Depends}')
            build_deps.append('python-all-dev')
        else:
            self.architecture = 'all'

        self.copyright_file = parse_val(cfg,module_name,'Copyright-File')
        self.mime_file = parse_val(cfg,module_name,'MIME-File')

        self.shared_mime_file = parse_val(cfg,module_name,'Shared-MIME-File')

        if self.mime_file == '' and self.shared_mime_file == '':
            self.dh_installmime_line = ''
        else:
            need_custom_binary_target = True
            self.dh_installmime_line = '\tdh_installmime'
            if self.architecture == 'all':
                self.dh_installmime_line += ' -i'
            else:
                self.dh_installmime_line += ' -a'

        mime_desktop_files = parse_vals(cfg,module_name,'MIME-Desktop-Files')
        if len(mime_desktop_files):
            need_custom_binary_target = True
            self.dh_desktop_line = '\tdh_desktop'
            if self.architecture == 'all':
                self.dh_desktop_line += ' -i'
            else:
                self.dh_desktop_line += ' -a'
        else:
            self.dh_desktop_line = ''

        #    E. any mime .desktop files
        self.install_file_lines = []
        for mime_desktop_file in mime_desktop_files:
            self.install_file_lines.append(
                '%s usr/share/applications'%mime_desktop_file)

        depends.extend(parse_vals(cfg,module_name,'Depends') )
	if install_requires is not None and len(install_requires):
            depends.extend(get_deb_depends_from_setuptools_requires(
                install_requires))
        self.depends = ', '.join(depends)

        self.debian_section = parse_val(cfg,module_name,'Section')

        self.description = description
        if long_description != 'UNKNOWN':
            ld2=[]
            for line in long_description.split('\n'):
                ls = line.strip()
                if len(ls):
                    ld2.append(' '+line)
                else:
                    ld2.append(' .')
            ld2 = ld2[:20]
            self.long_description = '\n'.join(ld2)
        else:
            self.long_description = ''

        if have_script_entry_points:
            if workaround_548392:
                build_deps.append( 'debhelper (>= %s)'%DH_MIN_VERS)
            else:
                build_deps.append( 'debhelper (>= %s)'%DH_IDEAL_VERS )
        else:
            build_deps.append( 'debhelper (>= %s)'%DH_MIN_VERS )

        build_deps.append('python-support (>= %s)'%PYSUPPORT_MIN_VERS)

        build_deps.extend( parse_vals(cfg,module_name,'Build-Depends') )
        self.build_depends = ', '.join(build_deps)

        suggests = ', '.join( parse_vals(cfg,module_name,'Suggests') )
        recommends = ', '.join( parse_vals(cfg,module_name,'Recommends') )

        self.source_stanza_extras = ''

        build_conflicts = parse_vals(cfg,module_name,'Build-Conflicts')
        if len(build_conflicts):
            self.source_stanza_extras += ('Build-Conflicts: '+
                                              ', '.join( build_conflicts )+'\n')

        self.patch_file = parse_val(cfg,module_name,'Stdeb-Patch-File')

        if patch_file is not None:
            if self.patch_file != '':
                raise RuntimeError('A patch file was specified on the command '
                                   'line and in .cfg file.')
            else:
                self.patch_file = patch_file

        self.patch_level = parse_val(cfg,module_name,'Stdeb-Patch-Level')
        if self.patch_level != '':
            if patch_level is not None:
                raise RuntimeError('A patch level was specified on the command '
                                   'line and in .cfg file.')
            else:
                self.patch_level = int(self.patch_level)
        else:
            if patch_level is not None:
                self.patch_level = patch_level
            else:
                self.patch_level = 0

        xs_python_version = parse_vals(cfg,module_name,'XS-Python-Version')
        if have_script_entry_points and workaround_548392:

            # Trap cases that might trigger Debian bug #548392 and
            # workaround. Disable this block once the bugfix has
            # become widespread and change Build-Depends: to include
            # sufficiently recent debhelper.

            if len(xs_python_version)==0:
                # No Python version specified. For now, just use default Python
                log.warn('working around Debian #548392, changing '
                         'XS-Python-Version: to \'current\'')
                xs_python_version = ['current']
            else:

                # The user specified a Python version. Check if s/he
                # specified more than one. (Specifying a single
                # version won't trigger the bug.)

                pyversions_fname = '/usr/bin/pyversions'
                assert os.path.exists(pyversions_fname)
                pyversions = load_module('pyversions',pyversions_fname)
                vstring = ', '.join(xs_python_version)
                pyversions_result = pyversions.parse_versions(vstring)
                if ('versions' in pyversions_result and
                    len(pyversions_result['versions'])>1):

                    vers = list(pyversions_result['versions'])
                    # More than one Python version specified.

                    # This is dubious as the following comparison
                    # happens at source build time, but what matters
                    # is what runs when building the binary package.

                    default_vers = pyversions.default_version(version_only=True)
                    if default_vers in vers:
                        log.warn('working around Debian #548392, changing '
                                 'XS-Python-Version: to \'current\'')
                        xs_python_version = ['current']
                    else:
                        vers.sort()
                        log.warn('working around Debian #548392, changing '
                                 'XS-Python-Version: to \'%s\''%vers[-1])
                        xs_python_version = [vers[-1]]
                elif 'all' in pyversions_result:
                    log.warn('working around Debian #548392, changing '
                             'XS-Python-Version: to \'current\'')
                    xs_python_version = ['current']

        if len(xs_python_version)!=0:
            self.source_stanza_extras += ('XS-Python-Version: '+
                                          ', '.join(xs_python_version)+'\n')
        self.package_stanza_extras = """\
XB-Python-Version: ${python:Versions}
"""

        dpkg_shlibdeps_params = parse_val(
            cfg,module_name,'dpkg-shlibdeps-params')
        if dpkg_shlibdeps_params:
            need_custom_binary_target = True
            self.dh_binary_lines = """\tdh binary --before dh_shlibdeps
\tdh_shlibdeps -a --dpkg-shlibdeps-params=%s
\tdh binary --after dh_shlibdeps"""%dpkg_shlibdeps_params

        else:
            self.dh_binary_lines = '\tdh binary'

        conflicts = parse_vals(cfg,module_name,'Conflicts')
        provides = parse_vals(cfg,module_name,'Provides')
        replaces = parse_vals(cfg,module_name,'Replaces')

        if guess_conflicts_provides_replaces:
            # Find list of binaries which we will conflict/provide/replace.

            cpr_binaries = set()

            # Get original Debian information for the package named the same.
            for version_info in apt_cache_info('showsrc',self.package):

                # Remember each of the binary packages produced by the Debian source
                for binary in version_info['Binary']:
                    cpr_binaries.add(binary)

                # TODO: do this for every version available , just the
                # first, or ???
                break

            # Descend each of the original binaries and see what
            # packages they conflict/ provide/ replace:
            for orig_binary in cpr_binaries:
                for version_info in apt_cache_info('show',orig_binary):
                    provides.extend( version_info['Provides'])
                    conflicts.extend(version_info['Conflicts'])
                    replaces.extend( version_info['Replaces'])

            if self.package in cpr_binaries:
                cpr_binaries.remove(self.package) # don't include ourself

            cpr_binaries = list(cpr_binaries) # convert to list

            conflicts.extend( cpr_binaries )
            provides.extend( cpr_binaries )
            replaces.extend( cpr_binaries )

            # round-trip through set to get unique entries
            conflicts = list(set(conflicts))
            provides = list(set(provides))
            replaces = list(set(replaces))

        if len(conflicts):
            self.package_stanza_extras += ('Conflicts: '+
                                              ', '.join( conflicts )+'\n')

        provides.insert(0, 'Provides: ${python:Provides}')
        self.package_stanza_extras += ', '.join( provides  )+'\n'

        if len(replaces):
            self.package_stanza_extras += ('Replaces: ' +
                                              ', '.join( replaces  )+'\n')
        if len(recommends):
            self.package_stanza_extras += ('Recommends: '+recommends+'\n')

        if len(suggests):
            self.package_stanza_extras += ('Suggests: '+suggests+'\n')

        self.dirlist = ""

        setup_env_vars = parse_vals(cfg,module_name,'Setup-Env-Vars')
        if force_buildsystem:
            setup_env_vars.append('DH_OPTIONS=--buildsystem=python_distutils')
        self.force_buildsystem = force_buildsystem
        self.exports = ""
        if len(setup_env_vars):
            self.exports += '\n'
            self.exports += '#exports specified using stdeb Setup-Env-Vars:\n'
            self.exports += '\n'.join(['export %s'%v for v in setup_env_vars])
            self.exports += '\n'
        self.udev_rules = parse_val(cfg,module_name,'Udev-Rules')

        if need_custom_binary_target:
            self.binary_target_lines = RULES_BINARY_TARGET%self.__dict__
        else:
            self.binary_target_lines = ''
Example #13
0
class common_debian_package_command(Command):
    def initialize_options(self):
        self.patch_already_applied = 0
        self.remove_expanded_source_dir = 0
        self.patch_posix = 0
        self.dist_dir = None
        self.extra_cfg_file = None
        self.patch_file = None
        self.patch_level = None
        self.ignore_install_requires = None
        self.debian_version = None
        self.force_buildsystem = None
        self.no_backwards_compatibility = None
        self.guess_conflicts_provides_replaces = None

        # deprecated options
        self.default_distribution = None
        self.default_maintainer = None

        # make distutils happy by filling in default values
        for longopt, shortopt, description in stdeb_cfg_options:
            assert longopt.endswith('=')
            name = longopt[:-1]
            name = name.replace('-', '_')
            setattr(self, name, None)

    def finalize_options(self):
        def str_to_bool(mystr):
            if mystr.lower() == 'false':
                return False
            elif mystr.lower() == 'true':
                return True
            else:
                raise ValueError('bool string "%s" is not "true" or "false"' %
                                 mystr)

        if self.dist_dir is None:
            self.dist_dir = 'deb_dist'
        if self.patch_level is not None:
            self.patch_level = int(self.patch_level)

        if self.force_buildsystem is not None:
            self.force_buildsystem = str_to_bool(self.force_buildsystem)

        if self.force_buildsystem is None:
            self.force_buildsystem = True

        if self.guess_conflicts_provides_replaces is None:
            # the default
            self.guess_conflicts_provides_replaces = False
        else:
            self.guess_conflicts_provides_replaces = str_to_bool(
                self.guess_conflicts_provides_replaces)

    def get_debinfo(self):
        ###############################################
        # 1. setup initial variables
        #    A. create config defaults
        module_name = self.distribution.get_name()

        if 1:
            # set default maintainer
            if (self.distribution.get_maintainer() != 'UNKNOWN'
                    and self.distribution.get_maintainer_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>" % (
                    self.distribution.get_maintainer(),
                    self.distribution.get_maintainer_email())
            elif (self.distribution.get_author() != 'UNKNOWN'
                  and self.distribution.get_author_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>" % (
                    self.distribution.get_author(),
                    self.distribution.get_author_email())
            else:
                guess_maintainer = "unknown <unknown@unknown>"
        if self.default_maintainer is not None:
            log.warn('Deprecation warning: you are using the '
                     '--default-maintainer option. '
                     'Switch to the --maintainer option.')
            guess_maintainer = self.default_maintainer

        #    B. find config files (if any)
        cfg_files = []
        if self.extra_cfg_file is not None:
            cfg_files.append(self.extra_cfg_file)

        use_setuptools = True
        try:
            ei_cmd = self.distribution.get_command_obj('egg_info')
        except DistutilsModuleError, err:
            use_setuptools = False

        have_script_entry_points = None

        config_fname = 'stdeb.cfg'
        # Distutils fails if not run from setup.py dir, so this is OK.
        if os.path.exists(config_fname):
            cfg_files.append(config_fname)

        if use_setuptools:
            self.run_command('egg_info')
            egg_info_dirname = ei_cmd.egg_info

            # Pickup old location of stdeb.cfg
            config_fname = os.path.join(egg_info_dirname, 'stdeb.cfg')
            if os.path.exists(config_fname):
                log.warn('Deprecation warning: stdeb detected old location of '
                         'stdeb.cfg in %s. This file will be used, but you '
                         'should move it alongside setup.py.' %
                         egg_info_dirname)
                cfg_files.append(config_fname)

            egg_module_name = egg_info_dirname[:egg_info_dirname.
                                               index('.egg-info')]
            egg_module_name = egg_module_name.split(os.sep)[-1]

            if 1:
                # determine whether script specifies setuptools entry_points
                ep_fname = os.path.join(egg_info_dirname, 'entry_points.txt')
                if os.path.exists(ep_fname):
                    entry_points = open(ep_fname, 'rU').readlines()
                else:
                    entry_points = ''
                entry_points = [ep.strip() for ep in entry_points]

                if ('[console_scripts]' in entry_points
                        or '[gui_scripts]' in entry_points):
                    have_script_entry_points = True
        else:
            # We don't have setuptools, so guess egg_info_dirname to
            # find old stdeb.cfg.

            entries = os.listdir(os.curdir)
            for entry in entries:
                if not (entry.endswith('.egg-info') and os.path.isdir(entry)):
                    continue
                # Pickup old location of stdeb.cfg
                config_fname = os.path.join(entry, 'stdeb.cfg')
                if os.path.exists(config_fname):
                    log.warn(
                        'Deprecation warning: stdeb detected '
                        'stdeb.cfg in %s. This file will be used, but you '
                        'should move it alongside setup.py.' % entry)
                    cfg_files.append(config_fname)

        if have_script_entry_points is None:
            have_script_entry_points = self.distribution.has_scripts()

        test_suite = None
        if hasattr(self.distribution, "test_suite"):
            test_suite = self.distribution.test_suite

        debinfo = DebianInfo(
            cfg_files=cfg_files,
            module_name=module_name,
            default_distribution=self.default_distribution,
            guess_maintainer=guess_maintainer,
            upstream_version=self.distribution.get_version(),
            has_ext_modules=self.distribution.has_ext_modules(),
            description=self.distribution.get_description()[:60],
            long_description=self.distribution.get_long_description(),
            patch_file=self.patch_file,
            patch_level=self.patch_level,
            debian_version=self.debian_version,
            force_buildsystem=self.force_buildsystem,
            have_script_entry_points=have_script_entry_points,
            setup_requires=(),  # XXX How do we get the setup_requires?
            use_setuptools=use_setuptools,
            guess_conflicts_provides_replaces=self.
            guess_conflicts_provides_replaces,
            sdist_dsc_command=self,
            test_suite=test_suite,
        )
        return debinfo
Example #14
0
    def get_debinfo(self):
        ###############################################
        # 1. setup initial variables
        #    A. create config defaults
        module_name = self.distribution.get_name()

        if 1:
            # set default maintainer
            if (self.distribution.get_maintainer() != 'UNKNOWN' and
                self.distribution.get_maintainer_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>"%(
                    self.distribution.get_maintainer(),
                    self.distribution.get_maintainer_email())
            elif (self.distribution.get_author() != 'UNKNOWN' and
                  self.distribution.get_author_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>"%(
                    self.distribution.get_author(),
                    self.distribution.get_author_email())
            else:
                guess_maintainer = "unknown <unknown@unknown>"
        if self.default_maintainer is not None:
            log.warn('Deprecation warning: you are using the '
                     '--default-maintainer option. '
                     'Switch to the --maintainer option.')
            guess_maintainer = self.default_maintainer
        if hasattr(guess_maintainer,'decode'):
            # python 2 : convert (back to) unicode
            guess_maintainer = guess_maintainer.decode('utf-8')

        #    B. find config files (if any)
        cfg_files = []
        if self.extra_cfg_file is not None:
            cfg_files.append(self.extra_cfg_file)

        use_setuptools = True
        try:
            ei_cmd = self.distribution.get_command_obj('egg_info')
        except DistutilsModuleError as err:
            use_setuptools = False

        have_script_entry_points = None

        config_fname = 'stdeb.cfg'
        # Distutils fails if not run from setup.py dir, so this is OK.
        if os.path.exists(config_fname):
            cfg_files.append(config_fname)

        if use_setuptools:
            self.run_command('egg_info')
            egg_info_dirname = ei_cmd.egg_info

            # Pickup old location of stdeb.cfg
            config_fname = os.path.join(egg_info_dirname,'stdeb.cfg')
            if os.path.exists(config_fname):
                log.warn('Deprecation warning: stdeb detected old location of '
                         'stdeb.cfg in %s. This file will be used, but you '
                         'should move it alongside setup.py.' %egg_info_dirname)
                cfg_files.append(config_fname)

            egg_module_name = egg_info_dirname[:egg_info_dirname.index('.egg-info')]
            egg_module_name = egg_module_name.split(os.sep)[-1]

            if 1:
                # determine whether script specifies setuptools entry_points
                ep_fname = os.path.join(egg_info_dirname,'entry_points.txt')
                if os.path.exists(ep_fname):
                    entry_points = open(ep_fname,'rU').readlines()
                else:
                    entry_points = ''
                entry_points = [ep.strip() for ep in entry_points]

                if ('[console_scripts]' in entry_points or
                    '[gui_scripts]' in entry_points):
                    have_script_entry_points = True
        else:
            # We don't have setuptools, so guess egg_info_dirname to
            # find old stdeb.cfg.

            entries = os.listdir(os.curdir)
            for entry in entries:
                if not (entry.endswith('.egg-info') and os.path.isdir(entry)):
                    continue
                # Pickup old location of stdeb.cfg
                config_fname = os.path.join(entry,'stdeb.cfg')
                if os.path.exists(config_fname):
                    log.warn('Deprecation warning: stdeb detected '
                             'stdeb.cfg in %s. This file will be used, but you '
                             'should move it alongside setup.py.' % entry)
                    cfg_files.append(config_fname)

        if have_script_entry_points is None:
            have_script_entry_points = self.distribution.has_scripts()

        upstream_version = self.distribution.get_version()
        bad_chars = ':_'
        for bad_char in bad_chars:
            if bad_char in upstream_version:
                raise ValueError("Illegal character (%r) detected in version. "
                                 "This will break the debian tools."%bad_char)

        description = self.distribution.get_description()
        if hasattr(description,'decode'):
            # python 2 : convert (back to) unicode
            description = description.decode('utf-8')
        description = description[:60]

        long_description = self.distribution.get_long_description()
        if hasattr(long_description,'decode'):
            # python 2 : convert (back to) unicode
            long_description = long_description.decode('utf-8')
        long_description = long_description


        debinfo = DebianInfo(
            cfg_files=cfg_files,
            module_name = module_name,
            default_distribution=self.default_distribution,
            guess_maintainer=guess_maintainer,
            upstream_version = upstream_version,
            has_ext_modules = self.distribution.has_ext_modules(),
            description = description,
            long_description = long_description,
            patch_file = self.patch_file,
            patch_level = self.patch_level,
            debian_version = self.debian_version,
            have_script_entry_points = have_script_entry_points,
            setup_requires = (), # XXX How do we get the setup_requires?
            use_setuptools = use_setuptools,
            guess_conflicts_provides_replaces=self.guess_conflicts_provides_replaces,
            sdist_dsc_command = self,
            with_python2 = self.with_python2,
            with_python3 = self.with_python3,
            no_python2_scripts = self.no_python2_scripts,
            no_python3_scripts = self.no_python3_scripts,
        )
        return debinfo
Example #15
0
def build_dsc(
    debinfo,
    dist_dir,
    repackaged_dirname,
    orig_sdist=None,
    patch_posix=0,
    remove_expanded_source_dir=0,
    debian_dir_only=False,
):
    """make debian source package"""
    #    A. Find new dirname and delete any pre-existing contents

    # dist_dir is usually 'deb_dist'

    # the location of the copied original source package (it was
    # re-recreated in dist_dir)
    if debian_dir_only:
        fullpath_repackaged_dirname = os.path.abspath(os.curdir)
    else:
        fullpath_repackaged_dirname = os.path.join(dist_dir,
                                                   repackaged_dirname)

    ###############################################
    # 1. make temporary original source tarball

    #    Note that, for the final tarball, best practices suggest
    #    using "dpkg-source -b".  See
    #    http://www.debian.org/doc/developers-reference/ch-best-pkging-practices.en.html

    # Create the name of the tarball that qualifies as the upstream
    # source. If the original was specified, we'll link to
    # it. Otherwise, we generate our own .tar.gz file from the output
    # of "python setup.py sdist" (done above) so that we avoid
    # packaging .svn directories, for example.

    if not debian_dir_only:
        repackaged_orig_tarball = (
            '%(source)s_%(upstream_version)s.orig.tar.gz' % debinfo.__dict__)
        repackaged_orig_tarball_path = os.path.join(dist_dir,
                                                    repackaged_orig_tarball)
        if orig_sdist is not None:
            if os.path.exists(repackaged_orig_tarball_path):
                os.unlink(repackaged_orig_tarball_path)
            link_func(orig_sdist, repackaged_orig_tarball_path)
        else:
            make_tarball(repackaged_orig_tarball,
                         repackaged_dirname,
                         cwd=dist_dir)

        # apply patch
        if debinfo.patch_file != '':
            apply_patch(debinfo.patch_file,
                        posix=patch_posix,
                        level=debinfo.patch_level,
                        cwd=fullpath_repackaged_dirname)

    for fname in ['Makefile', 'makefile']:
        if os.path.exists(os.path.join(fullpath_repackaged_dirname, fname)):
            sys.stderr.write('*' * 1000 + '\n')
            if debinfo.force_buildsystem:
                sys.stderr.write('WARNING: a Makefile exists in this package. '
                                 'stdeb will tell debhelper 7 to use setup.py '
                                 'to build and install the package, and the '
                                 'Makefile will be ignored. You can disable '
                                 'this behavior with the '
                                 '--force-buildsystem=False argument to the '
                                 'stdeb command.\n')
            else:
                sys.stderr.write(
                    'WARNING: a Makefile exists in this package. '
                    'debhelper 7 will attempt to use this rather '
                    'than setup.py to build and install the '
                    'package. You can disable this behavior with '
                    'the --force-buildsystem=True argument to the '
                    'stdeb command.\n')
            sys.stderr.write('*' * 1000 + '\n')

    ###############################################
    # 2. create debian/ directory and contents
    debian_dir = os.path.join(fullpath_repackaged_dirname, 'debian')
    if not os.path.exists(debian_dir):
        os.mkdir(debian_dir)

    #    A. debian/changelog
    fd = open(os.path.join(debian_dir, 'changelog'), mode='w')
    fd.write("""\
%(source)s (%(full_version)s) %(distname)s; urgency=low

  * source package automatically created by stdeb %(stdeb_version)s

 -- %(maintainer)s  %(date822)s\n""" % debinfo.__dict__)
    fd.close()

    #    B. debian/control
    if debinfo.uploaders:
        debinfo.uploaders = 'Uploaders: %s\n' % ', '.join(debinfo.uploaders)
    else:
        debinfo.uploaders = ''
    control = CONTROL_FILE % debinfo.__dict__
    fd = open(os.path.join(debian_dir, 'control'), mode='w')
    fd.write(control)
    fd.close()

    #    C. debian/rules
    debinfo.percent_symbol = '%'
    rules = RULES_MAIN % debinfo.__dict__

    if debinfo.test_suite:
        rules = rules + RULES_OVERRIDE_DH_AUTO_TEST

    rules = rules.replace('        ', '\t')
    rules_fname = os.path.join(debian_dir, 'rules')
    fd = open(rules_fname, mode='w')
    fd.write(rules)
    fd.close()
    os.chmod(rules_fname, 0755)

    #    D. debian/compat
    fd = open(os.path.join(debian_dir, 'compat'), mode='w')
    fd.write('7\n')
    fd.close()

    #    E. debian/package.mime
    if debinfo.mime_file != '':
        if not os.path.exists(debinfo.mime_file):
            raise ValueError(
                'a MIME file was specified, but does not exist: %s' %
                (debinfo.mime_file, ))
        link_func(debinfo.mime_file,
                  os.path.join(debian_dir, debinfo.package + '.mime'))
    if debinfo.shared_mime_file != '':
        if not os.path.exists(debinfo.shared_mime_file):
            raise ValueError(
                'a shared MIME file was specified, but does not exist: %s' %
                (debinfo.shared_mime_file, ))
        link_func(
            debinfo.shared_mime_file,
            os.path.join(debian_dir, debinfo.package + '.sharedmimeinfo'))

    #    F. debian/copyright
    if debinfo.copyright_file != '':
        link_func(debinfo.copyright_file, os.path.join(debian_dir,
                                                       'copyright'))

    #    H. debian/<package>.install
    if len(debinfo.install_file_lines):
        fd = open(os.path.join(debian_dir, '%s.install' % debinfo.package),
                  mode='w')
        fd.write('\n'.join(debinfo.install_file_lines) + '\n')
        fd.close()

    #    I. debian/<package>.udev
    if debinfo.udev_rules != '':
        fname = debinfo.udev_rules
        if not os.path.exists(fname):
            raise ValueError('udev rules file specified, but does not exist')
        link_func(fname, os.path.join(debian_dir, '%s.udev' % debinfo.package))

    #    J. debian/source/format
    os.mkdir(os.path.join(debian_dir, 'source'))
    fd = open(os.path.join(debian_dir, 'source', 'format'), mode='w')
    fd.write('1.0\n')
    fd.close()

    if debian_dir_only:
        return

    ###############################################
    # 3. unpack original source tarball

    debianized_package_dirname = fullpath_repackaged_dirname + '.debianized'
    if os.path.exists(debianized_package_dirname):
        raise RuntimeError('debianized_package_dirname exists: %s' %
                           debianized_package_dirname)
    #    A. move debianized tree away
    os.rename(fullpath_repackaged_dirname, debianized_package_dirname)
    if orig_sdist is not None:
        #    B. expand repackaged original tarball
        tmp_dir = os.path.join(dist_dir, 'tmp-expand')
        os.mkdir(tmp_dir)
        try:
            expand_tarball(orig_sdist, cwd=tmp_dir)
            orig_tarball_top_contents = os.listdir(tmp_dir)

            # make sure original tarball has exactly one directory
            assert len(orig_tarball_top_contents) == 1
            orig_dirname = orig_tarball_top_contents[0]
            fullpath_orig_dirname = os.path.join(tmp_dir, orig_dirname)

            #    C. move original repackaged tree to .orig
            target = fullpath_repackaged_dirname + '.orig'
            if os.path.exists(target):
                # here from previous invocation, probably
                shutil.rmtree(target)
            os.rename(fullpath_orig_dirname, target)

        finally:
            shutil.rmtree(tmp_dir)

    if 1:
        # check versions of debhelper and python-all
        debhelper_version_str = get_version_str('debhelper')
        if len(debhelper_version_str) == 0:
            log.warn('This version of stdeb requires debhelper >= %s, but you '
                     'do not have debhelper installed. '
                     'Could not check compatibility.' % DH_MIN_VERS)
        else:
            if not dpkg_compare_versions(debhelper_version_str, 'ge',
                                         DH_MIN_VERS):
                log.warn('This version of stdeb requires debhelper >= %s. '
                         'Use stdeb 0.3.x to generate source packages '
                         'compatible with older versions of debhelper.' %
                         (DH_MIN_VERS, ))

        python_defaults_version_str = get_version_str('python-all')
        if len(python_defaults_version_str) == 0:
            log.warn('This version of stdeb requires python-all >= %s, '
                     'but you do not have this package installed. '
                     'Could not check compatibility.' % PYTHON_ALL_MIN_VERS)
        else:
            if not dpkg_compare_versions(python_defaults_version_str, 'ge',
                                         PYTHON_ALL_MIN_VERS):
                log.warn(
                    'This version of stdeb requires python-all >= %s. '
                    'Use stdeb 0.6.0 or older to generate source packages '
                    'that use python-support.' % (PYTHON_ALL_MIN_VERS, ))

    #    D. restore debianized tree
    os.rename(fullpath_repackaged_dirname + '.debianized',
              fullpath_repackaged_dirname)

    #    Re-generate tarball using best practices see
    #    http://www.debian.org/doc/developers-reference/ch-best-pkging-practices.en.html
    #    call "dpkg-source -b new_dirname orig_dirname"
    log.info('CALLING dpkg-source -b %s %s (in dir %s)' %
             (repackaged_dirname, repackaged_orig_tarball, dist_dir))

    dpkg_source('-b',
                repackaged_dirname,
                repackaged_orig_tarball,
                cwd=dist_dir)

    if 1:
        shutil.rmtree(fullpath_repackaged_dirname)

    if not remove_expanded_source_dir:
        # expand the debian source package
        dsc_name = debinfo.source + '_' + debinfo.dsc_version + '.dsc'
        dpkg_source('-x', dsc_name, cwd=dist_dir)
Example #16
0
            emo = E.search(l)
            assert emo, l
            dmo = D.search(l)
            assert dmo, l
            eggsndebs.add((emo.group(1), dmo.group(1)))

    for (egginfo, debname) in eggsndebs:
        pydist = pkg_resources.Distribution.from_filename(egginfo)
        try:
            dd.setdefault(pydist.project_name.lower(),
                          {}).setdefault(pydist, set()).add(debname)
        except ValueError, le:
            log.warn("I got an error parsing a .egg-info file named \"%s\" "
                     "from Debian package \"%s\" as a pkg_resources "
                     "Distribution: %s" % (
                         egginfo,
                         debname,
                         le,
                     ))
            pass

    # Now for each requirement, see if a Debian package satisfies it.
    ops = {'<': '<<', '>': '>>', '==': '=', '<=': '<=', '>=': '>='}
    for req in parsed_reqs:
        reqname = req.project_name.lower()
        gooddebs = set()
        for pydist, debs in dd.get(reqname, {}).iteritems():
            if pydist in req:
                ## log.info("I found Debian packages \"%s\" which provides "
                ##          "Python package \"%s\", version \"%s\", which "
                ##          "satisfies our version requirements: \"%s\""
Example #17
0
    def get_debinfo(self):
        ###############################################
        # 1. setup initial variables
        #    A. create config defaults
        module_name = self.distribution.get_name()

        if 1:
            # set default maintainer
            if (self.distribution.get_maintainer() != 'UNKNOWN' and
                self.distribution.get_maintainer_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>"%(
                    self.distribution.get_maintainer(),
                    self.distribution.get_maintainer_email())
            elif (self.distribution.get_author() != 'UNKNOWN' and
                  self.distribution.get_author_email() != 'UNKNOWN'):
                guess_maintainer = "%s <%s>"%(
                    self.distribution.get_author(),
                    self.distribution.get_author_email())
            else:
                guess_maintainer = "unknown <unknown@unknown>"
        if self.default_maintainer is not None:
            log.warn('Deprecation warning: you are using the '
                     '--default-maintainer option. '
                     'Switch to the --maintainer option.')
            guess_maintainer = self.default_maintainer
        if hasattr(guess_maintainer,'decode'):
            # python 2 : convert (back to) unicode
            guess_maintainer = guess_maintainer.decode('utf-8')

        #    B. find config files (if any)
        cfg_files = []
        if self.extra_cfg_file is not None:
            cfg_files.append(self.extra_cfg_file)

        use_setuptools = True
        try:
            ei_cmd = self.distribution.get_command_obj('egg_info')
        except DistutilsModuleError as err:
            use_setuptools = False

        have_script_entry_points = None

        config_fname = 'stdeb.cfg'
        # Distutils fails if not run from setup.py dir, so this is OK.
        if os.path.exists(config_fname):
            cfg_files.append(config_fname)

        if use_setuptools:
            self.run_command('egg_info')
            egg_info_dirname = ei_cmd.egg_info

            # Pickup old location of stdeb.cfg
            config_fname = os.path.join(egg_info_dirname,'stdeb.cfg')
            if os.path.exists(config_fname):
                log.warn('Deprecation warning: stdeb detected old location of '
                         'stdeb.cfg in %s. This file will be used, but you '
                         'should move it alongside setup.py.' %egg_info_dirname)
                cfg_files.append(config_fname)

            egg_module_name = egg_info_dirname[:egg_info_dirname.index('.egg-info')]
            egg_module_name = egg_module_name.split(os.sep)[-1]

            if 1:
                # determine whether script specifies setuptools entry_points
                ep_fname = os.path.join(egg_info_dirname,'entry_points.txt')
                if os.path.exists(ep_fname):
                    entry_points = open(ep_fname,'rU').readlines()
                else:
                    entry_points = ''
                entry_points = [ep.strip() for ep in entry_points]

                if ('[console_scripts]' in entry_points or
                    '[gui_scripts]' in entry_points):
                    have_script_entry_points = True
        else:
            # We don't have setuptools, so guess egg_info_dirname to
            # find old stdeb.cfg.

            entries = os.listdir(os.curdir)
            for entry in entries:
                if not (entry.endswith('.egg-info') and os.path.isdir(entry)):
                    continue
                # Pickup old location of stdeb.cfg
                config_fname = os.path.join(entry,'stdeb.cfg')
                if os.path.exists(config_fname):
                    log.warn('Deprecation warning: stdeb detected '
                             'stdeb.cfg in %s. This file will be used, but you '
                             'should move it alongside setup.py.' % entry)
                    cfg_files.append(config_fname)

        if have_script_entry_points is None:
            have_script_entry_points = self.distribution.has_scripts()

        upstream_version = self.distribution.get_version()
        bad_chars = ':_'
        for bad_char in bad_chars:
            if bad_char in upstream_version:
                raise ValueError("Illegal character (%r) detected in version. "
                                 "This will break the debian tools."%bad_char)

        description = self.distribution.get_description()
        if hasattr(description,'decode'):
            # python 2 : convert (back to) unicode
            description = description.decode('utf-8')
        description = description[:60]

        long_description = self.distribution.get_long_description()
        if hasattr(long_description,'decode'):
            # python 2 : convert (back to) unicode
            long_description = long_description.decode('utf-8')
        long_description = long_description


        debinfo = DebianInfo(
            cfg_files=cfg_files,
            module_name = module_name,
            default_distribution=self.default_distribution,
            guess_maintainer=guess_maintainer,
            upstream_version = upstream_version,
            has_ext_modules = self.distribution.has_ext_modules(),
            description = description,
            long_description = long_description,
            patch_file = self.patch_file,
            patch_level = self.patch_level,
            debian_version = self.debian_version,
            have_script_entry_points = have_script_entry_points,
            setup_requires = (), # XXX How do we get the setup_requires?
            use_setuptools = use_setuptools,
            guess_conflicts_provides_replaces=self.guess_conflicts_provides_replaces,
            sdist_dsc_command = self,
            with_python2 = self.with_python2,
            with_python3 = self.with_python3,
            no_python2_scripts = self.no_python2_scripts,
            no_python3_scripts = self.no_python3_scripts,
        )
        return debinfo
Example #18
0
    def run(self):
        debinfo = self.get_debinfo()
        if debinfo.patch_file != '' and self.patch_already_applied:
            raise RuntimeError('A patch was already applied, but another '
                               'patch is requested.')

        repackaged_dirname = debinfo.source+'-'+debinfo.upstream_version
        fullpath_repackaged_dirname = os.path.join(self.dist_dir,
                                                   repackaged_dirname)

        cleanup_dirs = []
        if self.use_premade_distfile is None:
            # generate original tarball
            sdist_cmd = self.distribution.get_command_obj('sdist')
            self.run_command('sdist')

            source_tarball = None
            for archive_file in sdist_cmd.get_archive_files():
                if archive_file.endswith('.tar.gz'):
                    source_tarball = archive_file

            if source_tarball is None:
                raise RuntimeError('sdist did not produce .tar.gz file')

            # make copy of source tarball in deb_dist/
            local_source_tarball = os.path.split(source_tarball)[-1]
            shutil.copy2( source_tarball, local_source_tarball )
            source_tarball = local_source_tarball
            self.use_premade_distfile = source_tarball
        else:
            source_tarball = self.use_premade_distfile

        # Copy source tree assuming that package-0.1.tar.gz contains
        # single top-level path 'package-0.1'. The contents of this
        # directory are then used.

        if os.path.exists(fullpath_repackaged_dirname):
            shutil.rmtree(fullpath_repackaged_dirname)

        tmpdir = tempfile.mkdtemp()
        expand_sdist_file( os.path.abspath(source_tarball),
                           cwd=tmpdir )
        expanded_base_files = os.listdir(tmpdir)
        assert len(expanded_base_files)==1
        actual_package_dirname = expanded_base_files[0]
        expected_package_dirname = debinfo.module_name + '-' + debinfo.upstream_version
        assert actual_package_dirname==expected_package_dirname
        shutil.move( os.path.join( tmpdir, actual_package_dirname ),
                     fullpath_repackaged_dirname)

        # ensure premade sdist can actually be used
        self.use_premade_distfile = os.path.abspath(self.use_premade_distfile)
        expand_dir = os.path.join(self.dist_dir,'tmp_sdist_dsc')
        cleanup_dirs.append(expand_dir)
        if os.path.exists(expand_dir):
            shutil.rmtree(expand_dir)
        if not os.path.exists(self.dist_dir):
            os.mkdir(self.dist_dir)
        os.mkdir(expand_dir)

        expand_sdist_file(self.use_premade_distfile,cwd=expand_dir)

        is_tgz=False
        if self.use_premade_distfile.lower().endswith('.tar.gz'):
            is_tgz=True

        # now the sdist package is expanded in expand_dir
        expanded_root_files = os.listdir(expand_dir)
        assert len(expanded_root_files)==1
        distname_in_premade_distfile = expanded_root_files[0]
        debianized_dirname = repackaged_dirname
        original_dirname = os.path.split(distname_in_premade_distfile)[-1]
        do_repack=False
        if is_tgz:
            source_tarball = self.use_premade_distfile
        else:
            log.warn('WARNING: .orig.tar.gz will be generated from sdist '
                     'archive ("%s") because it is not a .tar.gz file',
                     self.use_premade_distfile)
            do_repack=True

        if do_repack:
            tmp_dir = os.path.join(self.dist_dir, 'tmp_repacking_dir' )
            os.makedirs( tmp_dir )
            cleanup_dirs.append(tmp_dir)
            source_tarball = os.path.join(tmp_dir,'repacked_sdist.tar.gz')
            repack_tarball_with_debianized_dirname(self.use_premade_distfile,
                                                   source_tarball,
                                                   debianized_dirname,
                                                   original_dirname )
        if source_tarball is not None:
            # Because we deleted all .pyc files above, if the
            # original source dist has them, we will have
            # (wrongly) deleted them. So, quit loudly rather
            # than fail silently.
            for root, dirs, files in os.walk(fullpath_repackaged_dirname):
                for name in files:
                    if name.endswith('.pyc'):
                        raise RuntimeError('original source dist cannot '
                                           'contain .pyc files')

        ###############################################
        # 3. Find all directories

        for pkgdir in self.distribution.packages or []:
            debinfo.dirlist += ' ' + pkgdir.replace('.', '/')

        ###############################################
        # 4. Build source tree and rename it to be in self.dist_dir

        build_dsc(debinfo,
                  self.dist_dir,
                  repackaged_dirname,
                  orig_sdist=source_tarball,
                  patch_posix = self.patch_posix,
                  remove_expanded_source_dir=self.remove_expanded_source_dir,
                  )

        for rmdir in cleanup_dirs:
            shutil.rmtree(rmdir)
Example #19
0
    def run(self):
        ###############################################
        # 1. setup initial variables

        #    A. create config defaults
        module_name = self.distribution.get_name()
        if self.default_maintainer is None:
            if (self.distribution.get_maintainer() != 'UNKNOWN' and
                self.distribution.get_maintainer_email() != 'UNKNOWN'):
                self.default_maintainer = "%s <%s>"%(
                    self.distribution.get_maintainer(),
                    self.distribution.get_maintainer_email())
            elif (self.distribution.get_author() != 'UNKNOWN' and
                  self.distribution.get_author_email() != 'UNKNOWN'):
                self.default_maintainer = "%s <%s>"%(
                    self.distribution.get_author(),
                    self.distribution.get_author_email())
            else:
                self.default_maintainer = "unknown <unknown@unknown>"

        #    B. find config files (if any)
        #         find .egg-info directory
        ei_cmd = self.distribution.get_command_obj('egg_info')

        self.run_command('egg_info')
        egg_info_dirname = ei_cmd.egg_info
        config_fname = os.path.join(egg_info_dirname,'stdeb.cfg')

        egg_module_name = egg_info_dirname[:egg_info_dirname.index('.egg-info')]
        egg_module_name = egg_module_name.split(os.sep)[-1]

        cfg_files = []
        if os.path.exists(config_fname):
            cfg_files.append(config_fname)
        if self.extra_cfg_file is not None:
            cfg_files.append(self.extra_cfg_file)

        install_requires = ()
        try:
            if not self.ignore_install_requires:
                install_requires = open(os.path.join(egg_info_dirname,'requires.txt'),'rU').read()
        except EnvironmentError:
            pass

        if 1:
            # determinc whether script specifies setuptools entry_points
            ep_fname = os.path.join(egg_info_dirname,'entry_points.txt')
            if os.path.exists(ep_fname):
                entry_points = open(ep_fname,'rU').readlines()
            else:
                entry_points = ''
            entry_points = [ep.strip() for ep in entry_points]

            if ('[console_scripts]' in entry_points or
                '[gui_scripts]' in entry_points):
                have_script_entry_points = True
            else:
                have_script_entry_points = False

        debinfo = DebianInfo(
            cfg_files=cfg_files,
            module_name = module_name,
            default_distribution=self.default_distribution,
            default_maintainer=self.default_maintainer,
            upstream_version = self.distribution.get_version(),
            egg_module_name = egg_module_name,
            has_ext_modules = self.distribution.has_ext_modules(),
            description = self.distribution.get_description()[:60],
            long_description = self.distribution.get_long_description(),
            patch_file = self.patch_file,
            patch_level = self.patch_level,
            install_requires = install_requires,
            debian_version = self.debian_version,
            workaround_548392=self.workaround_548392,
            force_xs_python_version=self.xs_python_version,
            have_script_entry_points = have_script_entry_points,
            pycentral_backwards_compatibility=self.pycentral_backwards_compatibility,
            setup_requires = (), # XXX How do we get the setup_requires?
        )
        if debinfo.patch_file != '' and self.patch_already_applied:
            raise RuntimeError('A patch was already applied, but another '
                               'patch is requested.')

        ###############################################
        # 2. Build source tree and rename it to be in self.dist_dir

        #    A. create source archive in new directory
        repackaged_dirname = debinfo.source+'-'+debinfo.upstream_version
        fullpath_repackaged_dirname = os.path.join(self.dist_dir,
                                                   repackaged_dirname)

        source_tarball = None
        cleanup_dirs = []

        exclude_dirs = ['.svn']
        # copy source tree
        if os.path.exists(fullpath_repackaged_dirname):
            shutil.rmtree(fullpath_repackaged_dirname)
        os.makedirs(fullpath_repackaged_dirname)
        orig_dir = os.path.abspath(os.curdir)
        for src in os.listdir(orig_dir):
            if src not in exclude_dirs+[self.dist_dir,'build','dist']:
                dst = os.path.join(fullpath_repackaged_dirname,src)
                if os.path.isdir(src):
                    shutil.copytree(src, dst, symlinks=True)
                else:
                    shutil.copy2(src, dst )
        # remove .pyc files which dpkg-source cannot package
        for root, dirs, files in os.walk(fullpath_repackaged_dirname):
            for name in files:
                if name.endswith('.pyc'):
                    fullpath = os.path.join(root,name)
                    os.unlink(fullpath)
            for name in dirs:
                if name in exclude_dirs:
                    fullpath = os.path.join(root,name)
                    shutil.rmtree(fullpath)

        if self.use_premade_distfile is not None:
        # ensure premade sdist can actually be used
            self.use_premade_distfile = os.path.abspath(self.use_premade_distfile)
            expand_dir = os.path.join(self.dist_dir,'tmp_sdist_dsc')
            cleanup_dirs.append(expand_dir)
            if os.path.exists(expand_dir):
                shutil.rmtree(expand_dir)
            if not os.path.exists(self.dist_dir):
                os.mkdir(self.dist_dir)
            os.mkdir(expand_dir)

            expand_sdist_file(self.use_premade_distfile,cwd=expand_dir)

            is_tgz=False
            if self.use_premade_distfile.lower().endswith('.tar.gz'):
                is_tgz=True

            # now the sdist package is expanded in expand_dir
            expanded_root_files = os.listdir(expand_dir)
            assert len(expanded_root_files)==1
            distname_in_premade_distfile = expanded_root_files[0]
            debianized_dirname = repackaged_dirname
            original_dirname = os.path.split(distname_in_premade_distfile)[-1]
            do_repack=False
            if is_tgz:
                source_tarball = self.use_premade_distfile
            else:
                log.warn('WARNING: .orig.tar.gz will be generated from sdist '
                         'archive ("%s") because it is not a .tar.gz file',
                         self.use_premade_distfile)
                do_repack=True

            if do_repack:
                tmp_dir = os.path.join(self.dist_dir, 'tmp_repacking_dir' )
                os.makedirs( tmp_dir )
                cleanup_dirs.append(tmp_dir)
                source_tarball = os.path.join(tmp_dir,'repacked_sdist.tar.gz')
                repack_tarball_with_debianized_dirname(self.use_premade_distfile,
                                                       source_tarball,
                                                       debianized_dirname,
                                                       original_dirname )
            if source_tarball is not None:
                # Because we deleted all .pyc files above, if the
                # original source dist has them, we will have
                # (wrongly) deleted them. So, quit loudly rather
                # than fail silently.
                for root, dirs, files in os.walk(fullpath_repackaged_dirname):
                    for name in files:
                        if name.endswith('.pyc'):
                            raise RuntimeError('original source dist cannot '
                                               'contain .pyc files')
        else:
            if 0:
                # haven't figured out why
                raise NotImplementedError("the code path is broken right now")


        ###############################################
        # 3. Find all directories

        for pkgdir in self.distribution.packages or []:
            debinfo.dirlist += ' ' + pkgdir.replace('.', '/')

        ###############################################
        # 4. Build source tree and rename it to be in self.dist_dir

        build_dsc(debinfo,
                  self.dist_dir,
                  repackaged_dirname,
                  orig_sdist=source_tarball,
                  patch_posix = self.patch_posix,
                  remove_expanded_source_dir=self.remove_expanded_source_dir)

        for rmdir in cleanup_dirs:
            shutil.rmtree(rmdir)