2023-08-28 15:26:00 +02:00
package rule
import (
"fmt"
"regexp"
"sync"
"github.com/mgechev/revive/lint"
)
// ImportAliasNamingRule lints import alias naming.
type ImportAliasNamingRule struct {
2023-10-29 14:19:53 +02:00
configured bool
allowRegexp * regexp . Regexp
denyRegexp * regexp . Regexp
2023-08-28 15:26:00 +02:00
sync . Mutex
}
2023-10-29 14:19:53 +02:00
const defaultImportAliasNamingAllowRule = "^[a-z][a-z0-9]{0,}$"
2023-08-28 15:26:00 +02:00
2023-10-29 14:19:53 +02:00
var defaultImportAliasNamingAllowRegexp = regexp . MustCompile ( defaultImportAliasNamingAllowRule )
2023-08-28 15:26:00 +02:00
func ( r * ImportAliasNamingRule ) configure ( arguments lint . Arguments ) {
r . Lock ( )
defer r . Unlock ( )
if r . configured {
return
}
2023-10-29 14:19:53 +02:00
if len ( arguments ) == 0 {
r . allowRegexp = defaultImportAliasNamingAllowRegexp
2023-08-28 15:26:00 +02:00
return
}
2023-10-29 14:19:53 +02:00
switch namingRule := arguments [ 0 ] . ( type ) {
case string :
r . setAllowRule ( namingRule )
case map [ string ] any : // expecting map[string]string
for k , v := range namingRule {
switch k {
case "allowRegex" :
r . setAllowRule ( v )
case "denyRegex" :
r . setDenyRule ( v )
default :
panic ( fmt . Sprintf ( "Invalid map key for 'import-alias-naming' rule. Expecting 'allowRegex' or 'denyRegex', got %v" , k ) )
}
}
default :
panic ( fmt . Sprintf ( "Invalid argument '%v' for 'import-alias-naming' rule. Expecting string or map[string]string, got %T" , arguments [ 0 ] , arguments [ 0 ] ) )
2023-08-28 15:26:00 +02:00
}
2023-10-29 14:19:53 +02:00
if r . allowRegexp == nil && r . denyRegexp == nil {
r . allowRegexp = defaultImportAliasNamingAllowRegexp
2023-08-28 15:26:00 +02:00
}
}
// 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
2023-11-26 09:57:34 +02:00
if alias == nil || alias . Name == "_" || alias . Name == "." { // "_" and "." are special types of import aiases and should be processed by another linter rule
2023-08-28 15:26:00 +02:00
continue
}
2023-10-29 14:19:53 +02:00
if r . allowRegexp != nil && ! r . allowRegexp . 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 . allowRegexp . String ( ) ) ,
Node : alias ,
Category : "imports" ,
} )
}
if r . denyRegexp != nil && r . denyRegexp . MatchString ( alias . Name ) {
2023-08-28 15:26:00 +02:00
failures = append ( failures , lint . Failure {
Confidence : 1 ,
2023-10-29 14:19:53 +02:00
Failure : fmt . Sprintf ( "import name (%s) must NOT match the regular expression: %s" , alias . Name , r . denyRegexp . String ( ) ) ,
2023-08-28 15:26:00 +02:00
Node : alias ,
Category : "imports" ,
} )
}
}
return failures
}
// Name returns the rule name.
func ( * ImportAliasNamingRule ) Name ( ) string {
return "import-alias-naming"
}
2023-10-29 14:19:53 +02:00
func ( r * ImportAliasNamingRule ) setAllowRule ( value any ) {
namingRule , ok := value . ( string )
if ! ok {
panic ( fmt . Sprintf ( "Invalid argument '%v' for import-alias-naming allowRegexp rule. Expecting string, got %T" , value , value ) )
}
namingRuleRegexp , err := regexp . Compile ( namingRule )
if err != nil {
panic ( fmt . Sprintf ( "Invalid argument to the import-alias-naming allowRegexp rule. Expecting %q to be a valid regular expression, got: %v" , namingRule , err ) )
}
r . allowRegexp = namingRuleRegexp
}
func ( r * ImportAliasNamingRule ) setDenyRule ( value any ) {
namingRule , ok := value . ( string )
if ! ok {
panic ( fmt . Sprintf ( "Invalid argument '%v' for import-alias-naming denyRegexp rule. Expecting string, got %T" , value , value ) )
}
namingRuleRegexp , err := regexp . Compile ( namingRule )
if err != nil {
panic ( fmt . Sprintf ( "Invalid argument to the import-alias-naming denyRegexp rule. Expecting %q to be a valid regular expression, got: %v" , namingRule , err ) )
}
r . denyRegexp = namingRuleRegexp
}