diff --git a/AGENTS.md b/AGENTS.md index e91c95f52a..d30e38bb84 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,9 +4,11 @@ - Build: `make build` - Test all: `make test` -- Test unit: `go test ./pkg/...` +- Test unit: `go test ./pkg/...` — needs no Docker daemon; the e2e suite is + gated behind the `e2e` build tag and is not picked up - Test single: `go test ./pkg/compose/ -run TestFunctionName` -- E2E tests: `go test -tags e2e ./pkg/e2e/ -run TestName` +- E2E tests: `go test -tags e2e ./pkg/e2e/ -run TestName` — requires a Docker + daemon and the locally built binary (`make build`) ## E2E tests @@ -17,6 +19,49 @@ `OutputContains` as last resort, new checks go in `pkg/e2e/checks.go`) and how to exploit failure artifacts and `E2E_KEEP_FAILED=1`. +## Architecture map + +Read this before changing lifecycle or CLI code — several of these facts are +not guessable from local reading. + +- **Packages**: `cmd/compose` is the cobra CLI layer; `pkg/api` is the public + SDK contract (interface `Compose` + option structs); `pkg/compose` is the + backend implementation (`NewComposeService`). Everything else under `pkg/` + is exported for historical reasons, not as a stability promise. +- **Two lifecycle engines coexist.** The plan-based reconciler + (`pkg/compose/reconcile.go`) has a single entry point: `create()` — so only + `create`/`up`/`run`/`scale`/`watch` go through it. `start`, `stop`, + `restart` and `down` use the imperative dependency-ordered engine + (`pkg/compose/dependencies.go`) with the shared helpers in + `service_containers.go`. The plan does **not** start containers: `up` runs + a separate start phase (`start.go`) that re-lists containers and starts + them in dependency order. +- **Operation convention**: exported `composeService` methods wrap the work + in `Run(ctx, …, "opname")`, which drives the `EventProcessor` + (`Start`/`On`/`Done`) used for progress display. Unexported methods + (`s.create`, `s.start`, …) are building blocks without their own event + cycle — calling an exported method from another operation nests event + cycles. +- **Output conventions**: progress/status rendering goes to **stderr** + (`dockerCli.Err()`); stdout is reserved for command payload (`ps`, + `config`, container logs' stdout stream). TTY detection for the renderer + probes stderr, color detection for logs probes stdout. +- **Environment resolution has two idioms**: `os.Getenv` sees only the + process environment; `project.Environment[...]` also sees the project's + `.env`. `cmd/compose/compose.go:setEnvWithDotEnv` additionally copies + `COMPOSE_*` keys from the project's env-files into the process environment + during `PersistentPreRunE` — variables read before that point (e.g. as + cobra flag defaults) do not see the `.env`. +- **Container/project identity is label-based**: listings filter on the + presence of `com.docker.compose.config-hash` (see + `pkg/compose/containers.go:getDefaultFilters`), not just the project label. + One-off (`compose run`) containers carry `oneoff=True` and no + container-number; lifecycle-hook helper containers carry neither and are + therefore invisible to `ps`/`down`. +- **Docker Desktop integrations** (`internal/desktop`, used from `up`, + `publish`, the keyboard menu) talk to Desktop over a private socket and are + expected to fail silently on non-Desktop engines. + ## Lint - Linter: golangci-lint v2 (config in `.golangci.yml`) diff --git a/Makefile b/Makefile index ee295c5524..85816f9796 100644 --- a/Makefile +++ b/Makefile @@ -77,11 +77,11 @@ install: binary .PHONY: e2e-compose e2e-compose: example-provider ## Run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test - go run gotest.tools/gotestsum@latest --format testname --junitfile "/tmp/report/report.xml" -- -v $(TEST_FLAGS) -count=1 -parallel=$(E2E_PARALLEL_PLUGIN) -timeout 20m ./pkg/e2e + go run gotest.tools/gotestsum@latest --format testname --junitfile "/tmp/report/report.xml" -- -v $(TEST_FLAGS) -count=1 -parallel=$(E2E_PARALLEL_PLUGIN) -timeout 20m -tags e2e ./pkg/e2e .PHONY: e2e-compose-standalone e2e-compose-standalone: ## Run End to end local tests in standalone mode. Set E2E_TEST=TestName to run a single test - go run gotest.tools/gotestsum@latest --format testname --junitfile "/tmp/report/report.xml" -- $(TEST_FLAGS) -v -count=1 -parallel=$(E2E_STANDALONE_PARALLEL) -timeout 20m --tags=standalone ./pkg/e2e + go run gotest.tools/gotestsum@latest --format testname --junitfile "/tmp/report/report.xml" -- $(TEST_FLAGS) -v -count=1 -parallel=$(E2E_STANDALONE_PARALLEL) -timeout 20m --tags=e2e,standalone ./pkg/e2e .PHONY: build-and-e2e-compose build-and-e2e-compose: build e2e-compose ## Compile the compose cli-plugin and run end to end local tests in plugin mode. Set E2E_TEST=TestName to run a single test diff --git a/docs/sdk.md b/docs/sdk.md index 3a03c7fdc1..a18e2c681a 100644 --- a/docs/sdk.md +++ b/docs/sdk.md @@ -107,7 +107,7 @@ options allow you to configure I/O streams, concurrency limits, dry-run mode, an - `WithDryRun` - Run operations in dry-run mode without actually applying changes - `WithContextInfo(api.ContextInfo)` - Set custom Docker context information - `WithProxyConfig(map[string]string)` - Configure HTTP proxy settings for builds -- `WithEventProcessor(progress.EventProcessor)` - Receive progress events and operation notifications +- `WithEventProcessor(api.EventProcessor)` - Receive progress events and operation notifications These options provide fine-grained control over the SDK's behavior, making it suitable for various integration scenarios including CLI tools, web services, automation scripts, and testing environments. @@ -145,13 +145,17 @@ Common status text values include: `Creating`, `Created`, `Starting`, `Started`, ### Built-in `EventProcessor` implementations -The SDK provides three ready-to-use `EventProcessor` implementations: +The `EventProcessor` interface is defined in `github.com/docker/compose/v5/pkg/api`. When no +`WithEventProcessor` option is passed, events are silently discarded. -- `progress.NewTTYWriter(io.Writer)` - Renders an interactive terminal UI with progress bars and task lists - (similar to the Docker Compose CLI output) -- `progress.NewPlainWriter(io.Writer)` - Outputs simple text-based progress messages suitable for non-interactive +The renderers used by the Docker Compose CLI live in the `github.com/docker/compose/v5/cmd/display` +package and can be reused: + +- `display.Full(out, info io.Writer, detached bool)` - Renders the interactive terminal UI with progress bars + and task lists (the default Docker Compose CLI output) +- `display.Plain(out io.Writer)` - Outputs simple text-based progress messages suitable for non-interactive environments or log files -- `progress.NewJSONWriter()` - Render events as JSON objects -- `progress.NewQuietWriter()` - (Default) Silently processes events without producing any output +- `display.JSON(out io.Writer)` - Renders each event as a JSON object +- `display.Quiet()` - Silently discards events (same behavior as the default) Using `EventProcessor`, a custom UI can be plugged into `docker/compose`. diff --git a/pkg/compose/build_bake.go b/pkg/compose/build_bake.go index 31e2a58c5d..29520d9116 100644 --- a/pkg/compose/build_bake.go +++ b/pkg/compose/build_bake.go @@ -64,7 +64,8 @@ func buildWithBake(dockerCli command.Cli) (bool, error) { _, err = manager.GetPlugin("buildx", dockerCli, &cobra.Command{}) if err != nil { if errdefs.IsNotFound(err) { - logrus.Warnf("Docker Compose requires buildx plugin to be installed") + logrus.Warnf("buildx Docker CLI plugin not found: falling back to the classic builder. " + + "BuildKit-only build features (multi-arch, secrets, ssh, additional contexts, ...) will not be available") return false, nil } return false, err diff --git a/pkg/compose/build_classic.go b/pkg/compose/build_classic.go index af94121f56..3e7afa2432 100644 --- a/pkg/compose/build_classic.go +++ b/pkg/compose/build_classic.go @@ -232,19 +232,19 @@ func (s *composeService) doBuildImage(ctx context.Context, project *types.Projec // doesn't implement func checkClassicBuilderSupported(service types.ServiceConfig) error { if len(service.Build.Platforms) > 1 { - return fmt.Errorf("the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit") + return fmt.Errorf("the classic builder doesn't support multi-arch build; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0") } if service.Build.Privileged { - return fmt.Errorf("the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit") + return fmt.Errorf("the classic builder doesn't support privileged mode; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0") } if len(service.Build.AdditionalContexts) > 0 { - return fmt.Errorf("the classic builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit") + return fmt.Errorf("the classic builder doesn't support additional contexts; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0") } if len(service.Build.SSH) > 0 { - return fmt.Errorf("the classic builder doesn't support SSH keys, set DOCKER_BUILDKIT=1 to use BuildKit") + return fmt.Errorf("the classic builder doesn't support SSH keys; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0") } if len(service.Build.Secrets) > 0 { - return fmt.Errorf("the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit") + return fmt.Errorf("the classic builder doesn't support secrets; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0") } return nil } diff --git a/pkg/compose/create.go b/pkg/compose/create.go index c52c2e5863..b0f60ce30d 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -124,8 +124,8 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt return err } - // Emit "Running" events for containers that are already up-to-date, - // matching the previous convergence behavior for progress display. + // Emit "Running" events for containers that are already up-to-date, so + // the progress display accounts for containers the plan will not touch. emitRunningEvents(project, observed, plan, s.events) return s.executePlan(ctx, project, observed, plan) @@ -659,7 +659,7 @@ func defaultNetworkSettings(project *types.Project, // in the network configuration instead of connecting the container to each extra // network individually after creation. // For older API versions, extra networks are connected via NetworkConnect after - // container creation (see createMobyContainer in convergence.go). + // container creation (see createMobyContainer in service_containers.go). if !versions.LessThan(version, apiVersion144) { for _, networkKey := range serviceNetworks { epSettings, err := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases) @@ -1461,8 +1461,8 @@ func (s *composeService) createNetwork(ctx context.Context, n *types.NetworkConf if _, err := s.apiClient().NetworkCreate(ctx, n.Name, networkCreateOptions); err != nil { // A concurrent `docker compose up|run` may have created the same network // between the observed-state snapshot and now. Treat the resulting - // conflict as success rather than failing hard, mirroring the retry the - // previous ensureNetwork performed. + // conflict as success rather than failing hard: the network we wanted + // exists. if errdefs.IsConflict(err) { s.events.On(createdEvent(networkEventName)) return nil diff --git a/pkg/compose/observed_state.go b/pkg/compose/observed_state.go index c2ade89db8..cfef7f3718 100644 --- a/pkg/compose/observed_state.go +++ b/pkg/compose/observed_state.go @@ -151,8 +151,9 @@ func (s *composeService) collectObservedState(ctx context.Context, project *type } // --- Containers --- - // Use oneOffInclude to detect orphaned one-off containers (matching the - // previous behavior of create() which used oneOffInclude + isOrphaned). + // One-off (run) containers are included in the listing on purpose: exited + // one-offs are classified as orphans below, so `--remove-orphans` can + // clean them up. raw, err := s.getContainers(ctx, project.Name, oneOffInclude, true) if err != nil { return nil, err @@ -365,8 +366,9 @@ func (s *ObservedState) setResolvedVolumes(volumes map[string]string) { } // emitRunningEvents emits "Running" progress events for containers that are already -// running and have no operations planned for them. This matches the previous behavior -// where convergence.ensureService emitted runningEvent for up-to-date containers. +// running and have no operations planned for them, so the progress display +// accounts for every container of the project — including the up-to-date ones +// the plan deliberately leaves alone. // // Iterates project.Services (not observed.Containers) so that containers of // disabled services (e.g. dependencies untouched by `compose run --no-deps`) diff --git a/pkg/compose/reconcile.go b/pkg/compose/reconcile.go index 752e303ba3..1d6b7f98e5 100644 --- a/pkg/compose/reconcile.go +++ b/pkg/compose/reconcile.go @@ -192,7 +192,8 @@ func (r *reconciler) resolveObserved() { // Divergence is detected by comparing NetworkHash(desired) with the config-hash // persisted on the live network (observed.ConfigHash). A network with no // recorded hash (e.g. created by an older Compose or manually) is left -// untouched, matching the previous ensureNetwork behavior. +// untouched: without a recorded hash there is no reliable way to tell +// configuration drift apart from deliberate manual setup. // // A rename (observed.Name != desired.Name) also diverges the hash — NetworkHash // includes the name — and is handled by the same recreation path: the old @@ -242,7 +243,8 @@ func (r *reconciler) planCreateNetwork(key string, networkConfig *types.NetworkC // Attached containers must be disconnected before the network can be removed // (Docker refuses to remove a network with active endpoints) and are reconnected // to the fresh network afterwards — they keep their identity and are not -// recreated, matching the previous ensureNetwork/removeDivergedNetwork behavior. +// recreated: a network definition change alone is not a reason to lose +// container state. // // Stops are deduplicated through stoppedByPlan so a container attached to several // diverged networks (or later recreated by reconcileContainers) is stopped once. @@ -345,8 +347,9 @@ func (r *reconciler) planRecreateNetworks(keys []string) { // // Divergence is detected by comparing VolumeHash(desired) with the config-hash // persisted on the live volume (observed.ConfigHash). A volume with no recorded -// hash (e.g. created by an older Compose) is left untouched, matching the -// previous ensureVolume behavior. +// hash (e.g. created by an older Compose) is left untouched: without a +// recorded hash there is no reliable way to tell configuration drift apart +// from deliberate manual setup, and volumes carry data. func (r *reconciler) reconcileVolumes() error { var diverged []string for _, key := range sortedKeys(r.project.Volumes) { @@ -368,16 +371,16 @@ func (r *reconciler) reconcileVolumes() error { } if observed.Name != desired.Name { // The volume was renamed: the live volume matched by label carries a - // different name, i.e. a distinct Docker resource. Match the - // historical additive behavior — create the new volume and leave the - // old one (and its data) untouched — instead of prompting to delete - // data under a name that does not exist yet. + // different name, i.e. a distinct Docker resource. A rename is + // additive — create the new volume and leave the old one (and its + // data) untouched — instead of prompting to delete data under a + // name that does not exist yet. r.planCreateVolume(key, &desired, "renamed") // Rewrite the observed name to the desired one so reconcileContainers // detects the mount mismatch and migrates existing containers onto - // the new volume within the same up (as the pre-reconcile ensureVolume - // path did), and so later runs match deterministically on the new - // name rather than split-braining between the two. + // the new volume within the same up, and so later runs match + // deterministically on the new name rather than split-braining + // between the two. observed.Name = desired.Name r.resolvedVolumes[key] = observed continue @@ -676,8 +679,9 @@ func (r *reconciler) reconcileService(service types.ServiceConfig) error { } parentRecreated := r.parentNamespaceRecreated(service) - // Sort containers: obsolete first, then by number descending, then reverse - // to get the same ordering as the existing convergence code. + // Order containers so that the scale-down below (i >= expected) trims + // obsolete containers and the highest replica numbers first — see + // sortContainers for the resulting ordering. r.sortContainers(containers, service, expectedHash, parentRecreated, strategy) // Collect dependency nodes that container creation should depend on @@ -716,7 +720,11 @@ func (r *reconciler) reconcileService(service types.ServiceConfig) error { // Container is up-to-date switch oc.State { case container.StateRunning, container.StateCreated, container.StateRestarting, container.StateExited: - // Nothing to do (exited containers are left as-is, matching convergence.go behavior) + // Nothing to plan. Starting created/exited containers is NOT the + // plan's job: `up` runs a separate start phase afterwards + // (start.go), which lists containers again and starts them in + // dependency order. Exited containers are deliberately left as-is + // here so that phase (or the user) decides. default: // Any other state (paused, dead, ...): attempt to (re)start lastNode = r.plan.addNode(Operation{ @@ -1009,8 +1017,13 @@ func (r *reconciler) infrastructureDeps(service types.ServiceConfig) []*PlanNode return deps } -// sortContainers sorts containers the same way as convergence.go:138-160: -// obsolete first, then by container number descending, then reversed. +// sortContainers orders the slice so that, read from the front, up-to-date +// containers come first in ascending replica-number order, followed by the +// containers that must be recreated (the comparator sorts obsolete-first and +// number-descending, then the slice is reversed). Scale-down trims the tail +// of this slice (i >= expected in reconcileService), so this ordering is what +// guarantees that obsolete containers and the highest replica numbers are +// removed first while low-numbered healthy replicas survive. // // mustRecreate is evaluated once per container before sorting to avoid // quadratic re-evaluation in the comparator. diff --git a/pkg/compose/convergence.go b/pkg/compose/service_containers.go similarity index 96% rename from pkg/compose/convergence.go rename to pkg/compose/service_containers.go index a5e0c146fe..4e49fb3988 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/service_containers.go @@ -38,17 +38,23 @@ import ( "github.com/docker/compose/v5/pkg/api" ) +// This file gathers the per-service container helpers shared by both +// lifecycle engines: the plan-based reconciler (reconcile.go, entered through +// create/up) and the imperative dependency-ordered engine (dependencies.go, +// used by start/stop/restart/down). It covers container naming, resolution of +// service references (volumes_from, network_mode/ipc/pid, links), dependency +// waiting, container creation through the Docker API, and service startup. + const ( doubledContainerNameWarning = "WARNING: The %q service is using the custom container name %q. " + "Docker requires each container to have a unique name. " + "Remove the custom name to scale the service" ) -// convergence manages service's container lifecycle. -// Based on initially observed state, it reconciles the existing container with desired state, which might include -// re-creating container, adding or removing replicas, or starting stopped containers. -// Cross services dependencies are managed by creating services in expected order and updating `service:xx` reference -// when a service has converged, so dependent ones can be managed with resolved containers references. +// getScale returns the number of replicas the service must run. A service +// pinned to a custom container_name cannot scale beyond one replica, as every +// container needs a distinct name: this is rejected here rather than at +// container-creation time. func getScale(config types.ServiceConfig) (int, error) { scale := config.GetScale() if scale > 1 && config.ContainerName != "" { diff --git a/pkg/compose/convergence_test.go b/pkg/compose/service_containers_test.go similarity index 100% rename from pkg/compose/convergence_test.go rename to pkg/compose/service_containers_test.go diff --git a/pkg/e2e/bridge_test.go b/pkg/e2e/bridge_test.go index 7212bcaf2c..19f8eec478 100644 --- a/pkg/e2e/bridge_test.go +++ b/pkg/e2e/bridge_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/build_test.go b/pkg/e2e/build_test.go index 25fd08b4fd..3992508946 100644 --- a/pkg/e2e/build_test.go +++ b/pkg/e2e/build_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors @@ -402,7 +404,7 @@ func TestBuildPlatformsStandardErrors(t *testing.T) { }) res.Assert(t, icmd.Expected{ ExitCode: 1, - Err: "the classic builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use BuildKit", + Err: "the classic builder doesn't support multi-arch build; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0", }) }) @@ -470,7 +472,7 @@ func TestBuildPlatformsStandardErrors(t *testing.T) { }) res.Assert(t, icmd.Expected{ ExitCode: 1, - Err: "the classic builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use BuildKit", + Err: "the classic builder doesn't support privileged mode; building with BuildKit requires the buildx Docker CLI plugin, and DOCKER_BUILDKIT must not be set to 0", }) }) } diff --git a/pkg/e2e/cancel_test.go b/pkg/e2e/cancel_test.go index 64f3ff609a..4802d64abb 100644 --- a/pkg/e2e/cancel_test.go +++ b/pkg/e2e/cancel_test.go @@ -1,4 +1,4 @@ -//go:build !windows +//go:build e2e && !windows /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/cascade_test.go b/pkg/e2e/cascade_test.go index a201acc2b3..f9f72ca1ef 100644 --- a/pkg/e2e/cascade_test.go +++ b/pkg/e2e/cascade_test.go @@ -1,4 +1,4 @@ -//go:build !windows +//go:build e2e && !windows /* Copyright 2022 Docker Compose CLI authors diff --git a/pkg/e2e/commit_test.go b/pkg/e2e/commit_test.go index 7298b6e798..c0e3217ac5 100644 --- a/pkg/e2e/commit_test.go +++ b/pkg/e2e/commit_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2023 Docker Compose CLI authors diff --git a/pkg/e2e/compose_environment_test.go b/pkg/e2e/compose_environment_test.go index 36fa855042..447104c963 100644 --- a/pkg/e2e/compose_environment_test.go +++ b/pkg/e2e/compose_environment_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/compose_exec_test.go b/pkg/e2e/compose_exec_test.go index 9e58d56684..b5cf163da9 100644 --- a/pkg/e2e/compose_exec_test.go +++ b/pkg/e2e/compose_exec_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/compose_run_build_once_test.go b/pkg/e2e/compose_run_build_once_test.go index 31b124665c..608adfe127 100644 --- a/pkg/e2e/compose_run_build_once_test.go +++ b/pkg/e2e/compose_run_build_once_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/compose_run_test.go b/pkg/e2e/compose_run_test.go index 3a80fdc86b..31feafe504 100644 --- a/pkg/e2e/compose_run_test.go +++ b/pkg/e2e/compose_run_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/compose_test.go b/pkg/e2e/compose_test.go index f0ff1da070..59d6cdd481 100644 --- a/pkg/e2e/compose_test.go +++ b/pkg/e2e/compose_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/compose_up_test.go b/pkg/e2e/compose_up_test.go index 1acaf7393d..35c2f5c57b 100644 --- a/pkg/e2e/compose_up_test.go +++ b/pkg/e2e/compose_up_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/config_test.go b/pkg/e2e/config_test.go index 585ee7419f..0be97c28eb 100644 --- a/pkg/e2e/config_test.go +++ b/pkg/e2e/config_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/configs_test.go b/pkg/e2e/configs_test.go index 899c5168ff..05b2c99bf6 100644 --- a/pkg/e2e/configs_test.go +++ b/pkg/e2e/configs_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/container_name_test.go b/pkg/e2e/container_name_test.go index 79332ab6ac..2f0fac7900 100644 --- a/pkg/e2e/container_name_test.go +++ b/pkg/e2e/container_name_test.go @@ -1,4 +1,4 @@ -//go:build !windows +//go:build e2e && !windows /* Copyright 2022 Docker Compose CLI authors diff --git a/pkg/e2e/cp_test.go b/pkg/e2e/cp_test.go index e9ea7691ad..5847af4e96 100644 --- a/pkg/e2e/cp_test.go +++ b/pkg/e2e/cp_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/env_file_test.go b/pkg/e2e/env_file_test.go index 5a5a964306..c7ae466dcb 100644 --- a/pkg/e2e/env_file_test.go +++ b/pkg/e2e/env_file_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/events_test.go b/pkg/e2e/events_test.go index 1c9b19334a..ef20d7264c 100644 --- a/pkg/e2e/events_test.go +++ b/pkg/e2e/events_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/exec_test.go b/pkg/e2e/exec_test.go index 1f8d1018c0..d5e70087f4 100644 --- a/pkg/e2e/exec_test.go +++ b/pkg/e2e/exec_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2023 Docker Compose CLI authors diff --git a/pkg/e2e/export_test.go b/pkg/e2e/export_test.go index 5cceb693a1..1244488006 100644 --- a/pkg/e2e/export_test.go +++ b/pkg/e2e/export_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2023 Docker Compose CLI authors diff --git a/pkg/e2e/expose_test.go b/pkg/e2e/expose_test.go index f7e7d3c2f4..0fb7d4d15d 100644 --- a/pkg/e2e/expose_test.go +++ b/pkg/e2e/expose_test.go @@ -1,4 +1,4 @@ -//go:build !windows +//go:build e2e && !windows /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/healthcheck_test.go b/pkg/e2e/healthcheck_test.go index 2cb42fd54a..b25376f9cc 100644 --- a/pkg/e2e/healthcheck_test.go +++ b/pkg/e2e/healthcheck_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2023 Docker Compose CLI authors diff --git a/pkg/e2e/hooks_test.go b/pkg/e2e/hooks_test.go index 8d44de8380..e7db829f33 100644 --- a/pkg/e2e/hooks_test.go +++ b/pkg/e2e/hooks_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2023 Docker Compose CLI authors diff --git a/pkg/e2e/image_identity_corner_test.go b/pkg/e2e/image_identity_corner_test.go index 810304219a..4f2d3154ff 100644 --- a/pkg/e2e/image_identity_corner_test.go +++ b/pkg/e2e/image_identity_corner_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2026 Docker Compose CLI authors diff --git a/pkg/e2e/image_identity_test.go b/pkg/e2e/image_identity_test.go index dd1a9b01f9..b2e881c15f 100644 --- a/pkg/e2e/image_identity_test.go +++ b/pkg/e2e/image_identity_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/images_test.go b/pkg/e2e/images_test.go index 8511d7ff85..5ffdf3a109 100644 --- a/pkg/e2e/images_test.go +++ b/pkg/e2e/images_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2026 Docker Compose CLI authors diff --git a/pkg/e2e/ipc_test.go b/pkg/e2e/ipc_test.go index 010854b60e..63dcddb955 100644 --- a/pkg/e2e/ipc_test.go +++ b/pkg/e2e/ipc_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/logs_test.go b/pkg/e2e/logs_test.go index afc2e08908..493385dae8 100644 --- a/pkg/e2e/logs_test.go +++ b/pkg/e2e/logs_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/main_test.go b/pkg/e2e/main_test.go index 415987bc71..9a710c7a9c 100644 --- a/pkg/e2e/main_test.go +++ b/pkg/e2e/main_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/model_test.go b/pkg/e2e/model_test.go index a9e6d3d6fd..baeb6c3d24 100644 --- a/pkg/e2e/model_test.go +++ b/pkg/e2e/model_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/multiplatform_test.go b/pkg/e2e/multiplatform_test.go index 651c51519b..2590a43408 100644 --- a/pkg/e2e/multiplatform_test.go +++ b/pkg/e2e/multiplatform_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2026 Docker Compose CLI authors diff --git a/pkg/e2e/networks_test.go b/pkg/e2e/networks_test.go index 438e31eb28..462ccb35d7 100644 --- a/pkg/e2e/networks_test.go +++ b/pkg/e2e/networks_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/noDeps_test.go b/pkg/e2e/noDeps_test.go index deacbf023b..f1ad0be2c9 100644 --- a/pkg/e2e/noDeps_test.go +++ b/pkg/e2e/noDeps_test.go @@ -1,4 +1,4 @@ -//go:build !windows +//go:build e2e && !windows /* Copyright 2022 Docker Compose CLI authors diff --git a/pkg/e2e/orphans_test.go b/pkg/e2e/orphans_test.go index 0e12a494a1..77eff1562c 100644 --- a/pkg/e2e/orphans_test.go +++ b/pkg/e2e/orphans_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/pause_test.go b/pkg/e2e/pause_test.go index d8b037c26c..0fa4489138 100644 --- a/pkg/e2e/pause_test.go +++ b/pkg/e2e/pause_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/profiles_test.go b/pkg/e2e/profiles_test.go index 6c1256a05f..0a2883aa84 100644 --- a/pkg/e2e/profiles_test.go +++ b/pkg/e2e/profiles_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/providers_test.go b/pkg/e2e/providers_test.go index 91b0ab0450..0b8031c3f4 100644 --- a/pkg/e2e/providers_test.go +++ b/pkg/e2e/providers_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/ps_test.go b/pkg/e2e/ps_test.go index 8ea47f7463..2aae0a53ae 100644 --- a/pkg/e2e/ps_test.go +++ b/pkg/e2e/ps_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/publish_test.go b/pkg/e2e/publish_test.go index e8c46c7d0a..902c542215 100644 --- a/pkg/e2e/publish_test.go +++ b/pkg/e2e/publish_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/pull_test.go b/pkg/e2e/pull_test.go index 979b08de42..906fff4f67 100644 --- a/pkg/e2e/pull_test.go +++ b/pkg/e2e/pull_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/recreate_no_deps_test.go b/pkg/e2e/recreate_no_deps_test.go index 8ba94b74eb..e9a5b0267c 100644 --- a/pkg/e2e/recreate_no_deps_test.go +++ b/pkg/e2e/recreate_no_deps_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2022 Docker Compose CLI authors diff --git a/pkg/e2e/restart_test.go b/pkg/e2e/restart_test.go index 21746e0dce..6f0e316b6a 100644 --- a/pkg/e2e/restart_test.go +++ b/pkg/e2e/restart_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/scale_test.go b/pkg/e2e/scale_test.go index 92e135075e..9184d03a49 100644 --- a/pkg/e2e/scale_test.go +++ b/pkg/e2e/scale_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/secrets_test.go b/pkg/e2e/secrets_test.go index 3147c3765b..78ead037d7 100644 --- a/pkg/e2e/secrets_test.go +++ b/pkg/e2e/secrets_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/start_stop_test.go b/pkg/e2e/start_stop_test.go index bad7fdb4a2..5bf1f3e589 100644 --- a/pkg/e2e/start_stop_test.go +++ b/pkg/e2e/start_stop_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/testdata_test.go b/pkg/e2e/testdata_test.go index 780fa27827..b0e43b45d7 100644 --- a/pkg/e2e/testdata_test.go +++ b/pkg/e2e/testdata_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/up_test.go b/pkg/e2e/up_test.go index c4d0856a14..01c11b7b93 100644 --- a/pkg/e2e/up_test.go +++ b/pkg/e2e/up_test.go @@ -1,4 +1,4 @@ -//go:build !windows +//go:build e2e && !windows /* Copyright 2022 Docker Compose CLI authors diff --git a/pkg/e2e/volumes_test.go b/pkg/e2e/volumes_test.go index 0407f016a3..1827d9fbba 100644 --- a/pkg/e2e/volumes_test.go +++ b/pkg/e2e/volumes_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/wait_test.go b/pkg/e2e/wait_test.go index 23a80020d1..b8fb8d86d7 100644 --- a/pkg/e2e/wait_test.go +++ b/pkg/e2e/wait_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2020 Docker Compose CLI authors diff --git a/pkg/e2e/watch_test.go b/pkg/e2e/watch_test.go index 225d7fa065..7267918505 100644 --- a/pkg/e2e/watch_test.go +++ b/pkg/e2e/watch_test.go @@ -1,3 +1,5 @@ +//go:build e2e + /* Copyright 2023 Docker Compose CLI authors