import logging import multiprocessing as mp import os import shlex import stat import subprocess import sys from pathlib import Path from typing import Any, Callable, Dict, List, Optional import ipdb log = logging.getLogger(__name__) def command_exec(cmd: List[str], work_dir: Path, env: Dict[str, str]) -> None: subprocess.run(cmd, check=True, env=env, cwd=work_dir.resolve()) def repro_env_break( work_dir: Path, env: Optional[Dict[str, str]] = None, cmd: Optional[List[str]] = None, ) -> None: if env is None: env = os.environ.copy() else: env = env.copy() # Error checking if "bash" in env["SHELL"]: raise Exception("I assumed you use zsh, not bash") # Cmd appending args = ["xterm", "-e", "zsh", "-df"] if cmd is not None: mycommand = shlex.join(cmd) write_command(mycommand, work_dir / "cmd.sh") print(f"Adding to zsh history the command: {mycommand}", file=sys.stderr) proc = spawn_process(func=command_exec, cmd=args, work_dir=work_dir, env=env) try: ipdb.set_trace() finally: proc.terminate() def write_command(command: str, loc: Path) -> None: with open(loc, "w") as f: f.write("#!/usr/bin/env bash\n") f.write(command) st = os.stat(loc) os.chmod(loc, st.st_mode | stat.S_IEXEC) def spawn_process(func: Callable, **kwargs: Any) -> mp.Process: mp.set_start_method(method="spawn") proc = mp.Process(target=func, kwargs=kwargs) proc.start() return proc def dump_env(env: Dict[str, str], loc: Path) -> None: cenv = env.copy() with open(loc, "w") as f: f.write("#!/usr/bin/env bash\n") for k, v in cenv.items(): if v.count("\n") > 0 or v.count('"') > 0 or v.count("'") > 0: continue f.write(f"export {k}='{v}'\n") st = os.stat(loc) os.chmod(loc, st.st_mode | stat.S_IEXEC)