diff --git a/cli-plugins/manager/plugin.go b/cli-plugins/manager/plugin.go index 4270bac2cc..e0fe504254 100644 --- a/cli-plugins/manager/plugin.go +++ b/cli-plugins/manager/plugin.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package manager import ( @@ -167,8 +170,7 @@ func (p *Plugin) RunHook(ctx context.Context, hookData hooks.Request) ([]byte, e out, err := pCmd.Output() if err != nil { - var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if _, ok := errors.AsType[*exec.ExitError](err); ok { return nil, wrapAsPluginError(err, "plugin hook subcommand exited unsuccessfully") } return nil, wrapAsPluginError(err, "failed to execute plugin hook subcommand: "+pCmd.String()) diff --git a/cli-plugins/plugin/plugin.go b/cli-plugins/plugin/plugin.go index 58ee3b8762..a90e4b6f6c 100644 --- a/cli-plugins/plugin/plugin.go +++ b/cli-plugins/plugin/plugin.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package plugin import ( @@ -97,8 +100,7 @@ func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata, ops . plugin := makeCmd(dockerCLI) if err := RunPlugin(dockerCLI, plugin, meta); err != nil { - var stErr cli.StatusError - if errors.As(err, &stErr) { + if stErr, ok := errors.AsType[cli.StatusError](err); ok { // StatusError should only be used for errors, and all errors should // have a non-zero exit status, so never exit with 0 if stErr.StatusCode == 0 { // FIXME(thaJeztah): this should never be used with a zero status-code. Check if we do this anywhere. diff --git a/cli/command/container/start.go b/cli/command/container/start.go index 916f5808d7..f6cdd0c211 100644 --- a/cli/command/container/start.go +++ b/cli/command/container/start.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package container import ( @@ -169,8 +172,7 @@ func RunStart(ctx context.Context, dockerCli command.Cli, opts *StartOptions) er } } if attachErr := <-cErr; attachErr != nil { - var escapeError term.EscapeError - if errors.As(attachErr, &escapeError) { + if _, ok := errors.AsType[term.EscapeError](attachErr); ok { // The user entered the detach escape sequence. return nil } diff --git a/cli/command/context/options.go b/cli/command/context/options.go index 429f47cc41..979b692736 100644 --- a/cli/command/context/options.go +++ b/cli/command/context/options.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package context import ( @@ -69,8 +72,7 @@ func parseBool(config map[string]string, name string) (bool, error) { } res, err := strconv.ParseBool(strVal) if err != nil { - var nErr *strconv.NumError - if errors.As(err, &nErr) { + if nErr, ok := errors.AsType[*strconv.NumError](err); ok { return res, fmt.Errorf("%s: parsing %q: %w", name, nErr.Num, nErr.Err) } return res, fmt.Errorf("%s: %w", name, err) diff --git a/cli/command/image/build.go b/cli/command/image/build.go index db33e0e7c6..26a8739854 100644 --- a/cli/command/image/build.go +++ b/cli/command/image/build.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package image import ( @@ -364,8 +367,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions) err = jsonstream.Display(ctx, response.Body, streams.NewOut(buildBuff), jsonstream.WithAuxCallback(aux)) if err != nil { - var jerr *jsonstream.JSONError - if errors.As(err, &jerr) { + if jerr, ok := errors.AsType[*jsonstream.JSONError](err); ok { // If no error code is set, default to 1 if jerr.Code == 0 { jerr.Code = 1 diff --git a/cli/command/network/create_test.go b/cli/command/network/create_test.go index 7de25edb63..dc5505023a 100644 --- a/cli/command/network/create_test.go +++ b/cli/command/network/create_test.go @@ -189,8 +189,6 @@ func TestNetworkCreateWithFlags(t *testing.T) { // TestNetworkCreateIPv4 verifies behavior of the "--ipv4" option. This option // is an optional bool, and must default to "nil", not "true" or "false". func TestNetworkCreateIPv4(t *testing.T) { - boolPtr := func(val bool) *bool { return &val } - tests := []struct { doc, name string flags []string @@ -205,19 +203,19 @@ func TestNetworkCreateIPv4(t *testing.T) { doc: "IPv4 enabled", name: "ipv4-enabled", flags: []string{"--ipv4=true"}, - expected: boolPtr(true), + expected: new(true), }, { doc: "IPv4 enabled (shorthand)", name: "ipv4-enabled-shorthand", flags: []string{"--ipv4"}, - expected: boolPtr(true), + expected: new(true), }, { doc: "IPv4 disabled", name: "ipv4-disabled", flags: []string{"--ipv4=false"}, - expected: boolPtr(false), + expected: new(false), }, } @@ -243,8 +241,6 @@ func TestNetworkCreateIPv4(t *testing.T) { // TestNetworkCreateIPv6 verifies behavior of the "--ipv6" option. This option // is an optional bool, and must default to "nil", not "true" or "false". func TestNetworkCreateIPv6(t *testing.T) { - strPtr := func(val bool) *bool { return &val } - tests := []struct { doc, name string flags []string @@ -259,19 +255,19 @@ func TestNetworkCreateIPv6(t *testing.T) { doc: "IPV6 enabled", name: "ipv6-enabled", flags: []string{"--ipv6=true"}, - expected: strPtr(true), + expected: new(true), }, { doc: "IPV6 enabled (shorthand)", name: "ipv6-enabled-shorthand", flags: []string{"--ipv6"}, - expected: strPtr(true), + expected: new(true), }, { doc: "IPV6 disabled", name: "ipv6-disabled", flags: []string{"--ipv6=false"}, - expected: strPtr(false), + expected: new(false), }, } diff --git a/cli/command/stack/loader.go b/cli/command/stack/loader.go index 7c535662ce..49366e4d50 100644 --- a/cli/command/stack/loader.go +++ b/cli/command/stack/loader.go @@ -29,8 +29,7 @@ func loadComposeFile(streams command.Streams, opts deployOptions) (*composetypes config, err := loader.Load(configDetails) if err != nil { - var fpe *loader.ForbiddenPropertiesError - if errors.As(err, &fpe) { + if fpe, ok := errors.AsType[*loader.ForbiddenPropertiesError](err); ok { // this error is intentionally formatted multi-line return nil, fmt.Errorf("compose file contains unsupported options:\n\n%s\n", propertyWarnings(fpe.Properties)) //nolint:staticcheck // ignore ST1005 } diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index e23d782c7e..762bf144ff 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -399,7 +399,7 @@ func convertFileObject( } mode := config.Mode if mode == nil { - mode = uint32Ptr(0o444) + mode = new(uint32(0o444)) } return swarmReferenceObject{ @@ -413,10 +413,6 @@ func convertFileObject( }, nil } -func uint32Ptr(value uint32) *uint32 { - return &value -} - // convertExtraHosts converts : mappings to SwarmKit notation: // "IP-address hostname(s)". The original order of mappings is preserved. func convertExtraHosts(extraHosts composetypes.HostsList) []string { @@ -501,8 +497,7 @@ func convertRestartPolicy(restart string, restartPolicy *composetypes.RestartPol if i <= 0 { return nil } - p := uint64(i) - return &p + return new(uint64(i)) } switch policy.Name { @@ -529,7 +524,7 @@ func convertUpdateConfig(source *composetypes.UpdateConfig) *swarm.UpdateConfig if source == nil { return nil } - parallel := uint64(1) + var parallel uint64 = 1 if source.Parallelism != nil { parallel = *source.Parallelism } diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index 2ef349e731..7cd4db46e6 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -66,14 +66,10 @@ func TestConvertRestartPolicy(t *testing.T) { } } -func strPtr(val string) *string { - return &val -} - func TestConvertEnvironment(t *testing.T) { source := map[string]*string{ - "foo": strPtr("bar"), - "key": strPtr("value"), + "foo": new("bar"), + "key": new("value"), } env := convertEnvironment(source) assert.Check(t, is.DeepEqual([]string{"foo=bar", "key=value"}, env)) @@ -81,7 +77,7 @@ func TestConvertEnvironment(t *testing.T) { func TestConvertEnvironmentWhenNilValueExists(t *testing.T) { source := map[string]*string{ - "key": strPtr("value"), + "key": new("value"), "keyWithNoValue": nil, } env := convertEnvironment(source) @@ -466,7 +462,7 @@ func TestConvertFileObject(t *testing.T) { Target: "target", UID: "user", GID: "group", - Mode: uint32Ptr(0o644), + Mode: new(uint32(0o644)), } swarmRef, err := convertFileObject(namespace, config, lookupConfig) assert.NilError(t, err) diff --git a/cli/compose/loader/full-struct_test.go b/cli/compose/loader/full-struct_test.go index 04176bbf5a..9a6e7a76d3 100644 --- a/cli/compose/loader/full-struct_test.go +++ b/cli/compose/loader/full-struct_test.go @@ -36,7 +36,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig { Build: types.BuildConfig{ Context: "./dir", Dockerfile: "Dockerfile", - Args: map[string]*string{"foo": strPtr("bar")}, + Args: map[string]*string{"foo": new("bar")}, Target: "foo", Network: "foo", CacheFrom: []string{"foo", "bar"}, @@ -59,17 +59,17 @@ func services(workingDir, homeDir string) []types.ServiceConfig { Target: "/my_config", UID: "103", GID: "103", - Mode: uint32Ptr(0o440), + Mode: new(uint32(0o440)), }, }, ContainerName: "my-web-container", DependsOn: []string{"db", "redis"}, Deploy: types.DeployConfig{ Mode: "replicated", - Replicas: uint64Ptr(6), + Replicas: new(uint64(6)), Labels: map[string]string{"FOO": "BAR"}, RollbackConfig: &types.UpdateConfig{ - Parallelism: uint64Ptr(3), + Parallelism: new(uint64(3)), Delay: types.Duration(10 * time.Second), FailureAction: "continue", Monitor: types.Duration(60 * time.Second), @@ -77,7 +77,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig { Order: "start-first", }, UpdateConfig: &types.UpdateConfig{ - Parallelism: uint64Ptr(3), + Parallelism: new(uint64(3)), Delay: types.Duration(10 * time.Second), FailureAction: "continue", Monitor: types.Duration(60 * time.Second), @@ -111,9 +111,9 @@ func services(workingDir, homeDir string) []types.ServiceConfig { }, RestartPolicy: &types.RestartPolicy{ Condition: "on-failure", - Delay: durationPtr(5 * time.Second), - MaxAttempts: uint64Ptr(3), - Window: durationPtr(2 * time.Minute), + Delay: new(types.Duration(5 * time.Second)), + MaxAttempts: new(uint64(3)), + Window: new(types.Duration(2 * time.Minute)), }, Placement: types.Placement{ Constraints: []string{"node=foo"}, @@ -132,10 +132,10 @@ func services(workingDir, homeDir string) []types.ServiceConfig { DomainName: "foo.com", Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"}, Environment: map[string]*string{ - "FOO": strPtr("foo_from_env_file"), - "BAR": strPtr("bar_from_env_file_2"), - "BAZ": strPtr("baz_from_service_def"), - "QUX": strPtr("qux_from_environment"), + "FOO": new("foo_from_env_file"), + "BAR": new("bar_from_env_file_2"), + "BAZ": new("baz_from_service_def"), + "QUX": new("qux_from_environment"), }, EnvFile: []string{ "./example1.env", @@ -158,11 +158,11 @@ func services(workingDir, homeDir string) []types.ServiceConfig { }, HealthCheck: &types.HealthCheckConfig{ Test: types.HealthCheckTest([]string{"CMD-SHELL", "echo \"hello world\""}), - Interval: durationPtr(10 * time.Second), - Timeout: durationPtr(1 * time.Second), - Retries: uint64Ptr(5), - StartPeriod: durationPtr(15 * time.Second), - StartInterval: durationPtr(1 * time.Second), + Interval: new(types.Duration(10 * time.Second)), + Timeout: new(types.Duration(1 * time.Second)), + Retries: new(uint64(5)), + StartPeriod: new(types.Duration(15 * time.Second)), + StartInterval: new(types.Duration(1 * time.Second)), }, Hostname: "foo", Image: "redis", @@ -348,7 +348,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig { Target: "my_secret", UID: "103", GID: "103", - Mode: uint32Ptr(0o440), + Mode: new(uint32(0o440)), }, }, SecurityOpt: []string{ @@ -357,7 +357,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig { }, StdinOpen: true, StopSignal: "SIGUSR1", - StopGracePeriod: durationPtr(20 * time.Second), + StopGracePeriod: new(types.Duration(20 * time.Second)), Sysctls: map[string]string{ "net.core.somaxconn": "1024", "net.ipv4.tcp_syncookies": "0", diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 294cec6567..1b97ffaf2d 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -9,7 +9,6 @@ import ( "runtime" "sort" "testing" - "time" "github.com/docker/cli/cli/compose/types" "github.com/google/go-cmp/cmp/cmpopts" @@ -179,10 +178,6 @@ var samplePortsConfig = []types.ServicePortConfig{ }, } -func strPtr(val string) *string { - return &val -} - var sampleConfig = types.Config{ Version: "3.13", Services: []types.ServiceConfig{ @@ -197,7 +192,7 @@ var sampleConfig = types.Config{ { Name: "bar", Image: "busybox", - Environment: map[string]*string{"FOO": strPtr("1")}, + Environment: map[string]*string{"FOO": new("1")}, Networks: map[string]*types.ServiceNetworkConfig{ "with_ipam": nil, }, @@ -530,10 +525,10 @@ services: assert.NilError(t, err) expected := types.MappingWithEquals{ - "FOO": strPtr("1"), - "BAR": strPtr("2"), - "BAZ": strPtr("2.5"), - "QUX": strPtr("qux"), + "FOO": new("1"), + "BAR": new("2"), + "BAZ": new("2.5"), + "QUX": new("qux"), "QUUX": nil, } @@ -685,31 +680,31 @@ networks: Configs: []types.ServiceConfigObjConfig{ { Source: "appconfig", - Mode: uint32Ptr(555), + Mode: new(uint32(555)), }, }, Secrets: []types.ServiceSecretConfig{ { Source: "super", - Mode: uint32Ptr(555), + Mode: new(uint32(555)), }, }, HealthCheck: &types.HealthCheckConfig{ - Retries: uint64Ptr(555), + Retries: new(uint64(555)), Disable: true, }, Deploy: types.DeployConfig{ - Replicas: uint64Ptr(555), + Replicas: new(uint64(555)), UpdateConfig: &types.UpdateConfig{ - Parallelism: uint64Ptr(555), + Parallelism: new(uint64(555)), MaxFailureRatio: 3.14, }, RollbackConfig: &types.UpdateConfig{ - Parallelism: uint64Ptr(555), + Parallelism: new(uint64(555)), MaxFailureRatio: 3.14, }, RestartPolicy: &types.RestartPolicy{ - MaxAttempts: uint64Ptr(555), + MaxAttempts: new(uint64(555)), }, Placement: types.Placement{ MaxReplicas: 555, @@ -798,10 +793,10 @@ services: - example2.env `)) expectedEnvironmentMap := types.MappingWithEquals{ - "FOO": strPtr("foo_from_env_file"), - "BAZ": strPtr("baz_from_env_file"), - "BAR": strPtr("bar_from_env_file_2"), // Original value is overwritten by example2.env - "QUX": strPtr("quz_from_env_file_2"), + "FOO": new("foo_from_env_file"), + "BAZ": new("baz_from_env_file"), + "BAR": new("bar_from_env_file_2"), // Original value is overwritten by example2.env + "QUX": new("quz_from_env_file_2"), } assert.NilError(t, err) configDetails := buildConfigDetails(dict, nil) @@ -957,19 +952,6 @@ volumes: assert.Check(t, is.ErrorContains(err, `external_volume`)) } -func durationPtr(value time.Duration) *types.Duration { - result := types.Duration(value) - return &result -} - -func uint64Ptr(value uint64) *uint64 { - return &value -} - -func uint32Ptr(value uint32) *uint32 { - return &value -} - func TestFullExample(t *testing.T) { skip.If(t, runtime.GOOS == "windows", "FIXME: substitutes platform-specific HOME-dirs and requires platform-specific golden files; see https://github.com/docker/cli/pull/4610") diff --git a/cli/compose/loader/merge_test.go b/cli/compose/loader/merge_test.go index 2f6b456174..cd09a2beb5 100644 --- a/cli/compose/loader/merge_test.go +++ b/cli/compose/loader/merge_test.go @@ -920,8 +920,8 @@ func TestLoadMultipleConfigs(t *testing.T) { Context: ".", Dockerfile: "foo.Dockerfile", Args: types.MappingWithEquals{ - "buildno": strPtr("1"), - "password": strPtr("secret"), + "buildno": new("1"), + "password": new("secret"), }, }, Ports: []types.ServicePortConfig{ @@ -1246,13 +1246,13 @@ func TestMergeServiceOverrideReplicasZero(t *testing.T) { base := types.ServiceConfig{ Name: "someService", Deploy: types.DeployConfig{ - Replicas: uint64Ptr(3), + Replicas: new(uint64(3)), }, } override := types.ServiceConfig{ Name: "someService", Deploy: types.DeployConfig{ - Replicas: uint64Ptr(0), + Replicas: new(uint64(0)), }, } services, err := mergeServices([]types.ServiceConfig{base}, []types.ServiceConfig{override}) @@ -1265,7 +1265,7 @@ func TestMergeServiceOverrideReplicasZero(t *testing.T) { types.ServiceConfig{ Name: "someService", Deploy: types.DeployConfig{ - Replicas: uint64Ptr(0), + Replicas: new(uint64(0)), }, }, ) @@ -1275,7 +1275,7 @@ func TestMergeServiceOverrideReplicasNotNil(t *testing.T) { base := types.ServiceConfig{ Name: "someService", Deploy: types.DeployConfig{ - Replicas: uint64Ptr(3), + Replicas: new(uint64(3)), }, } override := types.ServiceConfig{ @@ -1292,7 +1292,7 @@ func TestMergeServiceOverrideReplicasNotNil(t *testing.T) { types.ServiceConfig{ Name: "someService", Deploy: types.DeployConfig{ - Replicas: uint64Ptr(3), + Replicas: new(uint64(3)), }, }, ) diff --git a/cli/compose/schema/schema.go b/cli/compose/schema/schema.go index 9ea79644e6..f42130a0de 100644 --- a/cli/compose/schema/schema.go +++ b/cli/compose/schema/schema.go @@ -101,8 +101,7 @@ func Validate(config map[string]any, version string) error { } if err := schema.Validate(toJSONValue(config)); err != nil { - var validationErr *jsonschema.ValidationError - if errors.As(err, &validationErr) { + if validationErr, ok := errors.AsType[*jsonschema.ValidationError](err); ok { return getMostSpecificError(validationErr) } return err diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index 73f46aae8e..2339f60ae3 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -79,8 +79,7 @@ func ConvertDurationPtr(d *Duration) *time.Duration { if d == nil { return nil } - res := time.Duration(*d) - return &res + return new(time.Duration(*d)) } // MarshalJSON makes Duration implement json.Marshaler diff --git a/cli/config/configfile/file.go b/cli/config/configfile/file.go index 5edce29158..e32b1e767c 100644 --- a/cli/config/configfile/file.go +++ b/cli/config/configfile/file.go @@ -232,8 +232,7 @@ func (c *ConfigFile) Save() (retErr error) { cfgFile = f } else if os.IsNotExist(err) { // extract the path from the error if the configfile does not exist or is a dangling symlink - var pathError *os.PathError - if errors.As(err, &pathError) { + if pathError, ok := errors.AsType[*os.PathError](err); ok { cfgFile = pathError.Path } } diff --git a/cli/connhelper/ssh/ssh.go b/cli/connhelper/ssh/ssh.go index 2fcb54a98f..b91f2bc02e 100644 --- a/cli/connhelper/ssh/ssh.go +++ b/cli/connhelper/ssh/ssh.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + // Package ssh provides the connection helper for ssh:// URL. package ssh @@ -15,8 +18,7 @@ import ( func ParseURL(daemonURL string) (*Spec, error) { u, err := url.Parse(daemonURL) if err != nil { - var urlErr *url.Error - if errors.As(err, &urlErr) { + if urlErr, ok := errors.AsType[*url.Error](err); ok { err = urlErr.Unwrap() } return nil, fmt.Errorf("invalid SSH URL: %w", err) diff --git a/cmd/docker/docker.go b/cmd/docker/docker.go index aca19c76cf..7987ffa3f7 100644 --- a/cmd/docker/docker.go +++ b/cmd/docker/docker.go @@ -101,8 +101,7 @@ func getExitCode(err error) int { return 0 } - var userTerminatedErr errCtxSignalTerminated - if errors.As(err, &userTerminatedErr) { + if userTerminatedErr, ok := errors.AsType[errCtxSignalTerminated](err); ok { s, ok := userTerminatedErr.signal.(syscall.Signal) if !ok { return 1 diff --git a/internal/registry/errors.go b/internal/registry/errors.go index 20a5fca373..7b12a8461f 100644 --- a/internal/registry/errors.go +++ b/internal/registry/errors.go @@ -12,8 +12,7 @@ import ( ) func translateV2AuthError(err error) error { - var e *url.Error - if errors.As(err, &e) { + if e, ok := errors.AsType[*url.Error](err); ok { var e2 errcode.Error if errors.As(e, &e2) && errors.Is(e2.Code, errcode.ErrorCodeUnauthorized) { return unauthorizedErr{err} diff --git a/internal/registryclient/fetcher.go b/internal/registryclient/fetcher.go index cad5451f8f..5bc308b4cb 100644 --- a/internal/registryclient/fetcher.go +++ b/internal/registryclient/fetcher.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package registryclient import ( @@ -244,8 +247,7 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named, repo, err := c.getRepositoryForReference(ctx, namedRef, repoEndpoint) if err != nil { logrus.Debugf("error %s with repo endpoint %+v", err, repoEndpoint) - var protoErr httpProtoError - if errors.As(err, &protoErr) { + if _, ok := errors.AsType[httpProtoError](err); ok { continue } return err diff --git a/opts/gpus.go b/opts/gpus.go index e68ede7a08..3905a691ac 100644 --- a/opts/gpus.go +++ b/opts/gpus.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package opts import ( @@ -21,8 +24,7 @@ func parseCount(s string) (int, error) { } i, err := strconv.Atoi(s) if err != nil { - var numErr *strconv.NumError - if errors.As(err, &numErr) { + if numErr, ok := errors.AsType[*strconv.NumError](err); ok { err = numErr.Err } return 0, fmt.Errorf(`invalid count (%s): value must be either "all" or an integer: %w`, s, err) diff --git a/opts/network.go b/opts/network.go index 489ef8be39..51f50f2070 100644 --- a/opts/network.go +++ b/opts/network.go @@ -1,3 +1,6 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.26 + package opts import ( @@ -100,8 +103,7 @@ func (n *NetworkOpt) Set(value string) error { //nolint:gocyclo case gwPriorityOpt: netOpt.GwPriority, err = strconv.Atoi(val) if err != nil { - var numErr *strconv.NumError - if errors.As(err, &numErr) { + if numErr, ok := errors.AsType[*strconv.NumError](err); ok { err = numErr.Err } return fmt.Errorf("invalid gw-priority (%s): %w", val, err) diff --git a/opts/swarmopts/port.go b/opts/swarmopts/port.go index f3caf32f46..589c127959 100644 --- a/opts/swarmopts/port.go +++ b/opts/swarmopts/port.go @@ -73,8 +73,7 @@ func (p *PortOpt) Set(value string) error { case portOptTargetPort: tPort, err := strconv.ParseUint(val, 10, 16) if err != nil { - var numErr *strconv.NumError - if errors.As(err, &numErr) { + if numErr, ok := errors.AsType[*strconv.NumError](err); ok { err = numErr.Err } return fmt.Errorf("invalid target port (%s): value must be an integer: %w", val, err) @@ -84,8 +83,7 @@ func (p *PortOpt) Set(value string) error { case portOptPublishedPort: pPort, err := strconv.ParseUint(val, 10, 16) if err != nil { - var numErr *strconv.NumError - if errors.As(err, &numErr) { + if numErr, ok := errors.AsType[*strconv.NumError](err); ok { err = numErr.Err } return fmt.Errorf("invalid published port (%s): value must be an integer: %w", val, err)