You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Windows CI tests fail repeatedly due to two Path.relative_to() pitfalls:
str(Path.relative_to()) produces backslashes on Windows — breaks string comparisons, stored paths, and test assertions
Path.relative_to() raises ValueError when Windows 8.3 short names (RUNNER~1) don't match .resolve()d long names (runneradmin)
We've been fixing these ad-hoc (PRs #410, #411) but have ~20+ call sites across the codebase with inconsistent handling. Need a systemic fix.
Proposed solution
1. Add a portable_relpath() utility function
Create a single helper in src/apm_cli/utils/paths.py that makes the correct pattern the easy pattern:
defportable_relpath(path: Path, base: Path) ->str:
"""Return a forward-slash relative path, resolving both sides first. Handles Windows 8.3 short names and ensures consistent POSIX output. Falls back to the absolute path string if path is not under base. """try:
returnpath.resolve().relative_to(base.resolve()).as_posix()
exceptValueError:
returnstr(path)
This centralizes the three-step pattern (.resolve() both sides → .relative_to() → .as_posix()) into one call that's impossible to get wrong.
2. Migrate all call sites (~23 locations)
Phase 1 (P0): str(path.relative_to()) without .as_posix() — ~9 locations
Add a grep-based check to CI that catches raw relative_to() → str() patterns:
# Fail if any new code uses str(x.relative_to(y)) instead of portable_relpath()! grep -rn 'str(.*\.relative_to(' src/apm_cli/ --include="*.py"| grep -v portable_relpath
This prevents backsliding without adding heavy tooling.
Notes
Integrator relative_to() calls need verification — some may be display-only (safe), others may feed into apm.lock.yaml keys (the lockfile write path already uses .as_posix())
Problem
Windows CI tests fail repeatedly due to two
Path.relative_to()pitfalls:str(Path.relative_to())produces backslashes on Windows — breaks string comparisons, stored paths, and test assertionsPath.relative_to()raisesValueErrorwhen Windows 8.3 short names (RUNNER~1) don't match.resolve()d long names (runneradmin)We've been fixing these ad-hoc (PRs #410, #411) but have ~20+ call sites across the codebase with inconsistent handling. Need a systemic fix.
Proposed solution
1. Add a
portable_relpath()utility functionCreate a single helper in
src/apm_cli/utils/paths.pythat makes the correct pattern the easy pattern:This centralizes the three-step pattern (
.resolve()both sides →.relative_to()→.as_posix()) into one call that's impossible to get wrong.2. Migrate all call sites (~23 locations)
Phase 1 (P0):
str(path.relative_to())without.as_posix()— ~9 locationssrc/apm_cli/compilation/context_optimizer.py:352src/apm_cli/compilation/agents_compiler.py:634,650src/apm_cli/security/gate.py:105src/apm_cli/integration/prompt_integrator.pysrc/apm_cli/integration/instruction_integrator.py:81src/apm_cli/integration/agent_integrator.py:164,179,188src/apm_cli/integration/hook_integrator.pysrc/apm_cli/integration/command_integrator.pyPhase 2 (P1):
relative_to()without.resolve()on both sides — ~12 locationssrc/apm_cli/compilation/context_optimizer.py:424,515,658,799,815,1115src/apm_cli/compilation/distributed_compiler.py:545,654,684,691src/apm_cli/compilation/claude_formatter.py:302src/apm_cli/compilation/template_builder.py:48Phase 3 (P2): Logging cosmetics — 2 locations
src/apm_cli/commands/uninstall/engine.py:135,2163. Add a CI lint guard
Add a grep-based check to CI that catches raw
relative_to()→str()patterns:This prevents backsliding without adding heavy tooling.
Notes
relative_to()calls need verification — some may be display-only (safe), others may feed intoapm.lock.yamlkeys (the lockfile write path already uses.as_posix())os.chdir()+TemporaryDirectorytest issues were fully fixed in PR fix: Windows test failures in config command and agents compiler #410References
.as_posix()).resolve()on both sides ofrelative_to()in compiler summaries