Skip to content

Commit 3a05279

Browse files
committed
feat: add confirmation step
1 parent 7e6db62 commit 3a05279

File tree

4 files changed

+76
-27
lines changed

4 files changed

+76
-27
lines changed

src/poetry/config/config_source.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,46 @@ class ConfigSourceMigration:
3939
new_key: str | None
4040
value_migration: dict[Any, Any] = dataclasses.field(default_factory=dict)
4141

42-
def apply(self, config_source: ConfigSource, io: IO | None = None) -> None:
42+
def dry_run(self, config_source: ConfigSource, io: IO | None = None) -> bool:
4343
io = io or NullIO()
4444

4545
try:
4646
old_value = config_source.get_property(self.old_key)
4747
except PropertyNotFoundError:
48-
return
48+
return False
4949

5050
new_value = (
5151
self.value_migration[old_value] if self.value_migration else old_value
5252
)
5353

54-
config_source.remove_property(self.old_key)
55-
5654
msg = f"<c1>{self.old_key}</c1> = <c2>{json.dumps(old_value)}</c2>"
5755

5856
if self.new_key is not None and new_value is not UNSET:
5957
msg += f" -> <c1>{self.new_key}</c1> = <c2>{json.dumps(new_value)}</c2>"
60-
config_source.add_property(self.new_key, new_value)
6158
elif self.new_key is None:
6259
msg += " -> <c1>Removed from config</c1>"
6360
elif self.new_key and new_value is UNSET:
6461
msg += f" -> <c1>{self.new_key}</c1> = <c2>Not explicit set</c2>"
6562

6663
io.write_line(msg)
6764

65+
return True
66+
67+
def apply(self, config_source: ConfigSource) -> None:
68+
try:
69+
old_value = config_source.get_property(self.old_key)
70+
except PropertyNotFoundError:
71+
return
72+
73+
new_value = (
74+
self.value_migration[old_value] if self.value_migration else old_value
75+
)
76+
77+
config_source.remove_property(self.old_key)
78+
79+
if self.new_key is not None and new_value is not UNSET:
80+
config_source.add_property(self.new_key, new_value)
81+
6882

6983
def drop_empty_config_category(
7084
keys: list[str], config: dict[Any, Any]

src/poetry/console/commands/config.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,22 @@ def _migrate(self) -> None:
356356

357357
config_source = FileConfigSource(config_file)
358358

359-
self.io.write_line("Starting config migration ...")
359+
self.io.write_line("Checking for required migrations ...")
360360

361-
for migration in CONFIG_MIGRATIONS:
362-
migration.apply(config_source, io=self.io)
361+
required_migrations = [
362+
migration
363+
for migration in CONFIG_MIGRATIONS
364+
if migration.dry_run(config_source, io=self.io)
365+
]
363366

364-
self.io.write_line("Config migration successfully done.")
367+
if not required_migrations:
368+
self.io.write_line("Already up to date.")
369+
return
370+
371+
if not self.io.is_interactive() or self.confirm(
372+
"Proceed with migration?: ", False
373+
):
374+
for migration in required_migrations:
375+
migration.apply(config_source)
376+
377+
self.io.write_line("Config migration successfully done.")

src/poetry/console/commands/init.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def _init_pyproject(
104104
if pyproject.file.exists():
105105
if pyproject.is_poetry_project():
106106
self.line_error(
107-
"<error>A pyproject.toml file with a project and/or"
107+
"<error>Ayproject.toml file with a project and/or"
108108
" a poetry section already exists.</error>"
109109
)
110110
return 1

tests/console/commands/test_config.py

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -563,32 +563,54 @@ def test_config_solver_lazy_wheel(
563563
assert not repo._lazy_wheel
564564

565565

566+
current_config = """\
567+
[experimental]
568+
system-git-client = true
569+
570+
[virtualenvs]
571+
prefer-active-python = false
572+
"""
573+
574+
config_migrated = """\
575+
system-git-client = true
576+
577+
[virtualenvs]
578+
use-poetry-python = true
579+
"""
580+
581+
582+
@pytest.mark.parametrize(
583+
["proceed", "expected_config"],
584+
[
585+
("yes", config_migrated),
586+
("no", current_config),
587+
],
588+
)
566589
def test_config_migrate(
567-
tester: CommandTester, mocker: MockerFixture, tmp_path: Path
590+
proceed: str,
591+
expected_config: str,
592+
tester: CommandTester,
593+
mocker: MockerFixture,
594+
tmp_path: Path,
568595
) -> None:
569596
config_dir = tmp_path / "config"
570597
mocker.patch("poetry.locations.CONFIG_DIR", config_dir)
571598

572599
config_file = Path(config_dir / "config.toml")
573-
config_data = textwrap.dedent("""\
574-
[experimental]
575-
system-git-client = true
576-
577-
[virtualenvs]
578-
prefer-active-python = false
579-
""")
580600
with config_file.open("w") as fh:
581-
fh.write(config_data)
582-
583-
tester.execute("--migrate")
601+
fh.write(current_config)
584602

585-
expected_config = textwrap.dedent("""\
586-
system-git-client = true
603+
tester.execute("--migrate", inputs=proceed)
587604

588-
[virtualenvs]
589-
use-poetry-python = true
605+
expected_output = textwrap.dedent("""\
606+
Checking for required migrations ...
607+
experimental.system-git-client = true -> system-git-client = true
608+
virtualenvs.prefer-active-python = false -> virtualenvs.use-poetry-python = true
590609
""")
591610

611+
output = tester.io.fetch_output()
612+
assert output.startswith(expected_output)
613+
592614
with config_file.open("r") as fh:
593615
assert fh.read() == expected_config
594616

@@ -606,7 +628,7 @@ def test_config_migrate_local_config(tester: CommandTester, poetry: Poetry) -> N
606628
with local_config.open("w") as fh:
607629
fh.write(config_data)
608630

609-
tester.execute("--migrate --local")
631+
tester.execute("--migrate --local", inputs="yes")
610632

611633
expected_config = textwrap.dedent("""\
612634
system-git-client = true
@@ -623,4 +645,4 @@ def test_config_migrate_local_config_should_raise_if_not_found(
623645
tester: CommandTester,
624646
) -> None:
625647
with pytest.raises(RuntimeError, match="No local config file found"):
626-
tester.execute("--migrate --local")
648+
tester.execute("--migrate --local", inputs="yes")

0 commit comments

Comments
 (0)