Repository: mgechev/revive
Pull request #1312: var-naming: detect meaningless package names
Author: login: alexandear
Created: 2025-04-10T16:43:42Z | Merged: 2025-04-16T09:30:28Z

This PR extends `var-naming` rule to detect meaningless package names: `common`, `interfaces`, `misc`, `types`, `util`, `utils`.

This rule comes from https://go.dev/wiki/CodeReviewComments#package-names:

> Avoid meaningless package names like util, common, misc, api, types, and interfaces. See https://go.dev/doc/effective_go#package-names and https://go.dev/blog/package-names for more.




Diff:
diff --git a/RULES_DESCRIPTIONS.md b/RULES_DESCRIPTIONS.md
index 6868890f2..d3145f336 100644
--- a/RULES_DESCRIPTIONS.md
+++ b/RULES_DESCRIPTIONS.md
@@ -1118,12 +1118,14 @@ _Configuration_: N/A
 
 _Description_: This rule warns when [initialism](https://go.dev/wiki/CodeReviewComments#initialisms), [variable](https://go.dev/wiki/CodeReviewComments#variable-names) or [package](https://go.dev/wiki/CodeReviewComments#package-names) naming conventions are not followed. It ignores functions starting with `Example`, `Test`, `Benchmark`, and `Fuzz` in test files, preserving `golint` original behavior.
 
-_Configuration_: This rule accepts two slices of strings and one optional slice with single map with named parameters.
-(it's due to TOML hasn't "slice of any" and we keep backward compatibility with previous config version)
-First slice is an allowlist and second one is a blocklist of initialisms.
-In map, you can add boolean `upperCaseConst` (`uppercaseconst`, `upper-case-const`) parameter to allow `UPPER_CASE` for `const`
-You can also add boolean `skipPackageNameChecks` (`skippackagenamechecks`, `skip-package-name-checks`) to skip package name checks.
-By default, the rule behaves exactly as the alternative in `golint` but optionally, you can relax it (see [golint/lint/issues/89](https://github.com/golang/lint/issues/89))
+_Configuration_: This rule accepts two slices of strings and one optional slice containing a single map with named parameters.
+(This is because TOML does not support "slice of any," and we maintain backward compatibility with the previous configuration version).
+The first slice is an allowlist, and the second one is a blocklist of initialisms.
+In the map, you can add a boolean `upperCaseConst` (`uppercaseconst`, `upper-case-const`) parameter to allow `UPPER_CASE` for `const`.
+You can also add a boolean `skipPackageNameChecks` (`skippackagenamechecks`, `skip-package-name-checks`) to skip package name checks.
+When `skipPackageNameChecks` is false (the default), you can configure `extraBadPackageNames` (`extrabadpackagenames`, `extra-bad-package-names`) to forbid using the values from the list as package names additionally to the standard meaningless ones: "common", "interfaces", "misc", "types", "util", "utils".
+
+By default, the rule behaves exactly as the alternative in `golint` but optionally, you can relax it (see [golint/lint/issues/89](https://github.com/golang/lint/issues/89)).
 
 Examples:
 
@@ -1137,6 +1139,11 @@ Examples:
   arguments = [[], [], [{skipPackageNameChecks=true}]]
 ```
 
+```toml
+[rule.var-naming]
+  arguments = [[], [], [{extraBadPackageNames=["helpers", "models"]}]]
+```
+
 ```toml
 [rule.var-naming]
   arguments = [["ID"], ["VM"], [{upper-case-const=true}]]
@@ -1147,6 +1154,11 @@ Examples:
   arguments = [[], [], [{skip-package-name-checks=true}]]
 ```
 
+```toml
+[rule.var-naming]
+  arguments = [[], [], [{extra-bad-package-names=["helpers", "models"]}]]
+```
+
 ## waitgroup-by-value
 
 _Description_: Function parameters that are passed by value, are in fact a copy of the original argument. Passing a copy of a `sync.WaitGroup` is usually not what the developer wants to do.
diff --git a/rule/var_naming.go b/rule/var_naming.go
index 2248d350b..503ef5bbc 100644
--- a/rule/var_naming.go
+++ b/rule/var_naming.go
@@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// defaultBadPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var defaultBadPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
+
 // VarNamingRule lints the name of a variable.
 type VarNamingRule struct {
 	allowList             []string
 	blockList             []string
-	allowUpperCaseConst   bool // if true - allows to use UPPER_SOME_NAMES for constants
-	skipPackageNameChecks bool
+	allowUpperCaseConst   bool                // if true - allows to use UPPER_SOME_NAMES for constants
+	skipPackageNameChecks bool                // check for meaningless and user-defined bad package names
+	extraBadPackageNames  map[string]struct{} // inactive if skipPackageNameChecks is false
 }
 
 // Configure validates the rule configuration, and configures the rule accordingly.
@@ -70,27 +84,62 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 				r.allowUpperCaseConst = fmt.Sprint(v) == "true"
 			case isRuleOption(k, "skipPackageNameChecks"):
 				r.skipPackageNameChecks = fmt.Sprint(v) == "true"
+			case isRuleOption(k, "extraBadPackageNames"):
+				extraBadPackageNames, ok := v.([]string)
+				if !ok {
+					return fmt.Errorf("invalid third argument to the var-naming rule. Expecting extraBadPackageNames of type slice of strings, but %T", v)
+				}
+				for _, name := range extraBadPackageNames {
+					if r.extraBadPackageNames == nil {
+						r.extraBadPackageNames = map[string]struct{}{}
+					}
+					r.extraBadPackageNames[strings.ToLower(name)] = struct{}{}
+				}
 			}
 		}
 	}
 	return nil
 }
 
-func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+func (r *VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	node := walker.fileAst.Name
+	packageName := node.Name
+	lowerPackageName := strings.ToLower(packageName)
+
+	if _, ok := r.extraBadPackageNames[lowerPackageName]; ok {
+		walker.onFailure(lint.Failure{
+			Failure:    "avoid bad package names",
+			Confidence: 1,
+			Node:       node,
+			Category:   lint.FailureCategoryNaming,
+		})
+		return
+	}
+
+	if _, ok := defaultBadPackageNames[lowerPackageName]; ok {
+		walker.onFailure(lint.Failure{
+			Failure:    "avoid meaningless package names",
+			Confidence: 1,
+			Node:       node,
+			Category:   lint.FailureCategoryNaming,
+		})
+		return
+	}
+
 	// Package names need slightly different handling than other names.
-	if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") {
+	if strings.Contains(packageName, "_") && !strings.HasSuffix(packageName, "_test") {
 		walker.onFailure(lint.Failure{
 			Failure:    "don't use an underscore in package name",
 			Confidence: 1,
-			Node:       walker.fileAst.Name,
+			Node:       node,
 			Category:   lint.FailureCategoryNaming,
 		})
 	}
-	if anyCapsRE.MatchString(walker.fileAst.Name.Name) {
+	if anyCapsRE.MatchString(packageName) {
 		walker.onFailure(lint.Failure{
-			Failure:    fmt.Sprintf("don't use MixedCaps in package name; %s should be %s", walker.fileAst.Name.Name, strings.ToLower(walker.fileAst.Name.Name)),
+			Failure:    fmt.Sprintf("don't use MixedCaps in package name; %s should be %s", packageName, lowerPackageName),
 			Confidence: 1,
-			Node:       walker.fileAst.Name,
+			Node:       node,
 			Category:   lint.FailureCategoryNaming,
 		})
 	}
diff --git a/rule/var_naming_test.go b/rule/var_naming_test.go
index 122c45325..7d901f214 100644
--- a/rule/var_naming_test.go
+++ b/rule/var_naming_test.go
@@ -2,6 +2,7 @@ package rule
 
 import (
 	"errors"
+	"reflect"
 	"testing"
 
 	"github.com/mgechev/revive/lint"
@@ -16,6 +17,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 		wantBlockList             []string
 		wantAllowUpperCaseConst   bool
 		wantSkipPackageNameChecks bool
+		wantBadPackageNames       map[string]struct{}
 	}{
 		{
 			name:                      "no arguments",
@@ -34,6 +36,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 				[]any{map[string]any{
 					"upperCaseConst":        true,
 					"skipPackageNameChecks": true,
+					"extraBadPackageNames":  []string{"helpers", "models"},
 				}},
 			},
 			wantErr:                   nil,
@@ -41,6 +44,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 			wantBlockList:             []string{"VM"},
 			wantAllowUpperCaseConst:   true,
 			wantSkipPackageNameChecks: true,
+			wantBadPackageNames:       map[string]struct{}{"helpers": {}, "models": {}},
 		},
 		{
 			name: "valid lowercased arguments",
@@ -50,6 +54,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 				[]any{map[string]any{
 					"uppercaseconst":        true,
 					"skippackagenamechecks": true,
+					"extrabadpackagenames":  []string{"helpers", "models"},
 				}},
 			},
 			wantErr:                   nil,
@@ -57,6 +62,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 			wantBlockList:             []string{"VM"},
 			wantAllowUpperCaseConst:   true,
 			wantSkipPackageNameChecks: true,
+			wantBadPackageNames:       map[string]struct{}{"helpers": {}, "models": {}},
 		},
 		{
 			name: "valid kebab-cased arguments",
@@ -66,6 +72,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 				[]any{map[string]any{
 					"upper-case-const":         true,
 					"skip-package-name-checks": true,
+					"extra-bad-package-names":  []string{"helpers", "models"},
 				}},
 			},
 			wantErr:                   nil,
@@ -73,6 +80,7 @@ func TestVarNamingRule_Configure(t *testing.T) {
 			wantBlockList:             []string{"VM"},
 			wantAllowUpperCaseConst:   true,
 			wantSkipPackageNameChecks: true,
+			wantBadPackageNames:       map[string]struct{}{"helpers": {}, "models": {}},
 		},
 		{
 			name:      "invalid allowlist type",
@@ -104,6 +112,11 @@ func TestVarNamingRule_Configure(t *testing.T) {
 			arguments: lint.Arguments{[]any{"ID"}, []any{"VM"}, []any{123}},
 			wantErr:   errors.New("invalid third argument to the var-naming rule. Expecting a options of type slice, of len==1, with map, but int"),
 		},
+		{
+			name:      "invalid third argument extraBadPackageNames",
+			arguments: lint.Arguments{[]any{""}, []any{""}, []any{map[string]any{"extraBadPackageNames": []int{1}}}},
+			wantErr:   errors.New("invalid third argument to the var-naming rule. Expecting extraBadPackageNames of type slice of strings, but []int"),
+		},
 	}
 
 	for _, tt := range tests {
@@ -131,6 +144,9 @@ func TestVarNamingRule_Configure(t *testing.T) {
 			if rule.skipPackageNameChecks != tt.wantSkipPackageNameChecks {
 				t.Errorf("unexpected skipPackageNameChecks: got = %v, want %v", rule.skipPackageNameChecks, tt.wantSkipPackageNameChecks)
 			}
+			if !reflect.DeepEqual(rule.extraBadPackageNames, tt.wantBadPackageNames) {
+				t.Errorf("unexpected extraBadPackageNames: got = %v, want %v", rule.extraBadPackageNames, tt.wantBadPackageNames)
+			}
 		})
 	}
 }
diff --git a/test/var_naming_test.go b/test/var_naming_test.go
index fd5d0a240..639773f40 100644
--- a/test/var_naming_test.go
+++ b/test/var_naming_test.go
@@ -29,4 +29,15 @@ func TestVarNaming(t *testing.T) {
 	testRule(t, "var_naming_skip_package_name_checks_true", &rule.VarNamingRule{}, &lint.RuleConfig{
 		Arguments: []any{[]any{}, []any{}, []any{map[string]any{"skip-package-name-checks": true}}},
 	})
+	testRule(t, "var_naming_meaningless_package_name", &rule.VarNamingRule{}, &lint.RuleConfig{})
+	testRule(t, "var_naming_meaningless_package_name", &rule.VarNamingRule{}, &lint.RuleConfig{
+		Arguments: []any{[]any{}, []any{},
+			[]any{map[string]any{"skip-package-name-checks": false}},
+		},
+	})
+	testRule(t, "var_naming_bad_package_name", &rule.VarNamingRule{}, &lint.RuleConfig{
+		Arguments: []any{[]any{}, []any{},
+			[]any{map[string]any{"skip-package-name-checks": false, "extra-bad-package-names": []string{"helpers"}}},
+		},
+	})
 }
diff --git a/testdata/var_naming_bad_package_name.go b/testdata/var_naming_bad_package_name.go
new file mode 100644
index 000000000..9d6665323
--- /dev/null
+++ b/testdata/var_naming_bad_package_name.go
@@ -0,0 +1 @@
+package helpers // MATCH /avoid bad package names/
diff --git a/testdata/var_naming_meaningless_package_name.go b/testdata/var_naming_meaningless_package_name.go
new file mode 100644
index 000000000..d22f6e404
--- /dev/null
+++ b/testdata/var_naming_meaningless_package_name.go
@@ -0,0 +1 @@
+package util // MATCH /avoid meaningless package names/


Reviews:
user: login: ccoVeille
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T17:05:06Z
user: login: copilot-pull-request-reviewer[bot]
body: 

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.


<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**test/var_naming_test.go:32**
* [nitpick] Consider renaming the test case identifier from "var_naming_package_util" to a more descriptive name that reflects it's specifically testing detection of meaningless package names.
```
testRule(t, "var_naming_package_util", &rule.VarNamingRule{}, &lint.RuleConfig{})
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T17:41:29Z
user: login: chavacava
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-10T18:47:55Z
user: login: alexandear
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-10T19:00:21Z
user: login: chavacava
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-11T12:11:19Z
user: login: ccoVeille
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T16:04:08Z
user: login: ccoVeille
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T18:55:47Z
user: login: alexandear
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-14T09:34:29Z
user: login: ccoVeille
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T11:54:22Z
user: login: alexandear
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-15T10:06:58Z
user: login: chavacava
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-15T14:43:13Z
user: login: chavacava
body: LGTM

Something that can be implemented later: generate one failure per packet (vs one for each file in a packet)
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-16T05:50:00Z
user: login: alexandear
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-16T08:32:59Z
user: login: ccoVeille
body: Except a small remark on a wording, I'm fine with the PR.

So I approve it.


state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:13:11Z
user: login: alexandear
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-16T09:16:27Z
user: login: alexandear
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-16T09:19:22Z

Review comments:
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
+		walker.onFailure(lint.Failure{
+			Failure:    "avoid meaningless package names",
+			Confidence: 1,
+			Node:       walker.fileAst.Name,
+			Category:   lint.FailureCategoryNaming,
+		})
+		return
+	}
+
 	// Package names need slightly different handling than other names.
-	if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") {
+	if strings.Contains(packageName, "_") && !strings.HasSuffix(packageName, "_test") {
 		walker.onFailure(lint.Failure{
 			Failure:    "don't use an underscore in package name",
 			Confidence: 1,
 			Node:       walker.fileAst.Name,
 			Category:   lint.FailureCategoryNaming,
 		})
 	}
-	if anyCapsRE.MatchString(walker.fileAst.Name.Name) {
+	if anyCapsRE.MatchString(packageName) {
path: rule/var_naming.go
user: login: ccoVeille
body: Not related to this PR, but a note for later

We can do better and faster than using a regexp for this.

Like iterating on runes of the package names
created_at: 2025-04-10T16:49:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,6 +22,15 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+var meaninglessPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: ccoVeille
body: Add a comment:
- about how it is used
- a link to the Go documentation
- the names have to be in lowercase
created_at: 2025-04-10T16:51:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
path: rule/var_naming.go
user: login: ccoVeille
body: You are reusing the lower cased package name multiple times.

Using a variable for the lower case would be better I think
created_at: 2025-04-10T16:53:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
+		walker.onFailure(lint.Failure{
+			Failure:    "avoid meaningless package names",
+			Confidence: 1,
+			Node:       walker.fileAst.Name,
+			Category:   lint.FailureCategoryNaming,
+		})
+		return
+	}
+
 	// Package names need slightly different handling than other names.
-	if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") {
+	if strings.Contains(packageName, "_") && !strings.HasSuffix(packageName, "_test") {
path: rule/var_naming.go
user: login: ccoVeille
body: This if statement was already there

But it should be improved, in another PR I think

A package name like this one would be accepted by the code

foo_bar_test

I think about using

- strings.CutSufix(packageName, "_test")
- then check if it was present
- then strings.Contains(packageNameWithoutSuffix, "_")
 


created_at: 2025-04-10T16:56:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
path: rule/var_naming.go
user: login: ccoVeille
body: The current code matches the Go documentation.

Maybe we should consider suffix and prefix too.

I'm always doubtful with package named

- jsonutils: some [examples](https://github.com/search?q=language%3Ago+%22package+jsonutils%22+-is%3Afork&type=code)
- commonutils : some [examples](https://github.com/search?q=language%3Ago+%22package+commonu%22++-is%3Afork&type=code)


 
It could be merged with it and discussed later.
created_at: 2025-04-10T16:58:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,6 +22,15 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+var meaninglessPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: chavacava
body: These are _some_ examples of meaningless package names. There are others (like _model_, _base_, _helpers_, ...); should these others also be in the list?
created_at: 2025-04-10T18:47:55Z
author_association: COLLABORATOR
diff_hunk: @@ -22,6 +22,15 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+var meaninglessPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: alexandear
body: I included only those package names that are mentioned in the Go blog and Go wiki. We could list all the meaningless packages in the world, but there are hundreds. Maybe it’s better to add a `blocklistedPackageNames` argument to the rule's config. What do you think?
created_at: 2025-04-10T19:00:21Z
author_association: COLLABORATOR
diff_hunk: @@ -22,6 +22,15 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+var meaninglessPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: chavacava
body: A rule argument with ad-hoc names seems a good idea.
created_at: 2025-04-11T12:11:18Z
author_association: COLLABORATOR
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
+		walker.onFailure(lint.Failure{
+			Failure:    "avoid meaningless package names",
+			Confidence: 1,
+			Node:       walker.fileAst.Name,
+			Category:   lint.FailureCategoryNaming,
+		})
+		return
+	}
+
 	// Package names need slightly different handling than other names.
-	if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") {
+	if strings.Contains(packageName, "_") && !strings.HasSuffix(packageName, "_test") {
 		walker.onFailure(lint.Failure{
 			Failure:    "don't use an underscore in package name",
 			Confidence: 1,
 			Node:       walker.fileAst.Name,
 			Category:   lint.FailureCategoryNaming,
 		})
 	}
-	if anyCapsRE.MatchString(walker.fileAst.Name.Name) {
+	if anyCapsRE.MatchString(packageName) {
path: rule/var_naming.go
user: login: ccoVeille
body: I opened

- https://github.com/mgechev/revive/issues/1313
created_at: 2025-04-11T16:04:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
+		walker.onFailure(lint.Failure{
+			Failure:    "avoid meaningless package names",
+			Confidence: 1,
+			Node:       walker.fileAst.Name,
+			Category:   lint.FailureCategoryNaming,
+		})
+		return
+	}
+
 	// Package names need slightly different handling than other names.
-	if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") {
+	if strings.Contains(packageName, "_") && !strings.HasSuffix(packageName, "_test") {
path: rule/var_naming.go
user: login: ccoVeille
body: I opened #1314 to track this

- https://github.com/mgechev/revive/issues/1314
created_at: 2025-04-11T18:55:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,6 +22,15 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+var meaninglessPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: alexandear
body: Added `badPackageNames` option. Please check.
created_at: 2025-04-14T09:34:28Z
author_association: COLLABORATOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// meaninglessPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var meaninglessPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
+
 // VarNamingRule lints the name of a variable.
 type VarNamingRule struct {
 	allowList             []string
 	blockList             []string
-	allowUpperCaseConst   bool // if true - allows to use UPPER_SOME_NAMES for constants
-	skipPackageNameChecks bool
+	allowUpperCaseConst   bool                // if true - allows to use UPPER_SOME_NAMES for constants
+	skipPackageNameChecks bool                // check for meaningless and user-defined bad package names
+	badPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
path: rule/var_naming.go
user: login: ccoVeille
body: ```suggestion
	blockedPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
```

Or


```suggestion
	disallowedPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
```

created_at: 2025-04-14T10:58:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// meaninglessPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var meaninglessPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
path: rule/var_naming.go
user: login: ccoVeille
body: Maybe renaming it to badPackagesNames to match the logic and the Go documentation

```suggestion
var badPackageNames = map[string]struct{}{
	"common":     {},
	"interfaces": {},
	"misc":       {},
	"types":      {},
	"util":       {},
	"utils":      {},
}
```

created_at: 2025-04-14T10:59:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// meaninglessPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var meaninglessPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
+
 // VarNamingRule lints the name of a variable.
 type VarNamingRule struct {
 	allowList             []string
 	blockList             []string
-	allowUpperCaseConst   bool // if true - allows to use UPPER_SOME_NAMES for constants
-	skipPackageNameChecks bool
+	allowUpperCaseConst   bool                // if true - allows to use UPPER_SOME_NAMES for constants
+	skipPackageNameChecks bool                // check for meaningless and user-defined bad package names
+	badPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
path: rule/var_naming.go
user: login: ccoVeille
body: Also, one point, these are appended to the one that are mentioned in the Go documentation.

Meaning, you cannot remove "common" from the list, by using this list.

I'm fine with this, but I would like you to consider two alternative options
- rename badPackageNames to something like extraWhateverPackageNames
- consider that the boolean is only about deactivating the list provided by golang

I feel like it could be clearer. If someone puts something in the exclusions, they wants it, and the boolean is only there for the hardcoded ones
created_at: 2025-04-14T11:05:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// meaninglessPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var meaninglessPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
+
 // VarNamingRule lints the name of a variable.
 type VarNamingRule struct {
 	allowList             []string
 	blockList             []string
-	allowUpperCaseConst   bool // if true - allows to use UPPER_SOME_NAMES for constants
-	skipPackageNameChecks bool
+	allowUpperCaseConst   bool                // if true - allows to use UPPER_SOME_NAMES for constants
+	skipPackageNameChecks bool                // check for meaningless and user-defined bad package names
+	badPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
path: rule/var_naming.go
user: login: alexandear
body: You're right, but I don't want to add complexity to the rule's implementation. In the future, we can add the proposed functionality if someone really needs it.

For now, we can disable the detection of wrong name in the `package common` in the following ways:

1. Using revive:
```go
package common //revive:disable-line:var-naming // we can't rename the package
```

2. Using golangci-lint with `nolint`:
```go
package common //nolint:revive // we can't rename the package
```

3. Using golangci-lint config with `linters.exclusions`.
created_at: 2025-04-15T10:06:58Z
author_association: COLLABORATOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// meaninglessPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var meaninglessPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
+
 // VarNamingRule lints the name of a variable.
 type VarNamingRule struct {
 	allowList             []string
 	blockList             []string
-	allowUpperCaseConst   bool // if true - allows to use UPPER_SOME_NAMES for constants
-	skipPackageNameChecks bool
+	allowUpperCaseConst   bool                // if true - allows to use UPPER_SOME_NAMES for constants
+	skipPackageNameChecks bool                // check for meaningless and user-defined bad package names
+	badPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
path: rule/var_naming.go
user: login: chavacava
body: side note: even if `revive` is (or seems to be) mainly used via `golangci-lint`, IMO we should think/design/decide on `revive` without coupling it with `golandci-lint` (for example, isn't because we can achieve some behavior through `golangci-lint` conf that `revive` will not provide the means to do the same)
created_at: 2025-04-15T14:43:13Z
author_association: COLLABORATOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// meaninglessPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var meaninglessPackageNames = map[string]struct{}{
+	"common":     {},
+	"interfaces": {},
+	"misc":       {},
+	"types":      {},
+	"util":       {},
+	"utils":      {},
+}
+
 // VarNamingRule lints the name of a variable.
 type VarNamingRule struct {
 	allowList             []string
 	blockList             []string
-	allowUpperCaseConst   bool // if true - allows to use UPPER_SOME_NAMES for constants
-	skipPackageNameChecks bool
+	allowUpperCaseConst   bool                // if true - allows to use UPPER_SOME_NAMES for constants
+	skipPackageNameChecks bool                // check for meaningless and user-defined bad package names
+	badPackageNames       map[string]struct{} // inactive if skipPackageNameChecks is false
path: rule/var_naming.go
user: login: alexandear
body: Renamed to `extraBadPackageNames`. Please check.
created_at: 2025-04-16T08:32:59Z
author_association: COLLABORATOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// extraBadPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var extraBadPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: ccoVeille
body: I wouldn't have renamed this one with the prefix extra, they are the default ones

The main reason is that it creates a confusion when reading `r.extraPackageNames` and `extraPackagesNames`

So here I would suggest this

```suggestion
var badPackageNames = map[string]struct{}{
```


```suggestion
var defaultBadPackageNames = map[string]struct{}{
```

Everything else is fine
created_at: 2025-04-16T09:09:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -77,18 +86,30 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
 }
 
 func (*VarNamingRule) applyPackageCheckRules(walker *lintNames) {
+	packageName := walker.fileAst.Name.Name
+
+	if _, ok := meaninglessPackageNames[strings.ToLower(packageName)]; ok {
path: rule/var_naming.go
user: login: alexandear
body: Will be implemented later if needed.
created_at: 2025-04-16T09:16:27Z
author_association: COLLABORATOR
diff_hunk: @@ -22,12 +22,26 @@ var knownNameExceptions = map[string]bool{
 	"kWh":          true,
 }
 
+// extraBadPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
+// and https://go.dev/blog/package-names#bad-package-names.
+// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
+// Values in the list should be lowercased.
+var extraBadPackageNames = map[string]struct{}{
path: rule/var_naming.go
user: login: alexandear
body: Thanks, renamed.
created_at: 2025-04-16T09:19:21Z
author_association: COLLABORATOR

PR comments:
user: login: ccoVeille
created_at: 2025-04-10T16:47:04Z
body: Hey !

So you read my mind !! 😁

I thought about creating an issue about it last week! You stole my idea 😱🤣

OK, I thought about it when I read the Go documentation,I assume you did the same.
author_association: CONTRIBUTOR
user: login: ccoVeille
created_at: 2025-04-16T09:18:24Z
body: One last thing, the following points were raised during the review, and will have to be addressed somehow.

So opening an issue for them should be considered

- https://github.com/mgechev/revive/pull/1312#discussion_r2037878040

- https://github.com/mgechev/revive/pull/1312#discussion_r2041920100

Please note, I have no problem if this ends with the decision of not doing it.

I just want to make sure they are not forgotten.

So here I will let @chavacava @denisvmedia @alexandear comes back to me in each discussion.

Thanks 
author_association: CONTRIBUTOR
user: login: rfay
created_at: 2025-06-30T13:22:42Z
body: IMO this needs improved docs, both here and golangci-lint. I'm trying to sort out how to ignore some things that certainly won't be changed just because of this rule, because it would be too intrusive. 
author_association: NONE
user: login: alexandear
created_at: 2025-07-01T09:28:52Z
body: > IMO this needs improved docs, both here and golangci-lint. I'm trying to sort out how to ignore some things that certainly won't be changed just because of this rule, because it would be too intrusive.

I'm not sure what exactly should be improved in the docs. Feel free to create a PR - happy to review!
author_association: COLLABORATOR