|
9 | 9 | import subprocess
|
10 | 10 | import sys
|
11 | 11 | from pathlib import Path
|
12 |
| -from tempfile import TemporaryDirectory |
13 | 12 | from typing import *
|
14 | 13 |
|
15 | 14 | from vien import is_posix
|
16 |
| -from vien._bash_runner import run_as_bash_script |
| 15 | +from vien._bash_runner import start_bash_shell |
17 | 16 | from vien._call_funcs import relative_fn_to_module_name, relative_inner_path
|
18 | 17 | from vien._cmdexe_escape_args import cmd_escape_arg
|
19 | 18 | from vien._colors import Colors
|
@@ -246,85 +245,45 @@ def _quoted(txt: str) -> str:
|
246 | 245 | return shlex.quote(txt)
|
247 | 246 |
|
248 | 247 |
|
249 |
| -class OptionalTempDir: |
250 |
| - def __init__(self): |
251 |
| - self._temp_dir: Optional[TemporaryDirectory] = None |
252 |
| - |
253 |
| - @property |
254 |
| - def path(self) -> Path: |
255 |
| - if self._temp_dir is None: |
256 |
| - self._temp_dir = TemporaryDirectory() |
257 |
| - return Path(self._temp_dir.name) |
258 |
| - |
259 |
| - def __enter__(self): |
260 |
| - return self |
261 |
| - |
262 |
| - def __exit__(self, exc_type, exc_val, exc_tb): |
263 |
| - if self._temp_dir is not None: |
264 |
| - self._temp_dir.cleanup() |
265 |
| - self._temp_dir = None |
266 |
| - |
267 |
| - |
268 | 248 | def main_shell(dirs: Dirs, input: Optional[str], input_delay: Optional[float]):
|
269 | 249 | dirs.venv_must_exist()
|
270 | 250 |
|
271 |
| - with OptionalTempDir() as opt_temp_dir: |
272 |
| - activate_path = dirs.venv_dir / "bin" / "activate" |
273 |
| - old_ps1 = os.environ.get("PS1") or guess_bash_ps1() |
274 |
| - |
275 |
| - if not old_ps1: |
276 |
| - old_ps1 = r"\h:\W \u\$" # default from MacOS |
277 |
| - |
278 |
| - color_start = Colors.YELLOW |
279 |
| - color_end = Colors.NOCOLOR |
| 251 | + # with OptionalTempDir() as opt_temp_dir: |
| 252 | + activate_path = dirs.venv_dir / "bin" / "activate" |
| 253 | + old_ps1 = os.environ.get("PS1") or guess_bash_ps1() |
280 | 254 |
|
281 |
| - venv_name = dirs.project_dir.name |
282 |
| - new_ps1 = f"{color_start}({venv_name}){color_end}:{old_ps1} " |
| 255 | + if not old_ps1: |
| 256 | + old_ps1 = r"\h:\W \u\$" # default from MacOS |
283 | 257 |
|
284 |
| - bashrc_file = Path(os.path.expanduser("~/.bashrc")).absolute() |
| 258 | + color_start = Colors.YELLOW |
| 259 | + color_end = Colors.NOCOLOR |
285 | 260 |
|
286 |
| - executable: Optional[str] = None |
287 |
| - args: Union[str, List[str]] |
| 261 | + venv_name = dirs.project_dir.name |
| 262 | + new_ps1 = f"{color_start}({venv_name}){color_end}:{old_ps1} " |
288 | 263 |
|
289 |
| - if bashrc_file.exists(): |
290 |
| - # Ubuntu |
291 |
| - temp_bash_rc = opt_temp_dir.path / "bash.rc" |
292 |
| - temp_bash_rc.write_bytes( |
293 |
| - b'\n'.join([ |
294 |
| - f"source {bashrc_file}".encode(), |
295 |
| - f"source {activate_path}".encode(), |
296 |
| - f'PS1={_quoted(new_ps1)}'.encode()])) |
297 |
| - args = ["/bin/bash", "--rcfile", str(temp_bash_rc), "-i"] |
298 |
| - |
299 |
| - else: |
300 |
| - # MacOS |
301 |
| - executable = "/bin/bash" |
302 |
| - args = "\n".join([ |
303 |
| - f'source {shlex.quote(str(activate_path))}', |
304 |
| - f"PS1={_quoted(new_ps1)}"]) |
305 |
| - |
306 |
| - # we will use [input] for testing: we will send a command to the stdin |
307 |
| - # of the interactive sub-shell and later check whether the command was |
308 |
| - # executed. |
309 |
| - # |
310 |
| - # We will also provide [input_delay] parameter. This allows the check |
311 |
| - # whether |
312 |
| - # the sub-shell was really interactive: did it wait for the input |
313 |
| - # |
314 |
| - # Surprisingly, the sub-shell will immediately close after executing |
315 |
| - # the command. It seems it closes immediately after the subprocess. |
316 |
| - # Popen closes the stdin. So it will not wait for "exit". But it serves |
317 |
| - # the task well |
318 |
| - |
319 |
| - cp = run_as_bash_script( |
320 |
| - args, |
321 |
| - executable=executable, |
322 |
| - input=input.encode() if input else None, |
323 |
| - input_delay=input_delay, |
324 |
| - env=child_env(dirs.project_dir)) |
325 |
| - |
326 |
| - # the vien will return the same exit code as the shell returned |
327 |
| - raise ChildExit(cp.returncode) |
| 264 | + # we use [input] for testing: we send a command to the stdin of the |
| 265 | + # interactive sub-shell and later check whether the command was |
| 266 | + # executed. |
| 267 | + # |
| 268 | + # We will also provide [input_delay] parameter. This allows the check |
| 269 | + # whether the sub-shell was really interactive: did it wait for |
| 270 | + # the input |
| 271 | + # |
| 272 | + # Surprisingly, the sub-shell will immediately close after executing |
| 273 | + # the command. It seems it closes immediately after the subprocess. |
| 274 | + # Popen closes the stdin. So it will not wait for "exit". But it serves |
| 275 | + # the task well |
| 276 | + |
| 277 | + cp = start_bash_shell(init_commands=[ |
| 278 | + f'source {shlex.quote(str(activate_path))}', |
| 279 | + f"PS1={_quoted(new_ps1)}"], |
| 280 | + input=input, |
| 281 | + input_delay=input_delay, |
| 282 | + env=child_env(dirs.project_dir) |
| 283 | + ) |
| 284 | + |
| 285 | + # the vien will return the same exit code as the shell returned |
| 286 | + raise ChildExit(cp.returncode) |
328 | 287 |
|
329 | 288 |
|
330 | 289 | def bash_args_to_str(args: List[str]) -> str:
|
|
0 commit comments