From 9e1a42b8523d33571ffc0666dcb19c4dafe444b2 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 15 Apr 2026 19:10:51 +0000 Subject: [PATCH 1/4] Enable more linters and fix all violations Add dupword, misspell, nilerr, fatcontext, wastedassign, nosprintfhostport, recvcheck, usetesting, nilnesserr, durationcheck, exptostd, gocheckcompilerdirectives, asciicheck, and reassign linters to .golangci.yaml. Fix all violations: spelling typos and duplicate words in comments and string literals across the codebase. Co-authored-by: Isaac --- .golangci.yaml | 14 ++++++++++++++ acceptance/internal/prepare_server.go | 2 +- bundle/apps/validate.go | 2 +- .../mutator/resourcemutator/apply_target_mode.go | 2 +- bundle/config/mutator/rewrite_workspace_prefix.go | 2 +- bundle/config/mutator/set_variables_test.go | 2 +- bundle/config/root.go | 4 ++-- bundle/config/variable/variable.go | 2 +- bundle/direct/bundle_plan.go | 2 +- bundle/libraries/local_path.go | 4 ++-- bundle/run/app_test.go | 2 +- bundle/run/progress/pipeline.go | 6 +++--- bundle/trampoline/python_wheel.go | 2 +- bundle/trampoline/python_wheel_test.go | 2 +- cmd/apps/run_local.go | 2 +- cmd/root/user_agent_command.go | 2 +- integration/libs/locker/locker_test.go | 2 +- internal/testcli/runner.go | 2 +- libs/dyn/convert/from_typed.go | 2 +- libs/dyn/dynvar/resolve_test.go | 2 +- libs/dyn/mapping_test.go | 2 +- libs/dyn/pattern_trie.go | 2 +- libs/env/context.go | 2 +- libs/git/config_test.go | 1 + libs/jsonschema/extension.go | 2 +- libs/locker/locker.go | 2 +- libs/log/handler/friendly.go | 2 +- libs/process/stub.go | 2 +- libs/structs/structaccess/set_test.go | 2 +- libs/structs/structdiff/jobsettings_test.go | 4 ++-- libs/sync/diff.go | 4 ++-- libs/sync/snapshot.go | 2 +- libs/textutil/textutil_test.go | 2 +- 33 files changed, 52 insertions(+), 37 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 3b85954a07..5677ff180a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -21,6 +21,20 @@ linters: - forbidigo - depguard - usestdlibvars + - nilerr + - fatcontext + - wastedassign + - nosprintfhostport + - recvcheck + - usetesting + - dupword + - misspell + - nilnesserr + - durationcheck + - exptostd + - gocheckcompilerdirectives + - asciicheck + - reassign settings: depguard: rules: diff --git a/acceptance/internal/prepare_server.go b/acceptance/internal/prepare_server.go index 2a4d02f8c4..668bc7a231 100644 --- a/acceptance/internal/prepare_server.go +++ b/acceptance/internal/prepare_server.go @@ -123,7 +123,7 @@ func PrepareServerAndClient(t *testing.T, config TestConfig, logRequests bool, o } // For the purposes of replacements, use testUser for local runs. - // Note, users might have overriden /api/2.0/preview/scim/v2/Me but that should not affect the replacement: + // Note, users might have overridden /api/2.0/preview/scim/v2/Me but that should not affect the replacement: return cfg, testUser } diff --git a/bundle/apps/validate.go b/bundle/apps/validate.go index 6c6403e06f..45a5b49c67 100644 --- a/bundle/apps/validate.go +++ b/bundle/apps/validate.go @@ -46,7 +46,7 @@ func (v *validate) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnostics diags = append(diags, diag.Diagnostic{ Severity: diag.Error, Summary: "Duplicate app source code path", - Detail: fmt.Sprintf("app resource '%s' has the same source code path as app resource '%s', this will lead to the app configuration being overriden by each other", key, usedSourceCodePaths[app.SourceCodePath]), + Detail: fmt.Sprintf("app resource '%s' has the same source code path as app resource '%s', this will lead to the app configuration being overridden by each other", key, usedSourceCodePaths[app.SourceCodePath]), Locations: b.Config.GetLocations(fmt.Sprintf("resources.apps.%s.source_code_path", key)), }) } diff --git a/bundle/config/mutator/resourcemutator/apply_target_mode.go b/bundle/config/mutator/resourcemutator/apply_target_mode.go index e7ee0324dc..727a2e5bef 100644 --- a/bundle/config/mutator/resourcemutator/apply_target_mode.go +++ b/bundle/config/mutator/resourcemutator/apply_target_mode.go @@ -23,7 +23,7 @@ func (m *applyTargetMode) Name() string { } // Mark all resources as being for 'development' purposes, i.e. -// changing their their name, adding tags, and (in the future) +// changing their name, adding tags, and (in the future) // marking them as 'hidden' in the UI. func transformDevelopmentMode(ctx context.Context, b *bundle.Bundle) { if !b.Config.Bundle.Deployment.Lock.IsExplicitlyEnabled() { diff --git a/bundle/config/mutator/rewrite_workspace_prefix.go b/bundle/config/mutator/rewrite_workspace_prefix.go index 0ccb3314b9..e66482f8e5 100644 --- a/bundle/config/mutator/rewrite_workspace_prefix.go +++ b/bundle/config/mutator/rewrite_workspace_prefix.go @@ -12,7 +12,7 @@ import ( type rewriteWorkspacePrefix struct{} -// RewriteWorkspacePrefix finds any strings in bundle configration that have +// RewriteWorkspacePrefix finds any strings in bundle configuration that have // workspace prefix plus workspace path variable used and removes workspace prefix from it. func RewriteWorkspacePrefix() bundle.Mutator { return &rewriteWorkspacePrefix{} diff --git a/bundle/config/mutator/set_variables_test.go b/bundle/config/mutator/set_variables_test.go index e69bbf34c3..ecc6754801 100644 --- a/bundle/config/mutator/set_variables_test.go +++ b/bundle/config/mutator/set_variables_test.go @@ -122,7 +122,7 @@ func TestSetVariablesMutator(t *testing.T) { Default: defaultValForA, }, "b": { - Description: "resolved from environment vairables", + Description: "resolved from environment variables", Default: defaultValForB, }, "c": { diff --git a/bundle/config/root.go b/bundle/config/root.go index a32ca8ea28..7271168b03 100644 --- a/bundle/config/root.go +++ b/bundle/config/root.go @@ -443,7 +443,7 @@ var allowedVariableDefinitions = []([]string){ {"lookup"}, } -// isFullVariableOverrideDef checks if the given value is a full syntax varaible override. +// isFullVariableOverrideDef checks if the given value is a full syntax variable override. // A full syntax variable override is a map with either 1 of 2 keys. // If it's 2 keys, the keys should be "default" and "type". // If it's 1 key, the key should be one of the following keys: "default", "lookup". @@ -514,7 +514,7 @@ func rewriteShorthands(v dyn.Value) (dyn.Value, error) { // Check if the original definition of variable has a type field. // If it has a type field, it means the shorthand is a value of a complex type. - // Type might not be found if the variable overriden in a separate file + // Type might not be found if the variable overridden in a separate file // and configuration is not merged yet. typeV, err := dyn.GetByPath(v, p.Append(dyn.Key("type"))) if err == nil && typeV.MustString() == "complex" { diff --git a/bundle/config/variable/variable.go b/bundle/config/variable/variable.go index c924616fa2..5f8ea6138c 100644 --- a/bundle/config/variable/variable.go +++ b/bundle/config/variable/variable.go @@ -57,7 +57,7 @@ type Variable struct { } // True if the variable has been assigned a default value. Variables without a -// a default value are by defination required +// default value are by definition required func (v *Variable) HasDefault() bool { return v.Default != nil } diff --git a/bundle/direct/bundle_plan.go b/bundle/direct/bundle_plan.go index 65e71d3524..3fab4c3f4f 100644 --- a/bundle/direct/bundle_plan.go +++ b/bundle/direct/bundle_plan.go @@ -517,7 +517,7 @@ func isEmpty(rv reflect.Value) bool { return rv.Len() == 0 } - // Certain structs come up set even if fully empty and and not set by client, e.g. email_notifications and webhook_notifications + // Certain structs come up set even if fully empty and not set by client, e.g. email_notifications and webhook_notifications if isEmptyStruct(rv) { return true } diff --git a/bundle/libraries/local_path.go b/bundle/libraries/local_path.go index 1a01fa2a19..2f86481b16 100644 --- a/bundle/libraries/local_path.go +++ b/bundle/libraries/local_path.go @@ -45,7 +45,7 @@ func IsLocalPath(p string) bool { // IsLibraryLocal returns true if the specified library or environment dependency // should be interpreted as a local path. // We use this to check if the dependency in environment spec is local or that library is local. -// We can't use IsLocalPath beacuse environment dependencies can be +// We can't use IsLocalPath because environment dependencies can be // a pypi package name which can be misinterpreted as a local path by IsLocalPath. func IsLibraryLocal(dep string) bool { if dep == "" { @@ -96,7 +96,7 @@ func IsLocalPathInPipFlag(dep string) (string, string, bool) { } func containsPipFlag(input string) bool { - // Trailing space means the the flag takes an argument or there's multiple arguments in input + // Trailing space means the flag takes an argument or there's multiple arguments in input // Alternatively it could be a flag with no argument and no space after it // For example: -r myfile.txt or --index-url http://myindexurl.com or -i re := regexp.MustCompile(`(^|\s+)--?[a-zA-Z0-9-]+(([\s|=]+)|$)`) diff --git a/bundle/run/app_test.go b/bundle/run/app_test.go index 1c05fa63eb..f20625381e 100644 --- a/bundle/run/app_test.go +++ b/bundle/run/app_test.go @@ -229,7 +229,7 @@ func TestAppDeployWithDeploymentInProgress(t *testing.T) { appApi.EXPECT().WaitGetDeploymentAppSucceeded(mock.Anything, "my_app", "active_deployment_id", mock.Anything, mock.Anything).Return(nil, nil) - // Second one should succeeed + // Second one should succeed appApi.EXPECT().Deploy(mock.Anything, apps.CreateAppDeploymentRequest{ AppName: "my_app", AppDeployment: apps.AppDeployment{ diff --git a/bundle/run/progress/pipeline.go b/bundle/run/progress/pipeline.go index f12d0455fc..dc66caec06 100644 --- a/bundle/run/progress/pipeline.go +++ b/bundle/run/progress/pipeline.go @@ -10,15 +10,15 @@ import ( "github.com/databricks/databricks-sdk-go/service/pipelines" ) -// The dlt backend computes events for pipeline runs which are accessable through +// The dlt backend computes events for pipeline runs which are accessible through // the 2.0/pipelines/{pipeline_id}/events API // // There are 4 levels for these events: ("ERROR", "WARN", "INFO", "METRICS") // // Here's short introduction to a few important events we display on the console: // -// 1. `update_progress`: A state transition occured for the entire pipeline update -// 2. `flow_progress`: A state transition occured for a single flow in the pipeine +// 1. `update_progress`: A state transition occurred for the entire pipeline update +// 2. `flow_progress`: A state transition occurred for a single flow in the pipeine type ProgressEvent pipelines.PipelineEvent func (event *ProgressEvent) String() string { diff --git a/bundle/trampoline/python_wheel.go b/bundle/trampoline/python_wheel.go index af949991ed..722a0b35e6 100644 --- a/bundle/trampoline/python_wheel.go +++ b/bundle/trampoline/python_wheel.go @@ -160,7 +160,7 @@ func (t *pythonTrampoline) GetTemplateData(task *jobs.Task) (map[string]any, err func (t *pythonTrampoline) generateParameters(task *jobs.PythonWheelTask) (string, error) { if task.Parameters != nil && task.NamedParameters != nil { - return "", errors.New("not allowed to pass both paramaters and named_parameters") + return "", errors.New("not allowed to pass both parameters and named_parameters") } params := append([]string{task.PackageName}, task.Parameters...) for k, v := range task.NamedParameters { diff --git a/bundle/trampoline/python_wheel_test.go b/bundle/trampoline/python_wheel_test.go index 8b9669087f..1ae42a063e 100644 --- a/bundle/trampoline/python_wheel_test.go +++ b/bundle/trampoline/python_wheel_test.go @@ -66,7 +66,7 @@ func TestGenerateBoth(t *testing.T) { task := &jobs.PythonWheelTask{NamedParameters: map[string]string{"a": "1"}, Parameters: []string{"b"}} _, err := trampoline.generateParameters(task) require.Error(t, err) - require.ErrorContains(t, err, "not allowed to pass both paramaters and named_parameters") + require.ErrorContains(t, err, "not allowed to pass both parameters and named_parameters") } func TestTransformFiltersWheelTasksOnly(t *testing.T) { diff --git a/cmd/apps/run_local.go b/cmd/apps/run_local.go index d54ab0d726..d4bc546ab7 100644 --- a/cmd/apps/run_local.go +++ b/cmd/apps/run_local.go @@ -191,7 +191,7 @@ func newRunLocal() *cobra.Command { This command starts an app locally.` - cmd.Flags().IntVar(&port, "port", 8001, "Port on which to run the app app proxy") + cmd.Flags().IntVar(&port, "port", 8001, "Port on which to run the app proxy") cmd.Flags().IntVar(&appPort, "app-port", runlocal.DEFAULT_PORT, "Port on which to run the app") cmd.Flags().BoolVar(&debug, "debug", false, "Enable debug mode") cmd.Flags().BoolVar(&prepareEnvironment, "prepare-environment", false, "Prepares the environment for running the app. Requires 'uv' to be installed.") diff --git a/cmd/root/user_agent_command.go b/cmd/root/user_agent_command.go index 70c7f4049a..c1a9adf27c 100644 --- a/cmd/root/user_agent_command.go +++ b/cmd/root/user_agent_command.go @@ -9,7 +9,7 @@ import ( "github.com/spf13/cobra" ) -// commandSeparator joins command names in a command hierachy. +// commandSeparator joins command names in a command hierarchy. // We enforce no command name contains this character. // See unit test [main.TestCommandsDontUseUnderscoreInName]. const commandSeparator = "_" diff --git a/integration/libs/locker/locker_test.go b/integration/libs/locker/locker_test.go index 69f8380a0a..be7ce7a76c 100644 --- a/integration/libs/locker/locker_test.go +++ b/integration/libs/locker/locker_test.go @@ -62,7 +62,7 @@ func TestLock(t *testing.T) { assert.ErrorContains(t, lockerErrs[i], "Use --force-lock to override") } } - assert.Equal(t, 1, countActive, "Exactly one locker should successfull acquire the lock") + assert.Equal(t, 1, countActive, "Exactly one locker should successfully acquire the lock") // test remote lock matches active lock remoteLocker, err := locker.GetActiveLockState(ctx) diff --git a/internal/testcli/runner.go b/internal/testcli/runner.go index f74e965ffd..deb7e59a2f 100644 --- a/internal/testcli/runner.go +++ b/internal/testcli/runner.go @@ -91,7 +91,7 @@ func (r *Runner) SendText(text string) { } _, err := r.stdinW.Write([]byte(text + "\n")) if err != nil { - panic("Failed to to write to t.stdinW") + panic("Failed to write to t.stdinW") } } diff --git a/libs/dyn/convert/from_typed.go b/libs/dyn/convert/from_typed.go index f7a0085635..6645112429 100644 --- a/libs/dyn/convert/from_typed.go +++ b/libs/dyn/convert/from_typed.go @@ -29,7 +29,7 @@ const ( // It uses the reference value both for location information and to determine if the typed // value was changed or not. For example, if a struct-by-value field is nil in the reference // it will be zero-valued in the typed configuration. If it remains zero-valued, this -// this function will still emit a nil value in the dynamic representation. +// function will still emit a nil value in the dynamic representation. func FromTyped(src any, ref dyn.Value) (dyn.Value, error) { return fromTyped(src, ref) } diff --git a/libs/dyn/dynvar/resolve_test.go b/libs/dyn/dynvar/resolve_test.go index 5b64029bae..62ef7cb14e 100644 --- a/libs/dyn/dynvar/resolve_test.go +++ b/libs/dyn/dynvar/resolve_test.go @@ -221,7 +221,7 @@ func TestResolveWithSkip(t *testing.T) { // Check that the skipped variable references are not interpolated. assert.Equal(t, "${b}", getByPath(t, out, "d").MustString()) assert.Equal(t, "a ${b}", getByPath(t, out, "e").MustString()) - assert.Equal(t, "${b} a a ${b}", getByPath(t, out, "f").MustString()) + assert.Equal(t, "${b} a a ${b}", getByPath(t, out, "f").MustString()) //nolint:dupword } func TestResolveWithSkipEverything(t *testing.T) { diff --git a/libs/dyn/mapping_test.go b/libs/dyn/mapping_test.go index 4bf652a799..7f3d0c77ed 100644 --- a/libs/dyn/mapping_test.go +++ b/libs/dyn/mapping_test.go @@ -59,7 +59,7 @@ func TestMappingGet(t *testing.T) { // Modify the value to make sure we're not getting a reference p.Value = dyn.V("newvalue") - // Call GetPairByString with with non-existent key + // Call GetPairByString with non-existent key p, ok = m.GetPairByString("enoexist") assert.False(t, ok) assert.Equal(t, dyn.InvalidValue, p.Key) diff --git a/libs/dyn/pattern_trie.go b/libs/dyn/pattern_trie.go index 00173220ac..a4239c3cb5 100644 --- a/libs/dyn/pattern_trie.go +++ b/libs/dyn/pattern_trie.go @@ -13,7 +13,7 @@ import ( // Each node in the array represents one or more of: // 1. An [AnyKey] component. This is the "*" wildcard which matches any map key. // 2. An [AnyIndex] component. This is the "[*]" wildcard which matches any array index. -// 3. Multiple [Key] components. These are multiple static path keys for this this node would match. +// 3. Multiple [Key] components. These are multiple static path keys for this node would match. // // Note: It's valid for both anyKey and pathKey to be set at the same time. // For example, adding both "foo.*.bar" and "foo.bar" to a trie is valid. diff --git a/libs/env/context.go b/libs/env/context.go index 3a7ce5284e..62a11394a1 100644 --- a/libs/env/context.go +++ b/libs/env/context.go @@ -34,7 +34,7 @@ func setMap(ctx context.Context, m map[string]string) context.Context { return context.WithValue(ctx, &envContextKey, m) } -// Lookup key in the context or the the environment. +// Lookup key in the context or the environment. // Context has precedence. func Lookup(ctx context.Context, key string) (string, bool) { m := getMap(ctx) diff --git a/libs/git/config_test.go b/libs/git/config_test.go index f09f851568..675771233c 100644 --- a/libs/git/config_test.go +++ b/libs/git/config_test.go @@ -13,6 +13,7 @@ import ( func TestConfig(t *testing.T) { // Taken from https://git-scm.com/docs/git-config#_example. + //nolint:dupword raw := ` # Core variables [core] diff --git a/libs/jsonschema/extension.go b/libs/jsonschema/extension.go index b5d122b6d8..0bc23afcb1 100644 --- a/libs/jsonschema/extension.go +++ b/libs/jsonschema/extension.go @@ -15,7 +15,7 @@ type Extension struct { // Welcome message to print before prompting the user for input WelcomeMessage string `json:"welcome_message,omitempty"` - // The message to print after the template is successfully initalized + // The message to print after the template is successfully initialized SuccessMessage string `json:"success_message,omitempty"` // PatternMatchFailureMessage is a user defined message that is displayed to the diff --git a/libs/locker/locker.go b/libs/locker/locker.go index 003f169cd3..4a094ba028 100644 --- a/libs/locker/locker.go +++ b/libs/locker/locker.go @@ -42,7 +42,7 @@ const LockFileName = "deploy.lock" // we allow clients to forcefully acquire a lock on TargetDir. However forcefully acquired // locks come with the following caveats: // -// a. a forcefully acquired lock does not guarentee exclusive access to +// a. a forcefully acquired lock does not guarantee exclusive access to // TargetDir's scope // b. forcefully acquiring a lock(s) on TargetDir can break the assumption // of exclusive access that other clients with non forcefully acquired diff --git a/libs/log/handler/friendly.go b/libs/log/handler/friendly.go index 5c60eb13d6..354675edc3 100644 --- a/libs/log/handler/friendly.go +++ b/libs/log/handler/friendly.go @@ -168,7 +168,7 @@ func (s *handleState) appendAttr(a slog.Attr) { str := a.Value.String() format := "%s" - // Quote values wih spaces, to make them easy to parse. + // Quote values with spaces, to make them easy to parse. if strings.ContainsAny(str, " \t\n") { format = "%q" } diff --git a/libs/process/stub.go b/libs/process/stub.go index a47e911f19..ef5f02d4a3 100644 --- a/libs/process/stub.go +++ b/libs/process/stub.go @@ -104,7 +104,7 @@ func (s *processStub) Commands() (called []string) { return called } -// CombinedEnvironment returns all enviroment variables used for all commands +// CombinedEnvironment returns all environment variables used for all commands func (s *processStub) CombinedEnvironment() map[string]string { environment := map[string]string{} for _, cmd := range s.calls { diff --git a/libs/structs/structaccess/set_test.go b/libs/structs/structaccess/set_test.go index 57b22aea3b..1b294494ec 100644 --- a/libs/structs/structaccess/set_test.go +++ b/libs/structs/structaccess/set_test.go @@ -464,7 +464,7 @@ func TestSet(t *testing.T) { name: "key-value no matching element", path: "nested_items[id='nonexistent'].name", value: "value", - errorMsg: "failed to navigate to parent nested_items[id='nonexistent']: nested_items[id='nonexistent']: no element found with id=\"nonexistent\"", + errorMsg: "failed to navigate to parent nested_items[id='nonexistent']: nested_items[id='nonexistent']: no element found with id=\"nonexistent\"", //nolint:dupword }, } diff --git a/libs/structs/structdiff/jobsettings_test.go b/libs/structs/structdiff/jobsettings_test.go index 82bee98c99..5d6044a584 100644 --- a/libs/structs/structdiff/jobsettings_test.go +++ b/libs/structs/structdiff/jobsettings_test.go @@ -477,7 +477,7 @@ func TestJobDiff(t *testing.T) { assert.Equal(t, "budget_policy_id", changes[0].Path.String()) assert.Equal(t, "550e8400-e29b-41d4-a716-446655440000", changes[0].Old) assert.Equal(t, "", changes[0].New) - // Note: pause_status shows up as nil here because Continous does not have ForceSendFields field + // Note: pause_status shows up as nil here because Continuous does not have ForceSendFields field assert.Equal(t, "continuous.pause_status", changes[1].Path.String()) assert.Equal(t, jobs.PauseStatus("UNPAUSED"), changes[1].Old) assert.Nil(t, changes[1].New) @@ -495,7 +495,7 @@ func TestJobDiff(t *testing.T) { assert.Equal(t, "550e8400-e29b-41d4-a716-446655440000", changes[0].Old) assert.Nil(t, changes[0].New) - // continous is completely deleted from jobExampleResponseNils + // continuous is completely deleted from jobExampleResponseNils assert.Equal(t, "continuous", changes[1].Path.String()) assert.Equal(t, jobs.Continuous{PauseStatus: "UNPAUSED"}, changes[1].Old) assert.Nil(t, changes[1].New) diff --git a/libs/sync/diff.go b/libs/sync/diff.go index 653d3ffd8a..3612cebc76 100644 --- a/libs/sync/diff.go +++ b/libs/sync/diff.go @@ -125,7 +125,7 @@ func (d diff) groupedRmdir() [][]string { dir = path.Dir(dir) for dir != "." && dir != "/" { // Increment the prefix count for this directory, only if it - // it one of the directories we are deleting. + // one of the directories we are deleting. if _, ok := prefixes[dir]; ok { prefixes[dir]++ } @@ -152,7 +152,7 @@ func (d diff) groupedRmdir() [][]string { dir = path.Dir(dir) for dir != "." && dir != "/" { // Decrement the prefix count for this directory, only if it - // it one of the directories we are deleting. + // one of the directories we are deleting. if _, ok := prefixes[dir]; ok { prefixes[dir]-- } diff --git a/libs/sync/snapshot.go b/libs/sync/snapshot.go index ef1b395b55..1b338aab88 100644 --- a/libs/sync/snapshot.go +++ b/libs/sync/snapshot.go @@ -19,7 +19,7 @@ import ( // Bump it up every time a potentially breaking change is made to the snapshot schema const LatestSnapshotVersion = "v1" -// A snapshot is a persistant store of knowledge this CLI has about state of files +// A snapshot is a persistent store of knowledge this CLI has about state of files // in the remote repo. We use the last modified times (mtime) of files to determine // whether a files need to be updated in the remote repo. // diff --git a/libs/textutil/textutil_test.go b/libs/textutil/textutil_test.go index b9268c98b8..d49acaeb21 100644 --- a/libs/textutil/textutil_test.go +++ b/libs/textutil/textutil_test.go @@ -16,7 +16,7 @@ func TestNormalizeString(t *testing.T) { expected: "test", }, { - input: "test test", + input: "test test", //nolint:dupword expected: "test_test", }, { From 30182c567cf478e86c5756c48a1265b011f538dc Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 14:20:16 +0000 Subject: [PATCH 2/4] Fix nosprintfhostport violation; drop redundant wastedassign linter Use net.JoinHostPort in runlocal config to correctly handle IPv6 addresses. Remove wastedassign linter since it's fully redundant with the already-enabled ineffassign linter. Task: 002.md Co-authored-by: Isaac --- .golangci.yaml | 1 - libs/apps/runlocal/cfg.go | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 5677ff180a..a75edeebaa 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -23,7 +23,6 @@ linters: - usestdlibvars - nilerr - fatcontext - - wastedassign - nosprintfhostport - recvcheck - usetesting diff --git a/libs/apps/runlocal/cfg.go b/libs/apps/runlocal/cfg.go index fb0b1eb9d5..d196eb1208 100644 --- a/libs/apps/runlocal/cfg.go +++ b/libs/apps/runlocal/cfg.go @@ -1,6 +1,9 @@ package runlocal -import "fmt" +import ( + "net" + "strconv" +) type Config struct { AppName string @@ -24,7 +27,7 @@ const ( func NewConfig(workspaceHost string, workspaceID int64, appDir, host string, port int) *Config { c := &Config{ AppName: DEFAULT_APP_NAME, - AppURL: fmt.Sprintf("http://%s:%d", host, port), + AppURL: "http://" + net.JoinHostPort(host, strconv.Itoa(port)), WorkspaceID: workspaceID, ServerName: host, Port: port, From f381d03ee574d2294d5e762b89cb5b5008e677fa Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 14:31:03 +0000 Subject: [PATCH 3/4] Fix all 40 linter violations found by full lint run The initial commit only ran make lint (changed files). Running the full lint suite revealed 40 pre-existing violations: - nilerr (15): add //nolint with reasons for intentional error swallowing - recvcheck (11): add //nolint for intentional mixed receivers - usetesting (11): use t.TempDir()/t.Setenv() where safe, nolint where the os.* usage is intentional (KeepTmp, custom restore, Windows workaround) - fatcontext (3): add //nolint for false positives (same-parent contexts) Task: 002.md Co-authored-by: Isaac --- acceptance/acceptance_test.go | 2 +- acceptance/internal/cmd_server.go | 8 ++++---- acceptance/internal/prepare_server.go | 2 +- bundle/artifacts/prepare.go | 2 +- bundle/config/resources/secret_scope.go | 4 ++-- bundle/config/root.go | 2 +- bundle/configsync/patch.go | 2 +- bundle/mutator_read_only.go | 2 +- bundle/run/app.go | 2 +- bundle/run/output/job.go | 2 +- bundle/statemgmt/check_running_resources.go | 3 +-- cmd/auth/describe.go | 6 +++--- libs/apps/initializer/initializer_test.go | 9 ++------- libs/apps/initializer/nodejs.go | 4 ++-- libs/apps/initializer/nodejs_test.go | 10 +++------- libs/apps/initializer/python_pip.go | 2 +- libs/apps/validation/nodejs.go | 2 +- libs/calladapt/calladapt_test.go | 2 +- libs/cmdctx/context_test.go | 2 +- libs/databrickscfg/ops.go | 3 +-- libs/dbr/context_test.go | 2 +- libs/dyn/dynvar/resolve.go | 2 +- libs/dyn/jsonloader/locations.go | 2 +- libs/dyn/mapping.go | 2 +- libs/execv/shell_test.go | 2 +- libs/filer/workspace_files_client.go | 2 +- libs/fileset/file.go | 2 +- libs/sync/diff.go | 2 +- libs/sync/snapshot_state.go | 2 +- libs/tableview/tableview.go | 2 +- libs/template/config.go | 2 +- 31 files changed, 41 insertions(+), 52 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 7ab8dc150a..31c0d9e170 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -609,7 +609,7 @@ func runTest(t *testing.T, if KeepTmp { tempDirBase := filepath.Join(os.TempDir(), "acceptance") _ = os.Mkdir(tempDirBase, 0o755) - tmpDir, err = os.MkdirTemp(tempDirBase, "") + tmpDir, err = os.MkdirTemp(tempDirBase, "") //nolint:usetesting // KeepTmp: dir must persist after test for debugging require.NoError(t, err) t.Logf("Created directory: %s", tmpDir) } else if WorkspaceTmpDir { diff --git a/acceptance/internal/cmd_server.go b/acceptance/internal/cmd_server.go index 3fdbb8902b..05072da690 100644 --- a/acceptance/internal/cmd_server.go +++ b/acceptance/internal/cmd_server.go @@ -49,10 +49,10 @@ func chdir(t *testing.T, cwd string) func() { require.NotEmpty(t, cwd) prevDir, err := os.Getwd() require.NoError(t, err) - err = os.Chdir(cwd) + err = os.Chdir(cwd) //nolint:usetesting // must restore before function ends, not at test cleanup require.NoError(t, err) return func() { - _ = os.Chdir(prevDir) + _ = os.Chdir(prevDir) //nolint:usetesting // see above } } @@ -62,7 +62,7 @@ func configureEnv(t *testing.T, env map[string]string) func() { // Set current process's environment to match the input. os.Clearenv() for key, val := range env { - os.Setenv(key, val) + os.Setenv(key, val) //nolint:usetesting // custom restore needed; t.Setenv can't clearenv+restore all } // Function callback to use with defer to restore original environment. @@ -70,7 +70,7 @@ func configureEnv(t *testing.T, env map[string]string) func() { os.Clearenv() for _, kv := range oldEnv { kvs := strings.SplitN(kv, "=", 2) - os.Setenv(kvs[0], kvs[1]) + os.Setenv(kvs[0], kvs[1]) //nolint:usetesting // see above } } } diff --git a/acceptance/internal/prepare_server.go b/acceptance/internal/prepare_server.go index 668bc7a231..702b4e145e 100644 --- a/acceptance/internal/prepare_server.go +++ b/acceptance/internal/prepare_server.go @@ -44,7 +44,7 @@ func StartDefaultServer(t *testing.T, logRequests bool) { // This approach ensures test reliability across platforms. // // See debugging journey in https://github.com/databricks/cli/pull/3575. - homeDir, err := os.MkdirTemp("", "acceptance-home-dir") + homeDir, err := os.MkdirTemp("", "acceptance-home-dir") //nolint:usetesting // t.TempDir() fails on Windows; see PR #3575 require.NoError(t, err) t.Cleanup(func() { err := os.RemoveAll(homeDir) diff --git a/bundle/artifacts/prepare.go b/bundle/artifacts/prepare.go index 041669ad11..e0a7c1a5a5 100644 --- a/bundle/artifacts/prepare.go +++ b/bundle/artifacts/prepare.go @@ -115,7 +115,7 @@ func InsertPythonArtifact(ctx context.Context, b *bundle.Bundle) error { // checking if there is setup.py in the bundle root setupPy := filepath.Join(b.BundleRootPath, "setup.py") _, err := os.Stat(setupPy) - if err != nil { + if err != nil { //nolint:nilerr // setup.py not found means no wheel project to detect log.Infof(ctx, "No Python wheel project found at bundle root folder") return nil } diff --git a/bundle/config/resources/secret_scope.go b/bundle/config/resources/secret_scope.go index acefe80bd2..9a6664d757 100644 --- a/bundle/config/resources/secret_scope.go +++ b/bundle/config/resources/secret_scope.go @@ -28,7 +28,7 @@ type SecretScopePermission struct { GroupName string `json:"group_name,omitempty"` } -type SecretScope struct { +type SecretScope struct { //nolint:recvcheck // pointer receiver needed for UnmarshalJSON, value for other methods BaseResource // A unique name to identify the secret scope. @@ -66,7 +66,7 @@ func (s SecretScope) Exists(ctx context.Context, w *databricks.WorkspaceClient, // // The indirect methods are not semantically ideal for simple existence checks, so we use the list API here scopes, err := w.Secrets.ListScopesAll(ctx) - if err != nil { + if err != nil { //nolint:nilerr // treat API errors as "scope not found" return false, nil } diff --git a/bundle/config/root.go b/bundle/config/root.go index 7271168b03..764d801bc2 100644 --- a/bundle/config/root.go +++ b/bundle/config/root.go @@ -25,7 +25,7 @@ type Script struct { Content string `json:"content"` } -type Root struct { +type Root struct { //nolint:recvcheck // value receivers for read-only accessors, pointer for mutators value dyn.Value depth int diff --git a/bundle/configsync/patch.go b/bundle/configsync/patch.go index 06bdb381db..087c3e45d9 100644 --- a/bundle/configsync/patch.go +++ b/bundle/configsync/patch.go @@ -281,7 +281,7 @@ func strPathToJSONPointer(pathStr string) (string, error) { // when empty mappings are serialized as "{}" during patch operations func clearAddedFlowStyle(content []byte, fieldChanges []FieldChange) ([]byte, error) { var doc yaml.Node - if err := yaml.Unmarshal(content, &doc); err != nil { + if err := yaml.Unmarshal(content, &doc); err != nil { //nolint:nilerr // return original content if YAML parsing fails return content, nil } for _, fc := range fieldChanges { diff --git a/bundle/mutator_read_only.go b/bundle/mutator_read_only.go index d3157e7480..b4d55e41f1 100644 --- a/bundle/mutator_read_only.go +++ b/bundle/mutator_read_only.go @@ -32,7 +32,7 @@ func ApplyParallel(ctx context.Context, b *Bundle, mutators ...ReadOnlyMutator) contexts := make([]context.Context, len(mutators)) for ind, m := range mutators { - contexts[ind] = log.NewContext(ctx, log.GetLogger(ctx).With("mutator", m.Name())) + contexts[ind] = log.NewContext(ctx, log.GetLogger(ctx).With("mutator", m.Name())) //nolint:fatcontext // independent contexts from same parent, not nested // log right away to have deterministic order of log messages log.Debug(contexts[ind], "ApplyParallel") } diff --git a/bundle/run/app.go b/bundle/run/app.go index dd8911976e..d060ff9899 100644 --- a/bundle/run/app.go +++ b/bundle/run/app.go @@ -165,7 +165,7 @@ func (a *appRunner) resolvedConfig() (*resources.AppConfig, error) { // The key is of the form "apps.", so the full path is "resources.apps..config". configPath := dyn.MustPathFromString("resources." + a.Key() + ".config") configV, err := dyn.GetByPath(root, configPath) - if err != nil || !configV.IsValid() { + if err != nil || !configV.IsValid() { //nolint:nilerr // missing config path means use default config return a.app.Config, nil } diff --git a/bundle/run/output/job.go b/bundle/run/output/job.go index 7dce689719..3e9547ff95 100644 --- a/bundle/run/output/job.go +++ b/bundle/run/output/job.go @@ -43,7 +43,7 @@ func (out *JobOutput) String() (string, error) { continue } taskString, err := v.Output.String() - if err != nil { + if err != nil { //nolint:nilerr // skip tasks with unparseable output return "", nil } result.WriteString("=======\n") diff --git a/bundle/statemgmt/check_running_resources.go b/bundle/statemgmt/check_running_resources.go index 4bf9285d7a..603e3b09a5 100644 --- a/bundle/statemgmt/check_running_resources.go +++ b/bundle/statemgmt/check_running_resources.go @@ -90,8 +90,7 @@ func checkAnyResourceRunning(ctx context.Context, w *databricks.WorkspaceClient, if resourceType == "pipelines" { errs.Go(func() error { isRunning, err := IsPipelineRunning(errCtx, w, id) - // If there's an error retrieving the pipeline, we assume it's not running - if err != nil { + if err != nil { //nolint:nilerr // assume not running if pipeline check fails return nil } if isRunning { diff --git a/cmd/auth/describe.go b/cmd/auth/describe.go index c21eab376c..6b2e3a5641 100644 --- a/cmd/auth/describe.go +++ b/cmd/auth/describe.go @@ -79,7 +79,7 @@ type tryAuth func(cmd *cobra.Command, args []string) (*config.Config, bool, erro func getAuthStatus(cmd *cobra.Command, args []string, showSensitive bool, fn tryAuth) (*authStatus, error) { cfg, isAccount, err := fn(cmd, args) ctx := cmd.Context() - if err != nil { + if err != nil { //nolint:nilerr // error is returned in the authStatus struct return &authStatus{ Status: "error", Error: err, @@ -92,7 +92,7 @@ func getAuthStatus(cmd *cobra.Command, args []string, showSensitive bool, fn try // Doing a simple API call to check if the auth is valid _, err := a.Workspaces.List(ctx) - if err != nil { + if err != nil { //nolint:nilerr // error is returned in the authStatus struct return &authStatus{ Status: "error", Error: err, @@ -112,7 +112,7 @@ func getAuthStatus(cmd *cobra.Command, args []string, showSensitive bool, fn try w := cmdctx.WorkspaceClient(ctx) me, err := w.CurrentUser.Me(ctx) - if err != nil { + if err != nil { //nolint:nilerr // error is returned in the authStatus struct return &authStatus{ Status: "error", Error: err, diff --git a/libs/apps/initializer/initializer_test.go b/libs/apps/initializer/initializer_test.go index d39076b2d4..9d02a29623 100644 --- a/libs/apps/initializer/initializer_test.go +++ b/libs/apps/initializer/initializer_test.go @@ -55,10 +55,7 @@ func TestGetProjectInitializer(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Create temp directory - tmpDir, err := os.MkdirTemp("", "initializer-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) + tmpDir := t.TempDir() // Create test files for name, content := range tt.files { @@ -140,9 +137,7 @@ func TestDetectPythonCommand(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "python-cmd-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) + tmpDir := t.TempDir() for name, content := range tt.files { err := os.WriteFile(filepath.Join(tmpDir, name), []byte(content), 0o644) diff --git a/libs/apps/initializer/nodejs.go b/libs/apps/initializer/nodejs.go index 958f533558..1227e19303 100644 --- a/libs/apps/initializer/nodejs.go +++ b/libs/apps/initializer/nodejs.go @@ -72,7 +72,7 @@ func (i *InitializerNodeJs) SupportsDevRemote() bool { // runNpmInstall runs npm install in the project directory. func (i *InitializerNodeJs) runNpmInstall(ctx context.Context, workDir string) error { // Check if npm is available - if _, err := exec.LookPath("npm"); err != nil { + if _, err := exec.LookPath("npm"); err != nil { //nolint:nilerr // npm not found is a non-critical warning cmdio.LogString(ctx, "⚠ npm not found. Please install Node.js and run 'npm install' manually.") return nil } @@ -90,7 +90,7 @@ func (i *InitializerNodeJs) runNpmInstall(ctx context.Context, workDir string) e // runAppkitSetup runs npx appkit-setup in the project directory. func (i *InitializerNodeJs) runAppkitSetup(ctx context.Context, workDir string) error { // Check if npx is available - if _, err := exec.LookPath("npx"); err != nil { + if _, err := exec.LookPath("npx"); err != nil { //nolint:nilerr // npx not found is a non-critical warning log.Debugf(ctx, "npx not found, skipping appkit setup") return nil } diff --git a/libs/apps/initializer/nodejs_test.go b/libs/apps/initializer/nodejs_test.go index eb9095453f..f20dd90e00 100644 --- a/libs/apps/initializer/nodejs_test.go +++ b/libs/apps/initializer/nodejs_test.go @@ -44,11 +44,9 @@ func TestHasAppkit(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "nodejs-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) + tmpDir := t.TempDir() - err = os.WriteFile(filepath.Join(tmpDir, "package.json"), []byte(tt.packageJSON), 0o644) + err := os.WriteFile(filepath.Join(tmpDir, "package.json"), []byte(tt.packageJSON), 0o644) require.NoError(t, err) init := &InitializerNodeJs{} @@ -58,9 +56,7 @@ func TestHasAppkit(t *testing.T) { } func TestHasAppkitNoPackageJSON(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "nodejs-test-*") - require.NoError(t, err) - defer os.RemoveAll(tmpDir) + tmpDir := t.TempDir() init := &InitializerNodeJs{} assert.False(t, init.hasAppkit(tmpDir)) diff --git a/libs/apps/initializer/python_pip.go b/libs/apps/initializer/python_pip.go index 17573175f2..b6d9f42e2c 100644 --- a/libs/apps/initializer/python_pip.go +++ b/libs/apps/initializer/python_pip.go @@ -96,7 +96,7 @@ func (i *InitializerPythonPip) createVenv(ctx context.Context, workDir string) e pythonCmd := "python3" if _, err := exec.LookPath(pythonCmd); err != nil { pythonCmd = "python" - if _, err := exec.LookPath(pythonCmd); err != nil { + if _, err := exec.LookPath(pythonCmd); err != nil { //nolint:nilerr // python not found is a non-critical warning cmdio.LogString(ctx, "⚠ Python not found. Please install Python and create a virtual environment manually.") return nil } diff --git a/libs/apps/validation/nodejs.go b/libs/apps/validation/nodejs.go index 0584d52b9a..f9d912ba93 100644 --- a/libs/apps/validation/nodejs.go +++ b/libs/apps/validation/nodejs.go @@ -93,7 +93,7 @@ func (v *ValidationNodeJs) Validate(ctx context.Context, workDir string, opts Va spinner.Close() stepDuration := time.Since(stepStart) - if stepErr != nil { + if stepErr != nil { //nolint:nilerr // validation error is returned in the ValidateResult struct log.Errorf(ctx, "%s failed (duration: %.1fs)", step.name, stepDuration.Seconds()) cmdio.LogString(ctx, fmt.Sprintf("❌ %s failed (%.1fs)", step.displayName, stepDuration.Seconds())) return &ValidateResult{ diff --git a/libs/calladapt/calladapt_test.go b/libs/calladapt/calladapt_test.go index e91923f9be..9153533304 100644 --- a/libs/calladapt/calladapt_test.go +++ b/libs/calladapt/calladapt_test.go @@ -18,7 +18,7 @@ type NewData struct { Y int } -type MyStruct struct { +type MyStruct struct { //nolint:recvcheck // intentionally tests both pointer and value receivers State int } diff --git a/libs/cmdctx/context_test.go b/libs/cmdctx/context_test.go index 6374b10d4d..58e2d1efdb 100644 --- a/libs/cmdctx/context_test.go +++ b/libs/cmdctx/context_test.go @@ -15,7 +15,7 @@ func TestCommandGenerateExecIdPanics(t *testing.T) { // Expect a panic if the execution ID is set twice. assert.Panics(t, func() { - ctx = GenerateExecId(ctx) + ctx = GenerateExecId(ctx) //nolint:fatcontext // test verifies this panics on second call }) } diff --git a/libs/databrickscfg/ops.go b/libs/databrickscfg/ops.go index e5c9c39063..b0dd39cd11 100644 --- a/libs/databrickscfg/ops.go +++ b/libs/databrickscfg/ops.go @@ -191,8 +191,7 @@ func ClearDefaultProfile(ctx context.Context, profileName, configFilePath string } section, err := configFile.GetSection(databricksSettingsSection) - if err != nil { - // No settings section means no default to clear. + if err != nil { //nolint:nilerr // no settings section means no default to clear return nil } diff --git a/libs/dbr/context_test.go b/libs/dbr/context_test.go index b779273838..637ee66193 100644 --- a/libs/dbr/context_test.go +++ b/libs/dbr/context_test.go @@ -14,7 +14,7 @@ func TestContext_DetectRuntimePanics(t *testing.T) { // Expect a panic if the detection is run twice. assert.Panics(t, func() { - ctx = DetectRuntime(ctx) + ctx = DetectRuntime(ctx) //nolint:fatcontext // test verifies this panics on second call }) } diff --git a/libs/dyn/dynvar/resolve.go b/libs/dyn/dynvar/resolve.go index 1cfcc028b7..6f9269f497 100644 --- a/libs/dyn/dynvar/resolve.go +++ b/libs/dyn/dynvar/resolve.go @@ -42,7 +42,7 @@ type lookupResult struct { err error } -type resolver struct { +type resolver struct { //nolint:recvcheck // value receiver for run(), pointer for mutation methods in dyn.Value fn Lookup diff --git a/libs/dyn/jsonloader/locations.go b/libs/dyn/jsonloader/locations.go index a692c7d037..120292d32e 100644 --- a/libs/dyn/jsonloader/locations.go +++ b/libs/dyn/jsonloader/locations.go @@ -11,7 +11,7 @@ type LineOffset struct { Start int64 } -type Offset struct { +type Offset struct { //nolint:recvcheck // value receiver for read-only GetPosition, pointer for SetSource offsets []LineOffset source string } diff --git a/libs/dyn/mapping.go b/libs/dyn/mapping.go index 119d609717..e7e1bbbc67 100644 --- a/libs/dyn/mapping.go +++ b/libs/dyn/mapping.go @@ -15,7 +15,7 @@ type Pair struct { // It exists because plain Go maps cannot use dynamic values for keys. // We need to use dynamic values for keys because it lets us associate metadata // with keys (i.e. their definition location). Keys must be strings. -type Mapping struct { +type Mapping struct { //nolint:recvcheck // value receivers for read-only accessors, pointer for mutators pairs []Pair index map[string]int } diff --git a/libs/execv/shell_test.go b/libs/execv/shell_test.go index 648b607828..693516dec7 100644 --- a/libs/execv/shell_test.go +++ b/libs/execv/shell_test.go @@ -27,7 +27,7 @@ func TestShell_Windows(t *testing.T) { // Configure PATH so that only cmd.exe shows up. binDir := t.TempDir() testutil.CopyFile(t, cmdExePath, filepath.Join(binDir, "cmd.exe")) - os.Setenv("PATH", binDir) + t.Setenv("PATH", binDir) tests := []struct { name string diff --git a/libs/filer/workspace_files_client.go b/libs/filer/workspace_files_client.go index d74fc2e94f..c6c62816bb 100644 --- a/libs/filer/workspace_files_client.go +++ b/libs/filer/workspace_files_client.go @@ -48,7 +48,7 @@ func wsfsDirEntriesFromObjectInfos(objects []workspace.ObjectInfo) []fs.DirEntry } // Type that implements fs.FileInfo for WSFS. -type wsfsFileInfo struct { +type wsfsFileInfo struct { //nolint:recvcheck // value receivers for fs.FileInfo interface, pointer for JSON marshaling workspace.ObjectInfo // The export format of a notebook. This is not exposed by the SDK. diff --git a/libs/fileset/file.go b/libs/fileset/file.go index fd846b2571..0a27b294cf 100644 --- a/libs/fileset/file.go +++ b/libs/fileset/file.go @@ -16,7 +16,7 @@ const ( Source // Any other file type ) -type File struct { +type File struct { //nolint:recvcheck // value receiver for read-only Modified(), pointer for IsNotebook() cache // Root path of the fileset. root vfs.Path diff --git a/libs/sync/diff.go b/libs/sync/diff.go index 3612cebc76..8ea28156dd 100644 --- a/libs/sync/diff.go +++ b/libs/sync/diff.go @@ -7,7 +7,7 @@ import ( ) // List of operations to apply to synchronize local file systems changes to WSFS. -type diff struct { +type diff struct { //nolint:recvcheck // value receivers for read-only methods, pointer for mutation delete []string rmdir []string mkdir []string diff --git a/libs/sync/snapshot_state.go b/libs/sync/snapshot_state.go index ee04881982..38ee288074 100644 --- a/libs/sync/snapshot_state.go +++ b/libs/sync/snapshot_state.go @@ -12,7 +12,7 @@ import ( // SnapshotState keeps track of files on the local filesystem and their corresponding // entries in WSFS. -type SnapshotState struct { +type SnapshotState struct { //nolint:recvcheck // value receiver for ToSlash() copy, pointer for mutation // Map of local file names to their last recorded modified time. Files found // to have a newer mtime have their content synced to their remote version. LastModifiedTimes map[string]time.Time `json:"last_modified_times"` diff --git a/libs/tableview/tableview.go b/libs/tableview/tableview.go index 18eca554ce..54266b72f2 100644 --- a/libs/tableview/tableview.go +++ b/libs/tableview/tableview.go @@ -142,7 +142,7 @@ func (m model) renderContent() string { return strings.Join(result, "\n") } -type model struct { +type model struct { //nolint:recvcheck // value receivers for tea.Model interface, pointer for cursor mutation viewport viewport.Model lines []string ready bool diff --git a/libs/template/config.go b/libs/template/config.go index 1bb1961cb0..fe68d94fe9 100644 --- a/libs/template/config.go +++ b/libs/template/config.go @@ -175,7 +175,7 @@ func (c *config) skipPrompt(p jsonschema.Property, r *renderer) (bool, error) { // Validate the partial config against skip_prompt_if schema validationErr := p.Schema.SkipPromptIf.ValidateInstance(c.values) - if validationErr != nil { + if validationErr != nil { //nolint:nilerr // validation failure means skip condition not met return false, nil } From 98f7d5632c36ae18e70fcdba17ceeb60a1cb3653 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Thu, 16 Apr 2026 14:33:12 +0000 Subject: [PATCH 4/4] Move nolint:nilerr comments to reported lines The nolint directive must be on the line where the issue is reported (the return statement), not on the if statement. Task: 002.md Co-authored-by: Isaac --- bundle/artifacts/prepare.go | 4 ++-- bundle/config/resources/secret_scope.go | 4 ++-- bundle/configsync/patch.go | 4 ++-- bundle/run/app.go | 4 ++-- bundle/run/output/job.go | 4 ++-- bundle/statemgmt/check_running_resources.go | 4 ++-- cmd/auth/describe.go | 12 ++++++------ libs/apps/initializer/nodejs.go | 8 ++++---- libs/apps/initializer/python_pip.go | 4 ++-- libs/apps/validation/nodejs.go | 4 ++-- libs/databrickscfg/ops.go | 4 ++-- libs/template/config.go | 4 ++-- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/bundle/artifacts/prepare.go b/bundle/artifacts/prepare.go index e0a7c1a5a5..9f8b2e6eae 100644 --- a/bundle/artifacts/prepare.go +++ b/bundle/artifacts/prepare.go @@ -115,9 +115,9 @@ func InsertPythonArtifact(ctx context.Context, b *bundle.Bundle) error { // checking if there is setup.py in the bundle root setupPy := filepath.Join(b.BundleRootPath, "setup.py") _, err := os.Stat(setupPy) - if err != nil { //nolint:nilerr // setup.py not found means no wheel project to detect + if err != nil { log.Infof(ctx, "No Python wheel project found at bundle root folder") - return nil + return nil //nolint:nilerr // setup.py not found means no wheel project to detect } log.Infof(ctx, "Found Python wheel project at %s", b.BundleRootPath) diff --git a/bundle/config/resources/secret_scope.go b/bundle/config/resources/secret_scope.go index 9a6664d757..702ee914f8 100644 --- a/bundle/config/resources/secret_scope.go +++ b/bundle/config/resources/secret_scope.go @@ -66,8 +66,8 @@ func (s SecretScope) Exists(ctx context.Context, w *databricks.WorkspaceClient, // // The indirect methods are not semantically ideal for simple existence checks, so we use the list API here scopes, err := w.Secrets.ListScopesAll(ctx) - if err != nil { //nolint:nilerr // treat API errors as "scope not found" - return false, nil + if err != nil { + return false, nil //nolint:nilerr // treat API errors as "scope not found" } for _, scope := range scopes { diff --git a/bundle/configsync/patch.go b/bundle/configsync/patch.go index 087c3e45d9..e002d31335 100644 --- a/bundle/configsync/patch.go +++ b/bundle/configsync/patch.go @@ -281,8 +281,8 @@ func strPathToJSONPointer(pathStr string) (string, error) { // when empty mappings are serialized as "{}" during patch operations func clearAddedFlowStyle(content []byte, fieldChanges []FieldChange) ([]byte, error) { var doc yaml.Node - if err := yaml.Unmarshal(content, &doc); err != nil { //nolint:nilerr // return original content if YAML parsing fails - return content, nil + if err := yaml.Unmarshal(content, &doc); err != nil { + return content, nil //nolint:nilerr // return original content if YAML parsing fails } for _, fc := range fieldChanges { for _, candidate := range fc.FieldCandidates { diff --git a/bundle/run/app.go b/bundle/run/app.go index d060ff9899..8623c1f46c 100644 --- a/bundle/run/app.go +++ b/bundle/run/app.go @@ -165,8 +165,8 @@ func (a *appRunner) resolvedConfig() (*resources.AppConfig, error) { // The key is of the form "apps.", so the full path is "resources.apps..config". configPath := dyn.MustPathFromString("resources." + a.Key() + ".config") configV, err := dyn.GetByPath(root, configPath) - if err != nil || !configV.IsValid() { //nolint:nilerr // missing config path means use default config - return a.app.Config, nil + if err != nil || !configV.IsValid() { + return a.app.Config, nil //nolint:nilerr // missing config path means use default config } resourcesPrefix := dyn.MustPathFromString("resources") diff --git a/bundle/run/output/job.go b/bundle/run/output/job.go index 3e9547ff95..28d8077c71 100644 --- a/bundle/run/output/job.go +++ b/bundle/run/output/job.go @@ -43,8 +43,8 @@ func (out *JobOutput) String() (string, error) { continue } taskString, err := v.Output.String() - if err != nil { //nolint:nilerr // skip tasks with unparseable output - return "", nil + if err != nil { + return "", nil //nolint:nilerr // skip tasks with unparseable output } result.WriteString("=======\n") result.WriteString(fmt.Sprintf("Task %s:\n", v.TaskKey)) diff --git a/bundle/statemgmt/check_running_resources.go b/bundle/statemgmt/check_running_resources.go index 603e3b09a5..92029e9d5b 100644 --- a/bundle/statemgmt/check_running_resources.go +++ b/bundle/statemgmt/check_running_resources.go @@ -90,8 +90,8 @@ func checkAnyResourceRunning(ctx context.Context, w *databricks.WorkspaceClient, if resourceType == "pipelines" { errs.Go(func() error { isRunning, err := IsPipelineRunning(errCtx, w, id) - if err != nil { //nolint:nilerr // assume not running if pipeline check fails - return nil + if err != nil { + return nil //nolint:nilerr // assume not running if pipeline check fails } if isRunning { return &ErrResourceIsRunning{resourceType: "pipeline", resourceId: id} diff --git a/cmd/auth/describe.go b/cmd/auth/describe.go index 6b2e3a5641..9199aac9e6 100644 --- a/cmd/auth/describe.go +++ b/cmd/auth/describe.go @@ -79,8 +79,8 @@ type tryAuth func(cmd *cobra.Command, args []string) (*config.Config, bool, erro func getAuthStatus(cmd *cobra.Command, args []string, showSensitive bool, fn tryAuth) (*authStatus, error) { cfg, isAccount, err := fn(cmd, args) ctx := cmd.Context() - if err != nil { //nolint:nilerr // error is returned in the authStatus struct - return &authStatus{ + if err != nil { + return &authStatus{ //nolint:nilerr // error is returned in the authStatus struct Status: "error", Error: err, Details: getAuthDetails(cmd, cfg, showSensitive), @@ -92,8 +92,8 @@ func getAuthStatus(cmd *cobra.Command, args []string, showSensitive bool, fn try // Doing a simple API call to check if the auth is valid _, err := a.Workspaces.List(ctx) - if err != nil { //nolint:nilerr // error is returned in the authStatus struct - return &authStatus{ + if err != nil { + return &authStatus{ //nolint:nilerr // error is returned in the authStatus struct Status: "error", Error: err, Details: getAuthDetails(cmd, cfg, showSensitive), @@ -112,8 +112,8 @@ func getAuthStatus(cmd *cobra.Command, args []string, showSensitive bool, fn try w := cmdctx.WorkspaceClient(ctx) me, err := w.CurrentUser.Me(ctx) - if err != nil { //nolint:nilerr // error is returned in the authStatus struct - return &authStatus{ + if err != nil { + return &authStatus{ //nolint:nilerr // error is returned in the authStatus struct Status: "error", Error: err, Details: getAuthDetails(cmd, cfg, showSensitive), diff --git a/libs/apps/initializer/nodejs.go b/libs/apps/initializer/nodejs.go index 1227e19303..2c0c697747 100644 --- a/libs/apps/initializer/nodejs.go +++ b/libs/apps/initializer/nodejs.go @@ -72,9 +72,9 @@ func (i *InitializerNodeJs) SupportsDevRemote() bool { // runNpmInstall runs npm install in the project directory. func (i *InitializerNodeJs) runNpmInstall(ctx context.Context, workDir string) error { // Check if npm is available - if _, err := exec.LookPath("npm"); err != nil { //nolint:nilerr // npm not found is a non-critical warning + if _, err := exec.LookPath("npm"); err != nil { cmdio.LogString(ctx, "⚠ npm not found. Please install Node.js and run 'npm install' manually.") - return nil + return nil //nolint:nilerr // npm not found is a non-critical warning } return prompt.RunWithSpinnerCtx(ctx, "Installing dependencies...", func() error { @@ -90,9 +90,9 @@ func (i *InitializerNodeJs) runNpmInstall(ctx context.Context, workDir string) e // runAppkitSetup runs npx appkit-setup in the project directory. func (i *InitializerNodeJs) runAppkitSetup(ctx context.Context, workDir string) error { // Check if npx is available - if _, err := exec.LookPath("npx"); err != nil { //nolint:nilerr // npx not found is a non-critical warning + if _, err := exec.LookPath("npx"); err != nil { log.Debugf(ctx, "npx not found, skipping appkit setup") - return nil + return nil //nolint:nilerr // npx not found is a non-critical warning } return prompt.RunWithSpinnerCtx(ctx, "Running setup...", func() error { diff --git a/libs/apps/initializer/python_pip.go b/libs/apps/initializer/python_pip.go index b6d9f42e2c..badb3a0138 100644 --- a/libs/apps/initializer/python_pip.go +++ b/libs/apps/initializer/python_pip.go @@ -96,9 +96,9 @@ func (i *InitializerPythonPip) createVenv(ctx context.Context, workDir string) e pythonCmd := "python3" if _, err := exec.LookPath(pythonCmd); err != nil { pythonCmd = "python" - if _, err := exec.LookPath(pythonCmd); err != nil { //nolint:nilerr // python not found is a non-critical warning + if _, err := exec.LookPath(pythonCmd); err != nil { cmdio.LogString(ctx, "⚠ Python not found. Please install Python and create a virtual environment manually.") - return nil + return nil //nolint:nilerr // python not found is a non-critical warning } } diff --git a/libs/apps/validation/nodejs.go b/libs/apps/validation/nodejs.go index f9d912ba93..3bd25bd561 100644 --- a/libs/apps/validation/nodejs.go +++ b/libs/apps/validation/nodejs.go @@ -93,10 +93,10 @@ func (v *ValidationNodeJs) Validate(ctx context.Context, workDir string, opts Va spinner.Close() stepDuration := time.Since(stepStart) - if stepErr != nil { //nolint:nilerr // validation error is returned in the ValidateResult struct + if stepErr != nil { log.Errorf(ctx, "%s failed (duration: %.1fs)", step.name, stepDuration.Seconds()) cmdio.LogString(ctx, fmt.Sprintf("❌ %s failed (%.1fs)", step.displayName, stepDuration.Seconds())) - return &ValidateResult{ + return &ValidateResult{ //nolint:nilerr // validation error is returned in the ValidateResult struct Success: false, Message: step.errorPrefix, Details: stepErr, diff --git a/libs/databrickscfg/ops.go b/libs/databrickscfg/ops.go index b0dd39cd11..9e632320bf 100644 --- a/libs/databrickscfg/ops.go +++ b/libs/databrickscfg/ops.go @@ -191,8 +191,8 @@ func ClearDefaultProfile(ctx context.Context, profileName, configFilePath string } section, err := configFile.GetSection(databricksSettingsSection) - if err != nil { //nolint:nilerr // no settings section means no default to clear - return nil + if err != nil { + return nil //nolint:nilerr // no settings section means no default to clear } section.DeleteKey(defaultProfileKey) diff --git a/libs/template/config.go b/libs/template/config.go index fe68d94fe9..95fd7c5caa 100644 --- a/libs/template/config.go +++ b/libs/template/config.go @@ -175,8 +175,8 @@ func (c *config) skipPrompt(p jsonschema.Property, r *renderer) (bool, error) { // Validate the partial config against skip_prompt_if schema validationErr := p.Schema.SkipPromptIf.ValidateInstance(c.values) - if validationErr != nil { //nolint:nilerr // validation failure means skip condition not met - return false, nil + if validationErr != nil { + return false, nil //nolint:nilerr // validation failure means skip condition not met } if p.Schema.Default == nil {