Commit 1c195b36 by Sébastien Eustace Committed by GitHub

debug:resolve command improvements (#402)

* Add a —tree option to debug:resolve

* Add support for git dependencies in debug:resolve

* Add tests for debug:resolve
parent bc3b7344
......@@ -13,6 +13,7 @@ class DebugResolveCommand(Command):
{ package?* : packages to resolve. }
{ --E|extras=* : Extras to activate for the dependency. }
{ --python= : Python version(s) to use for resolution. }
{ --tree : Displays the dependency tree. }
"""
_loggers = ["poetry.repositories.pypi_repository"]
......@@ -29,16 +30,14 @@ class DebugResolveCommand(Command):
if not packages:
package = self.poetry.package
else:
requirements = self._determine_requirements(packages)
requirements = self._format_requirements(requirements)
# validate requirements format
for constraint in requirements.values():
parse_constraint(constraint)
package = ProjectPackage(
self.poetry.package.name, self.poetry.package.version
)
requirements = self._format_requirements(packages)
dependencies = []
for name, constraint in requirements.items():
dep = Dependency(name, constraint)
dep = package.add_dependency(name, constraint)
extras = []
for extra in self.option("extras"):
if " " in extra:
......@@ -49,17 +48,9 @@ class DebugResolveCommand(Command):
for ex in extras:
dep.extras.append(ex)
dependencies.append(dep)
package = ProjectPackage(
self.poetry.package.name, self.poetry.package.version
)
package.python_versions = (
self.option("python") or self.poetry.package.python_versions
)
for dep in dependencies:
package.requires.append(dep)
solver = Solver(
package, self.poetry.pool, Repository(), Repository(), self.output
......@@ -71,6 +62,23 @@ class DebugResolveCommand(Command):
self.line("Resolution results:")
self.line("")
if self.option("tree"):
show_command = self.get_application().find("show")
show_command.output = self.output
show_command.init_styles()
packages = [op.package for op in ops]
repo = Repository(packages)
requires = package.requires + package.dev_requires
for pkg in repo.packages:
for require in requires:
if pkg.name == require.name:
show_command.display_package_tree(pkg, repo)
break
return 0
for op in ops:
package = op.package
self.line(
......@@ -83,23 +91,37 @@ class DebugResolveCommand(Command):
self.line(" - {}: {}".format(req_name, req_value))
def _determine_requirements(self, requires): # type: (List[str]) -> List[str]
from poetry.semver import parse_constraint
if not requires:
return []
requires = self._parse_name_version_pairs(requires)
result = []
for requirement in requires:
if "version" not in requirement:
requirement["version"] = "*"
if "version" in requirement:
parse_constraint(requirement["version"])
result.append("{} {}".format(requirement["name"], requirement["version"]))
return result
return requires
def _parse_name_version_pairs(self, pairs): # type: (list) -> list
result = []
for i in range(len(pairs)):
if pairs[i].startswith("git+https://"):
url = pairs[i].lstrip("git+")
rev = None
if "@" in url:
url, rev = url.split("@")
pair = {"name": url.split("/")[-1].rstrip(".git"), "git": url}
if rev:
pair["rev"] = rev
result.append(pair)
continue
pair = re.sub("^([^=: ]+)[=: ](.*)$", "\\1 \\2", pairs[i].strip())
pair = pair.strip()
......@@ -107,14 +129,16 @@ class DebugResolveCommand(Command):
name, version = pair.split(" ", 2)
result.append({"name": name, "version": version})
else:
result.append({"name": pair})
result.append({"name": pair, "version": "*"})
return result
def _format_requirements(self, requirements): # type: (List[str]) -> dict
requires = {}
requirements = self._parse_name_version_pairs(requirements)
requirements = self._determine_requirements(requirements)
for requirement in requirements:
requires[requirement["name"]] = requirement["version"]
name = requirement.pop("name")
requires[name] = requirement
return requires
......@@ -193,7 +193,11 @@ lists all packages available."""
def display_package_tree(self, package, installed_repo):
self.write("<info>{}</info>".format(package.pretty_name))
self.line(" {} {}".format(package.pretty_version, package.description))
description = ""
if package.description:
description = " " + package.description
self.line(" {}{}".format(package.pretty_version, description))
dependencies = package.requires
dependencies = sorted(dependencies, key=lambda x: x.name)
......
import sys
from cleo.testers import CommandTester
from tests.helpers import get_dependency
from tests.helpers import get_package
def test_debug_resolve_gives_resolution_results(app, repo):
command = app.find("debug:resolve")
tester = CommandTester(command)
cachy2 = get_package("cachy", "0.2.0")
cachy2.add_dependency("msgpack-python", ">=0.5 <0.6")
repo.add_package(get_package("cachy", "0.1.0"))
repo.add_package(cachy2)
repo.add_package(get_package("msgpack-python", "0.5.3"))
tester.execute([("command", command.get_name()), ("package", ["cachy"])])
expected = """\
Resolving dependencies...
Resolution results:
- msgpack-python (0.5.3)
- cachy (0.2.0)
"""
assert tester.get_display(True) == expected
def test_debug_resolve_tree_option_gives_the_dependency_tree(app, repo):
command = app.find("debug:resolve")
tester = CommandTester(command)
cachy2 = get_package("cachy", "0.2.0")
cachy2.add_dependency("msgpack-python", ">=0.5 <0.6")
repo.add_package(get_package("cachy", "0.1.0"))
repo.add_package(cachy2)
repo.add_package(get_package("msgpack-python", "0.5.3"))
tester.execute(
[("command", command.get_name()), ("package", ["cachy"]), ("--tree", True)]
)
expected = """\
Resolving dependencies...
Resolution results:
cachy 0.2.0
`-- msgpack-python >=0.5 <0.6
"""
assert tester.get_display(True) == expected
def test_debug_resolve_git_dependency(app, repo):
repo.add_package(get_package("pendulum", "2.0.3"))
command = app.find("debug:resolve")
tester = CommandTester(command)
tester.execute(
[
("command", command.get_name()),
("package", ["git+https://github.com/demo/demo.git"]),
]
)
expected = """\
Resolving dependencies...
Resolution results:
- pendulum (2.0.3)
- demo (0.1.2)
"""
assert tester.get_display(True) == expected
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment