mirror of
https://github.com/mgechev/revive.git
synced 2025-11-23 22:04:49 +02:00
feat: add support for import-alias-naming rule (#881)
This commit is contained in:
@@ -533,6 +533,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a
|
|||||||
| [`datarace`](./RULES_DESCRIPTIONS.md#datarace) | n/a | Spots potential dataraces | no | no |
|
| [`datarace`](./RULES_DESCRIPTIONS.md#datarace) | n/a | Spots potential dataraces | no | no |
|
||||||
| [`comment-spacings`](./RULES_DESCRIPTIONS.md#comment-spacings) | []string | Warns on malformed comments | no | no |
|
| [`comment-spacings`](./RULES_DESCRIPTIONS.md#comment-spacings) | []string | Warns on malformed comments | no | no |
|
||||||
| [`redundant-import-alias`](./RULES_DESCRIPTIONS.md#redundant-import-alias) | n/a | Warns on import aliases matching the imported package name | no | no |
|
| [`redundant-import-alias`](./RULES_DESCRIPTIONS.md#redundant-import-alias) | n/a | Warns on import aliases matching the imported package name | no | no |
|
||||||
|
| [`import-alias-naming`](./RULES_DESCRIPTIONS.md#import-alias-naming) | string (defaults to ^[a-z][a-z0-9]{0,}$) | Conventions around the naming of import aliases. | no | no |
|
||||||
|
|
||||||
|
|
||||||
## Configurable rules
|
## Configurable rules
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ List of all available rules.
|
|||||||
- [indent-error-flow](#indent-error-flow)
|
- [indent-error-flow](#indent-error-flow)
|
||||||
- [imports-blacklist](#imports-blacklist)
|
- [imports-blacklist](#imports-blacklist)
|
||||||
- [import-shadowing](#import-shadowing)
|
- [import-shadowing](#import-shadowing)
|
||||||
|
- [import-alias-naming](#import-alias-naming)
|
||||||
- [line-length-limit](#line-length-limit)
|
- [line-length-limit](#line-length-limit)
|
||||||
- [max-public-structs](#max-public-structs)
|
- [max-public-structs](#max-public-structs)
|
||||||
- [modifies-parameter](#modifies-parameter)
|
- [modifies-parameter](#modifies-parameter)
|
||||||
@@ -489,6 +490,22 @@ name of an imported package. This rule spots identifiers that shadow an import.
|
|||||||
|
|
||||||
_Configuration_: N/A
|
_Configuration_: N/A
|
||||||
|
|
||||||
|
## import-alias-naming
|
||||||
|
|
||||||
|
_Description_: Aligns with Go's naming conventions, as outlined in the official
|
||||||
|
[blog post](https://go.dev/blog/package-names). It enforces clear and lowercase import alias names, echoing
|
||||||
|
the principles of good package naming. Users can follow these guidelines by default or define a custom regex rule.
|
||||||
|
Importantly, aliases with underscores ("_") are always allowed.
|
||||||
|
|
||||||
|
_Configuration_: (string) regular expression to match the aliases (default: ^[a-z][a-z0-9]{0,}$)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[rule.import-alias-naming]
|
||||||
|
arguments =["^[a-z][a-z0-9]{0,}$"]
|
||||||
|
```
|
||||||
|
|
||||||
## line-length-limit
|
## line-length-limit
|
||||||
|
|
||||||
_Description_: Warns in the presence of code lines longer than a configured maximum.
|
_Description_: Warns in the presence of code lines longer than a configured maximum.
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ var allRules = append([]lint.Rule{
|
|||||||
&rule.CommentSpacingsRule{},
|
&rule.CommentSpacingsRule{},
|
||||||
&rule.IfReturnRule{},
|
&rule.IfReturnRule{},
|
||||||
&rule.RedundantImportAlias{},
|
&rule.RedundantImportAlias{},
|
||||||
|
&rule.ImportAliasNamingRule{},
|
||||||
}, defaultRules...)
|
}, defaultRules...)
|
||||||
|
|
||||||
var allFormatters = []lint.Formatter{
|
var allFormatters = []lint.Formatter{
|
||||||
|
|||||||
79
rule/import-alias-naming.go
Normal file
79
rule/import-alias-naming.go
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package rule
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/mgechev/revive/lint"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ImportAliasNamingRule lints import alias naming.
|
||||||
|
type ImportAliasNamingRule struct {
|
||||||
|
configured bool
|
||||||
|
namingRuleRegexp *regexp.Regexp
|
||||||
|
sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultNamingRule = "^[a-z][a-z0-9]{0,}$"
|
||||||
|
|
||||||
|
var defaultNamingRuleRegexp = regexp.MustCompile(defaultNamingRule)
|
||||||
|
|
||||||
|
func (r *ImportAliasNamingRule) configure(arguments lint.Arguments) {
|
||||||
|
r.Lock()
|
||||||
|
defer r.Unlock()
|
||||||
|
if r.configured {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(arguments) < 1 {
|
||||||
|
r.namingRuleRegexp = defaultNamingRuleRegexp
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
namingRule, ok := arguments[0].(string) // Alt. non panicking version
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("Invalid argument '%v' for 'import-alias-naming' rule. Expecting string, got %T", arguments[0], arguments[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
r.namingRuleRegexp, err = regexp.Compile(namingRule)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Invalid argument to the import-alias-naming rule. Expecting %q to be a valid regular expression, got: %v", namingRule, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply applies the rule to given file.
|
||||||
|
func (r *ImportAliasNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
|
||||||
|
r.configure(arguments)
|
||||||
|
|
||||||
|
var failures []lint.Failure
|
||||||
|
|
||||||
|
for _, is := range file.AST.Imports {
|
||||||
|
path := is.Path
|
||||||
|
if path == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
alias := is.Name
|
||||||
|
if alias == nil || alias.Name == "_" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !r.namingRuleRegexp.MatchString(alias.Name) {
|
||||||
|
failures = append(failures, lint.Failure{
|
||||||
|
Confidence: 1,
|
||||||
|
Failure: fmt.Sprintf("import name (%s) must match the regular expression: %s", alias.Name, r.namingRuleRegexp.String()),
|
||||||
|
Node: alias,
|
||||||
|
Category: "imports",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return failures
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the rule name.
|
||||||
|
func (*ImportAliasNamingRule) Name() string {
|
||||||
|
return "import-alias-naming"
|
||||||
|
}
|
||||||
15
test/import-alias-naming_test.go
Normal file
15
test/import-alias-naming_test.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mgechev/revive/lint"
|
||||||
|
"github.com/mgechev/revive/rule"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestImportAliasNaming(t *testing.T) {
|
||||||
|
testRule(t, "import-alias-naming", &rule.ImportAliasNamingRule{})
|
||||||
|
testRule(t, "import-alias-naming-custom-config", &rule.ImportAliasNamingRule{}, &lint.RuleConfig{
|
||||||
|
Arguments: []any{`^[a-z]+$`},
|
||||||
|
})
|
||||||
|
}
|
||||||
16
testdata/import-alias-naming-custom-config.go
vendored
Normal file
16
testdata/import-alias-naming-custom-config.go
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "strings"
|
||||||
|
bar_foo "strings" // MATCH /import name (bar_foo) must match the regular expression: ^[a-z]+$/
|
||||||
|
fooBAR "strings" // MATCH /import name (fooBAR) must match the regular expression: ^[a-z]+$/
|
||||||
|
v1 "strings" // MATCH /import name (v1) must match the regular expression: ^[a-z]+$/
|
||||||
|
magical "magic/hat"
|
||||||
|
)
|
||||||
|
|
||||||
|
func somefunc() {
|
||||||
|
fooBAR.Clone("")
|
||||||
|
bar_foo.Clone("")
|
||||||
|
v1.Clone("")
|
||||||
|
magical.Clone("")
|
||||||
|
}
|
||||||
16
testdata/import-alias-naming.go
vendored
Normal file
16
testdata/import-alias-naming.go
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "strings"
|
||||||
|
bar_foo "strings" // MATCH /import name (bar_foo) must match the regular expression: ^[a-z][a-z0-9]{0,}$/
|
||||||
|
fooBAR "strings" // MATCH /import name (fooBAR) must match the regular expression: ^[a-z][a-z0-9]{0,}$/
|
||||||
|
v1 "strings"
|
||||||
|
magical "magic/hat"
|
||||||
|
)
|
||||||
|
|
||||||
|
func somefunc() {
|
||||||
|
fooBAR.Clone("")
|
||||||
|
bar_foo.Clone("")
|
||||||
|
v1.Clone("")
|
||||||
|
magical.Clone("")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user