Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not raise error if package is already in pyproject.toml on poetry add #2886

Merged
merged 3 commits into from
Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 41 additions & 11 deletions poetry/console/commands/add.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# -*- coding: utf-8 -*-
from typing import Dict
from typing import List

from cleo import argument
from cleo import option

Expand Down Expand Up @@ -86,18 +90,19 @@ def handle(self):
if section not in poetry_content:
poetry_content[section] = {}

for name in packages:
for key in poetry_content[section]:
if key.lower() == name.lower():
pair = self._parse_requirements([name])[0]
if (
"git" in pair
or "url" in pair
or pair.get("version") == "latest"
):
continue
existing_packages = self.get_existing_packages_from_input(
packages, poetry_content, section
)

raise ValueError("Package {} is already present".format(name))
if existing_packages:
abn marked this conversation as resolved.
Show resolved Hide resolved
self.notify_about_existing_packages(existing_packages)

packages = [name for name in packages if name not in existing_packages]
abn marked this conversation as resolved.
Show resolved Hide resolved

if not packages:
self.poetry.file.write(content)
self.line("Nothing to add.")
return 0

requirements = self._determine_requirements(
packages,
Expand Down Expand Up @@ -184,3 +189,28 @@ def handle(self):
self.poetry.file.write(original_content)

return status

def get_existing_packages_from_input(
self, packages, poetry_content, target_section
): # type: (List[str], Dict, str) -> List[str]
existing_packages = []

for name in packages:
for key in poetry_content[target_section]:
if key.lower() == name.lower():
existing_packages.append(name)

return existing_packages

def notify_about_existing_packages(
self, existing_packages
): # type: (List[str]) -> None
self.line(
"The following packages are already present in the pyproject.toml and will be skipped:\n"
)
for name in existing_packages:
self.line(" • <c1>{name}</c1>".format(name=name))
self.line(
"\nIf you want to update it to the latest compatible version, you can use `poetry update package`.\n"
"If you prefer to upgrade it to the latest available version, you can use `poetry add package@latest`.\n"
)
31 changes: 23 additions & 8 deletions tests/console/commands/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,19 +714,26 @@ def test_add_should_not_select_prereleases(app, repo, tester):
assert content["dependencies"]["pyyaml"] == "^3.13"


def test_add_should_display_an_error_when_adding_existing_package_with_no_constraint(
def test_add_should_skip_when_adding_existing_package_with_no_constraint(
app, repo, tester
):
content = app.poetry.file.read()
content["tool"]["poetry"]["dependencies"]["foo"] = "^1.0"
app.poetry.file.write(content)

repo.add_package(get_package("foo", "1.1.2"))
tester.execute("foo")

with pytest.raises(ValueError) as e:
tester.execute("foo")
expected = """\
The following packages are already present in the pyproject.toml and will be skipped:

• foo

assert "Package foo is already present" == str(e.value)
If you want to update it to the latest compatible version, you can use `poetry update package`.
If you prefer to upgrade it to the latest available version, you can use `poetry add package@latest`.
"""

assert expected in tester.io.fetch_output()


def test_add_should_work_when_adding_existing_package_with_latest_constraint(
Expand Down Expand Up @@ -1527,7 +1534,7 @@ def test_add_should_not_select_prereleases_old_installer(
assert content["dependencies"]["pyyaml"] == "^3.13"


def test_add_should_display_an_error_when_adding_existing_package_with_no_constraint_old_installer(
def test_add_should_skip_when_adding_existing_package_with_no_constraint_old_installer(
app, repo, installer, old_tester
):
content = app.poetry.file.read()
Expand All @@ -1536,10 +1543,18 @@ def test_add_should_display_an_error_when_adding_existing_package_with_no_constr

repo.add_package(get_package("foo", "1.1.2"))

with pytest.raises(ValueError) as e:
old_tester.execute("foo")
old_tester.execute("foo")

expected = """\
The following packages are already present in the pyproject.toml and will be skipped:

• foo

assert "Package foo is already present" == str(e.value)
If you want to update it to the latest compatible version, you can use `poetry update package`.
If you prefer to upgrade it to the latest available version, you can use `poetry add package@latest`.
"""

assert expected in old_tester.io.fetch_output()


def test_add_should_work_when_adding_existing_package_with_latest_constraint_old_installer(
Expand Down