Skip to content

Commit

Permalink
feat(cli): introduce --directory to actually switch the directory
Browse files Browse the repository at this point in the history
  • Loading branch information
finswimmer committed Nov 8, 2024
1 parent c17bb3d commit 2b8a3b6
Showing 1 changed file with 76 additions and 39 deletions.
115 changes: 76 additions & 39 deletions src/poetry/console/application.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import annotations

import contextlib
import logging
import os
import re

from contextlib import suppress
Expand All @@ -25,6 +27,7 @@

if TYPE_CHECKING:
from collections.abc import Callable
from collections.abc import Iterator

from cleo.events.event import Event
from cleo.io.inputs.argv_input import ArgvInput
Expand All @@ -48,6 +51,17 @@ def _load() -> Command:
return _load


@contextlib.contextmanager
def switch_working_directory(path: Path) -> Iterator[Path]:
original_cwd = Path.cwd()
os.chdir(path)

try:
yield path
finally:
os.chdir(original_cwd)


COMMANDS = [
"about",
"add",
Expand Down Expand Up @@ -111,6 +125,63 @@ def __init__(self) -> None:
command_loader = CommandLoader({name: load_command(name) for name in COMMANDS})
self.set_command_loader(command_loader)

@property
def _default_definition(self) -> Definition:
from cleo.io.inputs.option import Option

definition = super()._default_definition

definition.add_option(
Option("--no-plugins", flag=True, description="Disables plugins.")
)

definition.add_option(
Option(
"--no-cache", flag=True, description="Disables Poetry source caches."
)
)

definition.add_option(
Option(
"--project",
"-P",
flag=False,
description=(
"Specify another path as the project root."
" All command-line arguments will be resolved relative to the current working directory."
),
)
)

definition.add_option(
Option(
"--directory",
"-C",
flag=False,
description=(
"The working directory for the Poetry command (defaults to the"
" current working directory). All command-line arguments will be"
" resolved relative to the given directory."
),
)
)

return definition

@cached_property
def _project_directory(self) -> Path:
if self._io and self._io.input.option("project"):
return Path(self._io.input.option("project")).absolute()

return self._working_directory

@cached_property
def _working_directory(self) -> Path:
if self._io and self._io.input.option("directory"):
return Path(self._io.input.option("directory")).absolute()

return Path.cwd()

@property
def poetry(self) -> Poetry:
from poetry.factory import Factory
Expand All @@ -119,7 +190,7 @@ def poetry(self) -> Poetry:
return self._poetry

self._poetry = Factory().create_poetry(
cwd=self._directory,
cwd=self._project_directory,
io=self._io,
disable_plugins=self._disable_plugins,
disable_cache=self._disable_cache,
Expand Down Expand Up @@ -172,7 +243,9 @@ def _run(self, io: IO) -> int:

self._load_plugins(io)

exit_code: int = super()._run(io)
with switch_working_directory(self._working_directory):
exit_code: int = super()._run(io)

return exit_code

def _configure_io(self, io: IO) -> None:
Expand Down Expand Up @@ -335,49 +408,13 @@ def _load_plugins(self, io: IO | None = None) -> None:
from poetry.plugins.application_plugin import ApplicationPlugin
from poetry.plugins.plugin_manager import PluginManager

PluginManager.add_project_plugin_path(self._directory)
PluginManager.add_project_plugin_path(self._project_directory)
manager = PluginManager(ApplicationPlugin.group)
manager.load_plugins()
manager.activate(self)

self._plugins_loaded = True

@property
def _default_definition(self) -> Definition:
from cleo.io.inputs.option import Option

definition = super()._default_definition

definition.add_option(
Option("--no-plugins", flag=True, description="Disables plugins.")
)

definition.add_option(
Option(
"--no-cache", flag=True, description="Disables Poetry source caches."
)
)

definition.add_option(
Option(
"--project",
"-P",
flag=False,
description=(
"Specify another path as the project root."
" All command-line arguments will be resolved relative to the current working directory."
),
)
)

return definition

@cached_property
def _directory(self) -> Path:
if self._io and self._io.input.option("project"):
return Path(self._io.input.option("project")).absolute()
return Path.cwd()


def main() -> int:
exit_code: int = Application().run()
Expand Down

0 comments on commit 2b8a3b6

Please sign in to comment.