From 15ce9fa98964d613d0ec7b26e4ee6132014bc38f Mon Sep 17 00:00:00 2001 From: Gustavo Bazan Date: Mon, 15 Jul 2024 14:05:21 +0100 Subject: [PATCH] task: enable more revive checks (#3106) --- .golangci.yml | 4 + internal/cli/auth/login_test.go | 4 +- internal/cli/config/set.go | 2 +- internal/cli/delete_opts.go | 2 +- internal/cli/deployments/logs.go | 9 +- internal/cli/deployments/setup.go | 4 +- internal/cli/events/list.go | 2 +- .../connectedorgsconfigs/update.go | 4 +- internal/cli/logs/download.go | 5 +- .../cli/networking/peering/create/aws_test.go | 16 +-- internal/cli/output_opts.go | 8 +- internal/cli/output_opts_test.go | 4 +- internal/cli/projects/list.go | 2 +- internal/cli/search/index_opts.go | 6 +- internal/cli/setup/dbuser_setup.go | 2 +- internal/cli/teams/describe.go | 2 +- internal/cli/users/describe.go | 2 +- internal/cli/watch_opts.go | 6 +- internal/config/profile.go | 16 +-- internal/container/docker.go | 4 +- internal/decryption/log_record.go | 4 +- internal/decryption/output.go | 14 +-- internal/file/file.go | 4 +- internal/file/file_test.go | 4 +- internal/jsonpathwriter/jsonpathwriter.go | 4 +- internal/jsonwriter/jsonwriter.go | 2 +- .../kubernetes/operator/install_resources.go | 30 ++--- .../kubernetes/operator/project/project.go | 8 +- internal/mongodbclient/client.go | 4 +- internal/mongodbclient/collection.go | 4 +- internal/mongodbclient/database.go | 20 +-- internal/mongodbclient/search_index.go | 41 +++---- internal/mongodbclient/user.go | 10 +- internal/podman/client.go | 13 +- internal/store/telemetry.go | 8 +- internal/telemetry/ask.go | 4 +- internal/telemetry/event.go | 8 +- internal/telemetry/read_answer.go | 6 +- internal/telemetry/read_answer_test.go | 14 +-- internal/telemetry/tracker.go | 6 +- internal/telemetry/tracker_test.go | 4 +- internal/templatewriter/templatewriter.go | 4 +- .../templatewriter/templatewriter_test.go | 2 +- internal/test/test.go | 2 +- internal/validate/validate.go | 18 +-- internal/validate/validate_test.go | 114 ++++++++---------- test/e2e/atlas/deployments_local_auth_test.go | 2 +- .../atlas/deployments_local_noauth_test.go | 6 +- test/e2e/atlas/helper_test.go | 2 +- test/e2e/atlas/project_settings_test.go | 2 +- test/e2e/brew/brew_test.go | 31 ++--- test/e2e/config/config_test.go | 8 +- test/e2e/decryption/decryption.go | 6 +- tools/cli-generator/generate.go | 3 +- .../astparsing/astparsing.go | 8 +- .../templateparsing/templateparsing.go | 6 +- 56 files changed, 260 insertions(+), 270 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index d0b94002f0..a69ce37492 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -60,12 +60,15 @@ linters-settings: - name: blank-imports - name: context-as-argument - name: context-keys-type + - name: defer - name: dot-imports - name: error-return - name: error-strings - name: error-naming + - name: early-return - name: errorf - name: exported + - name: import-shadowing - name: indent-error-flow - name: if-return - name: increment-decrement @@ -89,6 +92,7 @@ linters-settings: - name: constant-logical-expr - name: confusing-naming - name: unnecessary-stmt + - name: use-any - name: imports-blocklist arguments: - "github.com/pkg/errors" diff --git a/internal/cli/auth/login_test.go b/internal/cli/auth/login_test.go index 86073b1ba0..7f36d26640 100644 --- a/internal/cli/auth/login_test.go +++ b/internal/cli/auth/login_test.go @@ -155,11 +155,11 @@ Successfully logged in as test@10gen.com. type confirmMock struct{} -func (confirmMock) Prompt(_ *survey.PromptConfig) (interface{}, error) { +func (confirmMock) Prompt(_ *survey.PromptConfig) (any, error) { return true, nil } -func (confirmMock) Cleanup(_ *survey.PromptConfig, _ interface{}) error { +func (confirmMock) Cleanup(_ *survey.PromptConfig, _ any) error { return nil } diff --git a/internal/cli/config/set.go b/internal/cli/config/set.go index 4c02deab24..b5414631c6 100644 --- a/internal/cli/config/set.go +++ b/internal/cli/config/set.go @@ -44,7 +44,7 @@ func (opts *SetOpts) Run() error { return err } } - var value interface{} + var value any value = opts.val if slices.Contains(config.BooleanProperties(), opts.prop) { value = config.IsTrue(opts.val) diff --git a/internal/cli/delete_opts.go b/internal/cli/delete_opts.go index 0017836d9e..d505da9345 100644 --- a/internal/cli/delete_opts.go +++ b/internal/cli/delete_opts.go @@ -46,7 +46,7 @@ func NewDeleteOpts(successMsg, failMsg string) *DeleteOpts { // Delete deletes a resource not associated to a project, it expects a callback // that should perform the deletion from the store. -func (opts *DeleteOpts) Delete(d interface{}, a ...string) error { +func (opts *DeleteOpts) Delete(d any, a ...string) error { if !opts.Confirm { fmt.Println(opts.FailMessage()) return nil diff --git a/internal/cli/deployments/logs.go b/internal/cli/deployments/logs.go index bf8c901c19..184dfc8d39 100644 --- a/internal/cli/deployments/logs.go +++ b/internal/cli/deployments/logs.go @@ -83,11 +83,16 @@ func (opts *DownloadOpts) RunAtlas() error { if err := opts.downloadLogFile(); err != nil { return err } - defer opts.Fs.Remove(opts.Out) //nolint:errcheck + defer func() { + _ = opts.Fs.Remove(opts.Out) + }() return nil } +// maxBytes 1k each write to avoid compression bomb. +const maxBytes = 1024 + func (*DownloadOpts) write(w io.Writer, r io.Reader) error { gr, errGz := gzip.NewReader(r) if errGz != nil { @@ -96,7 +101,7 @@ func (*DownloadOpts) write(w io.Writer, r io.Reader) error { written := false for { - n, err := io.CopyN(w, gr, 1024) //nolint:mnd // 1k each write to avoid compression bomb + n, err := io.CopyN(w, gr, maxBytes) if n > 0 { written = true } diff --git a/internal/cli/deployments/setup.go b/internal/cli/deployments/setup.go index 1225ff31d7..f54b0325e8 100644 --- a/internal/cli/deployments/setup.go +++ b/internal/cli/deployments/setup.go @@ -281,7 +281,7 @@ func (opts *SetupOpts) promptDeploymentName() error { Default: opts.DeploymentName, } - return telemetry.TrackAskOne(p, &opts.DeploymentName, survey.WithValidator(func(ans interface{}) error { + return telemetry.TrackAskOne(p, &opts.DeploymentName, survey.WithValidator(func(ans any) error { name, _ := ans.(string) return options.ValidateDeploymentName(name) })) @@ -342,7 +342,7 @@ func (opts *SetupOpts) promptPort() error { Default: exportPort, } - err := telemetry.TrackAskOne(p, &exportPort, survey.WithValidator(func(ans interface{}) error { + err := telemetry.TrackAskOne(p, &exportPort, survey.WithValidator(func(ans any) error { input, _ := ans.(string) value, err := strconv.Atoi(input) if err != nil { diff --git a/internal/cli/events/list.go b/internal/cli/events/list.go index c491b4c828..7dd92de84a 100644 --- a/internal/cli/events/list.go +++ b/internal/cli/events/list.go @@ -59,7 +59,7 @@ var listTemplate = `ID TYPE CREATED{{range valueOrEmptySlice .Results}} ` func (opts *ListOpts) Run() error { - var r interface{} + var r any var err error if opts.orgID != "" { diff --git a/internal/cli/federatedauthentication/federationsettings/connectedorgsconfigs/update.go b/internal/cli/federatedauthentication/federationsettings/connectedorgsconfigs/update.go index 4928df8be9..5b8aff37d7 100644 --- a/internal/cli/federatedauthentication/federationsettings/connectedorgsconfigs/update.go +++ b/internal/cli/federatedauthentication/federationsettings/connectedorgsconfigs/update.go @@ -53,8 +53,8 @@ func (opts *UpdateOpts) InitStore(ctx context.Context) func() error { } } -func (opts *UpdateOpts) fillReadOnlyValues(config *atlasv2.ConnectedOrgConfig) { - config.OrgId = opts.ConfigOrgID() +func (opts *UpdateOpts) fillReadOnlyValues(c *atlasv2.ConnectedOrgConfig) { + c.OrgId = opts.ConfigOrgID() } func (opts *UpdateOpts) Run() error { diff --git a/internal/cli/logs/download.go b/internal/cli/logs/download.go index 641e8ba69b..ff108e7c80 100644 --- a/internal/cli/logs/download.go +++ b/internal/cli/logs/download.go @@ -58,6 +58,9 @@ func (opts *DownloadOpts) initStore(ctx context.Context) func() error { } } +// maxBytes 1k each write to avoid compression bomb. +const maxBytes = 1024 + func (opts *DownloadOpts) write(w io.Writer, r io.Reader) error { if !opts.decompress { _, err := io.Copy(w, r) @@ -71,7 +74,7 @@ func (opts *DownloadOpts) write(w io.Writer, r io.Reader) error { written := false for { - n, err := io.CopyN(w, gr, 1024) //nolint:mnd // 1k each write to avoid compression bomb + n, err := io.CopyN(w, gr, maxBytes) if n > 0 { written = true } diff --git a/internal/cli/networking/peering/create/aws_test.go b/internal/cli/networking/peering/create/aws_test.go index 8e109ce6a1..d2152ced94 100644 --- a/internal/cli/networking/peering/create/aws_test.go +++ b/internal/cli/networking/peering/create/aws_test.go @@ -24,6 +24,7 @@ import ( "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/mocks" "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/pointer" "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/test" + "github.com/stretchr/testify/assert" atlasv2 "go.mongodb.org/atlas-sdk/v20240530002/admin" ) @@ -84,12 +85,12 @@ func TestAwsOpts_Run(t *testing.T) { } func TestNormalizeAtlasRegion(t *testing.T) { - type test struct { + type tc struct { input string want string } - tests := []test{ + tests := []tc{ {input: "eu-west-1", want: "EU_WEST_1"}, {input: "eu_west-1", want: "EU_WEST_1"}, {input: "eu-west_1", want: "EU_WEST_1"}, @@ -97,11 +98,12 @@ func TestNormalizeAtlasRegion(t *testing.T) { {input: "eu_west_1", want: "EU_WEST_1"}, } - for _, tc := range tests { - got := normalizeAtlasRegion(tc.input) - if tc.want != got { - t.Errorf("expected: %s, got: %s", tc.want, got) - } + for _, c := range tests { + t.Run(c.input, func(t *testing.T) { + t.Parallel() + got := normalizeAtlasRegion(c.input) + assert.Equal(t, c.want, got) + }) } } diff --git a/internal/cli/output_opts.go b/internal/cli/output_opts.go index ad9f2fd4b8..6184c0579c 100644 --- a/internal/cli/output_opts.go +++ b/internal/cli/output_opts.go @@ -109,7 +109,7 @@ func (opts *OutputOpts) IsCygwinTerminal() bool { } // Print will evaluate the defined format and try to parse it accordingly outputting to the set writer. -func (opts *OutputOpts) Print(o interface{}) error { +func (opts *OutputOpts) Print(o any) error { if opts.ConfigOutput() == jsonFormat { return jsonwriter.Print(opts.ConfigWriter(), o) } @@ -131,7 +131,7 @@ func (opts *OutputOpts) Print(o interface{}) error { return err } -func (opts *OutputOpts) PrintForCompactResultsResponse(o interface{}) error { +func (opts *OutputOpts) PrintForCompactResultsResponse(o any) error { if opts.ConfigOutput() == jsonFormat { compactResponse, err := mapReduceResults(o) if err == nil { @@ -159,13 +159,13 @@ func (opts *OutputOpts) PrintForCompactResultsResponse(o interface{}) error { return err } -func mapReduceResults(o interface{}) (interface{}, error) { +func mapReduceResults(o any) (any, error) { jsonString, err := json.Marshal(o) if err != nil { return nil, err } - var val interface{} + var val any if e := json.Unmarshal(jsonString, &val); e != nil { return nil, e } diff --git a/internal/cli/output_opts_test.go b/internal/cli/output_opts_test.go index a067e3c838..a6cc66821c 100644 --- a/internal/cli/output_opts_test.go +++ b/internal/cli/output_opts_test.go @@ -86,8 +86,8 @@ func TestOutputOpts_mapReduceResults(t *testing.T) { t.Fatalf("mapReduceResults() unexpected error: %v", err) } - mapArrayResponse := reflect.ValueOf(compactResults).Interface().([]interface{}) - mapResponse := mapArrayResponse[0].(map[string]interface{}) + mapArrayResponse := reflect.ValueOf(compactResults).Interface().([]any) + mapResponse := mapArrayResponse[0].(map[string]any) gotID := mapResponse["id"] gotName := mapResponse["name"] if gotID != wantID { diff --git a/internal/cli/projects/list.go b/internal/cli/projects/list.go index 4c2cd84ff9..86232be36d 100644 --- a/internal/cli/projects/list.go +++ b/internal/cli/projects/list.go @@ -48,7 +48,7 @@ func (opts *ListOpts) initStore(ctx context.Context) func() error { func (opts *ListOpts) Run() error { listOptions := opts.NewAtlasListOptions() - var r interface{} + var r any var err error if opts.OrgID != "" { r, err = opts.store.GetOrgProjects(opts.OrgID, listOptions) diff --git a/internal/cli/search/index_opts.go b/internal/cli/search/index_opts.go index 6e86a7952d..8311c75139 100644 --- a/internal/cli/search/index_opts.go +++ b/internal/cli/search/index_opts.go @@ -158,17 +158,17 @@ func (opts *IndexOpts) NewSearchIndex() (*atlasv2.ClusterSearchIndex, error) { // indexFieldParts index field should be fieldName:analyzer:fieldType. const indexFieldParts = 2 -func (opts *IndexOpts) indexFields() (map[string]interface{}, error) { +func (opts *IndexOpts) indexFields() (map[string]any, error) { if len(opts.fields) == 0 { return nil, nil } - fields := make(map[string]interface{}) + fields := make(map[string]any) for _, p := range opts.fields { f := strings.Split(p, ":") if len(f) != indexFieldParts { return nil, fmt.Errorf("partition should be fieldName:fieldType, got: %s", p) } - fields[f[0]] = map[string]interface{}{ + fields[f[0]] = map[string]any{ "type": f[1], } } diff --git a/internal/cli/setup/dbuser_setup.go b/internal/cli/setup/dbuser_setup.go index 7bcef6cf0c..86fe87bfd9 100644 --- a/internal/cli/setup/dbuser_setup.go +++ b/internal/cli/setup/dbuser_setup.go @@ -74,7 +74,7 @@ func (opts *Opts) askDBUserOptions() error { return telemetry.TrackAsk(qs, opts) } -func (opts *Opts) validateUniqueUsername(val interface{}) error { +func (opts *Opts) validateUniqueUsername(val any) error { username, ok := val.(string) if !ok { return fmt.Errorf("the username %s is not valid", username) diff --git a/internal/cli/teams/describe.go b/internal/cli/teams/describe.go index ef4dbba5f6..158f93a31e 100644 --- a/internal/cli/teams/describe.go +++ b/internal/cli/teams/describe.go @@ -49,7 +49,7 @@ func (opts *DescribeOpts) initStore(ctx context.Context) func() error { } func (opts *DescribeOpts) Run() error { - var r interface{} + var r any var err error if opts.name != "" { diff --git a/internal/cli/users/describe.go b/internal/cli/users/describe.go index d2ebc04ccd..65cbb99dee 100644 --- a/internal/cli/users/describe.go +++ b/internal/cli/users/describe.go @@ -48,7 +48,7 @@ func (opts *DescribeOpts) initStore(ctx context.Context) func() error { } func (opts *DescribeOpts) Run() error { - var r interface{} + var r any var err error if opts.username != "" { diff --git a/internal/cli/watch_opts.go b/internal/cli/watch_opts.go index 19767a434a..57b4d35746 100644 --- a/internal/cli/watch_opts.go +++ b/internal/cli/watch_opts.go @@ -38,10 +38,10 @@ const ( speed = 100 * time.Millisecond ) -type Watcher func() (interface{}, bool, error) +type Watcher func() (any, bool, error) // Watch allow to init the OutputOpts in a functional way. -func (opts *WatchOpts) Watch(f Watcher) (interface{}, error) { +func (opts *WatchOpts) Watch(f Watcher) (any, error) { if f == nil { return nil, errors.New("no watcher provided") } @@ -63,7 +63,7 @@ func (opts *WatchOpts) Watch(f Watcher) (interface{}, error) { var backoffCoefficients = []float32{0.5, 1, 2} -func (opts *WatchOpts) exponentialBackoff(f Watcher) (interface{}, bool, error) { +func (opts *WatchOpts) exponentialBackoff(f Watcher) (any, bool, error) { if opts.IsRetryableErr == nil { return f() } diff --git a/internal/config/profile.go b/internal/config/profile.go index 30efb941ac..525f7ee956 100644 --- a/internal/config/profile.go +++ b/internal/config/profile.go @@ -82,11 +82,11 @@ var ( ) type Setter interface { - Set(string, interface{}) + Set(string, any) } type GlobalSetter interface { - SetGlobal(string, interface{}) + SetGlobal(string, any) } type Saver interface { @@ -263,20 +263,20 @@ func (p *Profile) SetName(name string) error { return nil } -func Set(name string, value interface{}) { Default().Set(name, value) } -func (p *Profile) Set(name string, value interface{}) { +func Set(name string, value any) { Default().Set(name, value) } +func (p *Profile) Set(name string, value any) { settings := viper.GetStringMap(p.Name()) settings[name] = value viper.Set(p.name, settings) } -func SetGlobal(name string, value interface{}) { viper.Set(name, value) } -func (*Profile) SetGlobal(name string, value interface{}) { +func SetGlobal(name string, value any) { viper.Set(name, value) } +func (*Profile) SetGlobal(name string, value any) { SetGlobal(name, value) } -func Get(name string) interface{} { return Default().Get(name) } -func (p *Profile) Get(name string) interface{} { +func Get(name string) any { return Default().Get(name) } +func (p *Profile) Get(name string) any { if viper.IsSet(name) && viper.Get(name) != "" { return viper.Get(name) } diff --git a/internal/container/docker.go b/internal/container/docker.go index 9f94cf3e46..5ef180b1f1 100644 --- a/internal/container/docker.go +++ b/internal/container/docker.go @@ -327,7 +327,7 @@ func (e *dockerImpl) ImagePull(ctx context.Context, name string) error { } func (e *dockerImpl) ImageHealthCheck(ctx context.Context, name string) (*ImageHealthCheck, error) { - bytes, err := e.run(ctx, "image", "inspect", "--format", "json", name) + b, err := e.run(ctx, "image", "inspect", "--format", "json", name) if err != nil { return nil, err } @@ -349,7 +349,7 @@ func (e *dockerImpl) ImageHealthCheck(ctx context.Context, name string) (*ImageH } var inspectOutput []PartialImageInspect - if err := json.Unmarshal(bytes, &inspectOutput); err != nil { + if err := json.Unmarshal(b, &inspectOutput); err != nil { return nil, err } diff --git a/internal/decryption/log_record.go b/internal/decryption/log_record.go index ce5edec4cd..40a8979566 100644 --- a/internal/decryption/log_record.go +++ b/internal/decryption/log_record.go @@ -67,7 +67,7 @@ func (logLine *AuditLogLine) decodeLogRecord() (*DecodedLogRecord, error) { }, nil } -func processLogRecord(decryptConfig *DecryptSection, logLine *AuditLogLine, lineNb int) (bsonData interface{}, keyInvocationCount uint64, err error) { +func processLogRecord(decryptConfig *DecryptSection, logLine *AuditLogLine, lineNb int) (bsonData any, keyInvocationCount uint64, err error) { encryptedLogRecord, decodeErr := logLine.decodeLogRecord() if decodeErr != nil { return nil, 0, fmt.Errorf("at line %v: %w: %w", lineNb, ErrLogCorrupted, decodeErr) @@ -90,7 +90,7 @@ func processLogRecord(decryptConfig *DecryptSection, logLine *AuditLogLine, line return nil, 0, fmt.Errorf("%w at line %v: %w", ErrDecompressionFailure, lineNb, decompressErr) } - var bsonParsedLogRecord map[string]interface{} + var bsonParsedLogRecord map[string]any if bsonErr := bson.Unmarshal(decompressedLogRecord, &bsonParsedLogRecord); bsonErr != nil { return nil, 0, fmt.Errorf("%w at line %v: %w", ErrParse, lineNb, bsonErr) } diff --git a/internal/decryption/output.go b/internal/decryption/output.go index 7db0907bbf..af98a4671d 100644 --- a/internal/decryption/output.go +++ b/internal/decryption/output.go @@ -23,10 +23,10 @@ import ( ) type AuditLogOutput interface { - Warningf(lineNb int, logLine *AuditLogLine, format string, a ...interface{}) error + Warningf(lineNb int, logLine *AuditLogLine, format string, a ...any) error Error(lineNb int, logLine *AuditLogLine, err error) error - Errorf(lineNb int, logLine *AuditLogLine, format string, a ...interface{}) error - LogRecord(lineNb int, logRecord interface{}) error + Errorf(lineNb int, logLine *AuditLogLine, format string, a ...any) error + LogRecord(lineNb int, logRecord any) error } type auditLogOutputWriter struct { @@ -71,7 +71,7 @@ func NewAuditLogOutput(out io.Writer) AuditLogOutput { } } -func (l *auditLogOutputWriter) writeRecord(value interface{}) error { +func (l *auditLogOutputWriter) writeRecord(value any) error { jsonVal, err := bson.MarshalExtJSON(value, false, false) if err != nil { return err @@ -85,7 +85,7 @@ func (l *auditLogOutputWriter) writeRecord(value interface{}) error { return err } -func (l *auditLogOutputWriter) Warningf(lineNb int, logLine *AuditLogLine, format string, a ...interface{}) error { +func (l *auditLogOutputWriter) Warningf(lineNb int, logLine *AuditLogLine, format string, a ...any) error { e := AuditLogError{ Level: AuditLogErrorLevelWarning, Line: lineNb, @@ -111,10 +111,10 @@ func (l *auditLogOutputWriter) Error(lineNb int, logLine *AuditLogLine, err erro return l.writeRecord(e) } -func (l *auditLogOutputWriter) Errorf(lineNb int, logLine *AuditLogLine, format string, a ...interface{}) error { +func (l *auditLogOutputWriter) Errorf(lineNb int, logLine *AuditLogLine, format string, a ...any) error { return l.Error(lineNb, logLine, fmt.Errorf(format, a...)) } -func (l *auditLogOutputWriter) LogRecord(_ int, logRecord interface{}) error { +func (l *auditLogOutputWriter) LogRecord(_ int, logRecord any) error { return l.writeRecord(logRecord) } diff --git a/internal/file/file.go b/internal/file/file.go index e900d28dfd..1293ec74fe 100644 --- a/internal/file/file.go +++ b/internal/file/file.go @@ -58,7 +58,7 @@ var ErrFileNotFound = errors.New("file not found") // Load loads a given filename into the out interface. // The file should be a valid json or yaml format. -func Load(fs afero.Fs, filename string, out interface{}) error { +func Load(fs afero.Fs, filename string, out any) error { file, err := LoadFile(fs, filename) if err != nil { return err @@ -93,7 +93,7 @@ func LoadFile(fs afero.Fs, filename string) ([]byte, error) { // Save saves a given data interface into a given file path // The file should be a yaml format. -func Save(fs afero.Fs, filePath string, data interface{}) error { +func Save(fs afero.Fs, filePath string, data any) error { var content []byte if _, err := configType(filePath, []string{yamlName}); err != nil { diff --git a/internal/file/file_test.go b/internal/file/file_test.go index 4ca6ab168b..09458c5b76 100644 --- a/internal/file/file_test.go +++ b/internal/file/file_test.go @@ -53,13 +53,13 @@ func TestLoad(t *testing.T) { t.Run("load valid json file", func(t *testing.T) { appFS := afero.NewMemMapFs() _ = afero.WriteFile(appFS, jsonFileName, []byte("{}"), 0600) - out := new(map[string]interface{}) + out := new(map[string]any) require.NoError(t, Load(appFS, jsonFileName, out)) }) t.Run("load valid yaml file", func(t *testing.T) { appFS := afero.NewMemMapFs() _ = afero.WriteFile(appFS, yamlFileName, []byte(""), 0600) - out := new(map[string]interface{}) + out := new(map[string]any) err := Load(appFS, yamlFileName, out) require.NotErrorIs(t, err, ErrMissingFileType) }) diff --git a/internal/jsonpathwriter/jsonpathwriter.go b/internal/jsonpathwriter/jsonpathwriter.go index f112e0023e..7ea0eb9f68 100644 --- a/internal/jsonpathwriter/jsonpathwriter.go +++ b/internal/jsonpathwriter/jsonpathwriter.go @@ -25,7 +25,7 @@ import ( var ErrEmptyPath = errors.New("empty jsonpath") -func Print(w io.Writer, path string, obj interface{}) error { +func Print(w io.Writer, path string, obj any) error { if path == "" { return ErrEmptyPath } @@ -35,7 +35,7 @@ func Print(w io.Writer, path string, obj interface{}) error { return err } - var val interface{} + var val any if e := json.Unmarshal(jsonString, &val); e != nil { return e } diff --git a/internal/jsonwriter/jsonwriter.go b/internal/jsonwriter/jsonwriter.go index 9648f35b5a..d728550191 100644 --- a/internal/jsonwriter/jsonwriter.go +++ b/internal/jsonwriter/jsonwriter.go @@ -25,7 +25,7 @@ const ( indent = " " ) -func Print(w io.Writer, obj interface{}) error { +func Print(w io.Writer, obj any) error { prettyJSON, err := json.MarshalIndent(obj, prefix, indent) if err != nil { return err diff --git a/internal/kubernetes/operator/install_resources.go b/internal/kubernetes/operator/install_resources.go index d0dda8e6f3..3f233acebd 100644 --- a/internal/kubernetes/operator/install_resources.go +++ b/internal/kubernetes/operator/install_resources.go @@ -53,7 +53,7 @@ type InstallConfig struct { } type Installer interface { - InstallCRDs(ctx context.Context, version string, namespaced bool) error + InstallCRDs(ctx context.Context, v string, namespaced bool) error InstallConfiguration(ctx context.Context, installConfig *InstallConfig) error InstallCredentials(ctx context.Context, namespace, orgID, publicKey, privateKey string, projectName string) error } @@ -66,14 +66,14 @@ type InstallResources struct { subDeletionProtection bool } -func (ir *InstallResources) InstallCRDs(ctx context.Context, version string, namespaced bool) error { +func (ir *InstallResources) InstallCRDs(ctx context.Context, v string, namespaced bool) error { target := installationTargetClusterWide if namespaced { target = installationTargetNamespaced } - data, err := ir.versionProvider.DownloadResource(ctx, version, fmt.Sprintf("deploy/%s/crds.yaml", target)) + data, err := ir.versionProvider.DownloadResource(ctx, v, fmt.Sprintf("deploy/%s/crds.yaml", target)) if err != nil { return fmt.Errorf("unable to retrieve CRDs from repository: %w", err) } @@ -130,7 +130,7 @@ func (ir *InstallResources) InstallConfiguration(ctx context.Context, installCon return nil } -func (ir *InstallResources) handleKind(ctx context.Context, installConfig *InstallConfig, config map[string]interface{}) error { +func (ir *InstallResources) handleKind(ctx context.Context, installConfig *InstallConfig, config map[string]any) error { switch config["kind"] { case "ServiceAccount": return ir.addServiceAccount(ctx, config, installConfig.Namespace) @@ -178,7 +178,7 @@ func (ir *InstallResources) InstallCredentials(ctx context.Context, namespace, o return nil } -func (ir *InstallResources) addServiceAccount(ctx context.Context, config map[string]interface{}, namespace string) error { +func (ir *InstallResources) addServiceAccount(ctx context.Context, config map[string]any, namespace string) error { obj := &corev1.ServiceAccount{} err := ir.objConverter.FromUnstructured(config, obj) if err != nil { @@ -195,7 +195,7 @@ func (ir *InstallResources) addServiceAccount(ctx context.Context, config map[st return nil } -func (ir *InstallResources) addRoles(ctx context.Context, config map[string]interface{}, namespace string, watch []string) error { +func (ir *InstallResources) addRoles(ctx context.Context, config map[string]any, namespace string, watch []string) error { namespaces := map[string]struct{}{namespace: {}} if !isLeaderElectionResource(config, leaderElectionRoleName) { @@ -222,7 +222,7 @@ func (ir *InstallResources) addRoles(ctx context.Context, config map[string]inte return nil } -func (ir *InstallResources) addClusterRole(ctx context.Context, config map[string]interface{}, namespace string) error { +func (ir *InstallResources) addClusterRole(ctx context.Context, config map[string]any, namespace string) error { obj := &rbacv1.ClusterRole{} err := ir.objConverter.FromUnstructured(config, obj) if err != nil { @@ -239,7 +239,7 @@ func (ir *InstallResources) addClusterRole(ctx context.Context, config map[strin return nil } -func (ir *InstallResources) addRoleBindings(ctx context.Context, config map[string]interface{}, namespace string, watch []string) error { +func (ir *InstallResources) addRoleBindings(ctx context.Context, config map[string]any, namespace string, watch []string) error { namespaces := map[string]struct{}{namespace: {}} if !isLeaderElectionResource(config, leaderElectionRoleBindingName) { @@ -267,7 +267,7 @@ func (ir *InstallResources) addRoleBindings(ctx context.Context, config map[stri return nil } -func (ir *InstallResources) addClusterRoleBinding(ctx context.Context, config map[string]interface{}, namespace string) error { +func (ir *InstallResources) addClusterRoleBinding(ctx context.Context, config map[string]any, namespace string) error { obj := &rbacv1.ClusterRoleBinding{} err := ir.objConverter.FromUnstructured(config, obj) if err != nil { @@ -285,7 +285,7 @@ func (ir *InstallResources) addClusterRoleBinding(ctx context.Context, config ma return nil } -func (ir *InstallResources) addDeployment(ctx context.Context, config map[string]interface{}, installConfig *InstallConfig) error { +func (ir *InstallResources) addDeployment(ctx context.Context, config map[string]any, installConfig *InstallConfig) error { obj := &appsv1.Deployment{} err := ir.objConverter.FromUnstructured(config, obj) if err != nil { @@ -338,13 +338,13 @@ func (ir *InstallResources) addDeployment(ctx context.Context, config map[string return nil } -func parseYaml(data io.ReadCloser) ([]map[string]interface{}, error) { - var k8sResources []map[string]interface{} +func parseYaml(data io.ReadCloser) ([]map[string]any, error) { + var k8sResources []map[string]any decoder := yaml.NewDecoder(data) for { - obj := map[string]interface{}{} + obj := map[string]any{} err := decoder.Decode(obj) if err != nil { if err == io.EOF { @@ -384,13 +384,13 @@ func joinNamespaces(namespace string, watched []string) string { return strings.Join(list, ",") } -func isLeaderElectionResource(config map[string]interface{}, leaderElectionID string) bool { +func isLeaderElectionResource(config map[string]any, leaderElectionID string) bool { value, ok := config["metadata"] if !ok { return false } - metadata, ok := value.(map[string]interface{}) + metadata, ok := value.(map[string]any) if !ok { return false } diff --git a/internal/kubernetes/operator/project/project.go b/internal/kubernetes/operator/project/project.go index b0bc7a9a3a..1ca4a5c03e 100644 --- a/internal/kubernetes/operator/project/project.go +++ b/internal/kubernetes/operator/project/project.go @@ -140,12 +140,12 @@ func BuildAtlasProject(br *AtlasProjectBuildRequest) (*AtlasProjectResult, error } if br.Validator.FeatureExist(features.ResourceAtlasProject, featureEncryptionAtRest) { - encryptionAtRest, secrets, ferr := buildEncryptionAtRest(br.ProjectStore, br.ProjectID, br.Project.Name, br.TargetNamespace, br.Dictionary) + encryptionAtRest, s, ferr := buildEncryptionAtRest(br.ProjectStore, br.ProjectID, br.Project.Name, br.TargetNamespace, br.Dictionary) if ferr != nil { return nil, ferr } projectResult.Spec.EncryptionAtRest = encryptionAtRest - result.Secrets = append(result.Secrets, secrets...) + result.Secrets = append(result.Secrets, s...) } if br.Validator.FeatureExist(features.ResourceAtlasProject, featureCloudProviderAccessRoles) { @@ -173,12 +173,12 @@ func BuildAtlasProject(br *AtlasProjectBuildRequest) (*AtlasProjectResult, error } if br.Validator.FeatureExist(features.ResourceAtlasProject, featureAlertConfiguration) { - alertConfigurations, secrets, ferr := buildAlertConfigurations(br.ProjectStore, br.ProjectID, br.Project.Name, br.TargetNamespace, br.Dictionary) + alertConfigurations, s, ferr := buildAlertConfigurations(br.ProjectStore, br.ProjectID, br.Project.Name, br.TargetNamespace, br.Dictionary) if ferr != nil { return nil, ferr } projectResult.Spec.AlertConfigurations = alertConfigurations - result.Secrets = append(result.Secrets, secrets...) + result.Secrets = append(result.Secrets, s...) } if br.Validator.FeatureExist(features.ResourceAtlasProject, featureCustomRoles) { diff --git a/internal/mongodbclient/client.go b/internal/mongodbclient/client.go index 7fa025f969..44d6c25b7d 100644 --- a/internal/mongodbclient/client.go +++ b/internal/mongodbclient/client.go @@ -49,9 +49,9 @@ func NewClient() MongoDBClient { } } -func NewClientWithContext(context context.Context) MongoDBClient { +func NewClientWithContext(ctx context.Context) MongoDBClient { return &mongodbClient{ - ctx: context, + ctx: ctx, } } diff --git a/internal/mongodbclient/collection.go b/internal/mongodbclient/collection.go index 556405840e..c44c8651b7 100644 --- a/internal/mongodbclient/collection.go +++ b/internal/mongodbclient/collection.go @@ -21,13 +21,13 @@ import ( ) type Collection interface { - Aggregate(context.Context, interface{}) (*mongo.Cursor, error) + Aggregate(context.Context, any) (*mongo.Cursor, error) } type collection struct { collection *mongo.Collection } -func (o *collection) Aggregate(ctx context.Context, pipeline interface{}) (*mongo.Cursor, error) { +func (o *collection) Aggregate(ctx context.Context, pipeline any) (*mongo.Cursor, error) { return o.collection.Aggregate(ctx, pipeline) } diff --git a/internal/mongodbclient/database.go b/internal/mongodbclient/database.go index 930e62b557..e8b61e7ba2 100644 --- a/internal/mongodbclient/database.go +++ b/internal/mongodbclient/database.go @@ -23,8 +23,8 @@ import ( ) type Database interface { - RunCommand(ctx context.Context, runCommand interface{}) (interface{}, error) - InsertOne(ctx context.Context, collection string, doc interface{}) (interface{}, error) + RunCommand(ctx context.Context, runCommand any) (any, error) + InsertOne(ctx context.Context, collection string, doc any) (any, error) InitiateReplicaSet(ctx context.Context, rsName string, hostname string, internalPort int, externalPort int) error SearchIndex User @@ -35,14 +35,14 @@ type database struct { db *mongo.Database } -func (o *database) Collection(name string) Collection { +func (d *database) Collection(name string) Collection { return &collection{ - collection: o.db.Collection(name), + collection: d.db.Collection(name), } } -func (o *database) RunCommand(ctx context.Context, runCmd interface{}) (interface{}, error) { - r := o.db.RunCommand(ctx, runCmd) +func (d *database) RunCommand(ctx context.Context, runCmd any) (any, error) { + r := d.db.RunCommand(ctx, runCmd) if err := r.Err(); err != nil { return nil, err } @@ -54,12 +54,12 @@ func (o *database) RunCommand(ctx context.Context, runCmd interface{}) (interfac return cmdResult, nil } -func (o *database) InsertOne(ctx context.Context, col string, doc interface{}) (interface{}, error) { - return o.db.Collection(col).InsertOne(ctx, doc) +func (d *database) InsertOne(ctx context.Context, col string, doc any) (any, error) { + return d.db.Collection(col).InsertOne(ctx, doc) } -func (o *database) InitiateReplicaSet(ctx context.Context, rsName string, hostname string, internalPort int, externalPort int) error { - return o.db.RunCommand(ctx, bson.D{{Key: "replSetInitiate", Value: bson.M{ +func (d *database) InitiateReplicaSet(ctx context.Context, rsName string, hostname string, internalPort int, externalPort int) error { + return d.db.RunCommand(ctx, bson.D{{Key: "replSetInitiate", Value: bson.M{ "_id": rsName, "version": 1, "configsvr": false, diff --git a/internal/mongodbclient/search_index.go b/internal/mongodbclient/search_index.go index f4a6ade2a9..1d52595dba 100644 --- a/internal/mongodbclient/search_index.go +++ b/internal/mongodbclient/search_index.go @@ -29,12 +29,11 @@ import ( ) const ( - listSearchIndexes = "$listSearchIndexes" - addFields = "$addFields" - idField = "id" - collectionField = "collection" - databaseField = "database" - defaultSearchIndexType = "search" + listSearchIndexes = "$listSearchIndexes" + addFields = "$addFields" + idField = "id" + collectionField = "collection" + databaseField = "database" ) var ErrSearchIndexNotFound = errors.New("search Index not found") @@ -59,7 +58,7 @@ type SearchIndexDefinition struct { } // todo: CLOUDP-199915 Use go-driver search index management helpers instead of createSearchIndex command -func (o *database) CreateSearchIndex(ctx context.Context, collection string, idx *admin.ClusterSearchIndex) (*admin.ClusterSearchIndex, error) { +func (d *database) CreateSearchIndex(ctx context.Context, collection string, idx *admin.ClusterSearchIndex) (*admin.ClusterSearchIndex, error) { // To maintain formatting of the SDK, marshal object into JSON and then unmarshal into BSON jsonIndex, err := json.Marshal(idx) if err != nil { @@ -75,14 +74,14 @@ func (o *database) CreateSearchIndex(ctx context.Context, collection string, idx // Empty these fields so that they are not included into the index definition for the MongoDB command index = removeFields(index, "id", "collectionName", "database", "type") - options := options.SearchIndexes().SetName(idx.Name) + o := options.SearchIndexes().SetName(idx.Name) if idx.Type != nil { - options.SetType(*idx.Type) + o.SetType(*idx.Type) } - _, err = o.db.Collection(collection).SearchIndexes().CreateOne(ctx, mongo.SearchIndexModel{ + _, err = d.db.Collection(collection).SearchIndexes().CreateOne(ctx, mongo.SearchIndexModel{ Definition: index, - Options: options, + Options: o, }) _, _ = log.Debugln("Creating search index with definition: ", index) @@ -90,7 +89,7 @@ func (o *database) CreateSearchIndex(ctx context.Context, collection string, idx return nil, err } - return o.SearchIndexByName(ctx, idx.Name, collection) + return d.SearchIndexByName(ctx, idx.Name, collection) } func removeFields(doc bson.D, fields ...string) bson.D { @@ -107,15 +106,15 @@ func removeFields(doc bson.D, fields ...string) bson.D { return cleanedDoc } -func (o *database) SearchIndex(ctx context.Context, id string) (*admin.ClusterSearchIndex, error) { - collectionNames, err := o.db.ListCollectionNames(ctx, bson.D{}, nil) +func (d *database) SearchIndex(ctx context.Context, id string) (*admin.ClusterSearchIndex, error) { + collectionNames, err := d.db.ListCollectionNames(ctx, bson.D{}, nil) if err != nil { return nil, err } // We search the index in all the collections of the database for _, coll := range collectionNames { - cursor, err := o.db.Collection(coll).Aggregate(ctx, newSearchIndexPipeline(id)) + cursor, err := d.db.Collection(coll).Aggregate(ctx, newSearchIndexPipeline(id)) if err != nil || cursor == nil { return nil, err } @@ -128,7 +127,7 @@ func (o *database) SearchIndex(ctx context.Context, id string) (*admin.ClusterSe ID: results[0].ID, Name: results[0].Name, Collection: coll, - Database: o.db.Name(), + Database: d.db.Name(), Status: results[0].Status, } return newClusterSearchIndex(searchIndexDef), nil @@ -138,14 +137,14 @@ func (o *database) SearchIndex(ctx context.Context, id string) (*admin.ClusterSe return nil, fmt.Errorf("index `%s` not found: %w", id, ErrSearchIndexNotFound) } -func (o *database) SearchIndexByName(ctx context.Context, name string, collection string) (*admin.ClusterSearchIndex, error) { - indexes, err := o.SearchIndexes(ctx, collection) +func (d *database) SearchIndexByName(ctx context.Context, name string, collection string) (*admin.ClusterSearchIndex, error) { + indexes, err := d.SearchIndexes(ctx, collection) if err != nil { return nil, err } for _, index := range indexes { - if index.Name == name && index.Database == o.db.Name() { + if index.Name == name && index.Database == d.db.Name() { return index, nil } } @@ -153,8 +152,8 @@ func (o *database) SearchIndexByName(ctx context.Context, name string, collectio return nil, ErrSearchIndexNotFound } -func (o *database) SearchIndexes(ctx context.Context, coll string) ([]*admin.ClusterSearchIndex, error) { - cursor, err := o.db.Collection(coll).Aggregate(ctx, newSearchIndexesPipeline(o.db.Name(), coll)) +func (d *database) SearchIndexes(ctx context.Context, coll string) ([]*admin.ClusterSearchIndex, error) { + cursor, err := d.db.Collection(coll).Aggregate(ctx, newSearchIndexesPipeline(d.db.Name(), coll)) if err != nil || cursor == nil { return nil, err } diff --git a/internal/mongodbclient/user.go b/internal/mongodbclient/user.go index d75aabc847..eb1b58db12 100644 --- a/internal/mongodbclient/user.go +++ b/internal/mongodbclient/user.go @@ -25,16 +25,16 @@ type User interface { DropUser(ctx context.Context, username string) error } -func (o *database) CreateUser(ctx context.Context, username, password string, roles []string) error { +func (d *database) CreateUser(ctx context.Context, username, password string, roles []string) error { rolesDoc := bson.A{} for _, r := range roles { rolesDoc = append(rolesDoc, bson.D{ {Key: "role", Value: r}, - {Key: "db", Value: o.db.Name()}, + {Key: "db", Value: d.db.Name()}, }) } - return o.db.Client(). + return d.db.Client(). Database("admin"). RunCommand(ctx, bson.D{ {Key: "createUser", Value: username}, @@ -43,8 +43,8 @@ func (o *database) CreateUser(ctx context.Context, username, password string, ro }).Err() } -func (o *database) DropUser(ctx context.Context, username string) error { - return o.db.Client(). +func (d *database) DropUser(ctx context.Context, username string) error { + return d.db.Client(). Database("admin"). RunCommand(ctx, bson.D{ {Key: "dropUser", Value: username}, diff --git a/internal/podman/client.go b/internal/podman/client.go index 3df42e2f87..cd297a36eb 100644 --- a/internal/podman/client.go +++ b/internal/podman/client.go @@ -28,8 +28,7 @@ import ( ) var ( - ErrPodmanNotFound = errors.New("podman not found in your system, check requirements at https://dochub.mongodb.org/core/atlas-cli-deploy-local-reqs") - ErrNetworkNotFound = errors.New("network ip range was not found") + ErrPodmanNotFound = errors.New("podman not found in your system, check requirements at https://dochub.mongodb.org/core/atlas-cli-deploy-local-reqs") ) type RunContainerOpts struct { @@ -103,7 +102,7 @@ type Client interface { PullImage(ctx context.Context, name string) ([]byte, error) ImageHealthCheck(ctx context.Context, name string) (*Schema2HealthConfig, error) ContainerHealthStatus(ctx context.Context, name string) (string, error) - Logs(ctx context.Context) (map[string]interface{}, []error) + Logs(ctx context.Context) (map[string]any, []error) ContainerLogs(ctx context.Context, name string) ([]string, error) ContainerStatusAndUptime(ctx context.Context, name string) (string, time.Duration, error) } @@ -355,14 +354,14 @@ func (o *client) Version(ctx context.Context) (map[string]any, error) { return version, err } -func (o *client) Logs(ctx context.Context) (map[string]interface{}, []error) { - l := map[string]interface{}{} +func (o *client) Logs(ctx context.Context) (map[string]any, []error) { + l := map[string]any{} var errs []error output, err := o.runPodman(ctx, "ps", "--all", "--format", "json", "--filter", "name=mongo") if err != nil { errs = append(errs, err) } else { - var podmanLogs []interface{} + var podmanLogs []any if err = json.Unmarshal(output, &podmanLogs); err != nil { errs = append(errs, err) } @@ -373,7 +372,7 @@ func (o *client) Logs(ctx context.Context) (map[string]interface{}, []error) { if err != nil { errs = append(errs, err) } else { - var networks []interface{} + var networks []any if err = json.Unmarshal(output, &networks); err != nil { errs = append(errs, err) } diff --git a/internal/store/telemetry.go b/internal/store/telemetry.go index f335981b9d..460867e317 100644 --- a/internal/store/telemetry.go +++ b/internal/store/telemetry.go @@ -23,14 +23,14 @@ import ( //go:generate mockgen -destination=../mocks/mock_telemetry.go -package=mocks github.com/mongodb/mongodb-atlas-cli/atlascli/internal/store EventsSender,UnauthEventsSender type EventsSender interface { - SendEvents(body interface{}) error + SendEvents(body any) error } type UnauthEventsSender interface { - SendUnauthEvents(body interface{}) error + SendUnauthEvents(body any) error } -func (s *Store) SendEvents(body interface{}) error { +func (s *Store) SendEvents(body any) error { switch s.service { case config.CloudService: client := s.client @@ -45,7 +45,7 @@ func (s *Store) SendEvents(body interface{}) error { } } -func (s *Store) SendUnauthEvents(body interface{}) error { +func (s *Store) SendUnauthEvents(body any) error { switch s.service { case config.CloudService: client := s.client diff --git a/internal/telemetry/ask.go b/internal/telemetry/ask.go index bb179bc093..46eb82f51c 100644 --- a/internal/telemetry/ask.go +++ b/internal/telemetry/ask.go @@ -20,7 +20,7 @@ import ( "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/log" ) -func TrackAsk(qs []*survey.Question, response interface{}, opts ...survey.AskOpt) error { +func TrackAsk(qs []*survey.Question, response any, opts ...survey.AskOpt) error { err := survey.Ask(qs, response, opts...) if !config.TelemetryEnabled() { return err @@ -35,7 +35,7 @@ func TrackAsk(qs []*survey.Question, response interface{}, opts ...survey.AskOpt return err } -func TrackAskOne(p survey.Prompt, response interface{}, opts ...survey.AskOpt) error { +func TrackAskOne(p survey.Prompt, response any, opts ...survey.AskOpt) error { err := survey.AskOne(p, response, opts...) if !config.TelemetryEnabled() { return err diff --git a/internal/telemetry/event.go b/internal/telemetry/event.go index e2e8314b52..b7a61eb815 100644 --- a/internal/telemetry/event.go +++ b/internal/telemetry/event.go @@ -35,9 +35,9 @@ import ( ) type Event struct { - Timestamp time.Time `json:"timestamp"` - Source string `json:"source"` - Properties map[string]interface{} `json:"properties"` + Timestamp time.Time `json:"timestamp"` + Source string `json:"source"` + Properties map[string]any `json:"properties"` } type EventOpt func(Event) @@ -336,7 +336,7 @@ func newEvent(opts ...EventOpt) Event { var event = Event{ Timestamp: time.Now(), Source: config.AtlasCLI, - Properties: map[string]interface{}{ + Properties: map[string]any{ "result": "SUCCESS", }, } diff --git a/internal/telemetry/read_answer.go b/internal/telemetry/read_answer.go index 93cb4ef96f..adb0c19d4d 100644 --- a/internal/telemetry/read_answer.go +++ b/internal/telemetry/read_answer.go @@ -44,7 +44,7 @@ func listFields(target reflect.Value) []fieldValue { return ret } -func findAnswerInStruct(target reflect.Value, name string) (interface{}, error) { // based on https://pkg.go.dev/github.com/AlecAivazis/survey/v2/core#WriteAnswer +func findAnswerInStruct(target reflect.Value, name string) (any, error) { // based on https://pkg.go.dev/github.com/AlecAivazis/survey/v2/core#WriteAnswer if target.Kind() == reflect.Ptr { target = target.Elem() } @@ -75,8 +75,8 @@ func findAnswerInStruct(target reflect.Value, name string) (interface{}, error) return nil, fmt.Errorf("%w: %s", ErrFieldNotFound, name) } -func readAnswer(response interface{}, name string) (interface{}, error) { - v, ok := response.(map[string]interface{}) +func readAnswer(response any, name string) (any, error) { + v, ok := response.(map[string]any) if ok { ret, ok := v[name] if !ok { diff --git a/internal/telemetry/read_answer_test.go b/internal/telemetry/read_answer_test.go index 08af4d0471..5cc37a9766 100644 --- a/internal/telemetry/read_answer_test.go +++ b/internal/telemetry/read_answer_test.go @@ -23,17 +23,17 @@ import ( func TestReadAnswer(t *testing.T) { testCases := []struct { - input interface{} + input any name string - expected interface{} + expected any }{ { - input: map[string]interface{}{"test": "value", "test2": 2}, + input: map[string]any{"test": "value", "test2": 2}, name: "test", expected: "value", }, { - input: map[string]interface{}{"test": "value", "test2": 2}, + input: map[string]any{"test": "value", "test2": 2}, name: "test2", expected: 2, }, @@ -130,11 +130,11 @@ func TestReadAnswer(t *testing.T) { func TestReadAnswerNotFound(t *testing.T) { testCases := []struct { - input interface{} + input any name string }{ { - input: map[string]interface{}{"test": "value", "test2": 2}, + input: map[string]any{"test": "value", "test2": 2}, name: "test3", }, { @@ -183,7 +183,7 @@ func TestReadAnswerNotStructOrMap(t *testing.T) { test := "value" testCases := []struct { - input interface{} + input any name string }{ { diff --git a/internal/telemetry/tracker.go b/internal/telemetry/tracker.go index 07114937f9..ba12b8e708 100644 --- a/internal/telemetry/tracker.go +++ b/internal/telemetry/tracker.go @@ -215,7 +215,7 @@ func (t *tracker) remove() error { return err } -func castBool(i interface{}) bool { +func castBool(i any) bool { b, ok := i.(bool) if ok { return b @@ -231,7 +231,7 @@ func castBool(i interface{}) bool { return ret } -func castString(i interface{}) string { +func castString(i any) string { s, ok := i.(string) if ok { return s @@ -247,7 +247,7 @@ func castString(i interface{}) string { return ret } -func (t *tracker) trackSurvey(p survey.Prompt, response interface{}, e error) error { +func (t *tracker) trackSurvey(p survey.Prompt, response any, e error) error { o := t.defaultCommandOptions() if e != nil { diff --git a/internal/telemetry/tracker_test.go b/internal/telemetry/tracker_test.go index 1e6dc5bb0e..af3ef28b49 100644 --- a/internal/telemetry/tracker_test.go +++ b/internal/telemetry/tracker_test.go @@ -153,7 +153,7 @@ func TestSave(t *testing.T) { cacheDir: cacheDir, } - var properties = map[string]interface{}{ + var properties = map[string]any{ "command": "mock-command", } var event = Event{ @@ -184,7 +184,7 @@ func TestSaveOverMaxCacheFileSize(t *testing.T) { cacheDir: cacheDir, } - var properties = map[string]interface{}{ + var properties = map[string]any{ "command": "mock-command", } var event = Event{ diff --git a/internal/templatewriter/templatewriter.go b/internal/templatewriter/templatewriter.go index 8f507b2355..f059c4fc5f 100644 --- a/internal/templatewriter/templatewriter.go +++ b/internal/templatewriter/templatewriter.go @@ -32,7 +32,7 @@ var funcMap = template.FuncMap{ "valueOrEmptySlice": valueOrEmptySlice, } -func valueOrEmptySlice(slice interface{}) (result interface{}) { +func valueOrEmptySlice(slice any) (result any) { if slice == nil { return result } @@ -54,7 +54,7 @@ func newTabWriter(output io.Writer) *tabwriter.Writer { // if the optional t is given then it's processed as a go-template, // this template will be handled with a tabwriter so you can use tabs (\t) // and new lines (\n) to space your content evenly. -func Print(writer io.Writer, t string, v interface{}) error { +func Print(writer io.Writer, t string, v any) error { tmpl, err := template.New("output").Funcs(funcMap).Parse(t) if err != nil { return err diff --git a/internal/templatewriter/templatewriter_test.go b/internal/templatewriter/templatewriter_test.go index 0d062c3ce8..dabf38787e 100644 --- a/internal/templatewriter/templatewriter_test.go +++ b/internal/templatewriter/templatewriter_test.go @@ -25,7 +25,7 @@ import ( type printTest struct { name string template string - data interface{} + data any expected string wantErr require.ErrorAssertionFunc } diff --git a/internal/test/test.go b/internal/test/test.go index 782d5da584..8c5109ffca 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -43,7 +43,7 @@ func CmdValidator(t *testing.T, subject *cobra.Command, nSubCommands int, flags } // VerifyOutputTemplate validates that the given template string is valid. -func VerifyOutputTemplate(t *testing.T, tmpl string, typeValue interface{}) { +func VerifyOutputTemplate(t *testing.T, tmpl string, typeValue any) { t.Helper() var buf bytes.Buffer require.NoError(t, templatewriter.Print(&buf, tmpl, typeValue)) diff --git a/internal/validate/validate.go b/internal/validate/validate.go index 2817f26163..ee04250bc3 100644 --- a/internal/validate/validate.go +++ b/internal/validate/validate.go @@ -30,7 +30,7 @@ import ( const minPasswordLength = 10 // toString tries to cast an interface to string. -func toString(val interface{}) (string, error) { +func toString(val any) (string, error) { var u string var ok bool if u, ok = val.(string); !ok { @@ -40,7 +40,7 @@ func toString(val interface{}) (string, error) { } // URL validates a value is a valid URL for the cli store. -func URL(val interface{}) error { +func URL(val any) error { s, err := toString(val) if err != nil { return err @@ -57,7 +57,7 @@ func URL(val interface{}) error { } // OptionalURL validates a value is a valid URL for the cli store. -func OptionalURL(val interface{}) error { +func OptionalURL(val any) error { if val == nil { return nil } @@ -73,7 +73,7 @@ func OptionalURL(val interface{}) error { } // OptionalObjectID validates a value is a valid ObjectID. -func OptionalObjectID(val interface{}) error { +func OptionalObjectID(val any) error { if val == nil { return nil } @@ -162,7 +162,7 @@ func ConditionalFlagNotInSlice(conditionalFlag string, conditionalFlagValue stri var ErrInvalidPath = errors.New("invalid path") -func Path(val interface{}) error { +func Path(val any) error { path, ok := val.(string) if !ok { return fmt.Errorf("%w: %v", ErrInvalidPath, val) @@ -175,7 +175,7 @@ func Path(val interface{}) error { return nil } -func OptionalPath(val interface{}) error { +func OptionalPath(val any) error { if val == nil { return nil } @@ -188,7 +188,7 @@ func OptionalPath(val interface{}) error { var ErrInvalidClusterName = errors.New("invalid cluster name") -func ClusterName(val interface{}) error { +func ClusterName(val any) error { name, ok := val.(string) if !ok { return fmt.Errorf("%w: %v", ErrInvalidClusterName, val) @@ -203,7 +203,7 @@ func ClusterName(val interface{}) error { var ErrInvalidDBUsername = errors.New("invalid db username") -func DBUsername(val interface{}) error { +func DBUsername(val any) error { name, ok := val.(string) if !ok { return fmt.Errorf("%w: %v", ErrInvalidDBUsername, val) @@ -219,7 +219,7 @@ func DBUsername(val interface{}) error { var ErrWeakPassword = errors.New("the password provided is too common") var ErrShortPassword = errors.New("the password provided is too short") -func WeakPassword(val interface{}) error { +func WeakPassword(val any) error { password, ok := val.(string) if !ok { return ErrWeakPassword diff --git a/internal/validate/validate_test.go b/internal/validate/validate_test.go index 17adf63c97..6658330f62 100644 --- a/internal/validate/validate_test.go +++ b/internal/validate/validate_test.go @@ -21,12 +21,13 @@ import ( "testing" "github.com/spf13/viper" + "github.com/stretchr/testify/require" ) func TestURL(t *testing.T) { tests := []struct { name string - val interface{} + val any wantErr bool }{ { @@ -60,7 +61,7 @@ func TestURL(t *testing.T) { func TestOptionalObjectID(t *testing.T) { tests := []struct { name string - val interface{} + val any wantErr bool }{ { @@ -273,7 +274,7 @@ func TestOptionalURL(t *testing.T) { t.Parallel() tests := []struct { name string - val interface{} + val any wantErr bool }{ { @@ -310,93 +311,87 @@ func TestOptionalURL(t *testing.T) { } func TestPath(t *testing.T) { - f, err := os.CreateTemp("", "sample") - if err != nil { - t.Fatal(err) - } + f, err := os.CreateTemp("", "TestPath") + require.NoError(t, err) t.Cleanup(func() { - os.Remove(f.Name()) + require.NoError(t, f.Close()) + require.NoError(t, os.Remove(f.Name())) }) - tests := []struct { name string - val interface{} - wantErr bool + val any + wantErr require.ErrorAssertionFunc }{ { name: "valid", val: f.Name(), - wantErr: false, + wantErr: require.NoError, }, { name: "empty", val: "", - wantErr: true, + wantErr: require.Error, }, { name: "nil", val: nil, - wantErr: true, + wantErr: require.Error, }, { name: "invalid value", val: 1, - wantErr: true, + wantErr: require.Error, }, } for _, tt := range tests { val := tt.val wantErr := tt.wantErr t.Run(tt.name, func(t *testing.T) { - if err2 := Path(val); (err2 != nil) != wantErr { - t.Errorf("Path() error = %v, wantErr %v", err2, wantErr) - } + t.Parallel() + wantErr(t, Path(val)) }) } } func TestOptionalPath(t *testing.T) { - f, err := os.CreateTemp("", "sample") - if err != nil { - t.Fatal(err) - } + f, err := os.CreateTemp("", "TestOptionalPath") + require.NoError(t, err) t.Cleanup(func() { - os.Remove(f.Name()) + require.NoError(t, f.Close()) + require.NoError(t, os.Remove(f.Name())) }) - tests := []struct { name string - val interface{} - wantErr bool + val any + wantErr require.ErrorAssertionFunc }{ { name: "valid", val: f.Name(), - wantErr: false, + wantErr: require.NoError, }, { name: "empty", val: "", - wantErr: false, + wantErr: require.NoError, }, { name: "nil", val: nil, - wantErr: false, + wantErr: require.NoError, }, { name: "invalid value", val: 1, - wantErr: true, + wantErr: require.Error, }, } for _, tt := range tests { val := tt.val wantErr := tt.wantErr t.Run(tt.name, func(t *testing.T) { - if err2 := OptionalPath(val); (err2 != nil) != wantErr { - t.Errorf("OptionalPath() error = %v, wantErr %v", err2, wantErr) - } + t.Parallel() + wantErr(t, OptionalPath(val)) }) } } @@ -404,42 +399,41 @@ func TestOptionalPath(t *testing.T) { func TestClusterName(t *testing.T) { tests := []struct { name string - val interface{} - wantErr bool + val any + wantErr require.ErrorAssertionFunc }{ { name: "valid (single word)", val: "Cluster0", - wantErr: false, + wantErr: require.NoError, }, { name: "valid (dashed)", val: "Cluster-0", - wantErr: false, + wantErr: require.NoError, }, { name: "invalid (space)", val: "Cluster 0", - wantErr: true, + wantErr: require.Error, }, { name: "invalid (underscore)", val: "Cluster_0", - wantErr: true, + wantErr: require.Error, }, { name: "invalid (spacial char)", val: "Cluster-ñ", - wantErr: true, + wantErr: require.Error, }, } for _, tt := range tests { val := tt.val wantErr := tt.wantErr t.Run(tt.name, func(t *testing.T) { - if err := ClusterName(val); (err != nil) != wantErr { - t.Errorf("ClusterName() error = %v, wantErr %v", err, wantErr) - } + t.Parallel() + wantErr(t, ClusterName(val)) }) } } @@ -447,42 +441,41 @@ func TestClusterName(t *testing.T) { func TestDBUsername(t *testing.T) { tests := []struct { name string - val interface{} - wantErr bool + val any + wantErr require.ErrorAssertionFunc }{ { name: "valid (single word)", val: "admin", - wantErr: false, + wantErr: require.NoError, }, { name: "valid (dashed)", val: "admin-test", - wantErr: false, + wantErr: require.NoError, }, { name: "valid (underscore)", val: "admin_test", - wantErr: false, + wantErr: require.NoError, }, { name: "invalid (space)", val: "admin test", - wantErr: true, + wantErr: require.Error, }, { name: "invalid (spacial char)", val: "admin-ñ", - wantErr: true, + wantErr: require.Error, }, } for _, tt := range tests { val := tt.val wantErr := tt.wantErr t.Run(tt.name, func(t *testing.T) { - if err := DBUsername(val); (err != nil) != wantErr { - t.Errorf("DBUsername() error = %v, wantErr %v", err, wantErr) - } + t.Parallel() + wantErr(t, DBUsername(val)) }) } } @@ -490,32 +483,31 @@ func TestDBUsername(t *testing.T) { func TestWeakPassword(t *testing.T) { tests := []struct { name string - val interface{} - wantErr bool + val any + wantErr require.ErrorAssertionFunc }{ { name: "valid password", val: "password!@3!", - wantErr: false, + wantErr: require.NoError, }, { name: "weak password", val: "password", - wantErr: true, + wantErr: require.Error, }, { name: "weak password", val: "password1", - wantErr: true, + wantErr: require.Error, }, } for _, tt := range tests { val := tt.val wantErr := tt.wantErr t.Run(tt.name, func(t *testing.T) { - if err := WeakPassword(val); (err != nil) != wantErr { - t.Errorf("WeakPassword() error = %v, wantErr %v", err, wantErr) - } + t.Parallel() + wantErr(t, WeakPassword(val)) }) } } diff --git a/test/e2e/atlas/deployments_local_auth_test.go b/test/e2e/atlas/deployments_local_auth_test.go index 041816df39..045544cc97 100644 --- a/test/e2e/atlas/deployments_local_auth_test.go +++ b/test/e2e/atlas/deployments_local_auth_test.go @@ -154,7 +154,7 @@ func TestDeploymentsLocalWithAuth(t *testing.T) { }) t.Run("Seed database", func(t *testing.T) { - ids, err := myCol.InsertMany(ctx, []interface{}{ + ids, err := myCol.InsertMany(ctx, []any{ bson.M{ "name": "test1", }, bson.M{ diff --git a/test/e2e/atlas/deployments_local_noauth_test.go b/test/e2e/atlas/deployments_local_noauth_test.go index 30bed72c39..761fa9914c 100644 --- a/test/e2e/atlas/deployments_local_noauth_test.go +++ b/test/e2e/atlas/deployments_local_noauth_test.go @@ -143,7 +143,7 @@ func TestDeploymentsLocal(t *testing.T) { }) t.Run("Seed database", func(t *testing.T) { - ids, err := myCol.InsertMany(ctx, []interface{}{ + ids, err := myCol.InsertMany(ctx, []any{ bson.M{ "name": "test1", }, @@ -157,7 +157,7 @@ func TestDeploymentsLocal(t *testing.T) { b, err := os.ReadFile("data/sample_embedded_movies.json") require.NoError(t, err) - var movies []interface{} + var movies []any require.NoError(t, json.Unmarshal(b, &movies)) ids, err = client.Database(vectorSearchDB).Collection(vectorSearchCol).InsertMany(ctx, movies) @@ -331,7 +331,7 @@ func TestDeploymentsLocal(t *testing.T) { b, err := os.ReadFile("data/sample_vector_search_pipeline.json") req.NoError(err) - var pipeline []map[string]interface{} + var pipeline []map[string]any err = json.Unmarshal(b, &pipeline) req.NoError(err) diff --git a/test/e2e/atlas/helper_test.go b/test/e2e/atlas/helper_test.go index f92cd00a8b..2c0935db64 100644 --- a/test/e2e/atlas/helper_test.go +++ b/test/e2e/atlas/helper_test.go @@ -1027,7 +1027,7 @@ func compareStingsWithHiddenPart(expectedSting, actualString string, specialChar // createJSONFile creates a new JSON file at the specified path with the specified data // and also registers its deletion on test cleanup. -func createJSONFile(t *testing.T, data interface{}, path string) { +func createJSONFile(t *testing.T, data any, path string) { t.Helper() jsonData, err := json.Marshal(data) if err != nil { diff --git a/test/e2e/atlas/project_settings_test.go b/test/e2e/atlas/project_settings_test.go index 9b31c4e666..e574f3fc26 100644 --- a/test/e2e/atlas/project_settings_test.go +++ b/test/e2e/atlas/project_settings_test.go @@ -54,7 +54,7 @@ func TestProjectSettings(t *testing.T) { cmd.Env = os.Environ() resp, err := e2e.RunAndGetStdOut(cmd) require.NoError(t, err, string(resp)) - var settings map[string]interface{} + var settings map[string]any if err := json.Unmarshal(resp, &settings); err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/test/e2e/brew/brew_test.go b/test/e2e/brew/brew_test.go index 921815e68f..0185f7cb2f 100644 --- a/test/e2e/brew/brew_test.go +++ b/test/e2e/brew/brew_test.go @@ -22,6 +22,8 @@ import ( "testing" "github.com/mongodb/mongodb-atlas-cli/atlascli/test/e2e" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ( @@ -31,46 +33,31 @@ const ( func TestAtlasCLIConfig(t *testing.T) { cliPath, err := e2e.AtlasCLIBin() - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - + require.NoError(t, err) tempDirEnv := "XDG_CONFIG_HOME=" + os.TempDir() // make sure no config.toml is detected t.Run("config ls", func(t *testing.T) { cmd := exec.Command(cliPath, "config", "ls") cmd.Env = append(os.Environ(), tempDirEnv) resp, err := e2e.RunAndGetStdOut(cmd) - if err != nil { - t.Fatalf("unexpected error: %v, resp: %v", err, string(resp)) - } + require.NoError(t, err, string(resp)) got := strings.TrimSpace(string(resp)) - want := profileString - - if got != want { - t.Errorf("want %q; got %q\n", want, got) - } + assert.Equal(t, profileString, got) }) t.Run("projects ls", func(t *testing.T) { cmd := exec.Command(cliPath, "projects", "ls") cmd.Env = append(os.Environ(), tempDirEnv) resp, err := cmd.CombinedOutput() - if err == nil { - t.Fatalf("expected error, resp: %v", string(resp)) - } got := string(resp) - - if !strings.Contains(got, errorMessage) { - t.Errorf("want %q; got %q\n", errorMessage, got) - } + require.Error(t, err, got) + assert.Contains(t, got, errorMessage) }) t.Run("help", func(t *testing.T) { cmd := exec.Command(cliPath, "help") cmd.Env = append(os.Environ(), tempDirEnv) - if resp, err := e2e.RunAndGetStdOut(cmd); err != nil { - t.Fatalf("unexpected error, resp: %v", string(resp)) - } + resp, err := e2e.RunAndGetStdOut(cmd) + require.NoError(t, err, string(resp)) }) } diff --git a/test/e2e/config/config_test.go b/test/e2e/config/config_test.go index f67cce464a..7e9fa40991 100644 --- a/test/e2e/config/config_test.go +++ b/test/e2e/config/config_test.go @@ -27,6 +27,7 @@ import ( pseudotty "github.com/creack/pty" "github.com/hinshun/vt10x" "github.com/mongodb/mongodb-atlas-cli/atlascli/test/e2e" + "github.com/stretchr/testify/require" ) const ( @@ -36,10 +37,7 @@ const ( func TestConfig(t *testing.T) { cliPath, err := e2e.AtlasCLIBin() - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - + require.NoError(t, err) t.Run("config", func(t *testing.T) { key := os.Getenv("MCLI_PRIVATE_API_KEY") _ = os.Unsetenv("MCLI_PRIVATE_API_KEY") @@ -142,7 +140,7 @@ func TestConfig(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v, resp: %v", err, string(resp)) } - var config map[string]interface{} + var config map[string]any if err := json.Unmarshal(resp, &config); err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/test/e2e/decryption/decryption.go b/test/e2e/decryption/decryption.go index bcf63e7d4d..12fc3132a3 100644 --- a/test/e2e/decryption/decryption.go +++ b/test/e2e/decryption/decryption.go @@ -41,12 +41,12 @@ func DumpToTemp(files embed.FS, srcFile, destFile string) error { return os.WriteFile(destFile, content, fs.ModePerm) } -func parseJSON(contents []byte) ([]map[string]interface{}, error) { - var res []map[string]interface{} +func parseJSON(contents []byte) ([]map[string]any, error) { + var res []map[string]any s := bufio.NewScanner(bytes.NewReader(contents)) for s.Scan() { - var item map[string]interface{} + var item map[string]any err := json.Unmarshal(s.Bytes(), &item) if err != nil { return nil, err diff --git a/tools/cli-generator/generate.go b/tools/cli-generator/generate.go index 124b019647..9e8b312a92 100644 --- a/tools/cli-generator/generate.go +++ b/tools/cli-generator/generate.go @@ -228,6 +228,8 @@ func (cli *CLI) generateCommand(cmd *Command) error { return nil } +const filePermissions = 0o600 + func cleanupFile(filePath string) error { b, err := os.ReadFile(filePath) if err != nil { @@ -237,7 +239,6 @@ func cleanupFile(filePath string) error { if err != nil { return err } - const filePermissions = 0600 return os.WriteFile(filePath, r, filePermissions) } diff --git a/tools/templates-checker/astparsing/astparsing.go b/tools/templates-checker/astparsing/astparsing.go index a3043e396a..8c40851d34 100644 --- a/tools/templates-checker/astparsing/astparsing.go +++ b/tools/templates-checker/astparsing/astparsing.go @@ -43,8 +43,8 @@ type CommandBuilderInfo struct { TemplateValue string } -func LoadCommandBuilderInfos(packages []*packages.Package) []*CommandBuilderInfo { - commandBuilderFuncDecls := findCommandBuilderFuncDecl(packages) +func LoadCommandBuilderInfos(p []*packages.Package) []*CommandBuilderInfo { + commandBuilderFuncDecls := findCommandBuilderFuncDecl(p) builderFuncs := make([]*CommandBuilderInfo, 0) @@ -63,11 +63,11 @@ func LoadCommandBuilderInfos(packages []*packages.Package) []*CommandBuilderInfo } // Iterate through all to find all command builder functions. -func findCommandBuilderFuncDecl(packages []*packages.Package) []*CommandBuilderFunc { +func findCommandBuilderFuncDecl(p []*packages.Package) []*CommandBuilderFunc { builderFuncs := make([]*CommandBuilderFunc, 0) // Loop through all declarations in every package, file - for _, pkg := range packages { + for _, pkg := range p { for _, file := range pkg.Syntax { // Loop through all declarations, this can be variable, function, ... declarations for _, declaration := range file.Decls { diff --git a/tools/templates-checker/templateparsing/templateparsing.go b/tools/templates-checker/templateparsing/templateparsing.go index 2e3988cbc3..40aa88ebd9 100644 --- a/tools/templates-checker/templateparsing/templateparsing.go +++ b/tools/templates-checker/templateparsing/templateparsing.go @@ -159,8 +159,8 @@ func ident(value string, depth int) string { return fmt.Sprintf("%*s%s", depth*spacesPerDepth, "", value) } -func ParseTemplate(template string) (*TemplateCallTree, error) { - parseTree, err := parse.Parse("templ", template, "{{", "}}", templateFuncs) +func ParseTemplate(t string) (*TemplateCallTree, error) { + parseTree, err := parse.Parse("templ", t, "{{", "}}", templateFuncs) if err != nil { return nil, err } @@ -349,7 +349,7 @@ func pipelineToIdentifiers(pipeline *parse.PipeNode) ([]string, error) { } } -func IsNil(i interface{}) bool { +func IsNil(i any) bool { return i == nil || (reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil()) }