| import os | |
| import sys | |
| import json | |
| import subprocess | |
| import argparse | |
| import shutil | |
| import platform | |
| CONFIG_PATH = "setup_config.json" | |
| ENVS_FILE = "envs.json" | |
| IS_WIN = os.name == 'nt' | |
| ENV_TEMPLATES = { | |
| "uv": { | |
| "create": "uv venv --python {ver} \"{dir}\"", | |
| "run": os.path.join("{dir}", "Scripts", "python.exe") if IS_WIN else os.path.join("{dir}", "bin", "python"), | |
| "install": (os.path.join("{dir}", "Scripts", "python.exe") if IS_WIN else os.path.join("{dir}", "bin", "python")) + " -m uv pip install" | |
| }, | |
| "venv": { | |
| "create": "{sys_py} -m venv \"{dir}\"", | |
| "run": os.path.join("{dir}", "Scripts", "python.exe") if IS_WIN else os.path.join("{dir}", "bin", "python"), | |
| "install": (os.path.join("{dir}", "Scripts", "python.exe") if IS_WIN else os.path.join("{dir}", "bin", "python")) + " -m pip install" | |
| }, | |
| "conda": { | |
| "create": "conda create -y -p \"{dir}\" python={ver}", | |
| "run": "conda run -p \"{dir}\" python", | |
| "install": "conda run -p \"{dir}\" pip install" | |
| }, | |
| "none": { | |
| "create": "", | |
| "run": "python" if IS_WIN else "python3", | |
| "install": "pip install" | |
| } | |
| } | |
| VERSION_CHECK_SCRIPT = """ | |
| import sys | |
| import importlib | |
| import importlib.metadata | |
| pkgs = ['torch', 'triton', 'sageattention', 'flash_attn'] | |
| res = [] | |
| try: | |
| res.append(f"python={sys.version.split()[0]}") | |
| except: | |
| res.append("python=Unknown") | |
| for p in pkgs: | |
| try: | |
| ver = importlib.metadata.version(p) | |
| res.append(f"{p}={ver}") | |
| except importlib.metadata.PackageNotFoundError: | |
| try: | |
| # Fallback to __version__ | |
| m = importlib.import_module(p) | |
| ver = getattr(m, '__version__', 'Installed') | |
| res.append(f"{p}={ver}") | |
| except ImportError: | |
| res.append(f"{p}=Missing") | |
| except Exception: | |
| res.append(f"{p}=Error") | |
| print("||".join(res)) | |
| """ | |
| class EnvsManager: | |
| def __init__(self): | |
| self.data = {"active": None, "envs": {}} | |
| self.load() | |
| def load(self): | |
| if os.path.exists(ENVS_FILE): | |
| try: | |
| with open(ENVS_FILE, 'r') as f: | |
| self.data = json.load(f) | |
| except: | |
| print(f"[!] Warning: {ENVS_FILE} corrupted. Starting fresh.") | |
| def save(self): | |
| with open(ENVS_FILE, 'w') as f: | |
| json.dump(self.data, f, indent=4) | |
| def get_active(self): | |
| return self.data.get("active") | |
| def set_active(self, name): | |
| if name in self.data["envs"]: | |
| self.data["active"] = name | |
| self.save() | |
| print(f"[*] '{name}' is now the active environment.") | |
| else: | |
| print(f"[!] Environment '{name}' not found.") | |
| def add_env(self, name, type, path): | |
| self.data["envs"][name] = {"type": type, "path": path} | |
| if not self.data["active"]: | |
| self.data["active"] = name | |
| self.save() | |
| def remove_env(self, name): | |
| if name in self.data["envs"]: | |
| entry = self.data["envs"][name] | |
| path = entry["path"] | |
| if os.path.exists(path) and entry["type"] != "none": | |
| try: | |
| print(f"[*] Deleting directory: {path}") | |
| if entry["type"] == "conda": | |
| run_cmd(f"conda env remove -p \"{path}\" -y") | |
| else: | |
| shutil.rmtree(path) | |
| except Exception as e: | |
| print(f"[!] Error removing directory: {e}") | |
| del self.data["envs"][name] | |
| if self.data["active"] == name: | |
| self.data["active"] = None | |
| keys = list(self.data["envs"].keys()) | |
| if keys: | |
| self.data["active"] = keys[0] | |
| print(f"[*] Active environment switched to '{keys[0]}'.") | |
| else: | |
| print("[*] No environments left.") | |
| self.save() | |
| def list_envs(self): | |
| return self.data["envs"] | |
| def resolve_target_env(self): | |
| """Intelligently determine which env to use for operations.""" | |
| envs = self.list_envs() | |
| if not envs: | |
| print("[!] No environments found. Please run install first.") | |
| sys.exit(1) | |
| active = self.get_active() | |
| if len(envs) == 1: | |
| return list(envs.keys())[0] | |
| print("\nMultiple environments detected:") | |
| keys = list(envs.keys()) | |
| for i, k in enumerate(keys): | |
| marker = "*" if k == active else " " | |
| print(f"{i+1}. [{marker}] {k} ({envs[k]['type']})") | |
| print(f"Default: {active}") | |
| choice = input("Select environment (Number) or Press Enter for Default: ").strip() | |
| if choice == "": | |
| return active | |
| try: | |
| idx = int(choice) - 1 | |
| if 0 <= idx < len(keys): | |
| return keys[idx] | |
| except: | |
| pass | |
| return active | |
| def load_config(): | |
| if not os.path.exists(CONFIG_PATH): | |
| print(f"Error: {CONFIG_PATH} not found.") | |
| sys.exit(1) | |
| with open(CONFIG_PATH, 'r') as f: return json.load(f) | |
| def get_gpu_info(): | |
| try: | |
| name = subprocess.check_output( | |
| ["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"], | |
| encoding='utf-8', | |
| stderr=subprocess.DEVNULL | |
| ).strip() | |
| return name, "NVIDIA" | |
| except: pass | |
| if IS_WIN: | |
| try: | |
| name = subprocess.check_output( | |
| "wmic path win32_VideoController get name", | |
| shell=True, | |
| encoding='utf-8', | |
| stderr=subprocess.DEVNULL | |
| ) | |
| name = name.replace("Name", "").strip().split('\n')[0].strip() | |
| if "Radeon" in name or "AMD" in name: return name, "AMD" | |
| return name, "INTEL" | |
| except: pass | |
| else: | |
| try: | |
| name = subprocess.check_output( | |
| "lspci | grep -i vga", | |
| shell=True, | |
| encoding='utf-8', | |
| stderr=subprocess.DEVNULL | |
| ) | |
| if "NVIDIA" in name: return name, "NVIDIA" | |
| if "AMD" in name or "Advanced Micro Devices" in name: return name, "AMD" | |
| except: pass | |
| return "Unknown", "UNKNOWN" | |
| def get_profile_key(gpu_name, vendor): | |
| g = gpu_name.upper() | |
| if vendor == "NVIDIA": | |
| if "50" in g: return "RTX_50" | |
| if "40" in g: return "RTX_40" | |
| if "30" in g: return "RTX_30" | |
| if "20" in g or "QUADRO" in g: return "RTX_20" | |
| return "GTX_10" | |
| elif vendor == "AMD": | |
| if any(x in g for x in ["7600", "7700", "7800", "7900"]): return "AMD_GFX110X" | |
| if any(x in g for x in ["7000", "Z1", "PHOENIX"]): return "AMD_GFX1151" | |
| if any(x in g for x in ["8000", "STRIX", "1201"]): return "AMD_GFX1201" | |
| return "AMD_GFX110X" | |
| return "RTX_40" | |
| def get_os_key(): | |
| return "win" if IS_WIN else "linux" | |
| def resolve_cmd(cmd_entry): | |
| if isinstance(cmd_entry, dict): | |
| return cmd_entry.get(get_os_key()) | |
| return cmd_entry | |
| def run_cmd(cmd, env_vars=None): | |
| if not cmd: return | |
| if "&&" in cmd and not IS_WIN: | |
| print(f"\n>>> Running (Shell): {cmd}") | |
| custom_env = os.environ.copy() | |
| if env_vars: custom_env.update(env_vars) | |
| subprocess.run(cmd, shell=True, check=True, env=custom_env) | |
| return | |
| print(f"\n>>> Running: {cmd}") | |
| custom_env = os.environ.copy() | |
| if env_vars: | |
| for k, v in env_vars.items(): | |
| print(f" [ENV SET] {k}={v}") | |
| custom_env[k] = v | |
| subprocess.run(cmd, shell=True, check=True, env=custom_env) | |
| def get_env_details(name, env_data): | |
| env_type = env_data["type"] | |
| dir_name = env_data["path"] | |
| entry = ENV_TEMPLATES[env_type] | |
| if env_type == "conda": | |
| cmd_base = entry['run'].format(dir=dir_name) | |
| full_cmd = f"{cmd_base} -c \"{VERSION_CHECK_SCRIPT.replace(chr(10), ';')}\"" | |
| else: | |
| py_exec = entry['run'].format(dir=dir_name) | |
| full_cmd = [py_exec, "-c", VERSION_CHECK_SCRIPT] | |
| try: | |
| if env_type == "conda": | |
| output = subprocess.check_output(full_cmd, shell=True, encoding='utf-8', stderr=subprocess.DEVNULL) | |
| else: | |
| output = subprocess.check_output(full_cmd, encoding='utf-8', stderr=subprocess.DEVNULL) | |
| data = {k: v for k, v in [x.split('=') for x in output.strip().split('||')]} | |
| data['path'] = dir_name | |
| data['type'] = env_type | |
| return data | |
| except Exception as e: | |
| return {'error': str(e), 'type': env_type, 'path': dir_name} | |
| def show_status(): | |
| manager = EnvsManager() | |
| print("\n" + "="*95) | |
| print(f"{'INSTALLED ENVIRONMENTS & VERSIONS':^95}") | |
| print("="*95) | |
| envs = manager.list_envs() | |
| active = manager.get_active() | |
| if not envs: | |
| print(" No environments installed.") | |
| print("="*95) | |
| return | |
| print(f"{'NAME':<15} | {'TYPE':<6} | {'PYTHON':<8} | {'TORCH':<15} | {'TRITON':<10} | {'SAGE':<12} | {'FLASH':<12}") | |
| print("-" * 95) | |
| for name, data in envs.items(): | |
| details = get_env_details(name, data) | |
| marker = "*" if name == active else " " | |
| display_name = f"[{marker}] {name}" | |
| if 'error' in details: | |
| print(f"{display_name:<15} | {data['type']:<6} | [Error reading environment]") | |
| continue | |
| print(f"{display_name:<15} | {data['type']:<6} | " | |
| f"{details.get('python','?'):<8} | " | |
| f"{details.get('torch','?'):<15} | " | |
| f"{details.get('triton','?'):<10} | " | |
| f"{details.get('sageattention','?'):<12} | " | |
| f"{details.get('flash_attn','?'):<12}") | |
| print("-" * 95) | |
| print(f" * = Active Environment") | |
| print("="*95 + "\n") | |
| def install_logic(env_name, env_type, env_path, py_k, torch_k, triton_k, sage_k, flash_k, kernel_list, config): | |
| template = ENV_TEMPLATES[env_type] | |
| target_py_ver = config['components']['python'][py_k]['ver'] | |
| print(f"\n[1/3] Preparing Environment: {env_name} ({env_type})...") | |
| if env_type != "none": | |
| create_cmd = template["create"].format(ver=target_py_ver, dir=env_path, sys_py=sys.executable) | |
| if create_cmd: | |
| run_cmd(create_cmd) | |
| pip = template["install"].format(dir=env_path) | |
| print(f"\n[2/3] Installing Torch: {config['components']['torch'][torch_k]['label']}...") | |
| torch_cmd = resolve_cmd(config['components']['torch'][torch_k]['cmd']) | |
| run_cmd(f"{pip} {torch_cmd}") | |
| print(f"\n[3/3] Installing Requirements & Extras...") | |
| run_cmd(f"{pip} -r requirements.txt") | |
| if triton_k: | |
| cmd = resolve_cmd(config['components']['triton'][triton_k]['cmd']) | |
| if cmd: run_cmd(f"{pip} {cmd}") | |
| if sage_k: | |
| cmd = resolve_cmd(config['components']['sage'][sage_k]['cmd']) | |
| if cmd.startswith("http") or cmd.startswith("sageattention"): | |
| run_cmd(f"{pip} {cmd}") | |
| else: | |
| if env_type == "venv" or env_type == "uv": | |
| act = f". {env_path}/bin/activate && " if not IS_WIN else "" | |
| run_cmd(f"{act}{cmd}") | |
| elif env_type == "conda": | |
| pass | |
| if flash_k: | |
| cmd = resolve_cmd(config['components']['flash'][flash_k]['cmd']) | |
| if cmd: run_cmd(f"{pip} {cmd}") | |
| for k in kernel_list: | |
| if k in config['components']['kernels']: | |
| cmd = resolve_cmd(config['components']['kernels'][k]['cmd']) | |
| if cmd: run_cmd(f"{pip} {cmd}") | |
| def menu(title, options, recommended_key=None): | |
| print(f"\n--- {title} ---") | |
| keys = list(options.keys()) | |
| for i, k in enumerate(keys): | |
| rec = " [RECOMMENDED FOR YOUR GPU]" if k == recommended_key else "" | |
| print(f"{i+1}. {options[k]['label']}{rec}") | |
| choice = input(f"Select option (Enter for Recommended): ") | |
| if choice == "" and recommended_key: return recommended_key | |
| try: return keys[int(choice)-1] | |
| except: return recommended_key | |
| def do_install_interactive(env_type, config, detected_key): | |
| manager = EnvsManager() | |
| create_wgp_config(detected_key, config) | |
| default_name = f"env_{env_type}" if env_type != "none" else "system" | |
| print(f"\n--- Configuration for {env_type} ---") | |
| name = input(f"Enter a name for this environment (Default: {default_name}): ").strip() | |
| if not name: name = default_name | |
| cwd = os.getcwd() | |
| path = os.path.join(cwd, name) if env_type != "none" else "" | |
| if name in manager.list_envs(): | |
| print(f"\n[!] Warning: Environment '{name}' already exists in registry.") | |
| choice = input("Do you want to overwrite it? (This will delete the old folder) [y/N]: ").lower() | |
| if choice != 'y': return | |
| manager.remove_env(name) | |
| elif os.path.exists(path) and env_type != "none": | |
| print(f"\n[!] Warning: Directory '{path}' exists but is not registered.") | |
| choice = input("Do you want to overwrite this directory? [y/N]: ").lower() | |
| if choice != 'y': return | |
| try: shutil.rmtree(path) | |
| except: pass | |
| print("\n--- Select Install Mode ---") | |
| print("1. Autoselect (Recommended - Based on your card)") | |
| print("2. Manual Selection (Custom versions)") | |
| print("3. Use Latest (Forces RTX 50 Profile)") | |
| mode = input("Select option (1-3) [Default: 1]: ").strip() | |
| if mode == "2": | |
| base = config['gpu_profiles'][detected_key] | |
| py_k = menu("Python Version", config['components']['python'], base['python']) | |
| torch_k = menu("Torch Version", config['components']['torch'], base['torch']) | |
| triton_k = menu("Triton", config['components']['triton'], base['triton']) | |
| sage_k = menu("Sage Attention", config['components']['sage'], base['sage']) | |
| flash_k = menu("Flash Attention", config['components']['flash'], base['flash']) | |
| kernels = base['kernels'] | |
| install_logic(name, env_type, path, py_k, torch_k, triton_k, sage_k, flash_k, kernels, config) | |
| elif mode == "3": | |
| p = config['gpu_profiles']['RTX_50'] | |
| install_logic(name, env_type, path, p['python'], p['torch'], p['triton'], p['sage'], p.get('flash'), p['kernels'], config) | |
| else: | |
| p = config['gpu_profiles'][detected_key] | |
| install_logic(name, env_type, path, p['python'], p['torch'], p['triton'], p['sage'], p.get('flash'), p['kernels'], config) | |
| manager.add_env(name, env_type, path) | |
| if len(manager.list_envs()) > 1: | |
| choice = input(f"\nDo you want to make '{name}' the active environment? [Y/n]: ").lower() | |
| if choice != 'n': | |
| manager.set_active(name) | |
| else: | |
| print(f"\n[*] '{name}' is the only environment, setting as active.") | |
| manager.set_active(name) | |
| def do_manage(): | |
| manager = EnvsManager() | |
| while True: | |
| os.system('cls' if IS_WIN else 'clear') | |
| print("======================================================") | |
| print(" ENVIRONMENT MANAGER") | |
| print("======================================================") | |
| envs = manager.list_envs() | |
| active = manager.get_active() | |
| if not envs: | |
| print(" No environments installed.") | |
| else: | |
| for name, data in envs.items(): | |
| status = "(Active)" if name == active else "" | |
| print(f" - {name:<15} [{data['type']}] {status}") | |
| print("------------------------------------------------------") | |
| print("1. Set Active Environment") | |
| print("2. Delete Environment") | |
| print("3. Add Existing Environment") | |
| print("4. List Environment Details") | |
| print("5. Return to Menu / Exit") | |
| choice = input("\nSelect option: ") | |
| if choice == "1": | |
| name = input("Enter name of environment to activate: ") | |
| manager.set_active(name) | |
| input("Press Enter...") | |
| elif choice == "2": | |
| name = input("Enter name of environment to DELETE: ") | |
| conf = input(f"Are you sure you want to delete '{name}' and its files? (y/n): ") | |
| if conf.lower() == 'y': | |
| manager.remove_env(name) | |
| input("Deleted. Press Enter...") | |
| elif choice == "3": | |
| path = input("Enter the path to the existing environment folder: ").strip() | |
| if not os.path.exists(path): | |
| print("[!] Error: Path does not exist.") | |
| else: | |
| name = input("Enter a nickname for this environment: ").strip() | |
| if not name: name = os.path.basename(path.rstrip(os.sep)) | |
| print("\nSelect Environment Type:") | |
| print("1. venv") | |
| print("2. uv") | |
| print("3. conda") | |
| t_choice = input("Choice (Default 1): ") | |
| e_type = "uv" if t_choice == "2" else "conda" if t_choice == "3" else "venv" | |
| manager.add_env(name, e_type, os.path.abspath(path)) | |
| print(f"[*] Registered '{name}' at {os.path.abspath(path)}") | |
| input("Press Enter...") | |
| elif choice == "4": | |
| show_status() | |
| input("Press Enter...") | |
| elif choice == "5": | |
| break | |
| def do_migrate(config): | |
| manager = EnvsManager() | |
| print("\n" + "="*60) | |
| print(" WAN2GP AUTOMATED PLATFORM MIGRATION (TO 3.11)") | |
| print("="*60) | |
| env_name = manager.resolve_target_env() | |
| env_data = manager.list_envs()[env_name] | |
| print(f"\nTarget Environment: {env_name} ({env_data['type']})") | |
| confirm = input(f"This will wipe '{env_name}' and rebuild it. Proceed? (y/n): ") | |
| if confirm.lower() != 'y': return | |
| target = config['gpu_profiles']['RTX_50'] | |
| manager.remove_env(env_name) | |
| install_logic(env_name, env_data['type'], env_data['path'], | |
| target['python'], target['torch'], target['triton'], | |
| target['sage'], target.get('flash'), target['kernels'], config) | |
| manager.add_env(env_name, env_data['type'], env_data['path']) | |
| def do_upgrade(config): | |
| manager = EnvsManager() | |
| print("\n" + "="*60) | |
| print(" WAN2GP MANUAL COMPONENT UPGRADE") | |
| print("="*60) | |
| env_name = manager.resolve_target_env() | |
| env_data = manager.list_envs()[env_name] | |
| gpu_name, vendor = get_gpu_info() | |
| rec = config['gpu_profiles'][get_profile_key(gpu_name, vendor)] | |
| py_k = menu("Python Version", config['components']['python'], rec['python']) | |
| torch_k = menu("Torch Version", config['components']['torch'], rec['torch']) | |
| triton_k = menu("Triton", config['components']['triton'], rec['triton']) | |
| sage_k = menu("Sage Attention", config['components']['sage'], rec['sage']) | |
| flash_k = menu("Flash Attention", config['components']['flash'], rec['flash']) | |
| install_logic(env_name, env_data['type'], env_data['path'], py_k, torch_k, triton_k, sage_k, flash_k, rec['kernels'], config) | |
| def get_system_specs(): | |
| ram_gb = 0 | |
| vram_gb = 0 | |
| if IS_WIN: | |
| try: | |
| out = subprocess.check_output( | |
| ["powershell", "-NoProfile", "-Command", "(Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory"], | |
| encoding='utf-8', stderr=subprocess.DEVNULL | |
| ).strip() | |
| if out: | |
| ram_gb = int(out) / (1024**3) | |
| except: | |
| try: | |
| out = subprocess.check_output( | |
| "wmic computersystem get TotalPhysicalMemory /value", | |
| shell=True, encoding='utf-8', stderr=subprocess.DEVNULL | |
| ) | |
| for line in out.splitlines(): | |
| if "TotalPhysicalMemory=" in line: | |
| ram_gb = int(line.split('=')[1]) / (1024**3) | |
| break | |
| except: | |
| pass | |
| else: | |
| try: | |
| with open('/proc/meminfo', 'r') as f: | |
| for line in f: | |
| if 'MemTotal' in line: | |
| kb_val = float(line.split()[1]) | |
| ram_gb = kb_val / (1024**2) | |
| break | |
| except: pass | |
| if ram_gb == 0: | |
| print("[!] Warning: Could not detect System RAM. Defaulting to 16GB.") | |
| ram_gb = 16 | |
| try: | |
| out = subprocess.check_output( | |
| ["nvidia-smi", "--query-gpu=memory.total", "--format=csv,noheader,nounits"], | |
| encoding='utf-8', stderr=subprocess.DEVNULL | |
| ).strip() | |
| vram_gb = float(out.split('\n')[0]) / 1024 | |
| except: | |
| print("[!] Warning: Could not detect VRAM via nvidia-smi. Defaulting to 8GB.") | |
| vram_gb = 8 | |
| return ram_gb, vram_gb | |
| def create_wgp_config(profile_key, config_data): | |
| WGP_CONFIG_FILE = "wgp_config.json" | |
| if os.path.exists(WGP_CONFIG_FILE): | |
| return | |
| print("\n[*] Auto-generating wgp_config.json based on hardware...") | |
| ram, vram = get_system_specs() | |
| print(f" Detected: {int(ram)}GB RAM / {int(vram)}GB VRAM") | |
| has_high_ram = ram > 60 | |
| has_mid_ram = ram > 30 | |
| has_huge_vram = vram > 22 | |
| has_high_vram = vram > 11 | |
| pid = 5 | |
| if has_high_ram and has_huge_vram: | |
| pid = 1 | |
| elif has_high_ram: | |
| pid = 2 | |
| elif has_mid_ram and has_huge_vram: | |
| pid = 3 | |
| elif has_mid_ram and has_high_vram: | |
| pid = 4 | |
| else: | |
| pid = 5 | |
| prof_settings = config_data['gpu_profiles'].get(profile_key, {}) | |
| attn_mode = "" | |
| if "50" in profile_key or "40" in profile_key or "30" in profile_key: | |
| attn_mode = "sage2" | |
| elif "20" in profile_key: | |
| attn_mode = "sage" | |
| compile_mode = "" | |
| triton_key = prof_settings.get('triton') | |
| if triton_key and triton_key != "none": | |
| compile_mode = "transformer" | |
| config_out = { | |
| "attention_mode": attn_mode, | |
| "compile": compile_mode, | |
| "video_profile": pid, | |
| "image_profile": pid, | |
| "audio_profile": pid, | |
| } | |
| try: | |
| with open(WGP_CONFIG_FILE, 'w') as f: | |
| json.dump(config_out, f, indent=4) | |
| print(f" Created config with Profile {pid}, Attention: '{attn_mode}', Compile: '{compile_mode}'") | |
| except Exception as e: | |
| print(f"[!] Error writing config: {e}") | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("mode", choices=["install", "run", "update", "migrate", "upgrade", "status", "manage"]) | |
| parser.add_argument("--env", default="venv", help="Type of env for install (venv, uv, conda, none)") | |
| args = parser.parse_args() | |
| cfg = load_config() | |
| if args.mode == "status": | |
| show_status() | |
| sys.exit(0) | |
| if args.mode == "manage": | |
| do_manage() | |
| sys.exit(0) | |
| gpu_name, vendor = get_gpu_info() | |
| profile_key = get_profile_key(gpu_name, vendor) | |
| profile = cfg['gpu_profiles'][profile_key] | |
| if args.mode == "install": | |
| print(f"Hardware Detected: {gpu_name} ({vendor})") | |
| do_install_interactive(args.env, cfg, profile_key) | |
| elif args.mode == "run": | |
| manager = EnvsManager() | |
| active = manager.get_active() | |
| if not active: | |
| print("[!] No active environment found. Run install or manage.") | |
| sys.exit(1) | |
| env_data = manager.list_envs().get(active) | |
| if not env_data: | |
| print(f"[!] Active environment '{active}' data missing from registry.") | |
| sys.exit(1) | |
| print(f"[*] Launching using active environment: {active}") | |
| extra_args = "" | |
| if os.path.exists("scripts/args.txt"): | |
| with open("scripts/args.txt", "r") as f: | |
| lines = [l.strip() for l in f.readlines() if l.strip() and not l.startswith("#")] | |
| extra_args = " ".join(lines) | |
| env_vars = profile.get("env", {}) | |
| cmd_fmt = ENV_TEMPLATES[env_data['type']]['run'] | |
| cmd = f"{cmd_fmt.format(dir=env_data['path'])} wgp.py {extra_args}" | |
| run_cmd(cmd, env_vars=env_vars) | |
| elif args.mode == "update": | |
| run_cmd("git pull") | |
| manager = EnvsManager() | |
| env_name = manager.resolve_target_env() | |
| env_data = manager.list_envs()[env_name] | |
| cmd_fmt = ENV_TEMPLATES[env_data['type']]['run'] | |
| cmd = f"{cmd_fmt.format(dir=env_data['path'])} -m pip install -r requirements.txt" | |
| run_cmd(cmd) | |
| elif args.mode == "migrate": | |
| do_migrate(cfg) | |
| elif args.mode == "upgrade": | |
| do_upgrade(cfg) |