插件
插件 #
Poetry 支持使用和构建插件,如果你希望用自己的插件来改变或扩展 Poetry 的功能。
例如,如果你的环境对 Poetry 的行为提出了特殊的要求,而这些要求不适用于大多数用户,或者你希望以大多数用户不希望的方式使用 Poetry 来完成某些事情。
在这些情况下,你可以考虑创建一个插件来处理你的特定逻辑。
创建插件 #
插件是一个普通的 Python 包,它将代码作为包的一部分进行发布,并且可能还依赖于其他包。
插件包 #
插件包必须依赖于 Poetry,并在 pyproject.toml
文件中声明一个合适的 插件。
[tool.poetry]
name = "my-poetry-plugin"
version = "1.0.0"
# ...
[tool.poetry.dependencies]
python = "^3.7"
poetry = "^1.2"
[tool.poetry.plugins."poetry.plugin"]
demo = "poetry_demo_plugin.plugin:MyPlugin"
通用插件 #
每个插件都必须提供一个实现 poetry.plugins.Plugin
接口的类。
插件的 activate()
方法在插件加载后被调用,并接收一个 Poetry
实例和一个 cleo.io.io.IO
实例。
使用这两个对象,可以读取所有配置,并根据需要操作所有公共内部对象和状态。
示例
from cleo.io.io import IO
from poetry.plugins.plugin import Plugin
from poetry.poetry import Poetry
class MyPlugin(Plugin):
def activate(self, poetry: Poetry, io: IO):
io.write_line("Setting readme")
poetry.package.readme = "README.md"
...
应用程序插件 #
如果你想在 poetry
脚本中添加命令或选项,你需要创建一个实现 poetry.plugins.ApplicationPlugin
接口的应用程序插件。
应用程序插件的 activate()
方法在插件加载后被调用,并接收一个 poetry.console.Application
实例。
from cleo.commands.command import Command
from poetry.plugins.application_plugin import ApplicationPlugin
class CustomCommand(Command):
name = "my-command"
def handle(self) -> int:
self.line("My command")
return 0
def factory():
return CustomCommand()
class MyApplicationPlugin(ApplicationPlugin):
def activate(self, application):
application.command_loader.register_factory("my-command", factory)
可以通过以下方式注册命令
application.add(MyCommand())
但是,强烈建议在命令加载器中注册一个新的工厂,以便在实际调用命令时延迟加载命令。
这将有助于保持 Poetry 的良好性能。
插件还必须在插件包的 pyproject.toml
文件中声明为 poetry.application.plugin
插件
[tool.poetry.plugins."poetry.application.plugin"]
foo-command = "poetry_demo_plugin.plugin:MyApplicationPlugin"
事件处理程序 #
插件还可以监听特定事件,并在必要时对其进行操作。
这些事件由 Cleo 触发,可以从 cleo.events.console_events
模块访问。
COMMAND
:此事件允许在执行任何命令之前附加监听器。SIGNAL
:此事件允许在命令执行被中断后执行某些操作。TERMINATE
:此事件允许在命令之后附加监听器。ERROR
:当抛出未捕获的异常时,会发生此事件。
让我们看看如何实现应用程序事件处理程序。在这个例子中,我们将看到如何在执行命令之前从 .env
文件加载环境变量。
from cleo.events.console_events import COMMAND
from cleo.events.console_command_event import ConsoleCommandEvent
from cleo.events.event_dispatcher import EventDispatcher
from dotenv import load_dotenv
from poetry.console.application import Application
from poetry.console.commands.env_command import EnvCommand
from poetry.plugins.application_plugin import ApplicationPlugin
class MyApplicationPlugin(ApplicationPlugin):
def activate(self, application: Application):
application.event_dispatcher.add_listener(
COMMAND, self.load_dotenv
)
def load_dotenv(
self,
event: ConsoleCommandEvent,
event_name: str,
dispatcher: EventDispatcher
) -> None:
command = event.command
if not isinstance(command, EnvCommand):
return
io = event.io
if io.is_debug():
io.write_line(
"<debug>Loading environment variables.</debug>"
)
load_dotenv()
使用插件 #
安装的插件包会在 Poetry 启动时自动加载。
你有几种方法可以为 Poetry 安装插件
使用 pipx inject
#
如果你使用 pipx
安装了 Poetry,你可以通过 pipx inject
命令添加插件包。
pipx inject poetry poetry-plugin
如果你想卸载插件,可以运行
pipx uninject poetry poetry-plugin # For pipx versions >= 1.2.0
pipx runpip poetry uninstall poetry-plugin # For pipx versions < 1.2.0
使用 pip
#
Poetry 虚拟环境中的 pip
二进制文件也可以用来安装和删除插件。这里的环境变量 $POETRY_HOME
用于表示虚拟环境的路径。如果你不确定 Poetry 安装在哪里,可以参考 安装说明。
要添加插件,可以使用 pip install
$POETRY_HOME/bin/pip install --user poetry-plugin
如果你想卸载插件,可以运行
$POETRY_HOME/bin/pip uninstall poetry-plugin
self add
命令 #
self add
和 self remove
可能会有问题,因此应该优先使用其他方法。poetry self add poetry-plugin
self add
命令将确保插件与当前版本的 Poetry 兼容,并安装插件工作所需的包。
self add
命令支持的包规范格式与 add
命令 支持的格式相同。
如果你不再需要插件并想卸载它,可以使用 self remove
命令。
poetry self remove poetry-plugin
你还可以通过运行以下命令列出所有当前安装的插件
poetry self show plugins
维护插件 #
在编写插件时,你可能会访问 Poetry 的内部,因为没有稳定的公共 API。虽然我们尽力在删除方法之前先将其弃用,但有时必须更改内部方法的签名。
作为插件的作者,你可能正在针对 Poetry 的最新版本测试你的插件。此外,你应该考虑针对 Poetry 的最新发布分支和主分支进行测试,并安排一个定期运行的 CI 作业,即使你没有对插件进行任何更改。这样,你就能立即注意到破坏插件的内部更改,并为下一个 Poetry 版本做好准备。