From 86c4db7ec105bc10779dd7ed635000b70a54f0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Eustace?= Date: Fri, 12 Jul 2019 17:52:44 +0200 Subject: [PATCH] Add the ability to add complete dependencies in one go --- poetry/console/commands/init.py | 44 +++++++++++- tests/console/commands/test_add.py | 106 ++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 6 deletions(-) diff --git a/poetry/console/commands/init.py b/poetry/console/commands/init.py index 52e1d2568f3..189caf35bf1 100644 --- a/poetry/console/commands/init.py +++ b/poetry/console/commands/init.py @@ -336,6 +336,13 @@ def _parse_requirements( 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("[") + if requirement.startswith(("git+https://", "git+ssh://")): url = requirement.lstrip("git+") rev = None @@ -348,6 +355,9 @@ def _parse_requirements( if rev: pair["rev"] = rev + if extras: + pair["extras"] = extras + package = Provider.get_package_from_vcs( "git", url, reference=pair.get("rev") ) @@ -368,19 +378,47 @@ def _parse_requirements( ("name", package.name), ("path", path.relative_to(cwd).as_posix()), ] + + ([("extras", extras)] if extras else []) ) ) continue - pair = re.sub("^([^=: ]+)[@=: ](.*)$", "\\1 \\2", requirement.strip()) + pair = re.sub( + "^([^@=: ]+)(?:@|==|(?~!])=|:| )(.*)$", "\\1 \\2", requirement + ) pair = pair.strip() + require = OrderedDict() if " " in pair: name, version = pair.split(" ", 2) - result.append({"name": name, "version": version}) + require["name"] = name + require["version"] = version else: - result.append({"name": pair}) + m = re.match( + "^([^><=!: ]+)((?:>=|<=|>|<|!=|~=|~|\^).*)$", 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 diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index 58526da6509..0ed94470446 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -42,14 +42,14 @@ def test_add_no_constraint(app, repo, installer): assert content["dependencies"]["cachy"] == "^0.2.0" -def test_add_constraint(app, repo, installer): +def test_add_equal_constraint(app, repo, installer): command = app.find("add") tester = CommandTester(command) repo.add_package(get_package("cachy", "0.1.0")) repo.add_package(get_package("cachy", "0.2.0")) - tester.execute("cachy=0.1.0") + tester.execute("cachy==0.1.0") expected = """\ @@ -69,6 +69,67 @@ def test_add_constraint(app, repo, installer): assert len(installer.installs) == 1 +def test_add_greater_constraint(app, repo, installer): + command = app.find("add") + tester = CommandTester(command) + + repo.add_package(get_package("cachy", "0.1.0")) + repo.add_package(get_package("cachy", "0.2.0")) + + tester.execute("cachy>=0.1.0") + + expected = """\ + +Updating dependencies +Resolving dependencies... + +Writing lock file + + +Package operations: 1 install, 0 updates, 0 removals + + - Installing cachy (0.2.0) +""" + + assert expected == tester.io.fetch_output() + + assert len(installer.installs) == 1 + + +def test_add_constraint_with_extras(app, repo, installer): + command = app.find("add") + tester = CommandTester(command) + + cachy1 = get_package("cachy", "0.1.0") + cachy1.extras = {"msgpack": [get_dependency("msgpack-python")]} + msgpack_dep = get_dependency("msgpack-python", ">=0.5 <0.6", optional=True) + cachy1.requires = [msgpack_dep] + + repo.add_package(get_package("cachy", "0.2.0")) + repo.add_package(cachy1) + repo.add_package(get_package("msgpack-python", "0.5.3")) + + tester.execute("cachy[msgpack]^0.1.0") + + expected = """\ + +Updating dependencies +Resolving dependencies... + +Writing lock file + + +Package operations: 2 installs, 0 updates, 0 removals + + - Installing msgpack-python (0.5.3) + - Installing cachy (0.1.0) +""" + + assert expected == tester.io.fetch_output() + + assert len(installer.installs) == 2 + + def test_add_constraint_dependencies(app, repo, installer): command = app.find("add") tester = CommandTester(command) @@ -164,6 +225,45 @@ def test_add_git_constraint_with_poetry(app, repo, installer): assert len(installer.installs) == 2 +def test_add_git_constraint_with_extras(app, repo, installer): + command = app.find("add") + tester = CommandTester(command) + + repo.add_package(get_package("pendulum", "1.4.4")) + repo.add_package(get_package("cleo", "0.6.5")) + repo.add_package(get_package("tomlkit", "0.5.5")) + + tester.execute("git+https://github.com/demo/demo.git[foo,bar]") + + expected = """\ + +Updating dependencies +Resolving dependencies... + +Writing lock file + + +Package operations: 4 installs, 0 updates, 0 removals + + - Installing cleo (0.6.5) + - Installing pendulum (1.4.4) + - Installing tomlkit (0.5.5) + - Installing demo (0.1.2 9cf87a2) +""" + + assert expected == tester.io.fetch_output() + + assert len(installer.installs) == 4 + + content = app.poetry.file.read()["tool"]["poetry"] + + assert "demo" in content["dependencies"] + assert content["dependencies"]["demo"] == { + "git": "https://github.com/demo/demo.git", + "extras": ["foo", "bar"], + } + + def test_add_directory_constraint(app, repo, installer, mocker): p = mocker.patch("poetry.utils._compat.Path.cwd") p.return_value = Path(__file__) / ".." @@ -304,7 +404,7 @@ def test_add_file_constraint_sdist(app, repo, installer, mocker): } -def test_add_constraint_with_extras(app, repo, installer): +def test_add_constraint_with_extras_option(app, repo, installer): command = app.find("add") tester = CommandTester(command)