def __init__(self, path, readonly=False): assert path is not None if readonly and path == sys.executable: self._path = sys.executable self._platform = distutils.util.get_platform() self._python_path = sys.path self._version = ".".join(map(str, sys.version_info[:2])) else: have_python, version = have_cmd( path, '-c', 'print "version", ' '".".join(map(str, __import__("sys").version_info[:2]))') if not have_python: raise InstallationError( "This configuration requires a specific Python " "you don't have:", path) self._version = version self._path = get_cmd_output( path, "-c", "print __import__('sys').executable")[0].strip() self._platform = None self._python_path = None self._setuptools = {} self._lock = threading.RLock()
def build(self, distribution, path, interpretor): working_dir = distribution.package_path logger.info("Building extensions in %s" % working_dir) environ = {'PYTHON': str(interpretor)} stdout, stderr, code = get_cmd_output( 'configure', '--prefix=%s' % path, '--cache-file=%s' % self.cache_name, path=working_dir, environ=environ, no_stdout=True) if code: raise PackageError( u"Extensions configuration failed for %s." % distribution) stdout, stderr, code = get_cmd_output( 'make', path=working_dir, no_stdout=True) if code: raise PackageError( u"Extensions build failed for %s." % distribution)
def install(self, distribution, path, interpretor): working_dir = distribution.package_path logger.info("Installing extensions from %s" % working_dir) stdout, stderr, code = get_cmd_output( 'make', 'install', path=working_dir, no_stdout=True) if code: raise PackageError( u"Extensions installation failed for %s." % distribution)
def create_autotools(distribution, source_prefix, extensions): """Create an autotools installation into the given distribution to compile the described extensions. """ makefiles = [] libraries = {} sub_dirs = {} working_dir = distribution.package_path logger.info("Creating autotools installation in %s" % working_dir) for extension in extensions: path = os.path.dirname(extension['name']) makefile = os.path.join(path, 'Makefile') if makefile not in makefiles: makefiles.append(makefile) path_libraries = libraries.setdefault(path, []) path_libraries.append(extension) # We need to make sure we have all Makefile, even those with no # exntensions (only subdirs) for makefile in makefiles: parts = makefile.split(os.path.sep) for index in range(len(parts) - 1): sub_dir = '' if index: sub_dir = os.path.join(*parts[:index]) sub_makefile = os.path.join(sub_dir, 'Makefile') if sub_makefile not in makefiles: makefiles.append(sub_makefile) sub_dirs.setdefault(sub_dir, set()).add(parts[index]) makefiles.sort() configure_info = {'project_name': distribution.name, 'project_version': distribution.version, 'source_prefix': source_prefix, 'makefiles': ' '.join(makefiles)} configure_ac = open(os.path.join(working_dir, 'configure.ac'), 'w') configure_ac.write(CONFIGURE_AC_TEMPLATE % configure_info) configure_ac.close() create_makefile_am(working_dir, source_prefix, '', sub_dirs, libraries) macros_dir = os.path.join(working_dir, 'm4') if not os.path.isdir(macros_dir): os.makedirs(macros_dir) python_m4 = os.path.join(os.path.dirname(__file__), 'python.m4') # XXX os.link doesn't work on windaube os.link(python_m4, os.path.join(macros_dir, 'python.m4')) stdout, stderr, code = get_cmd_output( 'autoreconf', '-v', '-f', '-i', path=working_dir) if code: raise PackageError(u"Autotools creation failed in %s." % working_dir)
def _run_git(self, arguments, error=None, path=None): command = ['git'] command.extend(arguments) options = dict(path=path) stdout, stderr, code = get_cmd_output(*command, **options) if code: if error is None: error = u"Error while running git command for" raise GitError( error, self.checkout.uri, command=command, detail=stderr) return stdout.strip()
def _run_mercurial(self, arguments, error=None, path=None): command = ["hg"] command.extend(arguments) command.extend(["--quiet", "--noninteractive"]) options = dict(path=path) stdout, stderr, code = get_cmd_output(*command, **options) if code: if error is None: error = u"Error while running mercurial command for" if code != 1 and (not stderr or stderr.startswith("warning:")): raise MercurialError(error, self.checkout.uri, command=command, detail=stderr) return stdout.strip()
def execute_module(self, module, *args, **opts): """Run the given module with the given args. """ module_file = module.__file__ if module_file.endswith('.pyc'): module_file = module_file[:-1] cmd = [self._path] if 'python_options' in opts: cmd.extend(opts['python_options']) del opts['python_options'] cmd.append(module_file) cmd.extend(args) return get_cmd_output(*cmd, **opts)
def _run_svn(self, arguments, error=None, path=None): command = ['svn'] command.extend(self.options) command.extend(arguments) options = dict(environ={'LC_ALL': 'C'}, path=path) stdout, stderr, code = get_cmd_output(*command, **options) if code: reason = stderr.strip().split('\n')[-1] if INVALID_CERTIFICATE in reason: raise SubversionError( u"Invalid certificate. " u"Please checkout and approve certificate by hand.", self.checkout.uri) if AUTHORIZATION_FAILED in reason: raise SubversionError( u"Invalid username or password", self.checkout.uri) if error is None: error = u"Error while running svn command" raise SubversionError( error, self.checkout.uri, detail=stderr, command=command) return stdout
def __call__(self, distribution, path, interpretor, trust=-99): setup_py = os.path.join(path, 'setup.py') if os.path.isfile(setup_py): # You need to clean first the egg_info. install_requires # will trigger strange things only if it exists. egg_info_parent, egg_info = find_egg_info(distribution, path) if egg_info is not None and os.path.isdir(egg_info): # We will use the egg SOURCES.txt as input for a # MANIFEST. Most of packages miss one or have a # incomplete one and won't install everything without # one. if trust < 0: source_file = os.path.join(egg_info, 'SOURCES.txt') manifest_file = os.path.join(path, 'MANIFEST.in') if os.path.isfile(source_file): create_manifest_from_source(source_file, manifest_file) shutil.rmtree(egg_info) # Determine which version of setuptools to use version = None environ = self.environ.get(distribution.name, {}) if distribution.name == 'setuptools': # To install setuptools, we need the same version. version = str(distribution.version) else: version = self.version def execute(*command, **options): kwargs = {'environ': environ, 'version': version} kwargs.update(options) return interpretor.execute_setuptools( *command, **kwargs) # Apply patches if distribution.name in self.patches: for patch in self.patches[distribution.name]: stream = open_uri(patch) try: output, errors, code = get_cmd_output( 'patch', '-p0', path=path, input=stream.read()) finally: stream.close() if code: raise InstallationError( u'Error while patching setuptools egg %s.' % ( distribution.name), detail='\n'.join((output, errors))) # Get fresh egg_info output, errors, code = execute('egg_info', path=path) if not code: egg_info_parent, egg_info = find_egg_info(distribution, path) if egg_info is not None and os.path.isdir(egg_info): return NativeSetuptoolsLoader( path, egg_info, distribution, source_path=egg_info_parent, execute=execute) else: logger.debug( u"Could not find egg-info in %s, " % (path)) elif self.errors: raise PackageError( u"Setuptools retuned status code %s in %s." % ( code, path), detail='\n'.join((output, errors))) else: logger.info( u"Setuptools retuned status code %s in %s, " % ( code, path)) return None
def execute_external(self, *command, **opts): """Run an external command with the given args. """ cmd = [self._path] cmd.extend(command) return get_cmd_output(*cmd, **opts)