prefer use of slices.DeleteFunc

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2025-05-27 14:27:45 +02:00 committed by Guillaume Lours
parent 12b73bea73
commit 23fef850b9
5 changed files with 14 additions and 150 deletions

View File

@ -24,6 +24,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"slices"
"strconv" "strconv"
"strings" "strings"
@ -32,7 +33,6 @@ import (
"github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/prompt" "github.com/docker/compose/v2/pkg/prompt"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/docker/api/types/blkiodev" "github.com/docker/docker/api/types/blkiodev"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
@ -1312,8 +1312,8 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
} }
// NetworkList Matches all or part of a network name, so we have to filter for a strict match // NetworkList Matches all or part of a network name, so we have to filter for a strict match
networks = utils.Filter(networks, func(net network.Summary) bool { networks = slices.DeleteFunc(networks, func(net network.Summary) bool {
return net.Name == n.Name return net.Name != n.Name
}) })
for _, net := range networks { for _, net := range networks {
@ -1436,18 +1436,19 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
if len(networks) == 0 { if len(networks) == 0 {
// in this instance, n.Name is really an ID // in this instance, n.Name is really an ID
sn, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{}) sn, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{})
if err != nil && !errdefs.IsNotFound(err) { if err == nil {
networks = append(networks, sn)
} else if !errdefs.IsNotFound(err) {
return "", err return "", err
} }
networks = append(networks, sn)
} }
// NetworkList API doesn't return the exact name match, so we can retrieve more than one network with a request // NetworkList API doesn't return the exact name match, so we can retrieve more than one network with a request
networks = utils.Filter(networks, func(net network.Inspect) bool { networks = slices.DeleteFunc(networks, func(net network.Inspect) bool {
// later in this function, the name is changed the to ID.
// this function is called during the rebuild stage of `compose watch`. // this function is called during the rebuild stage of `compose watch`.
// we still require just one network back, but we need to run the search on the ID // we still require just one network back, but we need to run the search on the ID
return net.Name == n.Name || net.ID == n.Name return net.Name != n.Name && net.ID != n.Name
}) })
switch len(networks) { switch len(networks) {

View File

@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
"slices"
"github.com/compose-spec/compose-go/v2/types" "github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
cmd "github.com/docker/cli/cli/command/container" cmd "github.com/docker/cli/cli/command/container"
"github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringid"
) )
@ -130,11 +130,11 @@ func applyRunOptions(project *types.Project, service *types.ServiceConfig, opts
if len(opts.CapAdd) > 0 { if len(opts.CapAdd) > 0 {
service.CapAdd = append(service.CapAdd, opts.CapAdd...) service.CapAdd = append(service.CapAdd, opts.CapAdd...)
service.CapDrop = utils.Remove(service.CapDrop, opts.CapAdd...) service.CapDrop = slices.DeleteFunc(service.CapDrop, func(e string) bool { return slices.Contains(opts.CapAdd, e) })
} }
if len(opts.CapDrop) > 0 { if len(opts.CapDrop) > 0 {
service.CapDrop = append(service.CapDrop, opts.CapDrop...) service.CapDrop = append(service.CapDrop, opts.CapDrop...)
service.CapAdd = utils.Remove(service.CapAdd, opts.CapDrop...) service.CapAdd = slices.DeleteFunc(service.CapAdd, func(e string) bool { return slices.Contains(opts.CapDrop, e) })
} }
if opts.WorkingDir != "" { if opts.WorkingDir != "" {
service.WorkingDir = opts.WorkingDir service.WorkingDir = opts.WorkingDir

View File

@ -265,7 +265,7 @@ func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo
if _, ok := watched[container.ID]; ok { if _, ok := watched[container.ID]; ok {
eType := api.ContainerEventStopped eType := api.ContainerEventStopped
if slices.Contains(replaced, container.ID) { if slices.Contains(replaced, container.ID) {
utils.Remove(replaced, container.ID) replaced = slices.DeleteFunc(replaced, func(e string) bool { return e == container.ID })
eType = api.ContainerEventRecreated eType = api.ContainerEventRecreated
} }
listener(api.ContainerEvent{ listener(api.ContainerEvent{
@ -292,7 +292,7 @@ func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo
eType := api.ContainerEventExit eType := api.ContainerEventExit
if slices.Contains(replaced, container.ID) { if slices.Contains(replaced, container.ID) {
utils.Remove(replaced, container.ID) replaced = slices.DeleteFunc(replaced, func(e string) bool { return e == container.ID })
eType = api.ContainerEventRecreated eType = api.ContainerEventRecreated
} }

View File

@ -1,42 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package utils
import (
"slices"
)
// Remove removes all elements from origin slice
func Remove[T comparable](origin []T, elements ...T) []T {
var filtered []T
for _, v := range origin {
if !slices.Contains(elements, v) {
filtered = append(filtered, v)
}
}
return filtered
}
func Filter[T any](elements []T, predicate func(T) bool) []T {
var filtered []T
for _, v := range elements {
if predicate(v) {
filtered = append(filtered, v)
}
}
return filtered
}

View File

@ -1,95 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package utils
import (
"testing"
specs "github.com/opencontainers/image-spec/specs-go/v1"
)
func TestContains(t *testing.T) {
source := []specs.Platform{
{
Architecture: "linux/amd64",
OS: "darwin",
OSVersion: "",
OSFeatures: nil,
Variant: "",
},
{
Architecture: "linux/arm64",
OS: "linux",
OSVersion: "12",
OSFeatures: nil,
Variant: "v8",
},
{
Architecture: "",
OS: "",
OSVersion: "",
OSFeatures: nil,
Variant: "",
},
}
type args struct {
origin []specs.Platform
element specs.Platform
}
tests := []struct {
name string
args args
want bool
}{
{
name: "element found",
args: args{
origin: source,
element: specs.Platform{
Architecture: "linux/arm64",
OS: "linux",
OSVersion: "12",
OSFeatures: nil,
Variant: "v8",
},
},
want: true,
},
{
name: "element not found",
args: args{
origin: source,
element: specs.Platform{
Architecture: "linux/arm64",
OS: "darwin",
OSVersion: "12",
OSFeatures: nil,
Variant: "v8",
},
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Contains(tt.args.origin, tt.args.element); got != tt.want {
t.Errorf("Contains() = %v, want %v", got, tt.want)
}
})
}
}