Skip to content

Commit

Permalink
feat: add stats output similar to treefmt.rs
Browse files Browse the repository at this point in the history
Signed-off-by: Brian McGee <[email protected]>
  • Loading branch information
brianmcgee committed May 1, 2024
1 parent 8e23c86 commit 04330a3
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 43 deletions.
12 changes: 10 additions & 2 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"runtime"
"time"

"git.numtide.com/numtide/treefmt/stats"

"git.numtide.com/numtide/treefmt/format"
"git.numtide.com/numtide/treefmt/walk"

Expand All @@ -33,9 +35,10 @@ type Entry struct {
}

var (
db *bolt.DB
db *bolt.DB
logger *log.Logger

ReadBatchSize = 1024 * runtime.NumCPU()
logger *log.Logger
)

// Open creates an instance of bolt.DB for a given treeRoot path.
Expand Down Expand Up @@ -234,11 +237,14 @@ func ChangeSet(ctx context.Context, walker walk.Walker, pathsCh chan<- string) e

changedOrNew := cached == nil || !(cached.Modified == info.ModTime() && cached.Size == info.Size())

stats.Add(stats.Traversed, 1)
if !changedOrNew {
// no change
return nil
}

stats.Add(stats.Emitted, 1)

// pass on the path
select {
case <-ctx.Done():
Expand Down Expand Up @@ -293,6 +299,8 @@ func Update(treeRoot string, paths []string) (int, error) {
continue
}

stats.Add(stats.Formatted, 1)

entry := Entry{
Size: pathInfo.Size(),
Modified: pathInfo.ModTime(),
Expand Down
14 changes: 10 additions & 4 deletions cli/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (
"sort"
"strings"
"syscall"
"time"

"git.numtide.com/numtide/treefmt/format"
"git.numtide.com/numtide/treefmt/stats"
"github.com/gobwas/glob"

"git.numtide.com/numtide/treefmt/cache"
Expand All @@ -32,7 +32,6 @@ const (
)

var (
start time.Time
globalExcludes []glob.Glob
formatters map[string]*format.Formatter
pipelines map[string]*format.Pipeline
Expand All @@ -43,7 +42,7 @@ var (
)

func (f *Format) Run() (err error) {
start = time.Now()
stats.Init()

Cli.Configure()

Expand Down Expand Up @@ -196,6 +195,8 @@ func walkFilesystem(ctx context.Context) func() error {
default:
// ignore symlinks and directories
if !(info.IsDir() || info.Mode()&os.ModeSymlink == os.ModeSymlink) {
stats.Add(stats.Traversed, 1)
stats.Add(stats.Emitted, 1)
pathsCh <- path
}
return nil
Expand Down Expand Up @@ -257,7 +258,7 @@ func updateCache(ctx context.Context) func() error {
return ErrFailOnChange
}

fmt.Printf("%v files changed in %v\n", changes, time.Now().Sub(start))
stats.Print()
return nil
}
}
Expand Down Expand Up @@ -322,12 +323,17 @@ func applyFormatters(ctx context.Context) func() error {
}()

for path := range pathsCh {
var matched bool
for key, pipeline := range pipelines {
if !pipeline.Wants(path) {
continue
}
matched = true
tryApply(key, path)
}
if matched {
stats.Add(stats.Matched, 1)
}
}

// flush any partial batches which remain
Expand Down
73 changes: 36 additions & 37 deletions cli/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cli

import (
"bufio"
"fmt"
"os"
"os/exec"
"path"
Expand Down Expand Up @@ -68,19 +67,19 @@ func TestSpecifyingFormatters(t *testing.T) {

out, err := cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), "3 files changed")
assertFormatted(t, as, out, 3)

out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir, "--formatters", "elm,nix")
as.NoError(err)
as.Contains(string(out), "2 files changed")
assertFormatted(t, as, out, 2)

out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir, "--formatters", "ruby,nix")
as.NoError(err)
as.Contains(string(out), "2 files changed")
assertFormatted(t, as, out, 2)

out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir, "--formatters", "nix")
as.NoError(err)
as.Contains(string(out), "1 files changed")
assertFormatted(t, as, out, 1)

// test bad names

Expand Down Expand Up @@ -110,23 +109,23 @@ func TestIncludesAndExcludes(t *testing.T) {
test.WriteConfig(t, configPath, cfg)
out, err := cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertFormatted(t, as, out, 31)

// globally exclude nix files
cfg.Global.Excludes = []string{"*.nix"}

test.WriteConfig(t, configPath, cfg)
out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 30))
assertFormatted(t, as, out, 30)

// add haskell files to the global exclude
cfg.Global.Excludes = []string{"*.nix", "*.hs"}

test.WriteConfig(t, configPath, cfg)
out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 24))
assertFormatted(t, as, out, 24)

echo := cfg.Formatters["echo"]

Expand All @@ -136,31 +135,31 @@ func TestIncludesAndExcludes(t *testing.T) {
test.WriteConfig(t, configPath, cfg)
out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 22))
assertFormatted(t, as, out, 22)

// remove go files from the echo formatter
echo.Excludes = []string{"*.py", "*.go"}

test.WriteConfig(t, configPath, cfg)
out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 21))
assertFormatted(t, as, out, 21)

// adjust the includes for echo to only include elm files
echo.Includes = []string{"*.elm"}

test.WriteConfig(t, configPath, cfg)
out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 1))
assertFormatted(t, as, out, 1)

// add js files to echo formatter
echo.Includes = []string{"*.elm", "*.js"}

test.WriteConfig(t, configPath, cfg)
out, err = cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 2))
assertFormatted(t, as, out, 2)
}

func TestCache(t *testing.T) {
Expand All @@ -182,34 +181,34 @@ func TestCache(t *testing.T) {
test.WriteConfig(t, configPath, cfg)
out, err := cmd(t, "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertFormatted(t, as, out, 31)

out, err = cmd(t, "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// clear cache
out, err = cmd(t, "--config-file", configPath, "--tree-root", tempDir, "-c")
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertFormatted(t, as, out, 31)

out, err = cmd(t, "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// clear cache
out, err = cmd(t, "--config-file", configPath, "--tree-root", tempDir, "-c")
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertFormatted(t, as, out, 31)

out, err = cmd(t, "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// no cache
out, err = cmd(t, "--config-file", configPath, "--tree-root", tempDir, "--no-cache")
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertStats(t, as, out, 31, 31, 31, 0)
}

func TestChangeWorkingDirectory(t *testing.T) {
Expand Down Expand Up @@ -243,7 +242,7 @@ func TestChangeWorkingDirectory(t *testing.T) {
// this should fail if the working directory hasn't been changed first
out, err := cmd(t, "-C", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertFormatted(t, as, out, 31)
}

func TestFailOnChange(t *testing.T) {
Expand Down Expand Up @@ -307,31 +306,31 @@ func TestBustCacheOnFormatterChange(t *testing.T) {
args := []string{"--config-file", configPath, "--tree-root", tempDir}
out, err := cmd(t, args...)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 3))
assertFormatted(t, as, out, 3)

// tweak mod time of elm formatter
as.NoError(test.RecreateSymlink(t, binPath+"/"+"elm-format"))

out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 3))
assertFormatted(t, as, out, 3)

// check cache is working
out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// tweak mod time of python formatter
as.NoError(test.RecreateSymlink(t, binPath+"/"+"black"))

out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 3))
assertFormatted(t, as, out, 3)

// check cache is working
out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// add go formatter
cfg.Formatters["go"] = &config2.Formatter{
Expand All @@ -343,38 +342,38 @@ func TestBustCacheOnFormatterChange(t *testing.T) {

out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 4))
assertFormatted(t, as, out, 4)

// check cache is working
out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// remove python formatter
delete(cfg.Formatters, "python")
test.WriteConfig(t, configPath, cfg)

out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 2))
assertFormatted(t, as, out, 2)

// check cache is working
out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)

// remove elm formatter
delete(cfg.Formatters, "elm")
test.WriteConfig(t, configPath, cfg)

out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 1))
assertFormatted(t, as, out, 1)

// check cache is working
out, err = cmd(t, args...)
as.NoError(err)
as.Contains(string(out), "0 files changed")
assertFormatted(t, as, out, 0)
}

func TestGitWorktree(t *testing.T) {
Expand Down Expand Up @@ -408,10 +407,10 @@ func TestGitWorktree(t *testing.T) {
wt, err := repo.Worktree()
as.NoError(err, "failed to get git worktree")

run := func(changed int) {
run := func(formatted int) {
out, err := cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", changed))
assertFormatted(t, as, out, formatted)
}

// run before adding anything to the worktree
Expand All @@ -429,7 +428,7 @@ func TestGitWorktree(t *testing.T) {
// walk with filesystem instead of git
out, err := cmd(t, "-c", "--config-file", configPath, "--tree-root", tempDir, "--walk", "filesystem")
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 59))
assertFormatted(t, as, out, 59)
}

func TestPathsArg(t *testing.T) {
Expand Down Expand Up @@ -464,12 +463,12 @@ func TestPathsArg(t *testing.T) {
// without any path args
out, err := cmd(t, "-C", tempDir)
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 31))
assertFormatted(t, as, out, 31)

// specify some explicit paths
out, err = cmd(t, "-C", tempDir, "-c", "elm/elm.json", "haskell/Nested/Foo.hs")
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 2))
assertFormatted(t, as, out, 2)

// specify a bad path
out, err = cmd(t, "-C", tempDir, "-c", "elm/elm.json", "haskell/Nested/Bar.hs")
Expand Down Expand Up @@ -529,7 +528,7 @@ go/main.go

out, err := cmd(t, "-C", tempDir, "--stdin")
as.NoError(err)
as.Contains(string(out), fmt.Sprintf("%d files changed", 3))
assertFormatted(t, as, out, 3)
}

func TestDeterministicOrderingInPipeline(t *testing.T) {
Expand Down
Loading

0 comments on commit 04330a3

Please sign in to comment.