|
4 | 4 | import os
|
5 | 5 | import subprocess
|
6 | 6 | import sys
|
| 7 | +import tempfile |
7 | 8 |
|
8 | 9 | def is_wsl():
|
9 |
| - try: |
10 |
| - with open("/proc/version", "r") as f: |
11 |
| - return "microsoft" in f.read().lower() |
12 |
| - except FileNotFoundError: |
13 |
| - return False |
14 |
| - |
15 |
| -def find_activate(): |
16 |
| - cwd = os.getcwd() |
17 |
| - for root, dirs, files in os.walk(cwd): |
18 |
| - if 'bin' in dirs: |
19 |
| - activate_path = os.path.join(root, 'bin', 'activate') |
20 |
| - if os.path.isfile(activate_path): |
21 |
| - return activate_path |
22 |
| - return None |
23 |
| - |
24 |
| -def activate_virtualenv(): |
25 |
| - activate_path = find_activate() |
26 |
| - if activate_path: |
27 |
| - print(f"Found activation script at: {activate_path}") |
28 |
| - shell = os.environ.get("SHELL", "/bin/bash") |
29 |
| - subprocess.run(f"exec {shell} --rcfile {activate_path}", shell=True) |
30 |
| - else: |
31 |
| - print("No virtual environment activation script found in the current directory or its subdirectories.") |
32 |
| - sys.exit(1) |
| 10 | + try: |
| 11 | + with open("/proc/version", "r") as f: |
| 12 | + return "microsoft" in f.read().lower() |
| 13 | + except FileNotFoundError: |
| 14 | + return False |
| 15 | + |
| 16 | +def find_all_venvs(): |
| 17 | + # Search for virtual environments in the user's WSL home directory |
| 18 | + home_dir = os.path.expanduser("~") |
| 19 | + venvs = [] |
| 20 | + for root, dirs, files in os.walk(home_dir): |
| 21 | + if 'bin' in dirs: |
| 22 | + activate_path = os.path.join(root, 'bin', 'activate') |
| 23 | + if os.path.isfile(activate_path): |
| 24 | + venvs.append(root) |
| 25 | + return venvs |
| 26 | + |
| 27 | +def select_virtualenv(): |
| 28 | + venvs = find_all_venvs() |
| 29 | + if not venvs: |
| 30 | + print("No virtual environments found in your home directory.") |
| 31 | + input("Press Enter to exit...") |
| 32 | + sys.exit(1) |
| 33 | + |
| 34 | + print("Virtual environments found in your home directory:") |
| 35 | + for i, venv in enumerate(venvs, start=1): |
| 36 | + print(f"{i}. {venv}") |
| 37 | + |
| 38 | + try: |
| 39 | + choice = int(input("Select the number of the virtual environment you want to activate: ")) |
| 40 | + if choice < 1 or choice > len(venvs): |
| 41 | + print("Invalid selection.") |
| 42 | + sys.exit(1) |
| 43 | + except ValueError: |
| 44 | + print("Please enter a valid number.") |
| 45 | + sys.exit(1) |
| 46 | + |
| 47 | + return venvs[choice - 1] |
| 48 | + |
| 49 | +def drop_to_shell(venv_path): |
| 50 | + # Prepare a temporary rcfile that sources the venv activation script, |
| 51 | + # echoes a message, and sets the prompt to display the venv name. |
| 52 | + activate_script = os.path.join(venv_path, "bin", "activate") |
| 53 | + venv_name = os.path.basename(venv_path) |
| 54 | + with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp: |
| 55 | + tmp.write(f'source "{activate_script}"\n') |
| 56 | + tmp.write('echo "The virtual environment is activated!"\n') |
| 57 | + # Set PS1 to include the virtual environment name (e.g., "(.venv)") |
| 58 | + tmp.write(f'export PS1="({venv_name}) \\u@\\h:\\w\\$ "\n') |
| 59 | + tmp_path = tmp.name |
| 60 | + print("\nDropping to an interactive shell. Type 'exit' to close the shell.") |
| 61 | + os.system(f"bash --rcfile {tmp_path} -i") |
| 62 | + os.remove(tmp_path) |
| 63 | + |
| 64 | +def main(): |
| 65 | + if not is_wsl(): |
| 66 | + print("This script must be run inside WSL2. Exiting...") |
| 67 | + sys.exit(1) |
| 68 | + |
| 69 | + # If not already in a virtual environment, let the user select one |
| 70 | + if sys.prefix == sys.base_prefix: |
| 71 | + selected_venv = select_virtualenv() |
| 72 | + venv_python = os.path.join(selected_venv, "bin", "python") |
| 73 | + if not os.path.exists(venv_python): |
| 74 | + print("Python interpreter not found in the selected virtual environment.") |
| 75 | + input("Press Enter to exit...") |
| 76 | + sys.exit(1) |
| 77 | + print("Re-launching the script with the virtual environment's interpreter...") |
| 78 | + os.execv(venv_python, [venv_python] + sys.argv) |
| 79 | + else: |
| 80 | + # We are already running inside a virtual environment. |
| 81 | + drop_to_shell(sys.prefix) |
33 | 82 |
|
34 | 83 | if __name__ == "__main__":
|
35 |
| - if not is_wsl(): |
36 |
| - print("This script must be run inside WSL2. Exiting...") |
37 |
| - sys.exit(1) |
38 |
| - |
39 |
| - activate_virtualenv() |
| 84 | + main() |
0 commit comments