116 lines
2.1 KiB
Go
116 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"gitea.com/jolheiser/imp/format"
|
|
|
|
"gitea.com/jolheiser/globber"
|
|
"github.com/gobuffalo/here"
|
|
)
|
|
|
|
func runImp(root, ignore string, write bool) error {
|
|
info, err := here.Current()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
module := info.Module.Path
|
|
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 := format.Source(data, module)
|
|
if err != nil {
|
|
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 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
|
|
)
|