From dc91a5f9aae6e2861e7b938e21ce8b3fe82329cd Mon Sep 17 00:00:00 2001 From: KotlinIsland <65446343+KotlinIsland@users.noreply.github.com> Date: Sat, 3 Sep 2022 03:58:45 +1000 Subject: [PATCH] Handle multiple extras and invalid extras (#103) Co-authored-by: KotlinIsland --- src/poetry_plugin_export/command.py | 12 +++++++++- tests/command/test_command_export.py | 36 ++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/poetry_plugin_export/command.py b/src/poetry_plugin_export/command.py index 6259c84..ee60220 100644 --- a/src/poetry_plugin_export/command.py +++ b/src/poetry_plugin_export/command.py @@ -82,9 +82,19 @@ def handle(self) -> None: "" ) + # Checking extras + extras = { + extra for extra_opt in self.option("extras") for extra in extra_opt.split() + } + invalid_extras = extras - self.poetry.package.extras.keys() + if invalid_extras: + raise ValueError( + f"Extra [{', '.join(sorted(invalid_extras))}] is not specified." + ) + exporter = Exporter(self.poetry) exporter.only_groups(list(self.activated_groups)) - exporter.with_extras(self.option("extras")) + exporter.with_extras(list(extras)) exporter.with_hashes(not self.option("without-hashes")) exporter.with_credentials(self.option("with-credentials")) exporter.with_urls(not self.option("without-urls")) diff --git a/tests/command/test_command_export.py b/tests/command/test_command_export.py index a6c44c2..0460adf 100644 --- a/tests/command/test_command_export.py +++ b/tests/command/test_command_export.py @@ -50,6 +50,7 @@ python = "~2.7 || ^3.6" foo = "^1.0" bar = { version = "^1.1", optional = true } +qux = { version = "^1.2", optional = true } [tool.poetry.group.dev.dependencies] baz = "^2.0" @@ -63,6 +64,7 @@ [tool.poetry.extras] feature_bar = ["bar"] +feature_qux = ["qux"] """ @@ -72,6 +74,7 @@ def setup(repo: Repository) -> None: repo.add_package(Package("bar", "1.1.0")) repo.add_package(Package("baz", "2.0.0")) repo.add_package(Package("opt", "2.2.0")) + repo.add_package(Package("qux", "1.2.0")) @pytest.fixture @@ -174,15 +177,40 @@ def test_export_groups( assert tester.io.fetch_output() == expected -def test_export_includes_extras_by_flag(tester: CommandTester, do_lock: None) -> None: - tester.execute("--format requirements.txt --extras feature_bar") - expected = f"""\ +@pytest.mark.parametrize( + "extras, expected", + [ + ( + "feature_bar", + f"""\ bar==1.1.0 ; {MARKER_PY} foo==1.0.0 ; {MARKER_PY} -""" +""", + ), + ( + "feature_bar feature_qux", + f"""\ +bar==1.1.0 ; {MARKER_PY} +foo==1.0.0 ; {MARKER_PY} +qux==1.2.0 ; {MARKER_PY} +""", + ), + ], +) +def test_export_includes_extras_by_flag( + tester: CommandTester, do_lock: None, extras: str, expected: str +) -> None: + tester.execute(f"--format requirements.txt --extras '{extras}'") assert tester.io.fetch_output() == expected +def test_export_reports_invalid_extras(tester: CommandTester, do_lock: None) -> None: + with pytest.raises(ValueError) as error: + tester.execute("--format requirements.txt --extras 'SUS AMONGUS'") + expected = "Extra [AMONGUS, SUS] is not specified." + assert str(error.value) == expected + + def test_export_with_urls( monkeypatch: MonkeyPatch, tester: CommandTester, poetry: Poetry ) -> None: