Repository navigation
internal/winpath: Windows to WSL path translation - #17
Merged
Merged
Conversation
Implements the translation Spike A proved necessary: the daemon rejects
"C:\src:/app" and "C:/src:/app" with `invalid mode: /app` and accepts
"/mnt/c/src:/app", and the CLI passes the string through untouched, so
the proxy has to rewrite it.
- ToWSL: C:\src -> /mnt/c/src, separator- and case-insensitive,
idempotent, POSIX paths pass through untouched
- TranslateBind: parses source:dest[:options] with a drive-letter source,
the case a naive Split(":") gets wrong; named volumes are never
translated (that would silently turn a volume into a bind mount)
- TranslateBinds: batch for HostConfig.Binds, fails loudly rather than
dropping a mount, preserves nil so re-encoded JSON keeps its shape
- UNC paths get a typed error naming the fix instead of a daemon rejection
28 subtests, 98% coverage, no I/O so it runs on any platform. Structural
checks are byte comparisons rather than regexps: a separator is a
backslash, and escaping one through a regexp literal is a bug waiting to
happen (it bit this file during development).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #7. First real v0.1 code, and it implements exactly what Spike A measured rather than what we guessed.
The requirement, from #2: the daemon rejects
C:\src:/appandC:/src:/appwithinvalid mode: /app, and accepts/mnt/c/src:/app. The error comes from the daemon, so the CLI passes the spec through untouched — the proxy must rewriteHostConfig.Binds.API
ToWSL—C:\src→/mnt/c/src. Separator-agnostic (\,/, mixed), drive case-insensitive, idempotent, and POSIX paths pass through unchanged so users who already speak WSL aren''t punished.TranslateBind— parsessource:dest[:options]where the source may contain its own colon. This is the case a naiveSplit(":")gets wrong, and it is precisely how the spike''s failure manifested.TranslateBinds— batch for a create request. Fails loudly on a bad spec rather than dropping a mount, and preservesnilso the re-encoded JSON keeps its shape (null, not[]).Two correctness details worth review:
myvolume:/datamust stay a volume; rewriting it would silently convert it into a bind mount against a host directory that doesn''t exist.*ErrUNCnaming the fix ("map it to a drive letter first") rather than letting the daemon reject them less legibly. WSL2 reaches Windows files via/mnt/<drive>, and a share has no drive letter.28 subtests, 98% statement coverage, no I/O — runs on any platform, so CI doesn''t need WSL for this.
One implementation note: the structural checks are plain byte comparisons rather than regexps. A path separator is a backslash, and escaping one through a regexp literal is a bug waiting to happen — it actually bit this file mid-development, and the tests caught it. Byte checks are also clearer for what amounts to "is byte 1 a colon".
🤖 Generated with Claude Code