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])))
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)
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)
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])))
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)
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
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
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)
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