diff --git a/cmd/format/format.go b/cmd/format/format.go index 7c053d5..acd23fa 100644 --- a/cmd/format/format.go +++ b/cmd/format/format.go @@ -159,7 +159,7 @@ func Run(v *viper.Viper, statz *stats.Stats, cmd *cobra.Command, paths []string) } // create a new walker for traversing the paths - walker, err := walk.NewCompositeReader(walkType, cfg.TreeRoot, paths, db, statz) + walker, err := walk.NewCompositeReader(walkType, cfg.TreeRoot, paths, cfg.IncludeGitSubmodules, db, statz) if err != nil { return fmt.Errorf("failed to create walker: %w", err) } diff --git a/config/config.go b/config/config.go index 2d80021..e11cac2 100644 --- a/config/config.go +++ b/config/config.go @@ -26,6 +26,7 @@ type Config struct { TreeRootFile string `mapstructure:"tree-root-file" toml:"tree-root-file,omitempty"` Verbose uint8 `mapstructure:"verbose" toml:"verbose,omitempty"` Walk string `mapstructure:"walk" toml:"walk,omitempty"` + IncludeGitSubmodules bool `mapstructure:"include-git-submodules toml:"include-git-subsmodules,omitempty"` WorkingDirectory string `mapstructure:"working-dir" toml:"-"` Stdin bool `mapstructure:"stdin" toml:"-"` // not allowed in config @@ -115,6 +116,10 @@ func SetFlags(fs *pflag.FlagSet) { "The method used to traverse the files within the tree root. Currently supports "+ ". (env $TREEFMT_WALK)", ) + fs.Bool( + "include-git-submodules", false, + "Also format files in submodules", + ) fs.StringP( "working-dir", "C", ".", "Run as if treefmt was started in the specified working directory instead of the current working "+ diff --git a/walk/git.go b/walk/git.go index cb5c4c8..36e48cf 100644 --- a/walk/git.go +++ b/walk/git.go @@ -19,6 +19,7 @@ import ( type GitReader struct { root string path string + includeSubmodules bool log *log.Logger stats *stats.Stats @@ -38,7 +39,13 @@ func (g *GitReader) Read(ctx context.Context, files []*File) (n int, err error) r, w := io.Pipe() // create a command which will execute from the specified sub path within root - cmd := exec.Command("git", "ls-files") + var cmd *exec.Cmd + if g.includeSubmodules { + cmd = exec.Command("git", "ls-files") + } else { + cmd = exec.Command("git", "ls-files", "--recurse-submodules") + } + cmd.Dir = filepath.Join(g.root, g.path) cmd.Stdout = w @@ -133,6 +140,7 @@ func (g *GitReader) Close() error { func NewGitReader( root string, path string, + includeSubmodules bool, statz *stats.Stats, ) (*GitReader, error) { // check if the root is a git repository @@ -148,6 +156,7 @@ func NewGitReader( return &GitReader{ root: root, path: path, + includeSubmodules: includeSubmodules, stats: statz, eg: &errgroup.Group{}, log: log.WithPrefix("walk | git"), diff --git a/walk/git_test.go b/walk/git_test.go index acef85b..c16cbfb 100644 --- a/walk/git_test.go +++ b/walk/git_test.go @@ -26,7 +26,7 @@ func TestGitReader(t *testing.T) { // read empty worktree statz := stats.New() - reader, err := walk.NewGitReader(tempDir, "", &statz) + reader, err := walk.NewGitReader(tempDir, "", false, &statz) as.NoError(err) files := make([]*walk.File, 8) @@ -42,7 +42,7 @@ func TestGitReader(t *testing.T) { cmd.Dir = tempDir as.NoError(cmd.Run(), "failed to add everything to the index") - reader, err = walk.NewGitReader(tempDir, "", &statz) + reader, err = walk.NewGitReader(tempDir, "", false, &statz) as.NoError(err) count := 0 diff --git a/walk/walk.go b/walk/walk.go index 7fc3fa0..4013489 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -192,6 +192,7 @@ func NewReader( walkType Type, root string, path string, + includeGitSubmodules bool, db *bolt.DB, statz *stats.Stats, ) (Reader, error) { @@ -203,9 +204,9 @@ func NewReader( switch walkType { case Auto: // for now, we keep it simple and try git first, filesystem second - reader, err = NewReader(Git, root, path, db, statz) + reader, err = NewReader(Git, root, path, includeGitSubmodules, db, statz) if err != nil { - reader, err = NewReader(Filesystem, root, path, db, statz) + reader, err = NewReader(Filesystem, root, path, includeGitSubmodules, db, statz) } return reader, err @@ -214,7 +215,7 @@ func NewReader( case Filesystem: reader = NewFilesystemReader(root, path, statz, BatchSize) case Git: - reader, err = NewGitReader(root, path, statz) + reader, err = NewGitReader(root, path, includeGitSubmodules, statz) default: return nil, fmt.Errorf("unknown walk type: %v", walkType) @@ -238,12 +239,13 @@ func NewCompositeReader( walkType Type, root string, paths []string, + includeGitSubmodules bool, db *bolt.DB, statz *stats.Stats, ) (Reader, error) { // if not paths are provided we default to processing the tree root if len(paths) == 0 { - return NewReader(walkType, root, "", db, statz) + return NewReader(walkType, root, "", includeGitSubmodules, db, statz) } readers := make([]Reader, len(paths)) @@ -275,10 +277,10 @@ func NewCompositeReader( if info.IsDir() { // for directories, we honour the walk type as we traverse them - readers[idx], err = NewReader(walkType, root, relPath, db, statz) + readers[idx], err = NewReader(walkType, root, relPath, includeGitSubmodules, db, statz) } else { // for files, we enforce a simple filesystem read - readers[idx], err = NewReader(Filesystem, root, relPath, db, statz) + readers[idx], err = NewReader(Filesystem, root, relPath, includeGitSubmodules, db, statz) } if err != nil {