diff --git a/internal/walk/filesystem.go b/internal/walk/filesystem.go index 830e9c0..bf84158 100644 --- a/internal/walk/filesystem.go +++ b/internal/walk/filesystem.go @@ -5,18 +5,18 @@ import ( "path/filepath" ) -type filesystem struct { +type filesystemWalker struct { root string } -func (f filesystem) Root() string { +func (f filesystemWalker) Root() string { return f.root } -func (f filesystem) Walk(_ context.Context, fn filepath.WalkFunc) error { +func (f filesystemWalker) Walk(_ context.Context, fn filepath.WalkFunc) error { return filepath.Walk(f.root, fn) } func NewFilesystem(root string) (Walker, error) { - return filesystem{root}, nil + return filesystemWalker{root}, nil } diff --git a/internal/walk/git.go b/internal/walk/git.go index 4f03afa..5d037d1 100644 --- a/internal/walk/git.go +++ b/internal/walk/git.go @@ -1,69 +1,53 @@ package walk import ( - "bufio" "context" "fmt" - "io" + "github.com/go-git/go-git/v5" "os" - "os/exec" "path/filepath" - - "golang.org/x/sync/errgroup" ) -type git struct { +type gitWalker struct { root string + repo *git.Repository } -func (g *git) Root() string { +func (g *gitWalker) Root() string { return g.root } -func (g *git) Walk(ctx context.Context, fn filepath.WalkFunc) error { - r, w := io.Pipe() +func (g *gitWalker) Walk(ctx context.Context, fn filepath.WalkFunc) error { - cmd := exec.Command("git", "-C", g.root, "ls-files") - cmd.Stdout = w - cmd.Stderr = w + idx, err := g.repo.Storer.Index() + if err != nil { + return fmt.Errorf("%w: failed to open index", err) + } - eg := errgroup.Group{} + for _, entry := range idx.Entries { - eg.Go(func() error { - scanner := bufio.NewScanner(r) + select { + case <-ctx.Done(): + return ctx.Err() + default: + path := filepath.Join(g.root, entry.Name) - for scanner.Scan() { - select { - case <-ctx.Done(): - return ctx.Err() - default: - line := scanner.Text() - path := filepath.Join(g.root, line) - - // stat the file - info, err := os.Lstat(path) - if err = fn(path, info, err); err != nil { - return err - } + // stat the file + info, err := os.Lstat(path) + if err = fn(path, info, err); err != nil { + return err } } - return nil - }) - - if err := w.CloseWithError(cmd.Run()); err != nil { - return err } - return eg.Wait() + return nil } func NewGit(root string) (Walker, error) { - // check if we're dealing with a git repository - cmd := exec.Command("git", "-C", root, "rev-parse", "--is-inside-work-tree") - _, err := cmd.CombinedOutput() + repo, err := git.PlainOpen(root) if err != nil { - return nil, fmt.Errorf("%w: git repo check failed", err) + return nil, fmt.Errorf("%w: failed to open git repo", err) } - return &git{root}, nil + return &gitWalker{root, repo}, nil } diff --git a/nix/packages.nix b/nix/packages.nix index a709a05..0259322 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -26,14 +26,9 @@ "-X 'build.Version=${version}'" ]; - # needed for git ls-files - buildInputs = [pkgs.git]; - nativeBuildInputs = - # needed for git ls-files - [pkgs.git] # we need some formatters available for the tests - ++ (import ./formatters.nix pkgs); + (import ./formatters.nix pkgs); preCheck = '' XDG_CACHE_HOME=$(mktemp -d)