Skip to content

Commit

Permalink
feat: Add new option --exclude
Browse files Browse the repository at this point in the history
  • Loading branch information
mzakharovcy committed Oct 9, 2023
1 parent 7f39918 commit c6bd601
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 1 deletion.
17 changes: 16 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="The dependency names to exclude.",
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_names = 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_names=exclude_names,
)

if dry_run:
Expand Down Expand Up @@ -115,10 +124,13 @@ def handle_dependency(
only_packages: List[str],
pyproject_content: TOMLDocument,
selector: VersionSelector,
exclude_names: List[str] = None,
) -> 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_names
):
return

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

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

constraint = dependency.pretty_constraint
if not latest:
Expand Down
33 changes: 33 additions & 0 deletions tests/e2e/test_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,36 @@ 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_excluded_names(
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_excluded_name.toml"
expected = PyProjectTOML(path).file.read()

assert (
app_tester.execute(
"up --exclude-name foo --exclude-name bar --exclude-name=grault"
)
== 0
)
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
command_call.assert_called_once_with(name="update")
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"
38 changes: 38 additions & 0 deletions tests/integration/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,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=[],
pyproject_content=content,
selector=selector,
exclude_names=["foo"],
)

selector.find_best_candidate.assert_not_called()
bump_version_in_pyproject_content.assert_not_called()
17 changes: 17 additions & 0 deletions tests/unit/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,3 +474,20 @@ def test_is_bumpable_is_true_when_version_less_than_or_equal_and_latest(
pinned=False,
)
assert is_bumpable is True


def test_is_bumpable_is_false_when_dependency_in_excluded_names(
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_names=["foo"],
)
assert is_bumpable is False

0 comments on commit c6bd601

Please sign in to comment.