def get_deb_depends_from_setuptools_requires(requirements): depends = [] # This will be the return value from this function. parsed_reqs=[] for extra,reqs in pkg_resources.split_sections(requirements): if extra: continue parsed_reqs.extend(pkg_resources.parse_requirements(reqs)) if not parsed_reqs: return depends if not os.path.exists('/usr/bin/apt-file'): raise ValueError('apt-file not in /usr/bin. Please install ' 'with: sudo apt-get install apt-file') # Ask apt-file for any packages which have a .egg-info file by # these names. # Note that apt-file appears to think that some packages # e.g. setuptools itself have "foo.egg-info/BLAH" files but not a # "foo.egg-info" directory. egginfore=("(/(%s)(?:-[^/]+)?(?:-py[0-9]\.[0-9.]+)?\.egg-info)" % '|'.join(req.project_name for req in parsed_reqs)) args = ["apt-file", "search", "--ignore-case", "--regexp", egginfore] try: cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) except Exception, le: log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('exception %s from subprocess %s' % (le,args))
def get_deb_depends_from_setuptools_requires(requirements, on_failure="warn"): """ Suppose you can't confidently figure out a .deb which satisfies a given requirement. If on_failure == 'warn', then log a warning. If on_failure == 'raise' then raise CantSatisfyRequirement exception. If on_failure == 'guess' then guess that python-$FOO will satisfy the dependency and that the Python version numbers will apply to the Debian packages (in addition to logging a warning message). """ assert on_failure in ("raise", "warn", "guess"), on_failure import pkg_resources depends = [] # This will be the return value from this function. parsed_reqs=[] for extra,reqs in pkg_resources.split_sections(requirements): if extra: continue parsed_reqs.extend(pkg_resources.parse_requirements(reqs)) if not parsed_reqs: return depends if not os.path.exists('/usr/bin/apt-file'): raise ValueError('apt-file not in /usr/bin. Please install ' 'with: sudo apt-get install apt-file') # Ask apt-file for any packages which have a .egg-info file by # these names. # Note that apt-file appears to think that some packages # e.g. setuptools itself have "foo.egg-info/BLAH" files but not a # "foo.egg-info" directory. egginfore=("(/(%s)(?:-[^/]+)?(?:-py[0-9]\.[0-9.]+)?\.egg-info)" % '|'.join(req.project_name.replace('-', '_') for req in parsed_reqs)) args = ["apt-file", "search", "--ignore-case", "--regexp", egginfore] if 1: # do dry run on apt-file dry_run_args = args[:] + ['--dummy','--non-interactive'] cmd = subprocess.Popen(dry_run_args,stderr=subprocess.PIPE) returncode = cmd.wait() if returncode: err_output = cmd.stderr.read() raise RuntimeError('Error running "apt-file search": ' + err_output.strip()) try: cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) except Exception, le: # TODO: catch rc=1 and "E: The cache directory is empty. You need to # run 'apt-file update' first.", and tell the user to follow those # instructions. log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('exception %s from subprocess %s' % (le,args))
def get_cmd_stdout(args): cmd = subprocess.Popen(args,stdout=subprocess.PIPE) returncode = cmd.wait() if returncode: log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('returncode %d', returncode) return cmd.stdout.read()
def get_cmd_stdout(args): cmd = subprocess.Popen(args, stdout=subprocess.PIPE) returncode = cmd.wait() if returncode: log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('returncode %d', returncode) return cmd.stdout.read()
def apply_patch(patchfile, cwd=None, posix=False, level=0): """call 'patch -p[level] [--posix] < arg1' posix mode is sometimes necessary. It keeps empty files so that dpkg-source removes their contents. """ if not os.path.exists(patchfile): raise RuntimeError('patchfile "%s" does not exist' % patchfile) fd = open(patchfile, mode='r') level_str = '-p%d' % level args = ['/usr/bin/patch', level_str] if posix: args.append('--posix') log.info('PATCH COMMAND: %s < %s', ' '.join(args), patchfile) log.info(' PATCHING in dir: %s', cwd) # print >> sys.stderr, 'PATCH COMMAND:',' '.join(args),'<',patchfile # print >> sys.stderr, ' PATCHING in dir:',cwd res = subprocess.Popen( args, cwd=cwd, stdin=fd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) returncode = None while returncode is None: returncode = res.poll() ready = select.select([res.stdout, res.stderr], [], [], 0.1) # XXX figure out how to do this without reading byte-by-byte if res.stdout in ready[0]: sys.stdout.write(res.stdout.read(1)) sys.stdout.flush() if res.stderr in ready[0]: sys.stderr.write(res.stderr.read(1)) sys.stderr.flush() # finish outputting file sys.stdout.write(res.stdout.read()) sys.stdout.flush() sys.stderr.write(res.stderr.read()) sys.stderr.flush() if returncode: log.error('ERROR running: %s', ' '.join(args)) log.error('ERROR in %s', cwd) # print >> sys.stderr, 'ERROR running: %s'%(' '.join(args),) # print >> sys.stderr, 'ERROR in',cwd raise RuntimeError('returncode %d' % returncode)
def apply_patch(patchfile,cwd=None,posix=False,level=0): """call 'patch -p[level] [--posix] < arg1' posix mode is sometimes necessary. It keeps empty files so that dpkg-source removes their contents. """ if not os.path.exists(patchfile): raise RuntimeError('patchfile "%s" does not exist'%patchfile) fd = open(patchfile,mode='r') level_str = '-p%d'%level args = ['/usr/bin/patch',level_str] if posix: args.append('--posix') log.info('PATCH COMMAND: %s < %s', ' '.join(args), patchfile) log.info(' PATCHING in dir: %s', cwd) # print >> sys.stderr, 'PATCH COMMAND:',' '.join(args),'<',patchfile # print >> sys.stderr, ' PATCHING in dir:',cwd res = subprocess.Popen( args, cwd=cwd, stdin=fd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) returncode=None while returncode is None: returncode = res.poll() ready = select.select( [res.stdout,res.stderr],[],[],0.1) # XXX figure out how to do this without reading byte-by-byte if res.stdout in ready[0]: sys.stdout.write(res.stdout.read(1)) sys.stdout.flush() if res.stderr in ready[0]: sys.stderr.write(res.stderr.read(1)) sys.stderr.flush() # finish outputting file sys.stdout.write(res.stdout.read()) sys.stdout.flush() sys.stderr.write(res.stderr.read()) sys.stderr.flush() if returncode: log.error('ERROR running: %s', ' '.join(args)) log.error('ERROR in %s', cwd) # print >> sys.stderr, 'ERROR running: %s'%(' '.join(args),) # print >> sys.stderr, 'ERROR in',cwd raise RuntimeError('returncode %d'%returncode)
def apt_cache_info(apt_cache_cmd, package_name): if apt_cache_cmd not in ('showsrc', 'show'): raise NotImplementedError( "don't know how to run apt-cache command '%s'" % apt_cache_cmd) result_list = [] args = ["apt-cache", apt_cache_cmd, package_name] cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) returncode = cmd.wait() if returncode: errline = cmd.stderr.read() if not (returncode == 100 and errline == "E: You must put some 'source' URIs in your sources.list\n"): log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('returncode %d from subprocess %s' % (returncode, args)) inlines = cmd.stdout.read() version_blocks = inlines.split('\n\n') for version_block in version_blocks: block_dict = {} if len(version_block) == 0: continue version_lines = version_block.split('\n') assert version_lines[0].startswith('Package: ') block_dict['Package'] = version_lines[0][len('Package: '):] if apt_cache_cmd == 'showsrc': assert version_lines[1].startswith('Binary: ') block_dict['Binary'] = version_lines[1][len('Binary: '):] block_dict['Binary'] = block_dict['Binary'].split(', ') elif apt_cache_cmd == 'show': for start in ('Provides: ', 'Conflicts: ', 'Replaces: '): key = start[:-2] for line in version_lines[2:]: if line.startswith(start): unsplit_line_result = line[len(start):] split_result = unsplit_line_result.split(', ') block_dict[key] = split_result if key not in block_dict: block_dict[key] = [] result_list.append(block_dict) return result_list
def apt_cache_info(apt_cache_cmd,package_name): if apt_cache_cmd not in ('showsrc','show'): raise NotImplementedError( "don't know how to run apt-cache command '%s'"%apt_cache_cmd) result_list = [] args = ["apt-cache", apt_cache_cmd, package_name] cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) returncode = cmd.wait() if returncode: errline = cmd.stderr.read() if not (returncode == 100 and errline == "E: You must put some 'source' URIs in your sources.list\n"): log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('returncode %d from subprocess %s' % (returncode, args)) inlines = cmd.stdout.read() version_blocks = inlines.split('\n\n') for version_block in version_blocks: block_dict = {} if len(version_block)==0: continue version_lines = version_block.split('\n') assert version_lines[0].startswith('Package: ') block_dict['Package'] = version_lines[0][ len('Package: '): ] if apt_cache_cmd == 'showsrc': assert version_lines[1].startswith('Binary: ') block_dict['Binary'] = version_lines[1][ len('Binary: '): ] block_dict['Binary'] = block_dict['Binary'].split(', ') elif apt_cache_cmd == 'show': for start in ('Provides: ','Conflicts: ','Replaces: '): key = start[:-2] for line in version_lines[2:]: if line.startswith(start): unsplit_line_result = line[ len(start): ] split_result = unsplit_line_result.split(', ') block_dict[key] = split_result if key not in block_dict: block_dict[key] = [] result_list.append(block_dict) return result_list
def expand_zip(zip_fname,cwd=None): "expand a zip" unzip_path = '/usr/bin/unzip' if not os.path.exists(unzip_path): log.error('ERROR: {} does not exist'.format(unzip_path)) sys.exit(1) args = [unzip_path, zip_fname] # Does it have a top dir res = subprocess.Popen( [args[0], '-l', args[1]], cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) contents = [] for line in res.stdout.readlines()[3:-2]: contents.append(line.split()[-1]) commonprefix = os.path.commonprefix(contents) if not commonprefix: extdir = os.path.join(cwd, os.path.basename(zip_fname[:-4])) args.extend(['-d', os.path.abspath(extdir)]) process_command(args, cwd=cwd)
# "foo.egg-info" directory. egginfore=("(/(%s)(?:-[^/]+)?(?:-py[0-9]\.[0-9.]+)?\.egg-info)" % '|'.join(req.project_name for req in parsed_reqs)) args = ["apt-file", "search", "--ignore-case", "--regexp", egginfore] try: cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) except Exception, le: log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('exception %s from subprocess %s' % (le,args)) returncode = cmd.wait() if returncode: log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('returncode %d from subprocess %s' % (returncode, args)) inlines = cmd.stdout.readlines() dd = {} # {pydistname: {pydist: set(debpackagename)}} E=re.compile(egginfore, re.I) D=re.compile("^([^:]*):", re.I) eggsndebs = set() for l in inlines: if l: emo = E.search(l) assert emo, l dmo = D.search(l) assert dmo, l
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 get_deb_depends_from_setuptools_requires(requirements, on_failure="warn"): """ Suppose you can't confidently figure out a .deb which satisfies a given requirement. If on_failure == 'warn', then log a warning. If on_failure == 'raise' then raise CantSatisfyRequirement exception. If on_failure == 'guess' then guess that python-$FOO will satisfy the dependency and that the Python version numbers will apply to the Debian packages (in addition to logging a warning message). """ assert on_failure in ("raise", "warn", "guess"), on_failure import pkg_resources depends = [] # This will be the return value from this function. parsed_reqs = [] for extra, reqs in pkg_resources.split_sections(requirements): if extra: continue parsed_reqs.extend(pkg_resources.parse_requirements(reqs)) if not parsed_reqs: return depends if not os.path.exists('/usr/bin/apt-file'): raise ValueError('apt-file not in /usr/bin. Please install ' 'with: sudo apt-get install apt-file') # Ask apt-file for any packages which have a .egg-info file by # these names. # Note that apt-file appears to think that some packages # e.g. setuptools itself have "foo.egg-info/BLAH" files but not a # "foo.egg-info" directory. egginfore = ( "(/(%s)(?:-[^/]+)?(?:-py[0-9]\.[0-9.]+)?\.egg-info)" % '|'.join(req.project_name.replace('-', '_') for req in parsed_reqs)) args = ["apt-file", "search", "--ignore-case", "--regexp", egginfore] if 1: # do dry run on apt-file dry_run_args = args[:] + ['--dummy', '--non-interactive'] cmd = subprocess.Popen(dry_run_args, stderr=subprocess.PIPE) returncode = cmd.wait() if returncode: err_output = cmd.stderr.read() raise RuntimeError('Error running "apt-file search": ' + err_output.strip()) try: cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) except Exception, le: # TODO: catch rc=1 and "E: The cache directory is empty. You need to # run 'apt-file update' first.", and tell the user to follow those # instructions. log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('exception %s from subprocess %s' % (le, args))
err_output.strip()) try: cmd = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) except Exception, le: # TODO: catch rc=1 and "E: The cache directory is empty. You need to # run 'apt-file update' first.", and tell the user to follow those # instructions. log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('exception %s from subprocess %s' % (le, args)) returncode = cmd.wait() if returncode: log.error('ERROR running: %s', ' '.join(args)) raise RuntimeError('returncode %d from subprocess %s' % (returncode, args)) inlines = cmd.stdout.readlines() dd = {} # {pydistname: {pydist: set(debpackagename)}} E = re.compile(egginfore, re.I) D = re.compile("^([^:]*):", re.I) eggsndebs = set() for l in inlines: if l: emo = E.search(l) assert emo, l dmo = D.search(l) assert dmo, l
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 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