Commit Graph
647 Commits
Author SHA1 Message Date
Nicolas De Loof cccb9f1f7e cli: display.Mode always resolves to the mode actually rendered
The display.Mode package global was left as "auto" on the most common
path (auto mode with an interactive or redirected terminal), so readers
like `up`'s NavigationMenu gate saw an unresolved value; that gate also
compared against the string literal "plain" instead of the constant.
applyDisplayMode wrote a mode that selectEventProcessor could then
contradict (--ansi always with a redirected stderr rendered Plain while
Mode said tty).

selectEventProcessor becomes the single resolution point: every branch
assigns the mode matching the renderer it returns, so after command
setup the global never holds ModeAuto. applyDisplayMode loses its
redundant writes and its misleading name (now applyAnsiMode); the
contract is documented on the Mode variable, and the existing
selectEventProcessor tests now pin the resolved mode for every branch.

Side effect, deliberate: with stderr redirected (auto -> plain
rendering) the navigation menu is no longer offered; it used to slip
through because Mode still read "auto".

Part of #14074 (section E).

Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-20 15:10:15 +02:00
Guillaume Lours 3a62ae63ce fix(ps): honor psFormat from Docker CLI config when no --format flag given
The --format flag defaulted to "table" instead of "", so the
opts.Format == "" guard in runPs never fired for a bare compose ps.
Setting the default to "" lets the existing config-fallback path work,
matching the behaviour of docker ps.

Fixes #13643
Supersedes #14032

Signed-off-by: Guillaume Lours <[email protected]>
2026-08-20 14:05:34 +02:00
Nicolas De Loof 24059c688c chore: explicit, unique, greppable names for internal identifiers
Rename-only change, no behavior difference, no exported identifier
renamed (only parameter names of a few exported functions, which are
not part of the Go API).

- names that hide what a value is: parameters holding a *name* or *ID*
  while named like the object — project→projectName, service→serviceName,
  container→containerID — so string vs struct is readable at every call
  site without opening the signature
- misleading receivers: monitor methods used c (reads as
  client/container/CLI) → m; jsonWriter used p while its ttyWriter
  sibling uses w → w
- cryptic abbreviations with non-trivial scope: nw (meant both
  network.Summary and types.NetworkConfig) → network/networkConfig,
  svc → service/serviceName/serviceCopy, oc/ocs → observedContainer(s),
  cnts → serviceContainers, cnx → attachResponse
- container.Summary loop variables unified on ctr (was a c/ctr mix);
  fillBindMounts also dropped its p/s/m single-letters, one of which
  was shadowed by a loop variable of a different type
- option-struct identifiers unified on options (opts remains only for
  variadic functional options); ambiguous ones get a precise name
  (bindOptions, networkCreateOptions, projectOptionsFns)

Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-20 11:17:11 +02:00
Nicolas De Loof 3ee4b5c793 api: ScaleOptions carries the replica counts it always pretended to
The Compose interface promised 'Scale manages numbers of container
instances running per service', but ScaleOptions had no replica count:
callers had to know they must mutate project.Services[x] via SetScale
before calling, and ScaleOptions.Services only tuned the recreation
policy. An SDK consumer following the interface doc got a no-op
convergence of the whole project.

ScaleOptions gains Replicas (service -> count); the backend applies it
to the model itself before converging, and derives the targeted
services from its keys when Services is not set. The CLI now does what
a CLI should: parse SERVICE=REPLICAS tuples and hand them to the
backend, instead of pre-mutating the model. Passing a pre-mutated
project with an empty Replicas map still behaves as before, so
existing SDK callers are unaffected.

Part of #14074 (B: pkg/api promises things the implementation does not
honor).

Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-20 10:16:06 +02:00
Nicolas De LoofandClaude Fable 5 e964454893 refactor: extract RootCommand's PersistentPreRunE concerns
RootCommand (cognitive complexity 62) buried four independent
concerns inside the PersistentPreRunE closure, where every branch
costs double. Each moves to a named function: runParentPreRun (cobra
doesn't chain the parent's PersistentPreRunE automatically),
resolveAnsiMode (--ansi vs deprecated --no-ansi vs COMPOSE_ANSI),
applyDisplayMode (ANSI + NO_COLOR + progress mode),
normalizeProjectOptions (--workdir deprecation, env-file paths) and
resolveMaxConcurrency (COMPOSE_PARALLEL_LIMIT vs --parallel). The
prerun now reads as the sequence of those steps; RootCommand drops to
complexity 22 and its FIXME suppression is gone.

No behavior change: same errors, same deprecation warnings, same
precedence rules.

Co-Authored-By: Claude Fable 5 <[email protected]>
Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-18 13:37:48 +02:00
Guillaume Lours 81bb4afed5 fix(events): validate service names before subscribing to events
docker compose events <name> was passing service arguments straight to
the event filter without checking they exist in the project, so a typo
would produce an event stream matching nothing and block forever with
no output and no error.

Switch to projectOrName (which validates args via ToProject) before
calling backend.Events, consistent with logs, kill, and restart.

Signed-off-by: Guillaume Lours <[email protected]>
2026-08-18 10:48:59 +02:00
Nicolas De LoofandClaude Fable 5 2340121f0e lint: replace gocyclo with gocognit
Cognitive complexity (gocognit, threshold 30 — the linter default) fits
this codebase better than raw cyclomatic complexity: it barely charges
guard clauses and early returns, and penalizes nesting instead. As a
result 8 of the 21 //nolint:gocyclo suppressions become unnecessary,
while deeply nested functions gocyclo never flagged are now caught.

The 19 functions still above the threshold keep a suppression, each
marked FIXME to complete the migration by restructuring them.

Co-Authored-By: Claude Fable 5 <[email protected]>
Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-18 10:42:37 +02:00
Nick Sieger 870908cc8f feat(ps): add ENGINE column gated on label presence
Show an ENGINE column in `compose ps` default table output when the
com.docker.compose.engine label is present. Expose {{.Engine}} for custom
--format templates.

Rename api.EngineLabel to api.ContainerEngineLabel to avoid the
name collision with desktop.EngineLabel (com.docker.desktop.address).

Signed-off-by: Nick Sieger <[email protected]>
2026-08-17 10:34:46 +02:00
Nicolas De Loof ddc4b044b6 chore: honest name for navigation-menu resolution, share setServiceScale
validateNavigationMenu validated nothing: it resolves the TTY /
COMPOSE_MENU / --menu precedence and mutates opts.navigationMenu —
rename to resolveNavigationMenu.

runScale duplicated setServiceScale's GetService/SetScale/write-back
dance inline; move the helper next to its natural home in scale.go and
use it from both callers.

Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-14 22:49:53 +02:00
Nicolas De Loof 1e80a0906f chore: inline needless single-use helpers
Inline small functions that were extracted from their single call site
without a real boundary to justify it — no reuse, no dedicated test, no
responsibility of their own — so each caller now tells its whole story
top-down:

- getExecTarget, attachContainer, logContainer: one-line trampolines to
  getSpecifiedContainer / doAttachContainer / doLogContainer, which
  other call sites already use directly
- removeImage: single-statement wrapper, unlike its removeVolume
  sibling which has actual logic
- checkSelectedServices: named like a validation, actually a filter;
  the subtle rule (an unknown service is only an error with an explicit
  compose file) now reads where options.Services is rewritten
- prepareLabels: mutated the map it received while looking pure at the
  call site; the label writes are now visible in getCreateConfigs
- setDefaultTarget: mutation-by-pointer of the loop copy, now visible
  in the loop of injectFileReferences
- buildVolumeOptions/buildTmpfsOptions/buildImageOptions: nil-guard +
  field copies; the buildMountOptions switch now shows side by side
  what each mount type propagates (buildBindOption keeps real logic and
  keeps buildMountOptions under the gocyclo limit)
- displayDryRunBuildEvent: was longer than its only caller
- hasMore: read like a predicate, was a one-line spinner restart
- escapeDollarSign: wrapped a single bytes.ReplaceAll
- extractEnvCLIDefined: replaced by the canonical compose-go helper
  types.NewMappingWithEquals().ToMapping(), as run.go already does
- isPullPolicyValid: rebuilt the valid-values slice on every call; now
  a package-level list checked at the call site
- viewFromStackList: projection now sits next to the render closure
  that consumes exactly its three fields

No behavior change; single gocyclo threshold untouched.

Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-14 22:49:53 +02:00
Nicolas De Loof 64cbcb2276 fix: address image-identity review findings
- pullRequiredImages resolves each distinct pulled image once, after
  all pulls completed, for the host default platform — the exact way
  getLocalImagesDigests resolves already-local images. Resolving from
  each pull's goroutine, for the pulled platform, let the recorded
  digest depend on pull completion order when several services pull
  the same tag for different platforms (last-writer-wins), and made
  the first up after a pull recreate containers. Platform-pinned
  services keep getting their own platform's digest from
  serviceImageDigest. In dry-run nothing was actually pulled, so the
  local inspect is skipped — it reached the real daemon through a
  DryRunClient dispatch that no longer matched and failed with 'No
  such image'.
- explicit 'compose pull' treats daily/weekly/every_N windows as due:
  it is the only way to force a refresh ahead of the window.
- 'compose pull' no longer silently skips services declaring both
  provider: and image:.
- pre_start hook images go through the same mustPull interpreter on the
  up path as on the pull path, so refresh windows apply consistently.
- matchLocalManifest falls back to the inspect's flat platform fields
  when the lone available manifest carries no ImageData (locally built
  images), instead of reporting the platform unsatisfied and pulling a
  possibly local-only image.
- scale resolves DOCKER_DEFAULT_PLATFORM without validating
  build.platforms: a conflict on a service that isn't being built must
  not abort the command. run needs nothing: createOptions.Apply
  resolves and validates platforms on its path already.
- resolveImageVolumes documents the accepted one-time-recreate and
  retag-race tradeoffs.

Signed-off-by: Nicolas De Loof <[email protected]>
2026-08-13 12:03:29 +02:00
Guillaume Lours 4b7f6149eb fix(scale, run): resolve DOCKER_DEFAULT_PLATFORM like up does
scale and run were the only container-creating commands that never
called applyPlatforms, yet both go through the regular create path and
its config-hash comparison (run for the dependencies it starts). With
DOCKER_DEFAULT_PLATFORM set, they hashed an empty service Platform where
up had hashed the resolved one, so every invocation recreated the
affected containers. run's project preparation is extracted to a helper
to keep runCommand under the complexity threshold.

No unit test: neither command has a test harness and the fix is the one
missing call, aligned on create/watch; the config-hash equality is
covered by the reconciler tests.

Signed-off-by: Guillaume Lours <[email protected]>
2026-08-13 12:03:29 +02:00
Guillaume Lours d4fe2aead5 fix(bridge): validate arguments of bridge subcommands
`docker compose bridge transformations create` panicked with an index
out of range when invoked without its PATH argument, as RunE indexed
args[0] without any validator. Add cli.ExactArgs(1) so the CLI reports
a proper usage error instead.

Also add cobra.NoArgs to `bridge convert` and `bridge transformations
list`, which silently ignored stray arguments.

Signed-off-by: Guillaume Lours <[email protected]>
2026-08-13 11:45:46 +02:00
Guillaume Lours 7bc2630b65 fix(config): resolve service environment when computing --hash
Containers are created from a project whose service environment is
resolved (env_file merged into environment), but since v2.22.0 `config
--hash` skipped that resolution, so hashes diverged from the
com.docker.compose.config-hash label for services using env_file.

Resolve the environment of the hashed services only, so a broken
env_file or platforms on an unrelated service still doesn't prevent
hashing, and honor --no-env-resolution as an escape hatch.

Fixes #14001

Signed-off-by: Guillaume Lours <[email protected]>
2026-08-11 08:37:13 +02:00
Guillaume Lours d8370536f0 fix: tolerate missing env file on scale, watch and shell completion
Follow-up to #13603: scale, watch and shell completion loaded the
project without any tolerance option, so a missing env_file on a
service not involved in the operation aborted the command, while
up/exec/ps already tolerate this since #13156 and #13603.

Mirror the WithServices pattern: load with WithoutEnvironmentResolution
and resolve the environment once the project has been reduced to the
selected services, so targeted services still get their env_file
validated. Completion only needs names and never resolves. This also
aligns the config hash of scale-created containers with up-created
ones.

Signed-off-by: Guillaume Lours <[email protected]>
2026-07-30 11:38:47 +02:00
Guillaume Lours 7bdc31c5de fix(config): apply config flags to --services/--volumes/--networks/--models/--hash
The runServices, runVolumes, runNetworks, runModels and runHash paths
called ProjectOptions.ToProject directly, bypassing the configOptions
wrapper that applies --no-consistency, --no-interpolate, --no-normalize,
--no-path-resolution, --profile filtering and env_file discarding.
Restore the variadic wrapper (mirroring configOptions.ToModel) and route
the five call sites through it.

Regression introduced by b80bb0586 (LoadProject API migration).

Fixes #13974

Signed-off-by: Guillaume Lours <[email protected]>
2026-07-30 11:38:20 +02:00
Nicolas De Loof 1cc5120af8 Dedup pre_start hook images against service and each other
Address review feedback on pre_start hook image resolution:

1. GetDependentImages now skips a hook image equal to the service image
   (resolved via GetImageNameOrDefault), so `config --images` no longer
   prints a duplicate line and pullRequiredImages no longer schedules a
   redundant pull for it.

2. pullRequiredImages (up/create path) now dedups dependent images by
   reference via a `scheduled` set, so several hooks/services sharing the
   same missing image don't schedule concurrent redundant pulls. The hook
   pass moved to a helper (addPreStartHookPulls) to keep complexity in check.

3. The `pull` command no longer skips hook images under `pull_policy: build`.
   A hook image is a registry image that can't be built, so only `never`
   justifies skipping it — making `pull` consistent with the `up` path.

Signed-off-by: Nicolas De Loof <[email protected]>
2026-07-30 10:40:06 +02:00
Nicolas De Loof c9266e6297 Resolve pre_start hook images alongside service images
pre_start hooks run as ephemeral init containers with their own image
(ServiceHook.Image), but that image was ignored by image resolution:
`config --images` didn't list it, `pull` didn't fetch it, and `up` failed
at runtime with "No such image" when it wasn't already present locally.

Add a GetDependentImages helper that returns a service's pre_start hook
images, and use it wherever service images are collected/pulled:
getLocalImagesDigests, pullRequiredImages (up path), the pull command, and
`config --images`. Hook images inherit the parent service pull policy.

post_start/pre_stop hooks run via ExecCreate inside the service container
and never use hook.Image, so they are intentionally out of scope.

Digest resolution/locking (--resolve-image-digests / --lock-image-digests)
is not covered: compose-go's WithImagesResolved only resolves service.Image
(needs an upstream change), and the --lock-image-digests override merges
pre_start by concatenation, which would duplicate hooks.

Signed-off-by: Nicolas De Loof <[email protected]>
2026-07-30 10:40:06 +02:00
Max Proske 54e0373f1c Tolerate missing env file on runtime commands
Signed-off-by: Max Proske <[email protected]>
2026-07-27 09:20:14 +02:00
Guillaume Lours 37dea37d67 fix(config): pin type:image volume sources and pre_start hook images
Rely on compose-go WithImagesResolved, which now resolves dependent
images — `type: image` volume sources and pre_start hook images —
with its already-digested guard, per-call memoization and
sibling-service detection (compose-spec/compose-go#894, #899), rather
than duplicating resolution logic CLI-side. The interpolated path gets
this for free; --no-interpolate maps the raw model onto a
pseudo-project keyed by service names to reuse the same resolution,
and --lock-image-digests keeps type:image volumes in its output.
pre_start hooks can't be carried into the lock override (hook lists
are appended on merge), so generating a lock warns that hook images
stay unpinned there.
As a side effect, `compose publish` now fails fast on unresolvable
dependent images.

Fixes #13827

Signed-off-by: Guillaume Lours <[email protected]>
2026-07-24 15:33:21 +02:00
Domantas PetrauskasandClaude Opus 4.8 5534be0a28 fix(oci): honor --insecure-registry when up re-loads the model
`docker compose -f oci://<insecure-registry>/... up` failed against a
plain-HTTP registry unless --yes was passed:

    failed to pull OCI resource "localhost:5000/test:interpolated":
    Head "https://localhost:5000/v2/test/manifests/interpolated":
    http: server gave HTTP response to HTTPS client

`up` loads the project twice. The first load goes through ToProject,
which built its OCI options from --insecure-registry correctly. Without
--yes, checksForRemoteStack then calls promptForInterpolatedVariables,
which re-loads the project through ToModel to list the interpolation
variables. That second load builds its own resource loaders via
remoteLoaders, and those passed an empty api.OCIOptions{}, dropping the
flag. Since the OCI loader always performs a network resolve, the
re-load spoke HTTPS to a plain-HTTP registry and failed before the
prompt could be shown.

The two construction sites had drifted apart, so rather than patching
the second one, both now share ProjectOptions.ociOptions(). `config`
and `viz` use the same ToModel path and are fixed as well.

Covered by an e2e case in TestPublish, which already runs an insecure
registry and an oci:// round-trip: it publishes a fixture carrying an
interpolation variable so the prompt fires, then runs `up` without
--yes and declines, asserting the re-load does not fail with
"server gave HTTP response to HTTPS client".

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Signed-off-by: Domantas Petrauskas <[email protected]>
2026-07-21 16:24:34 +02:00
Guillaume Lours efb63f2e6e fix(config): warn when service selection is silently ignored
`docker compose config --no-interpolate <service>` and
`docker compose config --variables <service>` load the raw model
without applying service filtering, so the full model is rendered
regardless of the services passed as arguments. Filtering will not
be supported on these paths, so emit a warning to make sure users
are no longer misled by silently ignored arguments.

Fixes #13614

Signed-off-by: Guillaume Lours <[email protected]>
2026-07-17 16:12:42 +02:00
Nick Janetakis 2a6a4e5179 Normalize --no-TTY flag to --no-tty
Signed-off-by: Nick Janetakis <[email protected]>
2026-06-29 20:56:31 +02:00
Guillaume Lours ef3238ab1f fix(progress): measure taskID width in runes, not bytes
maxBeforeStatusWidth used len(l.taskID) (bytes) while applyPadding
used utf8.RuneCountInString (runes). For ASCII task IDs the two
agree and no symptom surfaces, but a taskID containing multi-byte
UTF-8 chars (CJK, emoji, accented Latin) reported a width larger
than its visual columns. computeOverflow then triggered truncation
where none was needed, and truncateLongestTaskID's byte-indexed
slice could land mid-multibyte sequence, corrupting the displayed
string.

Align the two measurements on rune count.

Signed-off-by: Guillaume Lours <[email protected]>
2026-06-15 15:00:57 +02:00
Guillaume Lours 1a6212c859 fix(progress): drop size info from progress bar when line overflows
In narrow terminals (e.g. tmux panes), the TTY progress UI emitted
lines wider than terminalWidth because adjustLineWidth could shrink
details and taskID but never the progress field. When progress
carried the "X.XMB / Y.YMB" size suffix, the truncation loop exited
with overflow > 0 and applyPadding's max(timerPad, 1) floor pushed
the line one char over. tmux then wrapped the line visually while
print() kept counting logical lines, desyncing aec.Up() on the next
render and producing the mangled "[+] pull X/Y" header overwriting
prior task lines.

Track the size suffix byte length on lineData and let
adjustLineWidth drop it as an intermediate truncation step before
abbreviating the taskID.

Fixes docker/compose#13595

Signed-off-by: Guillaume Lours <[email protected]>
2026-06-15 15:00:57 +02:00
Guillaume Lours b8fba27032 fix(progress): probe stderr (not stdout) for TTY auto-detection
The progress UI writes to dockerCli.Err() but the auto-mode selector
was probing dockerCli.Out().IsTerminal(), introduced when the
EventProcessor was moved to the CLI layer. Any context that pipes
stdout while keeping stderr attached — `docker compose up | tee log`,
some CI wrappers, PowerShell native-command capture — silently
dropped to plain mode.

Align the detection with the stream the renderer actually targets,
restoring v4 behavior. Extract the switch into selectEventProcessor
so the auto-mode logic can be unit-tested with a real pty pair.

Fixes docker/compose#13570

Signed-off-by: Guillaume Lours <[email protected]>
2026-06-15 14:17:07 +02:00
bigmomma 6ded3140df test: cover up remote-stack variable prompt
Signed-off-by: bigmomma <[email protected]>
2026-06-12 15:34:20 +02:00
bigmomma fc83fbfa9e Skip validation when extracting config variables
Signed-off-by: bigmomma <[email protected]>
2026-06-12 15:34:20 +02:00
Sebastiaan van Stijn 39ee1d02b6 docs: compose logs: add more links for flag descriptions
follow-up to 7eeb7de7a2, adding more
links now that the CLI reference for docker logs has anchors for them.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
2026-06-10 09:36:31 +02:00
Sebastiaan van Stijn 7eeb7de7a2 docs: compose logs: add links for since/until flag descriptions
Link to the corresponding `docker container logs` equivalents, which
contain more details on the accepted formats and use.

The container logs documentation still needs some updates to provide
per-flag sections, so follow-ups can be made once those are done.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
2026-05-26 14:28:34 +02:00
Guillaume Lours c59e13cde5 feat: pre-filter Desktop Logs view by Compose project
Pass the active project name as the appId query parameter on the
docker-desktop://dashboard/logs deep link, both from the post-command
hint (compose up -d, compose logs) and the interactive nav menu
('l' key during compose up). The hook subprocess re-runs compose-go's
project loader so the name matches what the parent computed; it skips
the appId when -p, -f, --project-directory, --workdir, or --env-file
is set, since the hook payload does not carry their values. docker
logs stays unfiltered: the CLI hook contract does not expose the
positional container id.

Signed-off-by: Guillaume Lours <[email protected]>
2026-05-18 17:28:03 +02:00
Guillaume Lours 554a2ba3e8 refactor: drop Desktop beta-settings check; gate hint on LogsTab flag
Docker Desktop is removing the "Enable Logs view" beta setting, so drop
the /app/settings check and rely on /features alone. With the setting
gate gone, the compose hook subprocess would print the Logs view hint
regardless of LogsTab; add a flag check in handleHook. Consolidate
engine-label discovery and feature-flag evaluation into internal/desktop.

Signed-off-by: Guillaume Lours <[email protected]>
2026-05-18 17:28:03 +02:00
Nicolas De loof 07832c4df1 refactor: fix lint issues from cleanup changes
Assisted-By: docker-agent
Signed-off-by: Nicolas De loof <[email protected]>
2026-05-12 11:31:40 +02:00
Nicolas De loof 616adea1b1 refactor(cmd): extract withBackend helper to remove CLI boilerplate
Assisted-By: docker-agent
Signed-off-by: Nicolas De loof <[email protected]>
2026-05-12 11:31:40 +02:00
Guillaume LoursandClaude Opus 4.6 efb090183f feat: make hook hint deep links clickable using OSC 8 terminal hyperlinks
Wrap the docker-desktop://dashboard/logs URL in OSC 8 escape sequences
with underline styling so it appears as a clickable link in supported
terminals. Respects NO_COLOR and COMPOSE_ANSI=never to suppress escapes.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Signed-off-by: Guillaume Lours <[email protected]>
2026-04-15 12:11:43 +02:00
Guillaume LoursandClaude Opus 4.6 182defa8aa feat: add Docker Desktop Logs view hints and navigation shortcut
Add CLI hooks handler to show "What's next:" hints pointing to the
Docker Desktop Logs view after `docker logs`, `docker compose logs`,
and `docker compose up -d`.

Add `l` keyboard shortcut in the `compose up` navigation menu to
open the Logs view, gated on Docker Desktop feature flag and settings.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Signed-off-by: Guillaume Lours <[email protected]>
2026-04-10 15:26:08 +02:00
Sebastiaan van Stijn 92a7ac1fa2 fix mixed assertion libraries in tests
Before this, assertion libraries were mixed, sometimes
even in the same file.

    git grep -l '"gotest.tools/v3/' | wc -l
    75
    git grep -l '"github.com/stretchr/testify' | wc -l
    24

Signed-off-by: Sebastiaan van Stijn <[email protected]>
2026-03-31 17:32:51 +02:00
Samarth Verma 0d8dc09048 cmd/display: left-pad timers for right-aligned column
Signed-off-by: Samarth Verma <[email protected]>
2026-03-20 15:14:05 +01:00
Samarth Verma 02aaf253c8 Fix TTY timer alignment leaving stale suffix
Signed-off-by: Samarth Verma <[email protected]>
2026-03-20 15:14:05 +01:00
maks2134 c7e8896360 Fix forbidigo linting error
- Replace context.Background() with t.Context() in TestDoneDeadlockFix
- Ensures .idea files are not included in commit

Signed-off-by: maks2134 <[email protected]>
2026-03-18 16:23:34 +01:00
maks2134 e3fcdb8238 Fix linting issues in tty_test.go
- Replace context.Background() with context.WithCancel() in test
- Fix formatting issues (remove extra empty line)

Signed-off-by: maks2134 <[email protected]>
2026-03-18 16:23:34 +01:00
maks2134 25b29d776b Fix deadlock in ttyWriter.Done()
Resolves race condition between main thread calling Done() and UI thread
calling printWithDimensions(). The issue was that Done() held the mutex
while sending to the done channel, but the UI thread needed the same
mutex to process the done signal.

Fixed by sending the done signal before acquiring the mutex, allowing
the UI thread to receive the signal and release any held locks.

Fixes #13639

Signed-off-by: maks2134 <[email protected]>
2026-03-18 16:23:34 +01:00
Max Proske 85d6770b7f Fix panic when watch rebuilds without up
Signed-off-by: Max Proske <[email protected]>
2026-02-24 17:21:59 +01:00
Sebastiaan van Stijn f9828dfab9 modernize some code
Results of running the modernize command, with some minor changes
afterwards (removing the `contains` and `hasStatus` helper functions);

    go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest
    modernize -fix ./...

Signed-off-by: Sebastiaan van Stijn <[email protected]>
2026-02-12 15:31:35 +01:00
Sebastiaan van Stijn bfb5511d0d go.mod: bump github.com/moby/moby/api v1.53.0, moby/client v0.2.2
Also update TestDefaultNetworkSettings:
Test that the network with the highest priority is returned as
"primary" network, and other networks as extra networks.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
2026-02-11 12:32:37 +01:00
Michael IrwinandClaude Sonnet 4.5 7f8814f4c5 Fix invalid path error when using OCI artifacts on Windows
When using OCI artifacts (e.g., `docker compose -f oci://dockersamples/welcome-to-docker up`)
on Windows, users encountered the following error:

  CreateFile C:\Users\username\oci:\dockersamples\.env: The filename, directory name,
  or volume label syntax is incorrect.

This issue was introduced between v5.0.0 and v5.0.1, specifically by commit 6c043929a
which fixed error handling in setEnvWithDotEnv. The bug existed in v5.0.0 but was
silently ignored due to improper error handling.

Root Cause:
-----------
The setEnvWithDotEnv function creates ProjectOptions without registering remote loaders.
Without remote loaders, the compose-go library doesn't recognize OCI paths as remote
resources. It falls through to filepath.Abs() which treats the OCI reference as a
relative path.

On Windows, filepath.Abs("oci://dockersamples/...") produces an invalid path like:
  C:\Users\username\oci:\dockersamples

Windows rejects this path because colons are only valid after drive letters.

Solution:
---------
Modified setEnvWithDotEnv to detect remote config paths and skip environment loading
for them. Instead of hardcoding string checks, the fix uses the actual remote loaders'
Accept() method to determine if a config path is remote. This is more maintainable
and consistent with how the compose-go library identifies remote resources.

The function now:
- Accepts a dockerCli parameter to access remote loaders
- Uses opts.remoteLoaders(dockerCli) to get loader instances
- Checks if any loader accepts the config path using loader.Accept()
- Skips .env loading for remote configs (happens later when loaders are initialized)
- Allows normal processing for local compose files

Testing:
--------
- Added tests for OCI artifacts, Git remotes, and local paths
- Verified fix works on Windows ARM64
- All existing tests pass

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: Michael Irwin <[email protected]>
2026-02-09 09:15:37 +01:00
Sebastiaan van Stijn c51b1fea29 replace some uses of strings.Split(N) for strings.Cut
Signed-off-by: Sebastiaan van Stijn <[email protected]>
2026-01-22 11:26:16 +01:00
Mahesh Thakur a061c17736 fix: emit container status events after network reconnection
Signed-off-by: Mahesh Thakur <[email protected]>
2026-01-21 09:40:05 +01:00
David Gageot 27faa3b84e test: replace os.MkdirTemp with t.TempDir()
Use t.TempDir() which automatically cleans up the temporary directory
when the test completes, eliminating the need for manual cleanup.

Go 1.14 modernization pattern.

Assisted-By: cagent
Signed-off-by: David Gageot <[email protected]>
2026-01-20 11:34:11 +01:00
David Gageot 093205121c test: replace context.Background()/context.TODO() with t.Context()
Replace manual context creation with t.Context() which is automatically
cancelled when the test completes.

Go 1.24 modernization pattern.

Assisted-By: cagent
Signed-off-by: David Gageot <[email protected]>
2026-01-20 11:34:11 +01:00