Fix go imports at least 2x faster (#11695)
Use native go implementation to sort and adjust imports. Compared to the previous bash version, this is at least 2X faster.
This commit is contained in:
parent
b909db394e
commit
b56af9b8b0
6
Makefile
6
Makefile
@ -332,7 +332,7 @@ actors-code-gen:
|
|||||||
$(GOCC) fmt ./...
|
$(GOCC) fmt ./...
|
||||||
|
|
||||||
actors-gen: actors-code-gen
|
actors-gen: actors-code-gen
|
||||||
./scripts/fiximports
|
$(GOCC) run ./scripts/fiximports
|
||||||
.PHONY: actors-gen
|
.PHONY: actors-gen
|
||||||
|
|
||||||
bundle-gen:
|
bundle-gen:
|
||||||
@ -392,10 +392,10 @@ docsgen-openrpc-gateway: docsgen-openrpc-bin
|
|||||||
.PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin
|
.PHONY: docsgen docsgen-md-bin docsgen-openrpc-bin
|
||||||
|
|
||||||
fiximports:
|
fiximports:
|
||||||
./scripts/fiximports
|
$(GOCC) run ./scripts/fiximports
|
||||||
|
|
||||||
gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen circleci
|
gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen circleci
|
||||||
./scripts/fiximports
|
$(GOCC) run ./scripts/fiximports
|
||||||
@echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO RUN 'make docsgen-cli'"
|
@echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO RUN 'make docsgen-cli'"
|
||||||
.PHONY: gen
|
.PHONY: gen
|
||||||
|
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
sed_replace='/import (/ {
|
|
||||||
:1
|
|
||||||
$!N
|
|
||||||
s/\n\n/\'$'\n''/
|
|
||||||
/)/!b1
|
|
||||||
}'
|
|
||||||
|
|
||||||
go_files() {
|
|
||||||
find . -type f -name \*.go -not -name \*_cbor_gen.go | grep -v './extern/filecoin-ffi' | grep -v './extern/test-vectors'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Because -i works differently on macOS, we need to use a different sed command
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
go_files | xargs -I '{}' sed -i '' -e "$sed_replace" '{}'
|
|
||||||
else
|
|
||||||
go_files | xargs -I '{}' sed -i -e "$sed_replace" '{}'
|
|
||||||
fi
|
|
||||||
|
|
||||||
go_files | xargs -I '{}' goimports -w -local "github.com/filecoin-project" '{}'
|
|
||||||
go_files | xargs -I '{}' goimports -w -local "github.com/filecoin-project/lotus" '{}'
|
|
92
scripts/fiximports/main.go
Normal file
92
scripts/fiximports/main.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user