Skip to content

cli/compose: assorted fixes and cleanups#6803

Open
thaJeztah wants to merge 6 commits intodocker:masterfrom
thaJeztah:compose_fixes
Open

cli/compose: assorted fixes and cleanups#6803
thaJeztah wants to merge 6 commits intodocker:masterfrom
thaJeztah:compose_fixes

Conversation

@thaJeztah
Copy link
Member

cli/compose/convert: convertUlimits: modernize

cli/compose/convert: convertEndpointSpec: fix sorting of ports

The existing code only sorted by PublishedPort (host port), and did
not account for multiple ports mapped to the same host-port, but
using a different protocol.

cli/compose/loader: mergeServices: tidy up and modernize

  • construct merge-opts as a slice
  • remove intermediate var for overrideServices
  • use slices.SortFunc for sorting

cli/compose/loader: mergeServices: remove intermediate map for overrides

The code was using an intermediate map, indexed by name, for both the
"base" services and for overrides. This meant that multiple files
containing an override for a service would be ignored.

Remove the intermediate map for overrides, and apply all overrides for
a service instead.

cli/compose/loader: mergeServices: inline mapByName

It's now only used once; let's inline it to remove some abstraction.

cli/compose/loader: remove getLoggingDriver

Inline it in mergeLoggingConfig and add some vars, which also
makes it more readable.

- Human readable description for the release notes

- A picture of a cute animal (not mandatory but encouraged)

@thaJeztah thaJeztah added status/2-code-review area/stack kind/refactor PR's that refactor, or clean-up code labels Feb 15, 2026
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 62.79070% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cli/compose/convert/service.go 33.33% 13 Missing and 1 partial ⚠️
cli/compose/loader/merge.go 90.90% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The existing code only sorted by PublishedPort (host port), and did
not account for multiple ports mapped to the same host-port, but
using a different protocol.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- construct merge-opts as a slice
- remove intermediate var for overrideServices
- use slices.SortFunc for sorting

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The code was using an intermediate map, indexed by name, for both the
"base" services _and_ for overrides. This meant that multiple files
containing an override for a service would be ignored.

Remove the intermediate map for overrides, and apply all overrides for
a service instead.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It's now only used once; let's inline it to remove some abstraction.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Inline it in mergeLoggingConfig and add some vars, which also
makes it more readable.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR applies a set of small Compose-related fixes and modernizations across the loader and Swarm conversion paths, improving determinism and correctness when merging/sorting configuration.

Changes:

  • Modernize mergeServices to apply service overrides sequentially (so multiple overrides for the same service aren’t dropped) and use slices.SortFunc for sorting.
  • Fix convertEndpointSpec port sorting to include secondary fields (target/protocol/mode), preventing ambiguous ordering when multiple entries share the same published port.
  • Simplify convertUlimits by removing an unnecessary intermediate map and sorting the resulting slice.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
cli/compose/loader/merge.go Refactors service merge logic to apply multiple overrides correctly and modernizes sorting/merge options setup.
cli/compose/convert/service.go Improves port sort determinism for Swarm endpoint specs and simplifies ulimit conversion logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 599 to +610
func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortConfig) *swarm.EndpointSpec {
portConfigs := make([]swarm.PortConfig, 0, len(source))
for _, port := range source {
portConfig := swarm.PortConfig{
portConfigs = append(portConfigs, swarm.PortConfig{
Protocol: network.IPProtocol(port.Protocol),
TargetPort: port.Target,
PublishedPort: port.Published,
PublishMode: swarm.PortConfigPublishMode(port.Mode),
}
portConfigs = append(portConfigs, portConfig)
})
}

sort.Slice(portConfigs, func(i, j int) bool {
return portConfigs[i].PublishedPort < portConfigs[j].PublishedPort
})
slices.SortFunc(portConfigs, compareSwarmPortConfig)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convertEndpointSpec now sorts ports using compareSwarmPortConfig to handle ties beyond PublishedPort, but the existing TestConvertEndpointSpec only covers distinct PublishedPort values. Add a test case with multiple ports sharing the same PublishedPort but different protocol/target/mode to prevent regressions in the new ordering logic.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that will come with the linked PR; it's how I stumbled on it

Comment on lines +78 to 87
for _, overrideService := range override {
if baseService, ok := baseServices[overrideService.Name]; ok {
if err := mergo.Merge(&baseService, &overrideService, mergeOpts...); err != nil {
return base, fmt.Errorf("cannot merge service %s: %w", overrideService.Name, err)
}
baseServices[name] = baseService
baseServices[overrideService.Name] = baseService
continue
}
baseServices[name] = overrideService
baseServices[overrideService.Name] = overrideService
}
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeServices now applies overrides sequentially (fixing the prior behavior of dropping earlier overrides), but there is no unit test asserting that multiple overrides for the same service name are all applied in order. Add a test that passes an override slice containing the same service name multiple times and verifies the final merged service includes all override changes.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving that for a later exercise

@thaJeztah thaJeztah requested a review from vvoland February 16, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/stack kind/refactor PR's that refactor, or clean-up code status/2-code-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants