fix: an explicit working dir must survive a remote resource loader - #930
Merged
Merged
Conversation
ndeloof
force-pushed
the
14224-working-dir
branch
2 times, most recently
from
September 18, 2026 06:51
8694fd1 to
4193736
Compare
LoadConfigFiles defaults the project's working dir to a remote loader's (git, oci) downloaded copy directory whenever config.WorkingDir is still empty -- intentional, so a self-contained remote artifact (extends, bundled env files) resolves against itself. But the check only looked at config.WorkingDir, never at whether the caller's workingDir parameter was itself an explicit request (--project-directory) or just a default (the current directory): an explicit request was silently overridden the same way a default was, with no way to tell the two apart once they reached LoadConfigFiles as a plain string. Options gains workingDirExplicit (set via SetWorkingDirExplicit, mirroring the existing projectName/projectNameImperativelySet pair), and LoadConfigFiles's remote-default assignment now skips itself when that flag is set. cli.ProjectOptions.ReadConfigFiles sets it from options.WorkingDir != "" -- exactly the same condition GetWorkingDir already uses to decide whether an explicit working dir was requested. Fixes docker/compose#14224: `docker compose -f oci://... --project-directory DIR` resolved relative bind mounts against the downloaded artifact's own cache directory instead of DIR. Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This PR introduces workingDirExplicit for the same "caller provided this on purpose, not a default/guess" distinction that the existing projectNameImperativelySet field already captures, but under a different name. Line them up under the same, more idiomatic term: "imperatively set" reads as a contrast between imperative and declarative styles, which isn't the distinction being made here and risks confusing readers about what the flag actually means. "Explicit" says plainly what both fields mean: user-provided, not defaulted. Renames projectNameImperativelySet -> projectNameExplicit and, correspondingly, SetProjectName's imperativelySet parameter -> explicit. SetProjectName is a public API, but the parameter is positional, so no caller is affected. Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
glours
force-pushed
the
14224-working-dir
branch
from
September 18, 2026 07:11
4193736 to
8ec34b7
Compare
glours
enabled auto-merge (rebase)
September 18, 2026 07:11
ndeloof
added a commit
to ndeloof/compose
that referenced
this pull request
Sep 21, 2026
Replaces the previous commit's temporary fork replace: compose-spec/compose-go#930 is merged, so TestOciRemoteProjectDirectory now passes against the real, released compose-go pin instead of a personal fork branch. Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
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.
Fixes docker/compose#14224:
docker compose -f oci://... --project-directory DIRresolved relative bind mounts against the downloaded artifact's own cache directory instead ofDIR.Context
LoadConfigFilesdefaults the project's working dir to a remote resource loader's (git, oci) downloaded copy directory whenever it's still empty — intentional, so a self-contained remote artifact (extends, bundled env files) resolves against itself. But the check only looked at whether a working dir had already been set, never at whether the caller'sworkingDirargument was itself an explicit request (--project-directory) or just a default (the current directory). Once that value reachesLoadConfigFilesas a plain string, the two are indistinguishable — so an explicit request was silently overridden the same way a mere default would be.What this PR brings
OptionsgainsworkingDirExplicit(set viaSetWorkingDirExplicit, mirroring the existingprojectName/projectNameImperativelySetpair), andLoadConfigFiles's remote-default assignment now skips itself when that flag is set.cli.ProjectOptions.ReadConfigFilessets it fromoptions.WorkingDir != ""— exactly the conditionGetWorkingDiralready uses to decide whether an explicit working dir was requested.The self-contained-artifact default is untouched for the common case (no explicit
--project-directory): only an explicit request is now protected from being overridden.🤖 Generated with Claude Code