Skip to content
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ linters:
- ineffassign
- makezero
- misspell
- modernize
- nakedret
- nilnil
- nolintlint
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/account/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (l *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou
}, nil
}

func formatRoles(val interface{}) (text.Colors, string, error) {
func formatRoles(val any) (text.Colors, string, error) {
roles, ok := val.([]string)
if !ok {
return nil, "", fmt.Errorf("cannot parse %T, expected []string", val)
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/account/permissions/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (l *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou
}, nil
}

func formatOptions(val interface{}) (text.Colors, string, error) {
func formatOptions(val any) (text.Colors, string, error) {
options, ok := val.(*upcloud.PermissionOptions)
if !ok {
return nil, "", fmt.Errorf("cannot parse %T, expected *upcloud.PermissionOptions", val)
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/account/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (s *showCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou
}, nil
}

func formatCredits(val interface{}) (text.Colors, string, error) {
func formatCredits(val any) (text.Colors, string, error) {
credits, ok := val.(float64)
if !ok {
return nil, "", fmt.Errorf("cannot parse %T, expected float64", val)
Expand Down
8 changes: 4 additions & 4 deletions internal/commands/account/token/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestCreateToken(t *testing.T) {
args: []string{
"--expires-in", "1h",
},
errFn: func(t assert.TestingT, err error, _ ...interface{}) bool {
errFn: func(t assert.TestingT, err error, _ ...any) bool {
return assert.ErrorContains(t, err, `required flag(s) "name" not set`)
},
},
Expand All @@ -65,7 +65,7 @@ func TestCreateToken(t *testing.T) {
"--name", "test",
"--expires-in", "seppo",
},
errFn: func(t assert.TestingT, err error, _ ...interface{}) bool {
errFn: func(t assert.TestingT, err error, _ ...any) bool {
return assert.ErrorContains(t, err, `invalid argument "seppo" for "--expires-in"`)
},
},
Expand All @@ -75,7 +75,7 @@ func TestCreateToken(t *testing.T) {
"--name", "test",
"--expires-at", "seppo",
},
errFn: func(t assert.TestingT, err error, _ ...interface{}) bool {
errFn: func(t assert.TestingT, err error, _ ...any) bool {
return assert.ErrorContains(t, err, `invalid expires-at: `)
},
},
Expand All @@ -84,7 +84,7 @@ func TestCreateToken(t *testing.T) {
args: []string{
"--name", "test",
},
errFn: func(t assert.TestingT, err error, _ ...interface{}) bool {
errFn: func(t assert.TestingT, err error, _ ...any) bool {
return assert.ErrorContains(t, err, `either expires-in or expires-at must be set`)
},
},
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/all/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou
}, nil
}

func formatUUID(val interface{}) (text.Colors, string, error) {
func formatUUID(val any) (text.Colors, string, error) {
str, ok := val.(string)
if !ok {
return nil, "", fmt.Errorf("cannot parse %T, expected string", val)
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/all/purge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ func TestPurgeCommand(t *testing.T) {
for _, test := range []struct {
name string
args []string
called [][]interface{}
called [][]any
}{
{
name: "purge non-persistent tf-acc-test resources",
args: []string{"--include", "*tf-acc-test*", "--exclude", "*persistent*"},
called: [][]interface{}{
called: [][]any{
{"DeleteManagedObjectStorage", &request.DeleteManagedObjectStorageRequest{
UUID: objectStorages[0].UUID,
}},
Expand Down
9 changes: 3 additions & 6 deletions internal/commands/all/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,7 @@ type findResult struct {
}

func findResources[T any](exec commands.Executor, wg *sync.WaitGroup, returnChan chan findResult, r resolver.CachingResolutionProvider[T], include, exclude []string) {
wg.Add(1)

go func() {
defer wg.Done()
wg.Go(func() {
var resources []Resource
matches, err := getMatches(exec, r, include, exclude)
if err != nil {
Expand All @@ -145,7 +142,7 @@ func findResources[T any](exec commands.Executor, wg *sync.WaitGroup, returnChan
resources = append(resources, resource)
}
returnChan <- findResult{Resources: resources, Error: nil}
}()
})
}

func ListResources(exec commands.Executor, include, exclude []string) ([]Resource, error) {
Expand Down Expand Up @@ -318,7 +315,7 @@ func DeleteResources(exec commands.Executor, resources []Resource, workerCount i
}

workerQueue := make(chan int, workerCount)
for n := 0; n < workerCount; n++ {
for n := range workerCount {
workerQueue <- n
}

Expand Down
8 changes: 2 additions & 6 deletions internal/commands/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"context"
"fmt"
"slices"
"strings"

"github.com/UpCloudLtd/upcloud-cli/v3/internal/completion"
Expand Down Expand Up @@ -161,12 +162,7 @@ func (s *BaseCommand) Aliases() []string {

// isDeprecatedAlias checks if an alias is deprecated
func (s *BaseCommand) isDeprecatedAlias(alias string) bool {
for _, deprecated := range s.deprecatedAliases {
if alias == deprecated {
return true
}
}
return false
return slices.Contains(s.deprecatedAliases, alias)
}

func (s *BaseCommand) DeprecatedAliases() []string {
Expand Down
6 changes: 3 additions & 3 deletions internal/commands/database/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func processProperties(in []string, t *upcloud.ManagedDatabaseType) (request.Man
continue
}

var parsedValue interface{}
var parsedValue any
if err := json.Unmarshal([]byte(value), &parsedValue); err != nil {
resp.Set(key, value) // Set as plain string if parsing fails
} else {
Expand All @@ -147,9 +147,9 @@ func processNetworks(in []string) ([]upcloud.ManagedDatabaseNetwork, error) {
var networks []upcloud.ManagedDatabaseNetwork
for _, netStr := range in {
network := upcloud.ManagedDatabaseNetwork{}
pairs := strings.Split(netStr, ",")
pairs := strings.SplitSeq(netStr, ",")

for _, pair := range pairs {
for pair := range pairs {
parts := strings.SplitN(pair, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid network format: %s, expected key=value", pair)
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/database/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ func TestCreateCommand(t *testing.T) {
Properties: request.ManagedDatabasePropertiesRequest{
"ism_enabled": true,
"custom_domain": "custom.upcloud.com",
"saml": map[string]interface{}{"enabled": true},
"openid": map[string]interface{}{"client_id": "test_client_id"},
"saml": map[string]any{"enabled": true},
"openid": map[string]any{"client_id": "test_client_id"},
"numeric_string": "123",
},
},
Expand Down
8 changes: 4 additions & 4 deletions internal/commands/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type Executor interface {
Account() service.Account
Token() service.Token
All() internal.AllServices
Debug(msg string, args ...interface{})
WithLogger(args ...interface{}) Executor
Debug(msg string, args ...any)
WithLogger(args ...any) Executor
WithProgress(progress *progress.Progress) Executor
}

Expand All @@ -55,7 +55,7 @@ type executorImpl struct {
sigIntChan chan os.Signal
}

func (e executorImpl) WithLogger(args ...interface{}) Executor {
func (e executorImpl) WithLogger(args ...any) Executor {
e.logger = e.logger.With(args...)
return &e
}
Expand All @@ -69,7 +69,7 @@ func (e *executorImpl) Context() context.Context {
return e.Config.Context()
}

func (e *executorImpl) Debug(msg string, args ...interface{}) {
func (e *executorImpl) Debug(msg string, args ...any) {
e.logger.Debug(msg, args...)
}

Expand Down
24 changes: 12 additions & 12 deletions internal/commands/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,25 @@ func TestExecutor_WaitForError(t *testing.T) {

type mockLogEntry struct {
Msg string
Args []interface{}
Args []any
}

type mockLogger struct {
debugLines []mockLogEntry
infoLines []mockLogEntry
errorLines []mockLogEntry
context []interface{}
context []any
}

func (m *mockLogger) Debug(msg string, args ...interface{}) {
func (m *mockLogger) Debug(msg string, args ...any) {
m.debugLines = append(m.debugLines, mockLogEntry{msg, args})
}

func (m *mockLogger) Info(msg string, args ...interface{}) {
func (m *mockLogger) Info(msg string, args ...any) {
m.infoLines = append(m.infoLines, mockLogEntry{msg, args})
}

func (m *mockLogger) Error(msg string, args ...interface{}) {
func (m *mockLogger) Error(msg string, args ...any) {
m.errorLines = append(m.errorLines, mockLogEntry{msg, args})
}

Expand All @@ -85,7 +85,7 @@ func (m mockLogger) IsInfo() bool {
return true
}

func (m mockLogger) With(args ...interface{}) flume.Logger {
func (m mockLogger) With(args ...any) flume.Logger {
return &mockLogger{
context: append(m.context, args...),
}
Expand All @@ -94,7 +94,7 @@ func (m mockLogger) With(args ...interface{}) flume.Logger {
func TestExecutor_Logging(t *testing.T) {
mService := &smock.Service{}
cfg := config.New()
logger := &mockLogger{context: []interface{}{"base", "context"}}
logger := &mockLogger{context: []any{"base", "context"}}
exec := NewExecutor(cfg, mService, logger)
exec.Debug("debug1", "hello", "world")
// create a contexted executor
Expand All @@ -104,15 +104,15 @@ func TestExecutor_Logging(t *testing.T) {
// make sure the main executor does not leak to the contexted one or vice versa
assert.Equal(t, &mockLogger{
debugLines: []mockLogEntry{
{Msg: "debug1", Args: []interface{}{"hello", "world"}},
{Msg: "debug2", Args: []interface{}{"hi", "earth"}},
{Msg: "debug1", Args: []any{"hello", "world"}},
{Msg: "debug2", Args: []any{"hi", "earth"}},
},
context: []interface{}{"base", "context"},
context: []any{"base", "context"},
}, logger)
assert.Equal(t, &mockLogger{
debugLines: []mockLogEntry{
{Msg: "debugcontext", Args: []interface{}{"helloz", "worldz"}},
{Msg: "debugcontext", Args: []any{"helloz", "worldz"}},
},
context: []interface{}{"base", "context", "added", "newcontext"},
context: []any{"base", "context", "added", "newcontext"},
}, contextExec.(*executorImpl).logger)
}
2 changes: 1 addition & 1 deletion internal/commands/gateway/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou
}, nil
}

func formatRouters(val interface{}) (text.Colors, string, error) {
func formatRouters(val any) (text.Colors, string, error) {
routers, ok := val.([]upcloud.GatewayRouter)
if !ok {
return nil, "", fmt.Errorf("cannot parse routers from %T, expected []upcloud.GatewayRouter", val)
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/host/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (s *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou
}, nil
}

func formatID(val interface{}) (text.Colors, string, error) {
func formatID(val any) (text.Colors, string, error) {
id, ok := val.(int)
if !ok {
return nil, "", fmt.Errorf("cannot parse IP addresses from %T, expected int", val)
Expand Down
15 changes: 5 additions & 10 deletions internal/commands/kubernetes/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kubernetes
import (
"errors"
"fmt"
"maps"

"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/completion"
Expand Down Expand Up @@ -101,7 +102,7 @@ func (c *configCommand) output(exec commands.Executor, config *api.Config, resp
})
}

var value interface{}
var value any
err := yaml.Unmarshal([]byte(resp), &value)
if err != nil {
return commands.HandleError(exec, msg, err)
Expand Down Expand Up @@ -174,15 +175,9 @@ func (c *configCommand) write(exec commands.Executor, uuid string, config *api.C
func mergeConfig(startingConfig, newConfig *api.Config) api.Config {
startingConfig.CurrentContext = newConfig.CurrentContext

for k, v := range newConfig.Clusters {
startingConfig.Clusters[k] = v
}
for k, v := range newConfig.AuthInfos {
startingConfig.AuthInfos[k] = v
}
for k, v := range newConfig.Contexts {
startingConfig.Contexts[k] = v
}
maps.Copy(startingConfig.Clusters, newConfig.Clusters)
maps.Copy(startingConfig.AuthInfos, newConfig.AuthInfos)
maps.Copy(startingConfig.Contexts, newConfig.Contexts)

return *startingConfig
}
4 changes: 1 addition & 3 deletions internal/commands/kubernetes/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ Flags:
expectedFileContents: exampleKubernetesKubeconfig("write-to-non-empty-file-with-override"),
},
} {
tt := tt

t.Run(tt.name, func(t *testing.T) {
mService := smock.Service{}
mService.On("GetKubernetesClusters", mock.Anything).
Expand Down Expand Up @@ -269,7 +267,7 @@ func yamlToJSON(yamlIn []byte) []byte {
return []byte{}
}

var jsonObj interface{}
var jsonObj any
_ = yaml.Unmarshal(yamlIn, &jsonObj)

out, _ := json.MarshalIndent(jsonObj, "", " ")
Expand Down
7 changes: 3 additions & 4 deletions internal/commands/kubernetes/nodegroup/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nodegroup
import (
"fmt"
"regexp"
"slices"
"strings"

"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
Expand Down Expand Up @@ -79,10 +80,8 @@ func validateStorageTier(tier string) error {
return nil // Empty is valid (uses plan default)
}

for _, validTier := range validStorageTiers {
if tier == validTier {
return nil
}
if slices.Contains(validStorageTiers, tier) {
return nil
}

return fmt.Errorf("invalid storage tier %q, must be one of: %s", tier, strings.Join(validStorageTiers, ", "))
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/network/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (s *showCommand) Execute(exec commands.Executor, arg string) (output.Output
}, nil
}

func formatShowDHCPDNS(val interface{}) (text.Colors, string, error) {
func formatShowDHCPDNS(val any) (text.Colors, string, error) {
addresses, ok := val.([]string)
if !ok {
return nil, "", fmt.Errorf("cannot parse IP addresses from %T, expected []string", val)
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/objectstorage/accesskey/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (s *createCommand) Execute(exec commands.Executor, serviceUUID string) (out
exec.PushProgressSuccess(msg)

// Handle SecretAccessKey which might be a pointer
var secretKey interface{}
var secretKey any
if res.SecretAccessKey != nil {
secretKey = *res.SecretAccessKey
} else {
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/objectstorage/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ func (s *createCommand) processNetworks() ([]upcloud.ManagedObjectStorageNetwork
var networks []upcloud.ManagedObjectStorageNetwork
for _, n := range s.networks {
var network upcloud.ManagedObjectStorageNetwork
parts := strings.Split(n, ",")
for _, part := range parts {
parts := strings.SplitSeq(n, ",")
for part := range parts {
kv := strings.SplitN(part, "=", 2)
if len(kv) != 2 {
return nil, fmt.Errorf("invalid network format: %s", part)
Expand Down
Loading