Skip to content

Commit

Permalink
feat: use go-git index instead of git ls-files (#23)
Browse files Browse the repository at this point in the history
Figured out how to use `go-git` properly.

```console
# git

❯ nix run .# -- --config-file ./test/echo.toml --tree-root /home/brian/Development/com/github/nixos/nixpkgs -c
38539 files changed in 272.843495ms

# filesystem

❯ nix run .# -- --config-file ./test/echo.toml --tree-root /home/brian/Development/com/github/nixos/nixpkgs -c --walk filesystem
38567 files changed in 348.84277ms
```

Signed-off-by: Brian McGee <[email protected]>
Reviewed-on: https://git.numtide.com/numtide/treefmt/pulls/23
Reviewed-by: Jonas Chevalier <[email protected]>
Co-authored-by: Brian McGee <[email protected]>
Co-committed-by: Brian McGee <[email protected]>
  • Loading branch information
brianmcgee authored and Brian McGee committed Jan 12, 2024
1 parent 5711cae commit 80e99b6
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 49 deletions.
8 changes: 4 additions & 4 deletions internal/walk/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
62 changes: 23 additions & 39 deletions internal/walk/git.go
Original file line number Diff line number Diff line change
@@ -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()

cmd := exec.Command("git", "-C", g.root, "ls-files")
cmd.Stdout = w
cmd.Stderr = w
func (g *gitWalker) Walk(ctx context.Context, fn filepath.WalkFunc) error {

eg := errgroup.Group{}
idx, err := g.repo.Storer.Index()
if err != nil {
return fmt.Errorf("%w: failed to open index", err)
}

eg.Go(func() error {
scanner := bufio.NewScanner(r)
for _, entry := range idx.Entries {

for scanner.Scan() {
select {
case <-ctx.Done():
return ctx.Err()
default:
line := scanner.Text()
path := filepath.Join(g.root, line)
select {
case <-ctx.Done():
return ctx.Err()
default:
path := filepath.Join(g.root, entry.Name)

// 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
}
7 changes: 1 addition & 6 deletions nix/packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 80e99b6

Please sign in to comment.