mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 05:17:15 +00:00
refactor(desktop): find vswhere through hermes_platform
Review (#141651): _msvc_identity hand-wrote the vswhere.exe install path, which is the known-path table the hermes_platform rule keeps in one place. Add visual_studio_installer_dirs() to resolver/known_dirs.py and locate vswhere with locate_command (PATH first, then the installer directory). Return None explicitly when vswhere reports no installations, before selecting the newest instance. Warn on stderr with the reason whenever MSVC identity detection returns None: missing vswhere, no matching installations, or a failed probe/version read.
This commit is contained in:
3 files changed
+28
-6
No files matched your search
@@ -85,6 +85,11 @@ def windows_user_program_dirs() -> tuple[str, ...]:
|
||||
)
|
||||
|
||||
|
||||
def visual_studio_installer_dirs() -> tuple[str, ...]:
|
||||
"""Where the Visual Studio installer puts vswhere.exe; it is never on PATH."""
|
||||
return ("%ProgramFiles(x86)%/Microsoft Visual Studio/Installer",) if _WIN else ()
|
||||
|
||||
|
||||
def mac_application_dirs() -> tuple[str, ...]:
|
||||
return ("/Applications", "~/Applications") if sys.platform == "darwin" else ()
|
||||
|
||||
|
||||
@@ -127,18 +127,29 @@ def prepare_tools(source: Path, work: Path, cache: Path,
|
||||
|
||||
def _msvc_identity() -> dict[str, str] | None:
|
||||
"""The newest VC toolset vswhere reports, with its default tools version."""
|
||||
vswhere = Path(os.environ.get("ProgramFiles(x86)", r"C:\Program Files (x86)"),
|
||||
"Microsoft Visual Studio/Installer/vswhere.exe")
|
||||
from hermes_platform.resolver import locate_command
|
||||
from hermes_platform.resolver.known_dirs import visual_studio_installer_dirs
|
||||
|
||||
vswhere = locate_command("vswhere.exe", known_dirs=visual_studio_installer_dirs())
|
||||
if not vswhere.found:
|
||||
print("warning: MSVC cache identity unavailable: vswhere.exe was not found", file=sys.stderr, flush=True)
|
||||
return None
|
||||
try:
|
||||
result = subprocess.run([str(vswhere), "-latest", "-products", "*", "-requires",
|
||||
result = subprocess.run([*vswhere.command, "-latest", "-products", "*", "-requires",
|
||||
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "-format", "json"],
|
||||
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
||||
timeout=30, stdin=subprocess.DEVNULL, check=False)
|
||||
instance = json.loads(result.stdout or "[]")[0]
|
||||
instances = json.loads(result.stdout or "[]")
|
||||
if not instances:
|
||||
print("warning: MSVC cache identity unavailable: vswhere found no matching installations",
|
||||
file=sys.stderr, flush=True)
|
||||
return None
|
||||
instance = instances[0]
|
||||
tools = Path(instance["installationPath"], "VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt")
|
||||
return {"installationVersion": instance["installationVersion"],
|
||||
"VCToolsVersion": tools.read_text(encoding="utf-8").strip()}
|
||||
except (OSError, subprocess.TimeoutExpired, ValueError, IndexError, KeyError):
|
||||
except (OSError, subprocess.TimeoutExpired, ValueError, IndexError, KeyError) as error:
|
||||
print(f"warning: MSVC cache identity unavailable: {error}", file=sys.stderr, flush=True)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@@ -308,9 +308,15 @@ def test_native_cache_is_stable_without_a_developer_environment(tmp_path, monkey
|
||||
version_file.parent.mkdir(parents=True)
|
||||
version_file.write_text("14.44.35207\n", encoding="utf-8")
|
||||
vswhere = json.dumps([{"installationPath": str(install), "installationVersion": "17.14.1"}])
|
||||
# vswhere is never on PATH; hermes_platform finds it in the installer directory.
|
||||
installer = tmp_path / "Program Files (x86)/Microsoft Visual Studio/Installer"
|
||||
installer.mkdir(parents=True)
|
||||
(installer / "vswhere.exe").write_bytes(b"")
|
||||
monkeypatch.setenv("ProgramFiles(x86)", str(tmp_path / "Program Files (x86)"))
|
||||
monkeypatch.setenv("PATH", "")
|
||||
|
||||
def probe(command, **kwargs):
|
||||
stdout = vswhere if command[0].endswith("vswhere.exe") else "rustc 1.98.0"
|
||||
stdout = vswhere if command[0] == str(installer / "vswhere.exe") else "rustc 1.98.0"
|
||||
return SimpleNamespace(returncode=0, stdout=stdout, stderr="")
|
||||
|
||||
desktop_toolchain.platform.platform()
|
||||
|
||||
Reference in new issue
Block a user