This repository has been archived on 2023-11-08. You can view files and clone it, but cannot push or open issues/pull-requests.
imp/imp.go

131 lines
2.6 KiB
Go

package main
import (
"bytes"
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"go.jolheiser.com/imp/format"
"gitea.com/jolheiser/globber"
gofumptFormat "mvdan.cc/gofumpt/format"
)
func runImp(root, ignore string, write, gofumpt, gofumptExtra bool) error {
mod := modInfo(root)
globs, err := globber.ParseFile(ignore)
if err != nil {
if !errors.Is(err, fs.ErrNotExist) {
return err
}
globs = globber.New()
}
var failed bool
if err := filepath.Walk(root, func(walkPath string, walkInfo os.FileInfo, walkErr error) error {
if walkErr != nil {
return walkErr
}
walkPath = filepath.ToSlash(walkPath)
if s := checkSkip(walkPath, walkInfo, globs); s != CHECK {
if s == SKIPDIR {
return filepath.SkipDir
}
return nil
}
data, err := os.ReadFile(walkPath)
if err != nil {
return fmt.Errorf("could not read file %q: %w", walkPath, err)
}
formatted, err := impFormat(data, mod, gofumpt, gofumptExtra)
if err != nil && !errors.Is(err, format.ErrNoImports) {
return fmt.Errorf("could not format file %q: %w", walkPath, err)
}
if write {
if err := os.WriteFile(walkPath, formatted, walkInfo.Mode()); err != nil {
return fmt.Errorf("could not write file %q: %w", walkPath, err)
}
return nil
}
if !bytes.Equal(data, formatted) {
failed = true
}
return nil
}); err != nil {
return err
}
if failed {
return errors.New("imports are formatted incorrectly; this can be fixed with the `--write` flag")
}
return nil
}
func impFormat(src []byte, mod module, gofumpt, gofumptExtra bool) ([]byte, error) {
formatted, err := format.Source(src, mod.Path)
if err != nil {
return src, err
}
if gofumpt {
formatted, err = gofumptFormat.Source(formatted, gofumptFormat.Options{
LangVersion: mod.GoVersion,
ModulePath: mod.Path,
ExtraRules: gofumptExtra,
})
if err != nil {
return src, err
}
}
return formatted, nil
}
func checkSkip(walkPath string, walkInfo os.FileInfo, globs *globber.GlobSet) walkStatus {
// Skip current directory
if strings.EqualFold(walkPath, ".") {
return SKIP
}
// Skip hidden paths (starting with ".")
if strings.HasPrefix(walkPath, ".") {
if walkInfo.IsDir() {
return SKIPDIR
}
return SKIP
}
// Skip directories
if walkInfo.IsDir() {
return SKIP
}
// Skip non-Go files
if !strings.HasSuffix(walkInfo.Name(), ".go") {
return SKIP
}
// Skip included (ignored) globs
i, e := globs.Explain(walkPath)
if len(i) > 0 && len(e) == 0 {
return SKIP
}
return CHECK
}
type walkStatus int
const (
SKIP walkStatus = iota
SKIPDIR
CHECK
)