Skip to content

Commit

Permalink
Add the ability to add complete dependencies in one go
Browse files Browse the repository at this point in the history
  • Loading branch information
sdispater committed Jul 13, 2019
1 parent abfc3f3 commit 154cdd1
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 8 deletions.
50 changes: 45 additions & 5 deletions poetry/console/commands/init.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import os
import re

from typing import Dict
Expand All @@ -10,7 +11,6 @@

from cleo import option
from tomlkit import inline_table
from tomlkit import table

from poetry.utils._compat import Path
from poetry.utils._compat import OrderedDict
Expand Down Expand Up @@ -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
Expand All @@ -348,14 +355,19 @@ 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")
)
pair["name"] = package.name
result.append(pair)

continue
elif cwd.joinpath(requirement).exists():
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())
Expand All @@ -368,19 +380,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

Expand Down
106 changes: 103 additions & 3 deletions tests/console/commands/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = """\
Expand All @@ -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)
Expand Down Expand Up @@ -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__) / ".."
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 154cdd1

Please sign in to comment.