preferredimports: support regular expressions for the import path

Having to list all packages isn't very manageable and requires constant
maintenance that is easy to miss. For example, test/e2e/framework/daemonset was
created without adding an entry for it. Promptly one file doesn't use the
intended e2edaemonset alias.

A simpler solution is to support matching the import path against a regular
expression and deriving the intended alias by expanding placeholders (${name},
$1, etc.) with the corresponding submatches from the import path. Example:

   k8s.io/kubernetes/test/e2e/framework/([^/]*) -> e2e$1

This support is backwards compatible because normal import paths don't contain
characters that are special in a regular expression and normal aliases don't
contain placeholders.

A regular expression must match the entire import path, otherwise it is
skipped.
This commit is contained in:
Patrick Ohly 2022-09-07 21:26:40 +02:00
parent 385cc255c7
commit a00a1c99d5

View File

@ -43,7 +43,7 @@ var (
regex = flag.String("include-path", "(test/e2e/|test/e2e_node)", "only files with paths matching this regex is touched")
isTerminal = term.IsTerminal(int(os.Stdout.Fd()))
logPrefix = ""
aliases map[string]string
aliases = map[*regexp.Regexp]string{}
)
type analyzer struct {
@ -95,7 +95,17 @@ func (a *analyzer) collect(dir string) {
if imp.Name != nil {
importName = imp.Name.Name
}
if alias, ok := aliases[importPath]; ok {
for re, template := range aliases {
match := re.FindStringSubmatchIndex(importPath)
if match == nil {
// No match.
continue
}
if match[0] > 0 || match[1] < len(importPath) {
// Not a full match.
continue
}
alias := string(re.ExpandString(nil, template, importPath, match))
if alias != importName {
if !*confirm {
fmt.Fprintf(os.Stderr, "%sERROR wrong alias for import \"%s\" should be %s in file %s\n", logPrefix, importPath, alias, pathToFile)
@ -108,6 +118,7 @@ func (a *analyzer) collect(dir string) {
imp.Name = ast.NewIdent(alias)
}
}
break
}
}
@ -238,10 +249,18 @@ func main() {
if err != nil {
log.Fatalf("Error reading import aliases: %v", err)
}
err = json.Unmarshal(bytes, &aliases)
var stringAliases map[string]string
err = json.Unmarshal(bytes, &stringAliases)
if err != nil {
log.Fatalf("Error loading aliases: %v", err)
}
for pattern, name := range stringAliases {
re, err := regexp.Compile(pattern)
if err != nil {
log.Fatalf("Error parsing import path pattern %q as regular expression: %v", pattern, err)
}
aliases[re] = name
}
}
if isTerminal {
logPrefix = "\r" // clear status bar when printing