def load(cls, env): # type: (Env) -> InstalledRepository """ Load installed packages. """ repo = cls() seen = set() for entry in reversed(env.sys_path): for distribution in sorted( metadata.distributions(path=[entry]), key=lambda d: str(d._path), ): name = distribution.metadata["name"] path = Path(str(distribution._path)) version = distribution.metadata["version"] package = Package(name, version, version) package.description = distribution.metadata.get("summary", "") if package.name in seen: continue try: path.relative_to(_VENDORS) except ValueError: pass else: continue seen.add(package.name) repo.add_package(package) is_standard_package = env.is_path_relative_to_lib(path) if is_standard_package: if path.name.endswith(".dist-info"): paths = cls.get_package_paths(env=env, name=package.pretty_name) if paths: for src in paths: if cls.is_vcs_package(src, env): cls.set_package_vcs_properties(package, env) break else: # TODO: handle multiple source directories? package.source_type = "directory" package.source_url = paths.pop().as_posix() continue if cls.is_vcs_package(path, env): cls.set_package_vcs_properties(package, env) else: # If not, it's a path dependency package.source_type = "directory" package.source_url = str(path.parent) return repo
def find_packages(self, name, constraint=None, extras=None, allow_prereleases=False): packages = [] if constraint is None: constraint = "*" if not isinstance(constraint, VersionConstraint): constraint = parse_constraint(constraint) if isinstance(constraint, VersionRange): if (constraint.max is not None and constraint.max.is_prerelease() or constraint.min is not None and constraint.min.is_prerelease()): allow_prereleases = True key = name if not constraint.is_any(): key = "{}:{}".format(key, str(constraint)) if self._cache.store("matches").has(key): versions = self._cache.store("matches").get(key) else: page = self._get("/{}/".format( canonicalize_name(name).replace(".", "-"))) if page is None: return [] versions = [] for version in page.versions: if version.is_prerelease() and not allow_prereleases: continue if constraint.allows(version): versions.append(version) self._cache.store("matches").put(key, versions, 5) for version in versions: package = Package(name, version) package.source_type = "legacy" package.source_reference = self.name package.source_url = self._url if extras is not None: package.requires_extras = extras packages.append(package) self._log( "{} packages found for {} {}".format(len(packages), name, str(constraint)), level="debug", ) return packages
def install_git(self, package): from poetry.core.packages import Package from poetry.core.vcs import Git src_dir = self._env.path / "src" / package.name if src_dir.exists(): safe_rmtree(str(src_dir)) src_dir.parent.mkdir(exist_ok=True) git = Git() git.clone(package.source_url, src_dir) git.checkout(package.source_reference, src_dir) # Now we just need to install from the source directory pkg = Package(package.name, package.version) pkg.source_type = "directory" pkg.source_url = str(src_dir) pkg.develop = package.develop self.install_directory(pkg)
def solve(self, use_latest=None): # type: (...) -> List[Operation] with self._provider.progress(): start = time.time() packages, depths = self._solve(use_latest=use_latest) end = time.time() if len(self._overrides) > 1: self._provider.debug( "Complete version solving took {:.3f} seconds with {} overrides" .format(end - start, len(self._overrides))) self._provider.debug("Resolved with overrides: {}".format( ", ".join("({})".format(b) for b in self._overrides))) operations = [] for i, package in enumerate(packages): installed = False for pkg in self._installed.packages: if package.name == pkg.name: installed = True if pkg.source_type == "git" and package.source_type == "git": from poetry.core.vcs.git import Git # Trying to find the currently installed version pkg_source_url = Git.normalize_url(pkg.source_url) package_source_url = Git.normalize_url( package.source_url) for locked in self._locked.packages: if locked.name != pkg.name or locked.source_type != "git": continue locked_source_url = Git.normalize_url( locked.source_url) if (locked.name == pkg.name and locked.source_type == pkg.source_type and locked_source_url == pkg_source_url and locked.source_reference == pkg.source_reference): pkg = Package(pkg.name, locked.version) pkg.source_type = "git" pkg.source_url = locked.source_url pkg.source_reference = locked.source_reference break if pkg_source_url != package_source_url or ( pkg.source_reference != package.source_reference and not pkg.source_reference.startswith( package.source_reference)): operations.append( Update(pkg, package, priority=depths[i])) else: operations.append( Install(package).skip("Already installed")) elif package.version != pkg.version: # Checking version operations.append( Update(pkg, package, priority=depths[i])) elif pkg.source_type and package.source_type != pkg.source_type: operations.append( Update(pkg, package, priority=depths[i])) else: operations.append( Install( package, priority=depths[i]).skip("Already installed")) break if not installed: operations.append(Install(package, priority=depths[i])) # Checking for removals for pkg in self._locked.packages: remove = True for package in packages: if pkg.name == package.name: remove = False break if remove: skip = True for installed in self._installed.packages: if installed.name == pkg.name: skip = False break op = Uninstall(pkg) if skip: op.skip("Not currently installed") operations.append(op) if self._remove_untracked: locked_names = {locked.name for locked in self._locked.packages} for installed in self._installed.packages: if installed.name == self._package.name: continue if installed.name in Provider.UNSAFE_PACKAGES: # Never remove pip, setuptools etc. continue if installed.name not in locked_names: operations.append(Uninstall(installed)) return sorted( operations, key=lambda o: ( -o.priority, o.package.name, o.package.version, ), )
def load(cls, env): # type: (Env) -> InstalledRepository """ Load installed packages. """ repo = cls() seen = set() for entry in reversed(env.sys_path): for distribution in sorted( metadata.distributions(path=[entry]), key=lambda d: str(d._path), ): name = distribution.metadata["name"] path = Path(str(distribution._path)) version = distribution.metadata["version"] package = Package(name, version, version) package.description = distribution.metadata.get("summary", "") if package.name in seen: continue try: path.relative_to(_VENDORS) except ValueError: pass else: continue seen.add(package.name) repo.add_package(package) is_standard_package = True try: path.relative_to(env.site_packages) except ValueError: is_standard_package = False if is_standard_package: if path.name.endswith(".dist-info"): paths = cls.get_package_paths( sitedir=env.site_packages, name=package.pretty_name) if paths: # TODO: handle multiple source directories? package.source_type = "directory" package.source_url = paths.pop().as_posix() continue src_path = env.path / "src" # A VCS dependency should have been installed # in the src directory. If not, it's a path dependency try: path.relative_to(src_path) from poetry.core.vcs.git import Git git = Git() revision = git.rev_parse("HEAD", src_path / package.name).strip() url = git.remote_url(src_path / package.name) package.source_type = "git" package.source_url = url package.source_reference = revision except ValueError: package.source_type = "directory" package.source_url = str(path.parent) return repo