From 73e6f782db49273a90c73a5cc15c0fdc7feb455b Mon Sep 17 00:00:00 2001 From: Brian McGee Date: Sat, 12 Oct 2024 12:08:08 +0100 Subject: [PATCH] wip: add git stage reader Signed-off-by: Brian McGee --- nix/packages/treefmt/default.nix | 2 +- walk/git.go | 29 +++++++++++++++++++----- walk/git_test.go | 18 +++++++++++---- walk/type_enum.go | 38 +++++++++++++++++++------------- walk/walk.go | 17 +++++++++----- 5 files changed, 72 insertions(+), 32 deletions(-) diff --git a/nix/packages/treefmt/default.nix b/nix/packages/treefmt/default.nix index 943ba82b..ab8f423d 100644 --- a/nix/packages/treefmt/default.nix +++ b/nix/packages/treefmt/default.nix @@ -46,7 +46,7 @@ in "-X github.com/numtide/treefmt/build.Version=v${version}" ]; - nativeBuildInputs = + nativeBuildInputs = [ pkgs.git ] ++ # we need some formatters available for the tests import ./formatters.nix pkgs; diff --git a/walk/git.go b/walk/git.go index 5621bf9e..0969def3 100644 --- a/walk/git.go +++ b/walk/git.go @@ -4,14 +4,15 @@ import ( "bufio" "context" "fmt" - "github.com/charmbracelet/log" - "github.com/numtide/treefmt/stats" - "golang.org/x/sync/errgroup" "io" "os" "os/exec" "path/filepath" "strings" + + "github.com/charmbracelet/log" + "github.com/numtide/treefmt/stats" + "golang.org/x/sync/errgroup" ) type GitReader struct { @@ -99,12 +100,12 @@ func (g *GitReader) Close() error { return g.eg.Wait() } -func NewGitWorktreeReader( +func newGitReader( root string, path string, + args []string, statz *stats.Stats, ) (*GitReader, error) { - // check if the root is a git repository cmd := exec.Command("git", "rev-parse", "--is-inside-work-tree") cmd.Dir = root @@ -118,9 +119,25 @@ func NewGitWorktreeReader( return &GitReader{ root: root, path: path, - args: []string{"ls-files"}, + args: args, stats: statz, eg: &errgroup.Group{}, log: log.WithPrefix("walk[git]"), }, nil } + +func NewGitStageReader( + root string, + path string, + statz *stats.Stats, +) (*GitReader, error) { + return newGitReader(root, path, []string{"diff", "--name-only", "--cached"}, statz) +} + +func NewGitWorktreeReader( + root string, + path string, + statz *stats.Stats, +) (*GitReader, error) { + return newGitReader(root, path, []string{"ls-files"}, statz) +} diff --git a/walk/git_test.go b/walk/git_test.go index d543c87f..46e25645 100644 --- a/walk/git_test.go +++ b/walk/git_test.go @@ -33,14 +33,24 @@ func TestGitWorktreeReader(t *testing.T) { ) as.NoError(err, "failed to init git repository") - // get worktree and add everything to it + // read empty worktree + statz := stats.New() + reader, err := walk.NewGitWorktreeReader(tempDir, "", &statz) + as.NoError(err) + + files := make([]*walk.File, 8) + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + n, err := reader.Read(ctx, files) + cancel() + as.Equal(0, n) + as.ErrorIs(err, io.EOF) + + // add everything to the worktree wt, err := repo.Worktree() as.NoError(err, "failed to get git worktree") as.NoError(wt.AddGlob(".")) - statz := stats.New() - - reader, err := walk.NewGitWorktreeReader(tempDir, "", &statz) + reader, err = walk.NewGitWorktreeReader(tempDir, "", &statz) as.NoError(err) count := 0 diff --git a/walk/type_enum.go b/walk/type_enum.go index ba377ab9..87619277 100644 --- a/walk/type_enum.go +++ b/walk/type_enum.go @@ -7,11 +7,11 @@ import ( "strings" ) -const _TypeName = "autogitfilesystemstdin" +const _TypeName = "autostdinfilesystemgitgit_worktreegit_stage" -var _TypeIndex = [...]uint8{0, 4, 7, 17, 22} +var _TypeIndex = [...]uint8{0, 4, 9, 19, 22, 34, 43} -const _TypeLowerName = "autogitfilesystemstdin" +const _TypeLowerName = "autostdinfilesystemgitgit_worktreegit_stage" func (i Type) String() string { if i < 0 || i >= Type(len(_TypeIndex)-1) { @@ -25,29 +25,37 @@ func (i Type) String() string { func _TypeNoOp() { var x [1]struct{} _ = x[Auto-(0)] - _ = x[Git-(1)] + _ = x[Stdin-(1)] _ = x[Filesystem-(2)] - _ = x[Stdin-(3)] + _ = x[Git-(3)] + _ = x[GitWorktree-(4)] + _ = x[GitStage-(5)] } -var _TypeValues = []Type{Auto, Git, Filesystem, Stdin} +var _TypeValues = []Type{Auto, Stdin, Filesystem, Git, GitWorktree, GitStage} var _TypeNameToValueMap = map[string]Type{ _TypeName[0:4]: Auto, _TypeLowerName[0:4]: Auto, - _TypeName[4:7]: Git, - _TypeLowerName[4:7]: Git, - _TypeName[7:17]: Filesystem, - _TypeLowerName[7:17]: Filesystem, - _TypeName[17:22]: Stdin, - _TypeLowerName[17:22]: Stdin, + _TypeName[4:9]: Stdin, + _TypeLowerName[4:9]: Stdin, + _TypeName[9:19]: Filesystem, + _TypeLowerName[9:19]: Filesystem, + _TypeName[19:22]: Git, + _TypeLowerName[19:22]: Git, + _TypeName[22:34]: GitWorktree, + _TypeLowerName[22:34]: GitWorktree, + _TypeName[34:43]: GitStage, + _TypeLowerName[34:43]: GitStage, } var _TypeNames = []string{ _TypeName[0:4], - _TypeName[4:7], - _TypeName[7:17], - _TypeName[17:22], + _TypeName[4:9], + _TypeName[9:19], + _TypeName[19:22], + _TypeName[22:34], + _TypeName[34:43], } // TypeString retrieves an enum value from the enum constants string name. diff --git a/walk/walk.go b/walk/walk.go index 9d1d935f..b308119a 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -20,9 +20,11 @@ type Type int const ( Auto Type = iota - Git - Filesystem Stdin + Filesystem + Git + GitWorktree + GitStage BatchSize = 1024 ) @@ -159,12 +161,15 @@ func NewReader( reader, err = NewReader(Filesystem, root, path, db, statz) } return reader, err - case Git: - reader, err = NewGitWorktreeReader(root, path, statz) - case Filesystem: - reader = NewFilesystemReader(root, path, statz, BatchSize) case Stdin: return nil, fmt.Errorf("stdin walk type is not supported") + case Filesystem: + reader = NewFilesystemReader(root, path, statz, BatchSize) + case Git, GitWorktree: + reader, err = NewGitWorktreeReader(root, path, statz) + case GitStage: + reader, err = NewGitStageReader(root, path, statz) + default: return nil, fmt.Errorf("unknown walk type: %v", walkType) }