Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugins/poetry): add poetry and pip extra args #940

Merged
merged 4 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion craft_parts/plugins/poetry_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ class PoetryPluginProperties(PluginProperties, frozen=True):
title="Optional dependency groups",
description="optional dependency groups to include when installing.",
)
poetry_export_extra_args: list[str] = pydantic.Field(
default_factory=list,
title="Extra arguments for poetry export",
description="extra arguments to pass to poetry export when creating requirements.txt.",
)
poetry_pip_extra_args: list[str] = pydantic.Field(
default_factory=list,
title="Extra arguments for pip install",
description="extra arguments to pass to pip install installing dependencies.",
)

# part properties required by the plugin
source: str # pyright: ignore[reportGeneralTypeIssues]
Expand Down Expand Up @@ -115,6 +125,7 @@ def _get_poetry_export_commands(self, requirements_path: pathlib.Path) -> list[s
export_command.append(
f"--with={','.join(sorted(self._options.poetry_with))}",
)
export_command.extend(self._options.poetry_export_extra_args)

return [shlex.join(export_command)]

Expand All @@ -128,10 +139,11 @@ def _get_pip_install_commands(self, requirements_path: pathlib.Path) -> list[str
:returns: A list of strings forming the install script.
"""
pip = self._get_pip()
pip_extra_args = shlex.join(self._options.poetry_pip_extra_args)
return [
# These steps need to be separate because poetry export defaults to including
# hashes, which don't work with installing from a directory.
f"{pip} install --requirement={requirements_path}",
f"{pip} install {pip_extra_args} --requirement={requirements_path}",
# All dependencies should be installed through the requirements file made by
# poetry.
f"{pip} install --no-deps .",
Expand Down
13 changes: 13 additions & 0 deletions docs/common/craft-parts/reference/plugins/poetry_plugin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ well as those for :ref:`sources <part-properties-sources>`.
Additionally, this plugin provides the plugin-specific keywords defined in the
following sections.

poetry-export-extra-args:
~~~~~~~~~~~~~~~~~~~~~~~~~
**Type:** list of strings

Extra arguments to pass at the end of the poetry `export command`_.

poetry-pip-extra-args:
~~~~~~~~~~~~~~~~~~~~~~
**Type:** list of strings

Extra arguments to pass to ``pip install`` when installing dependencies.

poetry-with:
~~~~~~~~~~~~
**Type:** list of strings
Expand Down Expand Up @@ -105,4 +117,5 @@ During the build step, the plugin performs the following actions:

.. _Poetry: https://python-poetry.org
.. _dependency groups: https://python-poetry.org/docs/managing-dependencies#dependency-groups
.. _export command: https://python-poetry.org/docs/cli/#export
.. _environment variables to configure Poetry: https://python-poetry.org/docs/configuration/#using-environment-variables
2 changes: 2 additions & 0 deletions docs/reference/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ New features:

- Add a :doc:`uv plugin</common/craft-parts/reference/plugins/uv_plugin>` for
projects that use the uv build system.
- Add new ``poetry-export-extra-args`` and ``poetry-pip-extra-args`` keys
to the :doc:`poetry plugin</common/craft-parts/reference/plugins/poetry_plugin>`

Bug fixes:

Expand Down
7 changes: 6 additions & 1 deletion tests/integration/plugins/test_poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ def source_directory(request):

@pytest.fixture
def poetry_part(source_directory):
return {"source": str(source_directory), "plugin": "poetry"}
return {
"source": str(source_directory),
"plugin": "poetry",
"poetry-export-extra-args": ["--without-hashes"],
"poetry-pip-extra-args": ["--no-deps"],
}


@pytest.fixture
Expand Down
30 changes: 24 additions & 6 deletions tests/unit/plugins/test_poetry_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,38 @@ def get_build_commands(


@pytest.mark.parametrize(
("optional_groups", "export_addendum"),
("optional_groups", "poetry_extra_args", "export_addendum"),
[
(set(), ""),
({"dev"}, " --with=dev"),
({"toml", "yaml", "silly-walks"}, " --with=silly-walks,toml,yaml"),
(set(), [], ""),
({"dev"}, [], " --with=dev"),
({"toml", "yaml", "silly-walks"}, [], " --with=silly-walks,toml,yaml"),
(set(), ["--no-binary=:all:"], " --no-binary=:all:"),
],
)
def test_get_build_commands(new_dir, optional_groups, export_addendum):
@pytest.mark.parametrize(
("pip_extra_args", "pip_addendum"),
[
([], ""),
(["--no-binary=:all:"], "--no-binary=:all:"),
(["--pre", "-U"], "--pre -U"),
],
)
def test_get_build_commands(
new_dir,
optional_groups,
poetry_extra_args,
export_addendum,
pip_extra_args,
pip_addendum,
):
info = ProjectInfo(application_name="test", cache_dir=new_dir)
part_info = PartInfo(project_info=info, part=Part("p1", {}))
properties = PoetryPlugin.properties_class.unmarshal(
{
"source": ".",
"poetry-with": optional_groups,
"poetry-export-extra-args": poetry_extra_args,
"poetry-pip-extra-args": pip_extra_args,
}
)

Expand All @@ -160,7 +178,7 @@ def test_get_build_commands(new_dir, optional_groups, export_addendum):
f'PARTS_PYTHON_VENV_INTERP_PATH="{new_dir}/parts/p1/install/bin/${{PARTS_PYTHON_INTERPRETER}}"',
f"poetry export --format=requirements.txt --output={new_dir}/parts/p1/build/requirements.txt --with-credentials"
+ export_addendum,
f"{new_dir}/parts/p1/install/bin/pip install --requirement={new_dir}/parts/p1/build/requirements.txt",
f"{new_dir}/parts/p1/install/bin/pip install {pip_addendum} --requirement={new_dir}/parts/p1/build/requirements.txt",
f"{new_dir}/parts/p1/install/bin/pip install --no-deps .",
f"{new_dir}/parts/p1/install/bin/pip check",
*get_build_commands(new_dir),
Expand Down
Loading