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

feat: Add a new option --exclude #31

Merged
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
21 changes: 20 additions & 1 deletion src/poetry_plugin_up/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class UpCommand(InstallerCommand):
"Include pinned (exact) dependencies when updating to latest."
),
),
option(
long_name="exclude",
short_name=None,
description="Exclude dependencies.",
multiple=True,
flag=False,
),
option(
long_name="no-install",
short_name=None,
Expand All @@ -60,6 +67,7 @@ def handle(self) -> int:
pinned = self.option("pinned")
no_install = self.option("no-install")
dry_run = self.option("dry-run")
exclude = self.option("exclude")

if pinned and not latest:
self.line_error("'--pinned' specified without '--latest'")
Expand All @@ -78,6 +86,7 @@ def handle(self) -> int:
only_packages=only_packages,
pyproject_content=pyproject_content,
selector=selector,
exclude=exclude,
)

if dry_run:
Expand Down Expand Up @@ -115,10 +124,17 @@ def handle_dependency(
only_packages: List[str],
pyproject_content: TOMLDocument,
selector: VersionSelector,
exclude: List[str],
) -> None:
"""Handles a dependency"""

if not self.is_bumpable(dependency, only_packages, latest, pinned):
if not self.is_bumpable(
dependency,
only_packages,
latest,
pinned,
exclude,
):
return

target_package_version = dependency.pretty_constraint
Expand Down Expand Up @@ -163,6 +179,7 @@ def is_bumpable(
only_packages: List[str],
latest: bool,
pinned: bool,
exclude: List[str],
) -> bool:
"""Determines if a dependency can be bumped in pyproject.toml"""

Expand All @@ -172,6 +189,8 @@ def is_bumpable(
return False
if only_packages and dependency.name not in only_packages:
return False
if dependency.name in exclude:
return False

constraint = dependency.pretty_constraint
if not latest:
Expand Down
31 changes: 31 additions & 0 deletions tests/e2e/test_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,34 @@ def test_command_reverts_pyproject_on_error(

def test_pinned_without_latest_fails(app_tester: ApplicationTester) -> None:
assert app_tester.execute("up --pinned") == 1


def test_command_with_exclude(
app_tester: ApplicationTester,
packages: List[Package],
mocker: MockerFixture,
project_path: Path,
tmp_pyproject_path: Path,
) -> None:
command_call = mocker.patch(
"poetry.console.commands.command.Command.call",
return_value=0,
)
mocker.patch(
"poetry.version.version_selector.VersionSelector.find_best_candidate",
side_effect=packages,
)
mocker.patch(
"poetry.console.commands.installer_command.InstallerCommand.reset_poetry", # noqa: E501
return_value=None,
)

path = project_path / "expected_pyproject_with_exclude.toml"
expected = PyProjectTOML(path).file.read()

assert (
app_tester.execute("up --exclude foo --exclude bar --exclude=grault")
== 0
)
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
command_call.assert_called_once_with(name="update")
30 changes: 30 additions & 0 deletions tests/fixtures/simple_project/expected_pyproject_with_exclude.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[tool.poetry]
name = "simple-project"
version = "1.2.3"
description = "Some description."
authors = ["Mousa Zeid Baker"]
license = "MIT"

[tool.poetry.dependencies]
python = "^3.7"
foo = "^1.1.1"
bar = "^1.1.1"
baz = {version = "^2.2.2", extras = ["qux", "quux"]}
corge = {version = "^2.2.2", optional = true}
grault = {version = "^1.1.1", allow-prereleases = true}
garply = {path = "./"}
waldo = {git = "https://example.com/test/project.git"}

[tool.poetry.group.dev.dependencies]
fred = "1.1.1"
plugh = "^2.2.2"
xyzzy = "~2.2.2"
nacho = "<1.1.1"
thud = ">1.1.1"

[tool.poetry.group.docs.dependencies]
foobar = "<=1.1.1"
foobaz = ">=2.2.2"
fooqux = "!=1.1.1"
fooquux = "*"
Foo_Corge = "^2.2.2"
41 changes: 41 additions & 0 deletions tests/integration/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def test_handle_dependency(
latest=False,
pinned=False,
only_packages=[],
exclude=[],
pyproject_content=content,
selector=selector,
)
Expand Down Expand Up @@ -83,6 +84,7 @@ def test_handle_dependency_with_latest(
latest=True,
pinned=True,
only_packages=[],
exclude=[],
pyproject_content=content,
selector=selector,
)
Expand Down Expand Up @@ -129,6 +131,7 @@ def test_handle_dependency_with_zero_caret(
latest=True,
pinned=False,
only_packages=[],
exclude=[],
pyproject_content=content,
selector=selector,
)
Expand All @@ -140,3 +143,41 @@ def test_handle_dependency_with_zero_caret(
source=dependency.source_name,
)
bump_version_in_pyproject_content.assert_not_called()


def test_handle_dependency_excluded(
up_cmd_tester: TestUpCommand,
mocker: MockerFixture,
) -> None:
dependency = Dependency(
name="foo",
constraint="^1.0",
groups=["main"],
)
new_version = "2.0.0"
package = Package(
name=dependency.name,
version=new_version,
)

content = parse("")

selector = Mock()
selector.find_best_candidate = Mock(return_value=package)
bump_version_in_pyproject_content = mocker.patch(
"poetry_plugin_up.command.UpCommand.bump_version_in_pyproject_content",
return_value=None,
)

up_cmd_tester.handle_dependency(
dependency=dependency,
latest=False,
pinned=False,
only_packages=[],
exclude=["foo"],
pyproject_content=content,
selector=selector,
)

selector.find_best_candidate.assert_not_called()
bump_version_in_pyproject_content.assert_not_called()
40 changes: 40 additions & 0 deletions tests/unit/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def test_is_bumpable_is_false_when_source_type_is_git(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -133,6 +134,7 @@ def test_is_bumpable_is_false_when_source_type_is_file(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -150,6 +152,7 @@ def test_is_bumpable_is_false_when_source_type_is_directory(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -163,6 +166,7 @@ def test_is_bumpable_is_false_when_name_is_python(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -176,6 +180,7 @@ def test_is_bumpable_is_false_when_dependency_not_in_only_packages(
only_packages=["bar"],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -192,6 +197,7 @@ def test_is_bumpable_is_false_when_version_pinned(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -208,6 +214,7 @@ def test_is_bumpable_is_false_when_version_wildcard(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -224,6 +231,7 @@ def test_is_bumpable_is_false_when_version_less_than(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -240,6 +248,7 @@ def test_is_bumpable_is_false_when_version_greater_than(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -256,6 +265,7 @@ def test_is_bumpable_is_false_when_version_less_than_or_equal(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -272,6 +282,7 @@ def test_is_bumpable_is_false_when_version_inequality(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -288,6 +299,7 @@ def test_is_bumpable_is_false_when_version_multiple_requirements(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -304,6 +316,7 @@ def test_is_bumpable_is_true_when_version_caret(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -320,6 +333,7 @@ def test_is_bumpable_is_true_when_version_tilde(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -336,6 +350,7 @@ def test_is_bumpable_is_true_when_version_greater_than_or_equal(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -352,6 +367,7 @@ def test_is_bumpable_is_true_when_version_tilde_pep440(
only_packages=[],
latest=False,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -368,6 +384,7 @@ def test_is_bumpable_is_false_when_version_pinned_and_latest(
only_packages=[],
latest=True,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -384,6 +401,7 @@ def test_is_bumpable_is_true_when_version_pinned_and_latest_and_pinned(
only_packages=[],
latest=True,
pinned=True,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -408,6 +426,7 @@ def test_is_bumpable_is_false_when_version_pinned_with_with_equals_and_latest(
only_packages=[],
latest=True,
pinned=False,
exclude=[],
)
assert is_bumpable is False

Expand All @@ -424,6 +443,7 @@ def test_is_bumpable_is_true_when_version_wildcard_and_latest(
only_packages=[],
latest=True,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -440,6 +460,7 @@ def test_is_bumpable_is_true_when_version_less_than_and_latest(
only_packages=[],
latest=True,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -456,6 +477,7 @@ def test_is_bumpable_is_true_when_version_greater_than_and_latest(
only_packages=[],
latest=True,
pinned=False,
exclude=[],
)
assert is_bumpable is True

Expand All @@ -472,5 +494,23 @@ def test_is_bumpable_is_true_when_version_less_than_or_equal_and_latest(
only_packages=[],
latest=True,
pinned=False,
exclude=[],
)
assert is_bumpable is True


def test_is_bumpable_is_false_when_dependency_excluded(
up_cmd_tester: TestUpCommand,
) -> None:
dependency = Dependency(
name="foo",
constraint="<=1.2.3",
)
is_bumpable = up_cmd_tester.is_bumpable(
dependency=dependency,
only_packages=[],
latest=True,
pinned=False,
exclude=["foo"],
)
assert is_bumpable is False