Skip to content

Commit 6e07010

Browse files
committed
feat(cli): introduce --directory to actually switch the directory
1 parent 9e9df43 commit 6e07010

File tree

1 file changed

+76
-39
lines changed

1 file changed

+76
-39
lines changed

src/poetry/console/application.py

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import annotations
22

3+
import contextlib
34
import logging
5+
import os
46
import re
57

68
from contextlib import suppress
@@ -24,6 +26,7 @@
2426

2527
if TYPE_CHECKING:
2628
from collections.abc import Callable
29+
from collections.abc import Iterator
2730

2831
from cleo.events.event import Event
2932
from cleo.io.inputs.argv_input import ArgvInput
@@ -47,6 +50,17 @@ def _load() -> Command:
4750
return _load
4851

4952

53+
@contextlib.contextmanager
54+
def switch_working_directory(path: Path) -> Iterator[Path]:
55+
original_cwd = Path.cwd()
56+
os.chdir(path)
57+
58+
try:
59+
yield path
60+
finally:
61+
os.chdir(original_cwd)
62+
63+
5064
COMMANDS = [
5165
"about",
5266
"add",
@@ -110,6 +124,63 @@ def __init__(self) -> None:
110124
command_loader = CommandLoader({name: load_command(name) for name in COMMANDS})
111125
self.set_command_loader(command_loader)
112126

127+
@property
128+
def _default_definition(self) -> Definition:
129+
from cleo.io.inputs.option import Option
130+
131+
definition = super()._default_definition
132+
133+
definition.add_option(
134+
Option("--no-plugins", flag=True, description="Disables plugins.")
135+
)
136+
137+
definition.add_option(
138+
Option(
139+
"--no-cache", flag=True, description="Disables Poetry source caches."
140+
)
141+
)
142+
143+
definition.add_option(
144+
Option(
145+
"--project",
146+
"-P",
147+
flag=False,
148+
description=(
149+
"Specify another path as the project root."
150+
" All command-line arguments will be resolved relative to the current working directory."
151+
),
152+
)
153+
)
154+
155+
definition.add_option(
156+
Option(
157+
"--directory",
158+
"-C",
159+
flag=False,
160+
description=(
161+
"The working directory for the Poetry command (defaults to the"
162+
" current working directory). All command-line arguments will be"
163+
" resolved relative to the given directory."
164+
),
165+
)
166+
)
167+
168+
return definition
169+
170+
@cached_property
171+
def _project_directory(self) -> Path:
172+
if self._io and self._io.input.option("project"):
173+
return Path(self._io.input.option("project")).absolute()
174+
175+
return self._working_directory
176+
177+
@cached_property
178+
def _working_directory(self) -> Path:
179+
if self._io and self._io.input.option("directory"):
180+
return Path(self._io.input.option("directory")).absolute()
181+
182+
return Path.cwd()
183+
113184
@property
114185
def poetry(self) -> Poetry:
115186
from poetry.factory import Factory
@@ -118,7 +189,7 @@ def poetry(self) -> Poetry:
118189
return self._poetry
119190

120191
self._poetry = Factory().create_poetry(
121-
cwd=self._directory,
192+
cwd=self._project_directory,
122193
io=self._io,
123194
disable_plugins=self._disable_plugins,
124195
disable_cache=self._disable_cache,
@@ -171,7 +242,9 @@ def _run(self, io: IO) -> int:
171242

172243
self._load_plugins(io)
173244

174-
exit_code: int = super()._run(io)
245+
with switch_working_directory(self._working_directory):
246+
exit_code: int = super()._run(io)
247+
175248
return exit_code
176249

177250
def _configure_io(self, io: IO) -> None:
@@ -331,49 +404,13 @@ def _load_plugins(self, io: IO) -> None:
331404
from poetry.plugins.application_plugin import ApplicationPlugin
332405
from poetry.plugins.plugin_manager import PluginManager
333406

334-
PluginManager.add_project_plugin_path(self._directory)
407+
PluginManager.add_project_plugin_path(self._project_directory)
335408
manager = PluginManager(ApplicationPlugin.group)
336409
manager.load_plugins()
337410
manager.activate(self)
338411

339412
self._plugins_loaded = True
340413

341-
@property
342-
def _default_definition(self) -> Definition:
343-
from cleo.io.inputs.option import Option
344-
345-
definition = super()._default_definition
346-
347-
definition.add_option(
348-
Option("--no-plugins", flag=True, description="Disables plugins.")
349-
)
350-
351-
definition.add_option(
352-
Option(
353-
"--no-cache", flag=True, description="Disables Poetry source caches."
354-
)
355-
)
356-
357-
definition.add_option(
358-
Option(
359-
"--project",
360-
"-P",
361-
flag=False,
362-
description=(
363-
"Specify another path as the project root."
364-
" All command-line arguments will be resolved relative to the current working directory."
365-
),
366-
)
367-
)
368-
369-
return definition
370-
371-
@cached_property
372-
def _directory(self) -> Path:
373-
if self._io and self._io.input.option("project"):
374-
return Path(self._io.input.option("project")).absolute()
375-
return Path.cwd()
376-
377414

378415
def main() -> int:
379416
exit_code: int = Application().run()

0 commit comments

Comments
 (0)