SDT/scripts/diag.py
2026-03-01 20:52:56 -06:00

129 lines
4.3 KiB
Python

#!/usr/bin/env python3
import argparse
import json
import os
import platform
import shutil
import subprocess
import sys
from script_common import resolve_command
def run_capture(cmd):
try:
proc = subprocess.run(cmd, capture_output=True, text=True, check=False)
out = (proc.stdout or "").strip()
err = (proc.stderr or "").strip()
text = out if out else err
return proc.returncode == 0, text
except Exception as ex:
return False, str(ex)
def probe_tool(tool):
mapping = {
"dotnet": ["dotnet", "--version"],
"node": ["node", "--version"],
"npm": ["npm", "--version"],
"python": ["python", "--version"],
"cargo": ["cargo", "--version"],
"tauri": ["tauri", "--version"],
"git": ["git", "--version"],
"docker": ["docker", "--version"],
}
cmd = mapping.get(tool, [tool, "--version"])
resolved = resolve_command(cmd[0])
if shutil.which(resolved) is None and not os.path.exists(resolved):
return {"tool": tool, "available": False, "version": None, "details": f"{cmd[0]} not found in PATH"}
cmd = [resolved, *cmd[1:]]
ok, text = run_capture(cmd)
return {"tool": tool, "available": ok, "version": text if ok else None, "details": None if ok else text}
def install_plan(tool):
is_windows = platform.system().lower().startswith("win")
if is_windows:
plans = {
"dotnet": [("winget", ["install", "Microsoft.DotNet.SDK.10"])],
"node": [("winget", ["install", "OpenJS.NodeJS.LTS"])],
"npm": [("winget", ["install", "OpenJS.NodeJS.LTS"])],
"python": [("winget", ["install", "Python.Python.3.12"])],
"cargo": [("winget", ["install", "Rustlang.Rustup"])],
"tauri": [("npm", ["install", "-g", "@tauri-apps/cli"])],
"git": [("winget", ["install", "Git.Git"])],
"docker": [("winget", ["install", "Docker.DockerDesktop"])],
}
else:
plans = {
"dotnet": [("sh", ["-c", "echo install dotnet sdk with your package manager"])],
"node": [("sh", ["-c", "echo install nodejs with your package manager"])],
"npm": [("sh", ["-c", "echo install npm with your package manager"])],
"python": [("sh", ["-c", "echo install python3 with your package manager"])],
"cargo": [("sh", ["-c", "curl https://sh.rustup.rs -sSf | sh"])],
"tauri": [("npm", ["install", "-g", "@tauri-apps/cli"])],
"git": [("sh", ["-c", "echo install git with your package manager"])],
"docker": [("sh", ["-c", "echo install docker with your package manager"])],
}
cmds = plans.get(tool, [])
return {
"tool": tool,
"supported": len(cmds) > 0,
"summary": f"Install plan for {tool} on {platform.system()}",
"commands": [{"command": c, "args": a} for c, a in cmds],
}
def run_install(tool):
plan = install_plan(tool)
if not plan["supported"]:
return 2
for cmd in plan["commands"]:
proc = subprocess.run([cmd["command"], *cmd["args"]], check=False)
if proc.returncode != 0:
return proc.returncode
return 0
def main():
parser = argparse.ArgumentParser(description="SDT diagnostics and install planner")
sub = parser.add_subparsers(dest="cmd", required=True)
p_probe = sub.add_parser("probe")
p_probe.add_argument("--tool", required=True)
p_probe.add_argument("--json", action="store_true")
p_plan = sub.add_parser("install-plan")
p_plan.add_argument("--tool", required=True)
p_plan.add_argument("--json", action="store_true")
p_run = sub.add_parser("install-run")
p_run.add_argument("--tool", required=True)
args = parser.parse_args()
if args.cmd == "probe":
result = probe_tool(args.tool.lower())
if args.json:
print(json.dumps(result))
else:
print(result)
return 0 if result["available"] else 1
if args.cmd == "install-plan":
result = install_plan(args.tool.lower())
if args.json:
print(json.dumps(result))
else:
print(result)
return 0 if result["supported"] else 2
if args.cmd == "install-run":
return run_install(args.tool.lower())
return 1
if __name__ == "__main__":
sys.exit(main())