diff --git a/poetry/console/commands/add.py b/poetry/console/commands/add.py index 3ad77ad686b..29cf07d2a26 100644 --- a/poetry/console/commands/add.py +++ b/poetry/console/commands/add.py @@ -100,7 +100,6 @@ def handle(self): packages = [name for name in packages if name not in existing_packages] if not packages: - self.poetry.file.write(content) self.line("Nothing to add.") return 0 @@ -152,29 +151,29 @@ def handle(self): poetry_content[section][_constraint["name"]] = constraint - # Write new content - self.poetry.file.write(content) + try: + # Write new content + self.poetry.file.write(content) - # Cosmetic new line - self.line("") + # Cosmetic new line + self.line("") - # Update packages - self.reset_poetry() + # Update packages + self.reset_poetry() - self._installer.set_package(self.poetry.package) - self._installer.dry_run(self.option("dry-run")) - self._installer.verbose(self._io.is_verbose()) - self._installer.update(True) - if self.option("lock"): - self._installer.lock() + self._installer.set_package(self.poetry.package) + self._installer.dry_run(self.option("dry-run")) + self._installer.verbose(self._io.is_verbose()) + self._installer.update(True) + if self.option("lock"): + self._installer.lock() - self._installer.whitelist([r["name"] for r in requirements]) + self._installer.whitelist([r["name"] for r in requirements]) - try: status = self._installer.run() - except Exception: + except BaseException: + # Using BaseException here as some exceptions, eg: KeyboardInterrupt, do not inherit from Exception self.poetry.file.write(original_content) - raise if status != 0 or self.option("dry-run"): diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index 09fae525aec..19998592ac3 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -1630,3 +1630,26 @@ def test_add_with_lock_old_installer(app, repo, installer, old_tester): """ assert expected == old_tester.io.fetch_output() + + +def test_add_keyboard_interrupt_restore_content(app, repo, installer, tester, mocker): + mocker.patch( + "poetry.installation.installer.Installer.run", side_effect=KeyboardInterrupt() + ) + original_content = app.poetry.file.read() + + repo.add_package(get_package("cachy", "0.2.0")) + + tester.execute("cachy --dry-run") + + assert original_content == app.poetry.file.read() + + +def test_dry_run_restore_original_content(app, repo, installer, tester): + original_content = app.poetry.file.read() + + repo.add_package(get_package("cachy", "0.2.0")) + + tester.execute("cachy --dry-run") + + assert original_content == app.poetry.file.read()