fix(windows): normalize MSYS Hermes environment paths - #93938
chrisluersen wants to merge 1 commit into
Conversation
git-bash/MSYS rewrites Win32 env vars to POSIX form when spawning native Python, so HERMES_HOME and LOCALAPPDATA arrive as /c/Users/... instead of C:/Users/... A bare Path() mangles the leading /c into a rooted relative path (\c\Users\...) pointing at a non-existent shadow tree, which breaks board enumeration and can create junk C:\c\... dirs. Add _normalize_msys_env_path() to convert only the intentional MSYS drive form /<ASCII drive letter>/... to <UPPER DRIVE>:/... on win32, applied at the three Path() construction sites for HERMES_HOME and LOCALAPPDATA. Native drive paths, UNC paths, custom root-relative paths, Unicode non-drive paths, a bare /c, and all non-Windows values pass through unchanged.
Nicely restrained fix: converting only the exact MSYS drive form (
No blocking issues. |
monerostar
left a comment
There was a problem hiding this comment.
Native Win11 + Git Bash verification from a live Hermes host (not CI).
Bug is real here. Unfixed Path("/c/Users/Admin/AppData/Local/hermes").resolve() lands on C:\c\Users\Admin\AppData\Local\hermes. That shadow tree already exists on this machine (created ~2026-07-17) with kanban.db (118784 bytes), cron/, sessions/, profiles/, etc. Current install hermes_constants.py still has no helper.
This patch works on this host. From the PR tree:
helper /c/Users/Admin/AppData/Local/hermes -> C:/Users/Admin/AppData/Local/hermes
get_process_hermes_home(HERMES_HOME=/c/Users/Admin/AppData/Local/hermes/profiles/main)
-> C:\Users\Admin\AppData\Local\hermes\profiles\main (exists, not the C:\c shadow)
python -m pytest tests/test_hermes_constants.py -k "Msys or msys or Normalization" -o addopts= → 13 passed on this Win11 box.
CI risk: several helper tests (test_direct_msys_hermes_home, lowercase-drive, native/UNC/passthrough-except-linux) do not monkeypatch sys.platform. On win32 they pass (as they did here). On Linux they call the helper which returns the input unchanged, so test_direct_msys_hermes_home would expect C:/Users/alex/... and get /c/Users/alex/.... gh pr checks currently reports no checks on this branch. Please pin sys.platform == "win32" on the conversion assertions (the process-home tests already do this).
Scope: converting only /<ascii letter>/... is the right narrow cut. Sibling #39910 is a much larger un-mangle (cygdrive/mnt + cron/logging). This PR is the smaller HERMES_HOME/LOCALAPPDATA fix; they should not both land as-is without a shared helper.
Nits already noted by the automated review: missing trailing newline in the test file; /cygdrive/c/... intentionally untouched (fine if git-bash-only).
Happy to re-run the focused tests after the platform guards land.
Native Win11 + git-bash verify (monerostar)Host: Windows 11 ( This is exactly the environment the PR describes. In this Hermes/cron process That shadow tree is not hypothetical on this machine: TestsAll conversion / passthrough / profile-unwrap / LOCALAPPDATA cases passed on native win32, including the linux monkeypatch passthrough. Notes (not blockers)
The bug is real here. The tests match the live pathlib behavior. |
|
Superseded by #115116 — same fix, rebased onto current |
What does this PR do?
Fixes
HERMES_HOME(andLOCALAPPDATA) path mangling when Hermes runs under git-bash / MSYS on Windows. MSYS rewrites Win32 env vars to POSIX form when spawning native Python, soHERMES_HOMEarrives as/c/Users/<user>/AppData/Local/hermesinstead ofC:/Users/<user>/.... A barePath(value)then mangles the leading/cinto a rooted relative path (\c\Users\...), silently pointing at a non-existent shadow tree — which breaks board enumeration and can create junkC:\c\...directories.Adds
_normalize_msys_env_path()tohermes_constants.py: on win32 only, it converts the intentional MSYS drive form/<ASCII drive letter>/...→<UPPER DRIVE>:/...beforePathconstruction. Native drive paths, UNC paths, custom root-relative paths, Unicode non-drive paths, a bare/c, and every non-Windows value pass through unchanged. Applied at the threePath()construction sites forHERMES_HOMEandLOCALAPPDATA(native default home, env-resolved home, andget_default_hermes_root()), preserving memoization and profile unwrapping.Related Issue
None (no issue opened; cross-platform compatibility fix).
Type of Change
Changes Made
hermes_constants.py— add_normalize_msys_env_path(); apply it at the three env-pathPath()sites (_get_platform_default_hermes_home,_hermes_home_from_env,get_default_hermes_root).tests/test_hermes_constants.py— 13 focused tests: direct MSYSHERMES_HOME; MSYS profile path resolving to the native root; MSYSLOCALAPPDATAwithHERMES_HOMEunset; native slash/backslash drive paths; UNC path;/custom/hermesand/é/not-a-drivepass-through; bare/cunchanged; non-Windows pass-through.How to Test
python -m pytest tests/test_hermes_constants.py -k "Msys or msys or normalize or Normalization" -q→13 passed, 66 deselected.ruff check hermes_constants.py tests/test_hermes_constants.py→ clean.HERMES_HOMEresolves to the correctC:\Users\...\AppData\Local\hermestree (no shadow\c\Users\...).Checklist
Code
fix(scope):)pytest tests/ -qand all tests pass — not fully run: the canonical full-suite run on this Windows host is non-diagnostic (untouched tests fail from missing async-test support, Pyright init timeouts, and Windows symlink privilege limits). Focusedtests/test_hermes_constants.pypasses green; ruff is clean.Documentation & Housekeeping
cli-config.yaml.exampleif config keys changed — N/A (no new config)Screenshots / Logs
N/A (no visual change).