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._branches) > 1: self._provider.debug( "Complete version solving took {:.3f} seconds for {} branches" .format(end - start, len(self._branches[1:]))) self._provider.debug("Resolved for branches: {}".format( ", ".join("({})".format(b) for b in self._branches[1:]))) operations = [] for package in 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.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: 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)) else: operations.append( Install(package).skip("Already installed")) elif package.version != pkg.version: # Checking version operations.append(Update(pkg, package)) elif package.source_type != pkg.source_type: operations.append(Update(pkg, package)) else: operations.append( Install(package).skip("Already installed")) break if not installed: operations.append(Install(package)) # 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) return sorted( operations, key=lambda o: ( o.job_type == "uninstall", # Packages to be uninstalled have no depth so we default to 0 # since it actually doesn't matter since removals are always on top. -depths[packages.index(o.package)] if o.job_type != "uninstall" else 0, o.package.name, o.package.version, ), )
def test_normalize_url(url, normalized): assert normalized == Git.normalize_url(url)
def _parse_requirements( self, requirements): # type: (List[str]) -> List[Dict[str, str]] from poetry.puzzle.provider import Provider result = [] try: cwd = self.poetry.file.parent except RuntimeError: cwd = Path.cwd() for requirement in requirements: requirement = requirement.strip() extras = [] extras_m = re.search(r"\[([\w\d,-_]+)\]$", requirement) if extras_m: extras = [e.strip() for e in extras_m.group(1).split(",")] requirement, _ = requirement.split("[") url_parsed = urlparse.urlparse(requirement) if url_parsed.scheme and url_parsed.netloc: # Url if url_parsed.scheme in ["git+https", "git+ssh"]: from poetry.vcs.git import Git from poetry.vcs.git import ParsedUrl parsed = ParsedUrl.parse(requirement) url = Git.normalize_url(requirement) pair = OrderedDict([("name", parsed.name), ("git", url.url)]) if parsed.rev: pair["rev"] = url.revision if extras: pair["extras"] = extras package = Provider.get_package_from_vcs( "git", url.url, reference=pair.get("rev")) pair["name"] = package.name result.append(pair) continue elif url_parsed.scheme in ["http", "https"]: package = Provider.get_package_from_url(requirement) pair = OrderedDict([("name", package.name), ("url", package.source_url)]) if extras: pair["extras"] = extras result.append(pair) continue elif (os.path.sep in requirement or "/" in requirement) and cwd.joinpath(requirement).exists(): path = cwd.joinpath(requirement) if path.is_file(): package = Provider.get_package_from_file(path.resolve()) else: package = Provider.get_package_from_directory(path) result.append( OrderedDict([ ("name", package.name), ("path", path.relative_to(cwd).as_posix()), ] + ([("extras", extras)] if extras else []))) continue pair = re.sub("^([^@=: ]+)(?:@|==|(?<![<>~!])=|:| )(.*)$", "\\1 \\2", requirement) pair = pair.strip() require = OrderedDict() if " " in pair: name, version = pair.split(" ", 2) extras_m = re.search(r"\[([\w\d,-_]+)\]$", name) if extras_m: extras = [e.strip() for e in extras_m.group(1).split(",")] name, _ = name.split("[") require["name"] = name if version != "latest": require["version"] = version else: m = re.match(r"^([^><=!: ]+)((?:>=|<=|>|<|!=|~=|~|\^).*)$", requirement.strip()) if m: name, constraint = m.group(1), m.group(2) extras_m = re.search(r"\[([\w\d,-_]+)\]$", name) if extras_m: extras = [ e.strip() for e in extras_m.group(1).split(",") ] name, _ = name.split("[") require["name"] = name require["version"] = constraint else: extras_m = re.search(r"\[([\w\d,-_]+)\]$", pair) if extras_m: extras = [ e.strip() for e in extras_m.group(1).split(",") ] pair, _ = pair.split("[") require["name"] = pair if extras: require["extras"] = extras result.append(require) return result