fix(build,compose): resolve dockerfile path per Docker semantics#30
Merged
Merged
Conversation
Fixes absolute -f paths being doubled onto the context (devcontainer regression) and relative -f paths being resolved against context instead of CWD, matching Docker parity for docker buildx build --file.
us
approved these changes
Jun 21, 2026
us
approved these changes
Jun 21, 2026
us
left a comment
Owner
There was a problem hiding this comment.
Nice fix 🙏 The absolute/relative split matches buildx semantics, and handling the Compose context-relative case in the same PR (instead of leaving it as a follow-up regression) is exactly right. The resolver tests cover the CWD-vs-context divergence cleanly.
One optional, non-blocking nit: composeDockerfilePath could take dockerfile: String? and forward nil straight to resolveDockerfilePath, dropping the ?? "Dockerfile" at both call sites and keeping the default in one place. Totally fine to leave as-is.
Approving — thanks for the thorough tests and write-up!
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.
What problem does this solve?
mocker build -f <abs path> <abs context>fails withDockerfile not found at <doubled-path>becauseImageManager.buildcallsURL.appendingPathComponenton the dockerfile argument, which doesn't treat absolute paths as special — it concatenates them onto the build context. ThefileExistsguard then throws beforecontainer buildis ever invoked.Per docs.docker.com (
docker buildx build --file): an absolute-fis used verbatim, a relative-fis resolved against the current working directory. mocker now matches both.Naïvely fixing only
mocker buildwould have shifted Compose (which reusesImageManager.build) from context-relative dockerfile resolution to CWD-relative — a regression, because the Compose spec resolvesbuild.dockerfilerelative to the service'sbuild.context. Both surfaces are corrected together so the Docker-compat contract holds on both:-f→ used verbatim-f→ CWD-relative formocker build, context-relative for Compose<context>/DockerfileWhat changed
Sources/MockerKit/Image/ImageManager.swift: extractedresolveContextPath(context:cwd:)from the inline absolute/relative branch inbuild(de-duplicates the same logic that lived inline); added pureresolveDockerfilePath(context:dockerfile:cwd:)withcwdinjected so it is testable without the filesystem; addedpublic static composeDockerfilePath(context:dockerfile:cwd:)that chains the two so Compose can pre-resolve the dockerfile against its context — no new path-resolution policy added, just reuse.build(dockerfile:)parameter widened fromString = "Dockerfile"toString? = nilso the three branches (nil / absolute / relative) stay distinguishable end-to-end.Sources/Mocker/Commands/Build.swift:@Option var fileis nowString?so ArgumentParser surfaces "not provided" asnilinstead of the literal"Dockerfile".Sources/MockerKit/Compose/ComposeOrchestrator.swift,Sources/Mocker/Commands/Compose.swift: pre-resolve the dockerfile viacomposeDockerfilePathbefore callingimageManager.build, so a relativebuild.dockerfilestays context-relative.How was it tested?
swift test: 151/151, 0 failures (14 new tests). 12 pure resolver tests inTests/MockerKitTests/ImageManagerBuildArgsTests.swiftcover all three branches, the CWD-vs-context divergence, the original doubled-path case, and Compose context-relative resolution; 2 parse tests inTests/MockerTests/CLITests.swiftassert-fomitted parses tonil.Any breaking changes?
No. Widening
dockerfile: String = "Dockerfile"todockerfile: String? = nilonImageManager.buildis source-compatible: callers that omitdockerfile:keep using the default, and callers passing aStringliteral widen implicitly toString?. No existing call-site outside the two Compose sites updated above required modification.