lotus/scripts/fiximports/main.go

93 lines
2.2 KiB
Go
Raw Normal View History

package main
import (
"bytes"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"regexp"
"strings"
"golang.org/x/tools/imports"
)
var (
// groupByPrefixes is the list of import prefixes that should _each_ be grouped separately.
// See: imports.LocalPrefix.
groupByPrefixes = []string{
"github.com/filecoin-project",
"github.com/filecoin-project/lotus",
}
newline = []byte("\n")
importBlockRegex = regexp.MustCompile(`(?s)import\s*\((.*?)\)`)
consecutiveNewlinesRegex = regexp.MustCompile(`\n\s*\n`)
)
func main() {
if err := filepath.Walk(".", func(path string, info fs.FileInfo, err error) error {
switch {
case err != nil:
return err
case // Skip the entire "./extern/..." directory and its contents.
strings.HasPrefix(path, "extern/"):
return filepath.SkipDir
case // Skip directories, generated cborgen go files and any other non-go files.
info.IsDir(),
strings.HasSuffix(info.Name(), "_cbor_gen.go"),
!strings.HasSuffix(info.Name(), ".go"):
return nil
}
return fixGoImports(path)
}); err != nil {
fmt.Printf("Error fixing go imports: %v\n", err)
os.Exit(1)
}
}
func fixGoImports(path string) error {
sourceFile, err := os.OpenFile(path, os.O_RDWR, 0666)
if err != nil {
return err
}
defer func() { _ = sourceFile.Close() }()
source, err := io.ReadAll(sourceFile)
if err != nil {
return err
}
formatted := collapseImportNewlines(source)
for _, prefix := range groupByPrefixes {
imports.LocalPrefix = prefix
formatted, err = imports.Process(path, formatted, nil)
if err != nil {
return err
}
}
if !bytes.Equal(source, formatted) {
if err := replaceFileContent(sourceFile, formatted); err != nil {
return err
}
}
return nil
}
func replaceFileContent(target *os.File, replacement []byte) error {
if _, err := target.Seek(0, io.SeekStart); err != nil {
return err
}
written, err := target.Write(replacement)
if err != nil {
return err
}
return target.Truncate(int64(written))
}
func collapseImportNewlines(content []byte) []byte {
return importBlockRegex.ReplaceAllFunc(content, func(importBlock []byte) []byte {
// Replace consecutive newlines with a single newline within the import block
return consecutiveNewlinesRegex.ReplaceAll(importBlock, newline)
})
}