Пример #1
0
def prepare_package(package_name, package_version, deb_dest_dir, multideb_config_parser, allow_unsafe_download, verbose=True):
    """
    :param package_name: name of the package to prepare
    :type package_name: :class:`str`
    :param package_version: version of the package to prepare
    :type package_version: :class:`str`
    :param deb_dest_dir: directory where to put created Debian packages
    :type deb_dest_dir: :class:`str`
    :param multideb_config_parser: multideb configuration file
    :type multideb_config_parser: :class:`configparser.ConfigParser`
    :param allow_unsafe_download:  allow unsafe downloads?  (see pip documentation)
    :type allow_unsafe_download: :class:`bool`
    """
    assert isinstance(multideb_config_parser, configparser.ConfigParser)
    print('downloading %s %s' % (package_name, package_version))
    filename = get_source_tarball(package_name, verbose=False, release=package_version, allow_unsafe_download=allow_unsafe_download)
    # expand source file
    expand_sdist_file(os.path.abspath(filename), cwd=os.getcwd())
    directories = [x for x in os.listdir(os.getcwd()) if os.path.isdir(os.path.join(os.getcwd(), x))]
    if len(directories) != 1:
        raise ValueError('Require a single directory in %s' % os.getcwd())
    os.chdir(directories[0])
    subprocess.check_output("rm -rf `find * | grep \\.pyc$`", shell=True)
    run_hook(package_name, package_version, 'pre_source', None, multideb_config_parser)

    # config file for each package?
    new_config_parser = configparser.ConfigParser()
    new_config_parser.read(['stdeb.cfg'])
    section_names = (package_name, )
    if sys.version_info[0] == 3:
        section_names = (package_name, package_name + '-python3')
    for section_name in section_names:
        if multideb_config_parser.has_section(section_name):
            for option_name in multideb_config_parser.options(section_name):
                option_value = multideb_config_parser.get(section_name, option_name)
                new_config_parser.set('DEFAULT', option_name, option_value)
    with codecs.open('stdeb.cfg', 'w', encoding='utf-8') as fd:
        new_config_parser.write(fd)
    call_kwargs = {} if verbose else {'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE}
    print('preparing Debian source')
    check_call(['python', 'setup.py', '--command-packages', 'stdeb.command', 'sdist_dsc'], **call_kwargs)

    # find the actual debian source dir
    directories = [x for x in os.listdir('deb_dist') if x != 'tmp_py2dsc' and os.path.isdir(os.path.join('deb_dist', x))]
    if len(directories) != 1:
        raise ValueError('Require a single directory in %s/deb_dist' % os.getcwd())
    debian_source_dir = os.path.abspath(os.path.join('deb_dist', directories[0]))
    # check if we have a post-source to execute
    run_hook(package_name, package_version, 'post_source', debian_source_dir, multideb_config_parser)
    # build .deb from the source
    print('creating package')
    check_call(['dpkg-buildpackage', '-rfakeroot', '-uc', '-b'], cwd=debian_source_dir, **call_kwargs)
    # move the .deb to destination dir
    packages = glob.glob('deb_dist/*.deb')
    if not packages:
        raise ValueError('Unable to create %s-%s' % (package_name, package_version))
    print('moving %s' % os.path.basename(packages[0]))
    shutil.move(packages[0], os.path.join(deb_dest_dir, os.path.basename(packages[0])))
Пример #2
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)
Пример #3
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)
Пример #4
0
def prepare_package(package_name,
                    package_version,
                    deb_dest_dir,
                    multideb_config_parser,
                    allow_unsafe_download,
                    verbose=True):
    """
    :param package_name: name of the package to prepare
    :type package_name: :class:`str`
    :param package_version: version of the package to prepare
    :type package_version: :class:`str`
    :param deb_dest_dir: directory where to put created Debian packages
    :type deb_dest_dir: :class:`str`
    :param multideb_config_parser: multideb configuration file
    :type multideb_config_parser: :class:`configparser.ConfigParser`
    :param allow_unsafe_download:  allow unsafe downloads?  (see pip documentation)
    :type allow_unsafe_download: :class:`bool`
    """
    assert isinstance(multideb_config_parser, configparser.ConfigParser)
    print('downloading %s %s' % (package_name, package_version))
    filename = get_source_tarball(package_name,
                                  verbose=False,
                                  release=package_version,
                                  allow_unsafe_download=allow_unsafe_download)
    # expand source file
    expand_sdist_file(os.path.abspath(filename), cwd=os.getcwd())
    directories = [
        x for x in os.listdir(os.getcwd())
        if os.path.isdir(os.path.join(os.getcwd(), x))
    ]
    if len(directories) != 1:
        raise ValueError('Require a single directory in %s' % os.getcwd())
    os.chdir(directories[0])
    subprocess.check_output("rm -rf `find * | grep \\.pyc$`", shell=True)
    run_hook(package_name, package_version, 'pre_source', None,
             multideb_config_parser)

    # config file for each package?
    new_config_parser = configparser.ConfigParser()
    new_config_parser.read(['stdeb.cfg'])
    section_names = (package_name, )
    if sys.version_info[0] == 3:
        section_names = (package_name, package_name + '-python3')
    for section_name in section_names:
        if multideb_config_parser.has_section(section_name):
            for option_name in multideb_config_parser.options(section_name):
                option_value = multideb_config_parser.get(
                    section_name, option_name)
                new_config_parser.set('DEFAULT', option_name, option_value)
    with codecs.open('stdeb.cfg', 'w', encoding='utf-8') as fd:
        new_config_parser.write(fd)
    call_kwargs = {} if verbose else {
        'stdout': subprocess.PIPE,
        'stderr': subprocess.PIPE
    }
    print('preparing Debian source')
    check_call([
        'python', 'setup.py', '--command-packages', 'stdeb.command',
        'sdist_dsc'
    ], **call_kwargs)

    # find the actual debian source dir
    directories = [
        x for x in os.listdir('deb_dist')
        if x != 'tmp_py2dsc' and os.path.isdir(os.path.join('deb_dist', x))
    ]
    if len(directories) != 1:
        raise ValueError('Require a single directory in %s/deb_dist' %
                         os.getcwd())
    debian_source_dir = os.path.abspath(
        os.path.join('deb_dist', directories[0]))
    # check if we have a post-source to execute
    run_hook(package_name, package_version, 'post_source', debian_source_dir,
             multideb_config_parser)
    # build .deb from the source
    print('creating package')
    check_call(['dpkg-buildpackage', '-rfakeroot', '-uc', '-b'],
               cwd=debian_source_dir,
               **call_kwargs)
    # move the .deb to destination dir
    packages = glob.glob('deb_dist/*.deb')
    if not packages:
        raise ValueError('Unable to create %s-%s' %
                         (package_name, package_version))
    print('moving %s' % os.path.basename(packages[0]))
    shutil.move(packages[0],
                os.path.join(deb_dest_dir, os.path.basename(packages[0])))
Пример #5
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)
Пример #6
0
def runit(cmd,usage):
    if cmd not in ['sdist_dsc','bdist_deb']:
        raise ValueError('unknown command %r'%cmd)
    # process command-line options
    bool_opts = map(translate_longopt, stdeb_cmd_bool_opts)
    parser = FancyGetopt(stdeb_cmdline_opts+[
        ('help', 'h', "show detailed help message"),
        ])
    optobj = OptObj()
    args = parser.getopt(object=optobj)
    for option in optobj.__dict__:
        value = getattr(optobj,option)
        is_string = type(value) == str
        if option in bool_opts and is_string:
            setattr(optobj, option, strtobool(value))

    if hasattr(optobj,'help'):
        print(usage)
        parser.set_option_table(stdeb_cmdline_opts)
        parser.print_help("Options:")
        return 0

    if len(args)!=1:
        log.error('not given single argument (distfile), args=%r', args)
        print(usage)
        return 1

    sdist_file = args[0]

    final_dist_dir = optobj.__dict__.get('dist_dir','deb_dist')
    tmp_dist_dir = os.path.join(final_dist_dir,'tmp_py2dsc')
    if os.path.exists(tmp_dist_dir):
        shutil.rmtree(tmp_dist_dir)
    os.makedirs(tmp_dist_dir)

    if not os.path.isfile(sdist_file):
        log.error("Package %s not found."%sdist_file)
        sys.exit(1)

    patch_file = optobj.__dict__.get('patch_file',None)
    patch_level = int(optobj.__dict__.get('patch_level',0))
    patch_posix = int(optobj.__dict__.get('patch_posix',0))

    expand_dir = os.path.join(tmp_dist_dir,'stdeb_tmp')
    if os.path.exists(expand_dir):
        shutil.rmtree(expand_dir)
    if not os.path.exists(tmp_dist_dir):
        os.mkdir(tmp_dist_dir)
    os.mkdir(expand_dir)

    expand_sdist_file(os.path.abspath(sdist_file),cwd=expand_dir)



    # now the sdist package is expanded in expand_dir
    expanded_root_files = os.listdir(expand_dir)
    assert len(expanded_root_files)==1
    repackaged_dirname = expanded_root_files[0]
    fullpath_repackaged_dirname = os.path.join(tmp_dist_dir,repackaged_dirname)
    base_dir = os.path.join(expand_dir,expanded_root_files[0])
    if os.path.exists(fullpath_repackaged_dirname):
        # prevent weird build errors if this dir exists
        shutil.rmtree(fullpath_repackaged_dirname)
    os.renames(base_dir, fullpath_repackaged_dirname)
    del base_dir # no longer useful

    ##############################################
    if patch_file is not None:
        log.info('py2dsc applying patch %s', patch_file)
        apply_patch(patch_file,
                    posix=patch_posix,
                    level=patch_level,
                    cwd=fullpath_repackaged_dirname)
        patch_already_applied = 1
    else:
        patch_already_applied = 0
    ##############################################


    abs_dist_dir = os.path.abspath(final_dist_dir)

    extra_args = []
    for long in parser.long_opts:
        if long in ['dist-dir=','patch-file=']:
            continue # dealt with by this invocation
        attr = parser.get_attr_name(long).rstrip('=')
        if hasattr(optobj,attr):
            val = getattr(optobj,attr)
            if attr=='extra_cfg_file':
                val = os.path.abspath(val)
            if long in bool_opts or long.replace('-', '_') in bool_opts:
                extra_args.append('--%s' % long)
            else:
                extra_args.append('--'+long+str(val))

    if patch_already_applied == 1:
        extra_args.append('--patch-already-applied')

    if cmd=='bdist_deb':
        extra_args.append('bdist_deb')

    args = [sys.executable,'setup.py','--command-packages','stdeb.command',
            'sdist_dsc','--dist-dir=%s'%abs_dist_dir,
            '--use-premade-distfile=%s'%os.path.abspath(sdist_file)]+extra_args

    log.info('-='*35 + '-')
#    print >> sys.stderr, '-='*20
#    print >> sys.stderr, "Note that the .cfg file(s), if present, have not "\
#          "been read at this stage. If options are necessary, pass them from "\
#          "the command line"
    log.info("running the following command in directory: %s\n%s",
             fullpath_repackaged_dirname, ' '.join(args))
    log.info('-='*35 + '-')

    try:
        returncode = subprocess.call(
            args,cwd=fullpath_repackaged_dirname,
            )
    except:
        log.error('ERROR running: %s', ' '.join(args))
        log.error('ERROR in %s', fullpath_repackaged_dirname)
        raise

    if returncode:
        log.error('ERROR running: %s', ' '.join(args))
        log.error('ERROR in %s', fullpath_repackaged_dirname)
        #log.error('   stderr: %s'res.stderr.read())
        #print >> sys.stderr, 'ERROR running: %s'%(' '.join(args),)
        #print >> sys.stderr, res.stderr.read()
        return returncode
        #raise RuntimeError('returncode %d'%returncode)
    #result = res.stdout.read().strip()

    shutil.rmtree(tmp_dist_dir)
    return returncode
Пример #7
0
def runit(cmd, usage):
    if cmd not in ['sdist_dsc', 'bdist_deb']:
        raise ValueError('unknown command %r' % cmd)
    # process command-line options
    bool_opts = list(map(translate_longopt, stdeb_cmd_bool_opts))
    parser = FancyGetopt(stdeb_cmdline_opts + [
        ('help', 'h', "show detailed help message"),
    ])
    optobj = OptObj()
    args = parser.getopt(object=optobj)
    for option in optobj.__dict__:
        value = getattr(optobj, option)
        is_string = type(value) == str
        if option in bool_opts and is_string:
            setattr(optobj, option, strtobool(value))

    if hasattr(optobj, 'help'):
        print(usage)
        parser.set_option_table(stdeb_cmdline_opts)
        parser.print_help("Options:")
        return 0

    if len(args) != 1:
        log.error('not given single argument (distfile), args=%r', args)
        print(usage)
        return 1

    sdist_file = args[0]

    final_dist_dir = optobj.__dict__.get('dist_dir', 'deb_dist')
    tmp_dist_dir = os.path.join(final_dist_dir, 'tmp_py2dsc')
    if os.path.exists(tmp_dist_dir):
        shutil.rmtree(tmp_dist_dir)
    os.makedirs(tmp_dist_dir)

    if not os.path.isfile(sdist_file):
        log.error("Package %s not found." % sdist_file)
        sys.exit(1)

    patch_file = optobj.__dict__.get('patch_file', None)
    patch_level = int(optobj.__dict__.get('patch_level', 0))
    patch_posix = int(optobj.__dict__.get('patch_posix', 0))

    expand_dir = os.path.join(tmp_dist_dir, 'stdeb_tmp')
    if os.path.exists(expand_dir):
        shutil.rmtree(expand_dir)
    if not os.path.exists(tmp_dist_dir):
        os.mkdir(tmp_dist_dir)
    os.mkdir(expand_dir)

    expand_sdist_file(os.path.abspath(sdist_file), cwd=expand_dir)

    # now the sdist package is expanded in expand_dir
    expanded_root_files = os.listdir(expand_dir)
    assert len(expanded_root_files) == 1
    repackaged_dirname = expanded_root_files[0]
    fullpath_repackaged_dirname = os.path.join(tmp_dist_dir,
                                               repackaged_dirname)
    base_dir = os.path.join(expand_dir, expanded_root_files[0])
    if os.path.exists(fullpath_repackaged_dirname):
        # prevent weird build errors if this dir exists
        shutil.rmtree(fullpath_repackaged_dirname)
    os.renames(base_dir, fullpath_repackaged_dirname)
    del base_dir  # no longer useful

    ##############################################
    if patch_file is not None:
        log.info('py2dsc applying patch %s', patch_file)
        apply_patch(patch_file,
                    posix=patch_posix,
                    level=patch_level,
                    cwd=fullpath_repackaged_dirname)
        patch_already_applied = 1
    else:
        patch_already_applied = 0
    ##############################################

    abs_dist_dir = os.path.abspath(final_dist_dir)

    extra_args = []
    for long in parser.long_opts:
        if long in ['dist-dir=', 'patch-file=']:
            continue  # dealt with by this invocation
        attr = parser.get_attr_name(long).rstrip('=')
        if hasattr(optobj, attr):
            val = getattr(optobj, attr)
            if attr == 'extra_cfg_file':
                val = os.path.abspath(val)
            if long in bool_opts or long.replace('-', '_') in bool_opts:
                extra_args.append('--%s' % long)
            else:
                extra_args.append('--' + long + str(val))

    if patch_already_applied == 1:
        extra_args.append('--patch-already-applied')

    if cmd == 'bdist_deb':
        extra_args.append('bdist_deb')

    args = [
        sys.executable, 'setup.py', '--command-packages', 'stdeb.command',
        'sdist_dsc',
        '--dist-dir=%s' % abs_dist_dir,
        '--use-premade-distfile=%s' % os.path.abspath(sdist_file)
    ] + extra_args

    log.info('-=' * 35 + '-')
    #    print >> sys.stderr, '-='*20
    #    print >> sys.stderr, "Note that the .cfg file(s), if present, have not "\
    #          "been read at this stage. If options are necessary, pass them "\
    #          "from the command line"
    log.info("running the following command in directory: %s\n%s",
             fullpath_repackaged_dirname, ' '.join(args))
    log.info('-=' * 35 + '-')

    try:
        returncode = subprocess.call(
            args,
            cwd=fullpath_repackaged_dirname,
        )
    except Exception:
        log.error('ERROR running: %s', ' '.join(args))
        log.error('ERROR in %s', fullpath_repackaged_dirname)
        raise

    if returncode:
        log.error('ERROR running: %s', ' '.join(args))
        log.error('ERROR in %s', fullpath_repackaged_dirname)
        # log.error('   stderr: %s'res.stderr.read())
        # print >> sys.stderr, 'ERROR running: %s'%(' '.join(args),)
        # print >> sys.stderr, res.stderr.read()
        return returncode
        # raise RuntimeError('returncode %d'%returncode)
    # result = res.stdout.read().strip()

    shutil.rmtree(tmp_dist_dir)
    return returncode
Пример #8
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)
Пример #9
0
def runit():
    # process command-line options
    bool_opts = map(translate_longopt, stdeb_cmd_bool_opts)
    bool_opts.append("process-dependencies")
    parser = FancyGetopt(stdeb_cmdline_opts + [("help", "h", "show detailed help message")] + EXTRA_OPTS)
    optobj = OptObj()
    args = parser.getopt(object=optobj)
    idx = PackageIndex()
    for option in optobj.__dict__:
        value = getattr(optobj, option)
        is_string = type(value) == str
        if option in bool_opts and is_string:
            setattr(optobj, option, strtobool(value))

    if hasattr(optobj, "help"):
        print USAGE
        parser.set_option_table(stdeb_cmdline_opts + EXTRA_OPTS)
        parser.print_help("Options:")
        return 0

    if len(args) != 1:
        log.error("not given single argument (distfile), args=%r", args)
        print USAGE
        return 1

    sdist_file = args[0]

    package = None

    final_dist_dir = optobj.__dict__.get("dist_dir", "deb_dist")
    tmp_dist_dir = os.path.join(final_dist_dir, "tmp_py2dsc")
    if os.path.exists(tmp_dist_dir):
        shutil.rmtree(tmp_dist_dir)
    os.makedirs(tmp_dist_dir)

    if not os.path.isfile(sdist_file):
        for ext in EXTENSIONS:
            if sdist_file.endswith(ext):
                raise IOError, "File not found"
        package = Requirement.parse(sdist_file)
        log.info("Package %s not found, trying PyPI..." % sdist_file)
        dist = idx.fetch_distribution(package, final_dist_dir, force_scan=True, source=True)
        if hasattr(dist, "location"):
            sdist_file = dist.location
        else:
            raise Exception, "Distribution not found on PyPi"
        log.info("Got %s", sdist_file)

    dist = list(distros_for_filename(sdist_file))[0]
    idx.scan_egg_links(dist.location)
    package = idx.obtain(Requirement.parse(dist.project_name))

    if hasattr(optobj, "process_dependencies"):
        if bool(int(getattr(optobj, "process_dependencies"))):
            backup_argv = sys.argv[:]
            oldargv = sys.argv[:]
            oldargv.pop(-1)

            if package.requires():
                log.info("Processing package dependencies for %s", package)
            for req in package.requires():
                #                print >> sys.stderr
                new_argv = oldargv + ["%s" % req]
                log.info("Bulding dependency package %s", req)
                log.info("  running '%s'", " ".join(new_argv))
                sys.argv = new_argv
                runit()
            #                print >> sys.stderr
            if package.requires():
                log.info("Completed building dependencies " "for %s, continuing...", package)
        sys.argv = backup_argv

    if package is not None and hasattr(optobj, "extra_cfg_file"):
        # Allow one to have patch-files setup on config file for example
        local_parser = SafeConfigParser()
        local_parser.readfp(open(optobj.__dict__.get("extra_cfg_file")))
        if local_parser.has_section(package.project_name):
            for opt in local_parser.options(package.project_name):
                _opt = opt.replace("_", "-")
                if parser.has_option(_opt) or parser.has_option(_opt + "="):
                    setattr(optobj, opt, local_parser.get(package.project_name, opt))

    patch_file = optobj.__dict__.get("patch_file", None)
    patch_level = int(optobj.__dict__.get("patch_level", 0))
    patch_posix = int(optobj.__dict__.get("patch_posix", 0))

    expand_dir = os.path.join(tmp_dist_dir, "stdeb_tmp")
    if os.path.exists(expand_dir):
        shutil.rmtree(expand_dir)
    if not os.path.exists(tmp_dist_dir):
        os.mkdir(tmp_dist_dir)
    os.mkdir(expand_dir)

    expand_sdist_file(os.path.abspath(sdist_file), cwd=expand_dir)

    # now the sdist package is expanded in expand_dir
    expanded_root_files = os.listdir(expand_dir)
    assert len(expanded_root_files) == 1
    repackaged_dirname = expanded_root_files[0]
    fullpath_repackaged_dirname = os.path.join(tmp_dist_dir, repackaged_dirname)
    base_dir = os.path.join(expand_dir, expanded_root_files[0])
    if os.path.exists(fullpath_repackaged_dirname):
        # prevent weird build errors if this dir exists
        shutil.rmtree(fullpath_repackaged_dirname)
    os.renames(base_dir, fullpath_repackaged_dirname)
    del base_dir  # no longer useful

    ##############################################
    if patch_file is not None:
        log.info("py2dsc applying patch %s", patch_file)
        apply_patch(patch_file, posix=patch_posix, level=patch_level, cwd=fullpath_repackaged_dirname)
        patch_already_applied = 1
    else:
        patch_already_applied = 0
    ##############################################

    abs_dist_dir = os.path.abspath(final_dist_dir)

    extra_args = []
    for long in parser.long_opts:
        if long in ["dist-dir=", "patch-file=", "process-dependencies"]:
            continue  # dealt with by this invocation
        attr = parser.get_attr_name(long).rstrip("=")
        if hasattr(optobj, attr):
            val = getattr(optobj, attr)
            if attr == "extra_cfg_file":
                val = os.path.abspath(val)
            if long in bool_opts or long.replace("-", "_") in bool_opts:
                extra_args.append("--%s" % long)
            else:
                extra_args.append("--" + long + str(val))

    if patch_already_applied == 1:
        extra_args.append("--patch-already-applied")

    args = [
        sys.executable,
        "-c",
        "import stdeb, sys; f='setup.py'; " + "sys.argv[0]=f; execfile(f,{'__file__':f,'__name__':'__main__'})",
        "sdist_dsc",
        "--dist-dir=%s" % abs_dist_dir,
        "--use-premade-distfile=%s" % os.path.abspath(sdist_file),
    ] + extra_args

    log.info("-=" * 35 + "-")
    #    print >> sys.stderr, '-='*20
    #    print >> sys.stderr, "Note that the .cfg file(s), if present, have not "\
    #          "been read at this stage. If options are necessary, pass them from "\
    #          "the command line"
    log.info("running the following command in directory: %s\n%s", fullpath_repackaged_dirname, " ".join(args))
    log.info("-=" * 35 + "-")

    try:
        returncode = subprocess.call(args, cwd=fullpath_repackaged_dirname)
    except:
        log.error("ERROR running: %s", " ".join(args))
        log.error("ERROR in %s", fullpath_repackaged_dirname)
        raise

    if returncode:
        log.error("ERROR running: %s", " ".join(args))
        log.error("ERROR in %s", fullpath_repackaged_dirname)
        # log.error('   stderr: %s'res.stderr.read())
        # print >> sys.stderr, 'ERROR running: %s'%(' '.join(args),)
        # print >> sys.stderr, res.stderr.read()
        return returncode
        # raise RuntimeError('returncode %d'%returncode)
    # result = res.stdout.read().strip()

    shutil.rmtree(tmp_dist_dir)
    return returncode