Skip to content

Commit ae073cb

Browse files
radoeringabn
andcommitted
introduce tool.poetry.requires-plugins section to define Poetry plugins that are required for the project (python-poetry#9547)
* when running `poetry install` and required plugins are not available in Poetry's own environment they are installed only for the project into .poetry/plugins inside the project folder * when creating the application .poetry/plugins is added to the front of sys.path Co-authored-by: Arun Babu Neelicattu <[email protected]>
1 parent 424a93a commit ae073cb

File tree

28 files changed

+1349
-97
lines changed

28 files changed

+1349
-97
lines changed

docs/plugins.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,28 @@ You can also list all currently installed plugins by running:
255255
poetry self show plugins
256256
```
257257

258+
### Project plugins
259+
260+
You can also specify that a plugin is required for your project
261+
in the `tool.poetry.requires-plugins` section of the pyproject.toml file:
262+
263+
```toml
264+
[tool.poetry.requires-plugins]
265+
my-application-plugin = ">1.0"
266+
```
267+
268+
If the plugin is not installed in Poetry's own environment when running `poetry install`,
269+
it will be installed only for the current project under `.poetry/plugins`
270+
in the project's directory.
271+
272+
The syntax to specify `plugins` is the same as for [dependencies]({{< relref "managing-dependencies" >}}).
273+
274+
{{% warning %}}
275+
You can even overwrite a plugin in Poetry's own environment with another version.
276+
However, if a plugin's dependencies are not compatible with packages in Poetry's own
277+
environment, installation will fail.
278+
{{% /warning %}}
279+
258280

259281
## Maintaining a plugin
260282

docs/pyproject.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,18 @@ any custom url in the `urls` section.
843843

844844
If you publish your package on PyPI, they will appear in the `Project Links` section.
845845

846+
## `requires-plugins`
847+
848+
In this section, you can specify that certain plugins are required for your project:
849+
850+
```toml
851+
[tool.poetry.requires-plugins]
852+
my-application-plugin = ">=1.0"
853+
my-plugin = ">=1.0,<2.0"
854+
```
855+
856+
See [Project plugins]({{< relref "plugins#project-plugins" >}}) for more information.
857+
846858
## Poetry and PEP-517
847859

848860
[PEP-517](https://www.python.org/dev/peps/pep-0517/) introduces a standard way

src/poetry/console/application.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import re
55

66
from contextlib import suppress
7+
from functools import cached_property
78
from importlib import import_module
9+
from pathlib import Path
810
from typing import TYPE_CHECKING
911
from typing import cast
1012

@@ -111,20 +113,13 @@ def __init__(self) -> None:
111113

112114
@property
113115
def poetry(self) -> Poetry:
114-
from pathlib import Path
115-
116116
from poetry.factory import Factory
117117

118118
if self._poetry is not None:
119119
return self._poetry
120120

121-
project_path = Path.cwd()
122-
123-
if self._io and self._io.input.option("directory"):
124-
project_path = Path(self._io.input.option("directory")).absolute()
125-
126121
self._poetry = Factory().create_poetry(
127-
cwd=project_path,
122+
cwd=self._directory,
128123
io=self._io,
129124
disable_plugins=self._disable_plugins,
130125
disable_cache=self._disable_cache,
@@ -340,6 +335,7 @@ def _load_plugins(self, io: IO | None = None) -> None:
340335
from poetry.plugins.application_plugin import ApplicationPlugin
341336
from poetry.plugins.plugin_manager import PluginManager
342337

338+
PluginManager.add_project_plugin_path(self._directory)
343339
manager = PluginManager(ApplicationPlugin.group)
344340
manager.load_plugins()
345341
manager.activate(self)
@@ -382,6 +378,12 @@ def _default_definition(self) -> Definition:
382378

383379
return definition
384380

381+
@cached_property
382+
def _directory(self) -> Path:
383+
if self._io and self._io.input.option("directory"):
384+
return Path(self._io.input.option("directory")).absolute()
385+
return Path.cwd()
386+
385387

386388
def main() -> int:
387389
exit_code: int = Application().run()

src/poetry/console/commands/install.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from cleo.helpers import option
77

88
from poetry.console.commands.installer_command import InstallerCommand
9+
from poetry.plugins.plugin_manager import PluginManager
910

1011

1112
if TYPE_CHECKING:
@@ -104,6 +105,8 @@ def handle(self) -> int:
104105

105106
from poetry.masonry.builders.editable import EditableBuilder
106107

108+
PluginManager.ensure_project_plugins(self.poetry, self.io)
109+
107110
if self.option("extras") and self.option("all-extras"):
108111
self.line_error(
109112
"<error>You cannot specify explicit"

src/poetry/console/commands/self/show/plugins.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ def _system_project_handle(self) -> int:
7070
}
7171

7272
for group in [ApplicationPlugin.group, Plugin.group]:
73-
for entry_point in PluginManager(group).get_plugin_entry_points(
74-
env=system_env
75-
):
73+
for entry_point in PluginManager(group).get_plugin_entry_points():
7674
assert entry_point.dist is not None
7775

7876
package = packages_by_name[canonicalize_name(entry_point.dist.name)]

0 commit comments

Comments
 (0)