Skip to content

Commit

Permalink
Add a plugin add command
Browse files Browse the repository at this point in the history
  • Loading branch information
sdispater committed Feb 28, 2021
1 parent ef24d3e commit e004ba9
Show file tree
Hide file tree
Showing 17 changed files with 506 additions and 52 deletions.
43 changes: 43 additions & 0 deletions docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,3 +534,46 @@ To only remove a specific package from a cache, you have to specify the cache en
```bash
poetry cache clear pypi:requests:2.24.0
```

## plugin

The `plugin` namespace regroups sub commands to manage Poetry plugins.

### `plugin add`

The `plugin add` command installs Poetry plugins and make them available at runtime.

For example, to install the `poetry-plugin` plugin, you can run:

```bash
poetry plugin add my-plugin
```

The package specification formats supported by the `plugin add` command are the same as the ones supported
by the [`add` command](#add).

If you just want to check what would happen by installing a plugin, you can use the `--dry-run` option

```bash
poetry plugin add my-plugin --dry-run
```

#### Options

* `--dry-run`: Outputs the operations but will not execute anything (implicitly enables --verbose).

### `plugin list`

The `plugin list` command lists all the currently installed plugins.

```bash
poetry plugin list
```

### `plugin remove`

The `plugin remove` command lists all the currently installed plugins.

```bash
poetry plugin remove poetry-plugin
```
73 changes: 67 additions & 6 deletions docs/docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ 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()

Expand Down Expand Up @@ -159,14 +159,75 @@ class MyApplicationPlugin(ApplicationPlugin):
def load_dotenv(
self, event: ConsoleCommandEvent, event_name: str, dispatcher: EventDispatcher
) -> None:
command = event.io
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()
```


## Using plugins

Installed plugin packages are automatically loaded when Poetry starts up.

You have multiple ways to install plugins for Poetry

### The `plugin add` command

This is the easiest way and should account for all the ways Poetry can be installed.

```bash
poetry plugin add poetry-plugin
```

The `plugin add` command will ensure that the plugin is compatible with the current version of Poetry
and install the needed packages for the plugin to work.

The package specification formats supported by the `plugin add` command are the same as the ones supported
by the [`add` command](/docs/cli/#add).

If you no longer need a plugin and want to uninstall it, you can use the `plugin remove` command.

```shell
poetry plugin remove poetry-plugin
```

You can also list all currently installed plugins by running:

```shell
poetry plugin list
```

### With `pipx inject`

If you used `pipx` to install Poetry you can add the plugin packages via the `pipx inject` command.

```shell
pips inject poetry poetry-plugin
```

If you want to uninstall a plugin, you can run:

```shell
pipx runpip poetry uninstall poetry-plugin
```

### With `pip`

If you used `pip` to install Poetry you can add the plugin packages via the `pip install` command.

```shell
pip install --user poetry-plugin
```

If you want to uninstall a plugin, you can run:

```shell
pip uninstall poetry-plugin
```
18 changes: 13 additions & 5 deletions poetry/console/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ def _load() -> Type[Command]:
"env list",
"env remove",
"env use",
# Plugin commands
"plugin add",
# Self commands
"self update",
]
Expand All @@ -78,6 +80,7 @@ def _load() -> Type[Command]:
if TYPE_CHECKING:
from cleo.io.inputs.definition import Definition

from poetry.console.commands.installer_command import InstallerCommand
from poetry.poetry import Poetry


Expand All @@ -92,8 +95,8 @@ def __init__(self) -> None:

dispatcher = EventDispatcher()
dispatcher.add_listener(COMMAND, self.register_command_loggers)
dispatcher.add_listener(COMMAND, self.set_env)
dispatcher.add_listener(COMMAND, self.set_installer)
dispatcher.add_listener(COMMAND, self.configure_env)
dispatcher.add_listener(COMMAND, self.configure_installer)
self.set_event_dispatcher(dispatcher)

command_loader = CommandLoader({name: load_command(name) for name in COMMANDS})
Expand Down Expand Up @@ -239,7 +242,9 @@ def register_command_loggers(

logger.setLevel(level)

def set_env(self, event: ConsoleCommandEvent, event_name: str, _: Any) -> None:
def configure_env(
self, event: ConsoleCommandEvent, event_name: str, _: Any
) -> None:
from .commands.env_command import EnvCommand

command: EnvCommand = cast(EnvCommand, event.command)
Expand All @@ -262,7 +267,7 @@ def set_env(self, event: ConsoleCommandEvent, event_name: str, _: Any) -> None:

command.set_env(env)

def set_installer(
def configure_installer(
self, event: ConsoleCommandEvent, event_name: str, _: Any
) -> None:
from .commands.installer_command import InstallerCommand
Expand All @@ -276,11 +281,14 @@ def set_installer(
if command.installer is not None:
return

self._configure_installer(command, event.io)

def _configure_installer(self, command: "InstallerCommand", io: "IO") -> None:
from poetry.installation.installer import Installer

poetry = command.poetry
installer = Installer(
event.io,
io,
command.env,
poetry.package,
poetry.locker,
Expand Down
11 changes: 10 additions & 1 deletion poetry/console/commands/command.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import TYPE_CHECKING
from typing import Optional

from cleo.commands.command import Command as BaseCommand

Expand All @@ -11,9 +12,17 @@
class Command(BaseCommand):
loggers = []

_poetry: Optional["Poetry"] = None

@property
def poetry(self) -> "Poetry":
return self.get_application().poetry
if self._poetry is None:
return self.get_application().poetry

return self._poetry

def set_poetry(self, poetry: "Poetry") -> None:
self._poetry = poetry

def get_application(self) -> "Application":
return self.application
Expand Down
6 changes: 3 additions & 3 deletions poetry/console/commands/env_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


if TYPE_CHECKING:
from poetry.utils.env import VirtualEnv
from poetry.utils.env import Env


class EnvCommand(Command):
Expand All @@ -14,8 +14,8 @@ def __init__(self) -> None:
super(EnvCommand, self).__init__()

@property
def env(self) -> "VirtualEnv":
def env(self) -> "Env":
return self._env

def set_env(self, env: "VirtualEnv") -> None:
def set_env(self, env: "Env") -> None:
self._env = env
21 changes: 16 additions & 5 deletions poetry/console/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,16 @@ def _parse_requirements(self, requirements: List[str]) -> List[Dict[str, str]]:

result.append(pair)
continue
elif (os.path.sep in requirement or "/" in requirement) and cwd.joinpath(
requirement
).exists():
path = cwd.joinpath(requirement)
elif (os.path.sep in requirement or "/" in requirement) and (
cwd.joinpath(requirement).exists()
or Path(requirement).expanduser().exists()
and Path(requirement).expanduser().is_absolute()
):
path = Path(requirement).expanduser()

if not path.is_absolute():
path = cwd.joinpath(requirement)

if path.is_file():
package = Provider.get_package_from_file(path.resolve())
else:
Expand All @@ -447,7 +453,12 @@ def _parse_requirements(self, requirements: List[str]) -> List[Dict[str, str]]:
dict(
[
("name", package.name),
("path", path.relative_to(cwd).as_posix()),
(
"path",
path.relative_to(cwd).as_posix()
if not path.is_absolute()
else path.as_posix(),
),
]
+ ([("extras", extras)] if extras else [])
)
Expand Down
Empty file.
Loading

0 comments on commit e004ba9

Please sign in to comment.