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

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
)