Skip to content

Commit 2217deb

Browse files
author
MousaZeidBaker
authored
Merge pull request #35 from MikeZaharov/feat/wildcard
feat: add --preserve-wildcard
2 parents 77b6ff4 + ca9fcdf commit 2217deb

File tree

5 files changed

+172
-0
lines changed

5 files changed

+172
-0
lines changed

src/poetry_plugin_up/command.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ class UpCommand(InstallerCommand):
5959
description="Output bumped <comment>pyproject.toml</> but do not "
6060
"execute anything.",
6161
),
62+
option(
63+
long_name="preserve-wildcard",
64+
short_name=None,
65+
description="Do not bump wildcard dependencies "
66+
"when updating to latest.",
67+
),
6268
]
6369

6470
def handle(self) -> int:
@@ -68,11 +74,18 @@ def handle(self) -> int:
6874
no_install = self.option("no-install")
6975
dry_run = self.option("dry-run")
7076
exclude = self.option("exclude")
77+
preserve_wildcard = self.option("preserve-wildcard")
7178

7279
if pinned and not latest:
7380
self.line_error("'--pinned' specified without '--latest'")
7481
raise Exception
7582

83+
if preserve_wildcard and not latest:
84+
self.line_error(
85+
"'--preserve-wildcard' specified without '--latest'"
86+
)
87+
raise Exception
88+
7689
selector = VersionSelector(self.poetry.pool)
7790
pyproject_content = self.poetry.file.read()
7891
original_pyproject_content = self.poetry.file.read()
@@ -87,6 +100,7 @@ def handle(self) -> int:
87100
pyproject_content=pyproject_content,
88101
selector=selector,
89102
exclude=exclude,
103+
preserve_wildcard=preserve_wildcard,
90104
)
91105

92106
if dry_run:
@@ -125,6 +139,7 @@ def handle_dependency(
125139
pyproject_content: TOMLDocument,
126140
selector: VersionSelector,
127141
exclude: List[str],
142+
preserve_wildcard: bool,
128143
) -> None:
129144
"""Handles a dependency"""
130145

@@ -134,6 +149,7 @@ def handle_dependency(
134149
latest,
135150
pinned,
136151
exclude,
152+
preserve_wildcard,
137153
):
138154
return
139155

@@ -180,6 +196,7 @@ def is_bumpable(
180196
latest: bool,
181197
pinned: bool,
182198
exclude: List[str],
199+
preserve_wildcard: bool,
183200
) -> bool:
184201
"""Determines if a dependency can be bumped in pyproject.toml"""
185202

@@ -193,6 +210,9 @@ def is_bumpable(
193210
return False
194211

195212
constraint = dependency.pretty_constraint
213+
if preserve_wildcard and constraint == "*":
214+
return False
215+
196216
if not latest:
197217
if is_pinned(constraint):
198218
# pinned

tests/e2e/test_e2e.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,40 @@ def test_command_with_exclude(
177177
)
178178
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
179179
command_call.assert_called_once_with(name="update")
180+
181+
182+
def test_command_preserve_wildcard(
183+
app_tester: ApplicationTester,
184+
packages: List[Package],
185+
mocker: MockerFixture,
186+
project_path: Path,
187+
tmp_pyproject_path: Path,
188+
) -> None:
189+
command_call = mocker.patch(
190+
"poetry.console.commands.command.Command.call",
191+
return_value=0,
192+
)
193+
mocker.patch(
194+
"poetry.version.version_selector.VersionSelector.find_best_candidate",
195+
side_effect=packages,
196+
)
197+
mocker.patch(
198+
"poetry.console.commands.installer_command.InstallerCommand.reset_poetry", # noqa: E501
199+
return_value=None,
200+
)
201+
202+
path = (
203+
project_path
204+
/ "expected_pyproject_with_latest_and_preserve_wildcard.toml"
205+
)
206+
expected = PyProjectTOML(path).file.read()
207+
208+
assert app_tester.execute("up --latest --preserve-wildcard") == 0
209+
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
210+
command_call.assert_called_once_with(name="update")
211+
212+
213+
def test_preserve_wildcard_without_latest_fails(
214+
app_tester: ApplicationTester,
215+
) -> None:
216+
assert app_tester.execute("up --preserve-wildcard") == 1
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[tool.poetry]
2+
name = "simple-project"
3+
version = "1.2.3"
4+
description = "Some description."
5+
authors = ["Mousa Zeid Baker"]
6+
license = "MIT"
7+
8+
[tool.poetry.dependencies]
9+
python = "^3.7"
10+
foo = "^2.2.2"
11+
bar = "^2.2.2"
12+
baz = {version = "^2.2.2", extras = ["qux", "quux"]}
13+
corge = {version = "^2.2.2", optional = true}
14+
grault = {version = "^2.2.2", allow-prereleases = true}
15+
garply = {path = "./"}
16+
waldo = {git = "https://example.com/test/project.git"}
17+
18+
[tool.poetry.group.dev.dependencies]
19+
fred = "1.1.1"
20+
plugh = "^2.2.2"
21+
xyzzy = "~2.2.2"
22+
nacho = "^2.2.2"
23+
thud = "^2.2.2"
24+
25+
[tool.poetry.group.docs.dependencies]
26+
foobar = "^2.2.2"
27+
foobaz = "^2.2.2"
28+
fooqux = "^2.2.2"
29+
fooquux = "*"
30+
Foo_Corge = "^2.2.2"

tests/integration/test_integration.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def test_handle_dependency(
4040
exclude=[],
4141
pyproject_content=content,
4242
selector=selector,
43+
preserve_wildcard=False,
4344
)
4445

4546
selector.find_best_candidate.assert_called_once_with(
@@ -87,6 +88,7 @@ def test_handle_dependency_with_latest(
8788
exclude=[],
8889
pyproject_content=content,
8990
selector=selector,
91+
preserve_wildcard=False,
9092
)
9193

9294
selector.find_best_candidate.assert_called_once_with(
@@ -134,6 +136,7 @@ def test_handle_dependency_with_zero_caret(
134136
exclude=[],
135137
pyproject_content=content,
136138
selector=selector,
139+
preserve_wildcard=False,
137140
)
138141

139142
selector.find_best_candidate.assert_called_once_with(
@@ -177,6 +180,46 @@ def test_handle_dependency_excluded(
177180
exclude=["foo"],
178181
pyproject_content=content,
179182
selector=selector,
183+
preserve_wildcard=False,
184+
)
185+
186+
selector.find_best_candidate.assert_not_called()
187+
bump_version_in_pyproject_content.assert_not_called()
188+
189+
190+
def test_handle_dependency_preserve_wildcard(
191+
up_cmd_tester: TestUpCommand,
192+
mocker: MockerFixture,
193+
) -> None:
194+
dependency = Dependency(
195+
name="foo",
196+
constraint="*",
197+
groups=["main"],
198+
)
199+
new_version = "2.0.0"
200+
package = Package(
201+
name=dependency.name,
202+
version=new_version,
203+
)
204+
205+
content = parse("")
206+
207+
selector = Mock()
208+
selector.find_best_candidate = Mock(return_value=package)
209+
bump_version_in_pyproject_content = mocker.patch(
210+
"poetry_plugin_up.command.UpCommand.bump_version_in_pyproject_content",
211+
return_value=None,
212+
)
213+
214+
up_cmd_tester.handle_dependency(
215+
dependency=dependency,
216+
latest=True,
217+
pinned=False,
218+
only_packages=[],
219+
exclude=[],
220+
pyproject_content=content,
221+
selector=selector,
222+
preserve_wildcard=True,
180223
)
181224

182225
selector.find_best_candidate.assert_not_called()

0 commit comments

Comments
 (0)