1
1
from __future__ import annotations
2
2
3
+ import contextlib
3
4
import logging
5
+ import os
4
6
import re
5
7
6
8
from contextlib import suppress
25
27
26
28
if TYPE_CHECKING :
27
29
from collections .abc import Callable
30
+ from collections .abc import Iterator
28
31
29
32
from cleo .events .event import Event
30
33
from cleo .io .inputs .argv_input import ArgvInput
@@ -48,6 +51,17 @@ def _load() -> Command:
48
51
return _load
49
52
50
53
54
+ @contextlib .contextmanager
55
+ def switch_working_directory (path : Path ) -> Iterator [Path ]:
56
+ original_cwd = Path .cwd ()
57
+ os .chdir (path )
58
+
59
+ try :
60
+ yield path
61
+ finally :
62
+ os .chdir (original_cwd )
63
+
64
+
51
65
COMMANDS = [
52
66
"about" ,
53
67
"add" ,
@@ -111,6 +125,63 @@ def __init__(self) -> None:
111
125
command_loader = CommandLoader ({name : load_command (name ) for name in COMMANDS })
112
126
self .set_command_loader (command_loader )
113
127
128
+ @property
129
+ def _default_definition (self ) -> Definition :
130
+ from cleo .io .inputs .option import Option
131
+
132
+ definition = super ()._default_definition
133
+
134
+ definition .add_option (
135
+ Option ("--no-plugins" , flag = True , description = "Disables plugins." )
136
+ )
137
+
138
+ definition .add_option (
139
+ Option (
140
+ "--no-cache" , flag = True , description = "Disables Poetry source caches."
141
+ )
142
+ )
143
+
144
+ definition .add_option (
145
+ Option (
146
+ "--project" ,
147
+ "-P" ,
148
+ flag = False ,
149
+ description = (
150
+ "Specify another path as the project root."
151
+ " All command-line arguments will be resolved relative to the current working directory."
152
+ ),
153
+ )
154
+ )
155
+
156
+ definition .add_option (
157
+ Option (
158
+ "--directory" ,
159
+ "-C" ,
160
+ flag = False ,
161
+ description = (
162
+ "The working directory for the Poetry command (defaults to the"
163
+ " current working directory). All command-line arguments will be"
164
+ " resolved relative to the given directory."
165
+ ),
166
+ )
167
+ )
168
+
169
+ return definition
170
+
171
+ @cached_property
172
+ def _project_directory (self ) -> Path :
173
+ if self ._io and self ._io .input .option ("project" ):
174
+ return Path (self ._io .input .option ("project" )).absolute ()
175
+
176
+ return self ._working_directory
177
+
178
+ @cached_property
179
+ def _working_directory (self ) -> Path :
180
+ if self ._io and self ._io .input .option ("directory" ):
181
+ return Path (self ._io .input .option ("directory" )).absolute ()
182
+
183
+ return Path .cwd ()
184
+
114
185
@property
115
186
def poetry (self ) -> Poetry :
116
187
from poetry .factory import Factory
@@ -119,7 +190,7 @@ def poetry(self) -> Poetry:
119
190
return self ._poetry
120
191
121
192
self ._poetry = Factory ().create_poetry (
122
- cwd = self ._directory ,
193
+ cwd = self ._project_directory ,
123
194
io = self ._io ,
124
195
disable_plugins = self ._disable_plugins ,
125
196
disable_cache = self ._disable_cache ,
@@ -172,7 +243,9 @@ def _run(self, io: IO) -> int:
172
243
173
244
self ._load_plugins (io )
174
245
175
- exit_code : int = super ()._run (io )
246
+ with switch_working_directory (self ._working_directory ):
247
+ exit_code : int = super ()._run (io )
248
+
176
249
return exit_code
177
250
178
251
def _configure_io (self , io : IO ) -> None :
@@ -335,49 +408,13 @@ def _load_plugins(self, io: IO | None = None) -> None:
335
408
from poetry .plugins .application_plugin import ApplicationPlugin
336
409
from poetry .plugins .plugin_manager import PluginManager
337
410
338
- PluginManager .add_project_plugin_path (self ._directory )
411
+ PluginManager .add_project_plugin_path (self ._project_directory )
339
412
manager = PluginManager (ApplicationPlugin .group )
340
413
manager .load_plugins ()
341
414
manager .activate (self )
342
415
343
416
self ._plugins_loaded = True
344
417
345
- @property
346
- def _default_definition (self ) -> Definition :
347
- from cleo .io .inputs .option import Option
348
-
349
- definition = super ()._default_definition
350
-
351
- definition .add_option (
352
- Option ("--no-plugins" , flag = True , description = "Disables plugins." )
353
- )
354
-
355
- definition .add_option (
356
- Option (
357
- "--no-cache" , flag = True , description = "Disables Poetry source caches."
358
- )
359
- )
360
-
361
- definition .add_option (
362
- Option (
363
- "--project" ,
364
- "-P" ,
365
- flag = False ,
366
- description = (
367
- "Specify another path as the project root."
368
- " All command-line arguments will be resolved relative to the current working directory."
369
- ),
370
- )
371
- )
372
-
373
- return definition
374
-
375
- @cached_property
376
- def _directory (self ) -> Path :
377
- if self ._io and self ._io .input .option ("project" ):
378
- return Path (self ._io .input .option ("project" )).absolute ()
379
- return Path .cwd ()
380
-
381
418
382
419
def main () -> int :
383
420
exit_code : int = Application ().run ()
0 commit comments