def _resolve_and_link(self, interpreter, requirement, target_link): # Short-circuit if there is a local copy. if os.path.exists(target_link) and os.path.exists(os.path.realpath(target_link)): bdist = Package.from_href(os.path.realpath(target_link)) if bdist.satisfies(requirement): return bdist # Since we're resolving to bootstrap a bare interpreter, we won't have wheel available. # Explicitly set the precedence to avoid resolution of wheels or distillation of sdists into # wheels. precedence = (EggPackage, SourcePackage) distributions = resolve(requirements=[requirement], fetchers=self._python_repos.get_fetchers(), interpreter=interpreter, platform=expand_and_maybe_adjust_platform( interpreter=interpreter, # The local interpreter cache is, by definition, composed of # interpreters for the 'current' platform. platform='current'), context=self._python_repos.get_network_context(), precedence=precedence) if not distributions: return None assert len(distributions) == 1, ('Expected exactly 1 distribution to be resolved for {}, ' 'found:\n\t{}'.format(requirement, '\n\t'.join(map(str, distributions)))) dist_location = distributions[0].location target_location = os.path.join(os.path.dirname(target_link), os.path.basename(dist_location)) shutil.move(dist_location, target_location) _safe_link(target_location, target_link) self._logger(' installed {}'.format(target_location)) return Package.from_href(target_location)
def resolve_multi(interpreter, requirements, platforms, find_links): """Multi-platform dependency resolution for PEX files. Returns a list of distributions that must be included in order to satisfy a set of requirements. That may involve distributions for multiple platforms. :param interpreter: The :class:`PythonInterpreter` to resolve for. :param requirements: A list of :class:`PythonRequirement` objects to resolve. :param platforms: A list of :class:`Platform`s to resolve for. :param find_links: Additional paths to search for source packages during resolution. :return: Map of platform name -> list of :class:`pkg_resources.Distribution` instances needed to satisfy the requirements on that platform. """ python_setup = PythonSetup.global_instance() python_repos = PythonRepos.global_instance() platforms = platforms or python_setup.platforms find_links = find_links or [] distributions = {} fetchers = python_repos.get_fetchers() fetchers.extend(Fetcher([path]) for path in find_links) for platform in platforms: requirements_cache_dir = os.path.join(python_setup.resolver_cache_dir, str(interpreter.identity)) distributions[platform] = resolve( requirements=[req.requirement for req in requirements], interpreter=interpreter, fetchers=fetchers, platform=expand_and_maybe_adjust_platform(interpreter=interpreter, platform=platform), context=python_repos.get_network_context(), cache=requirements_cache_dir, cache_ttl=python_setup.resolver_cache_ttl, allow_prereleases=python_setup.resolver_allow_prereleases, pkg_blacklist=python_setup.resolver_blacklist, use_manylinux=python_setup.use_manylinux) return distributions
def resolve_multi(interpreter, requirements, platforms, find_links): """Multi-platform dependency resolution for PEX files. Returns a list of distributions that must be included in order to satisfy a set of requirements. That may involve distributions for multiple platforms. :param interpreter: The :class:`PythonInterpreter` to resolve for. :param requirements: A list of :class:`PythonRequirement` objects to resolve. :param platforms: A list of :class:`Platform`s to resolve for. :param find_links: Additional paths to search for source packages during resolution. :return: Map of platform name -> list of :class:`pkg_resources.Distribution` instances needed to satisfy the requirements on that platform. """ python_setup = PythonSetup.global_instance() python_repos = PythonRepos.global_instance() platforms = platforms or python_setup.platforms find_links = find_links or [] distributions = {} fetchers = python_repos.get_fetchers() fetchers.extend(Fetcher([path]) for path in find_links) for platform in platforms: requirements_cache_dir = os.path.join(python_setup.resolver_cache_dir, str(interpreter.identity)) distributions[platform] = resolve( requirements=[req.requirement for req in requirements], interpreter=interpreter, fetchers=fetchers, platform=expand_and_maybe_adjust_platform(interpreter=interpreter, platform=platform), context=python_repos.get_network_context(), cache=requirements_cache_dir, cache_ttl=python_setup.resolver_cache_ttl, allow_prereleases=python_setup.resolver_allow_prereleases, pkg_blacklist=python_setup.resolver_blacklist, use_manylinux=python_setup.use_manylinux) return distributions