mirror of
https://github.com/numtide/treefmt.git
synced 2024-10-05 13:07:17 +03:00
Merge pull request #318 from numtide/feat/improve-unmatched
feat: improve unmatched logic
This commit is contained in:
commit
251012657a
@ -3,11 +3,12 @@ package cli
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
|
||||
"git.numtide.com/numtide/treefmt/format"
|
||||
"git.numtide.com/numtide/treefmt/walk"
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/gobwas/glob"
|
||||
)
|
||||
|
||||
func New() *Format {
|
||||
@ -36,8 +37,8 @@ type Format struct {
|
||||
|
||||
CpuProfile string `optional:"" help:"The file into which a cpu profile will be written."`
|
||||
|
||||
excludes []glob.Glob
|
||||
formatters map[string]*format.Formatter
|
||||
globalExcludes []glob.Glob
|
||||
|
||||
filesCh chan *walk.File
|
||||
processedCh chan *walk.File
|
||||
|
@ -97,7 +97,7 @@ func (f *Format) Run() (err error) {
|
||||
}
|
||||
|
||||
// compile global exclude globs
|
||||
if f.excludes, err = format.CompileGlobs(cfg.Global.Excludes); err != nil {
|
||||
if f.globalExcludes, err = format.CompileGlobs(cfg.Global.Excludes); err != nil {
|
||||
return fmt.Errorf("failed to compile global excludes: %w", err)
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ func (f *Format) Run() (err error) {
|
||||
f.formatters = make(map[string]*format.Formatter)
|
||||
|
||||
for name, formatterCfg := range cfg.Formatters {
|
||||
formatter, err := format.NewFormatter(name, f.TreeRoot, formatterCfg, f.excludes)
|
||||
formatter, err := format.NewFormatter(name, f.TreeRoot, formatterCfg)
|
||||
|
||||
if errors.Is(err, format.ErrCommandNotFound) && f.AllowMissingFormatter {
|
||||
log.Debugf("formatter command not found: %v", name)
|
||||
@ -390,7 +390,15 @@ func (f *Format) applyFormatters(ctx context.Context) func() error {
|
||||
// iterate the files channel
|
||||
for file := range f.filesCh {
|
||||
|
||||
// determine a list of formatters that are interested in file
|
||||
// first check if this file has been globally excluded
|
||||
if format.PathMatches(file.RelPath, f.globalExcludes) {
|
||||
log.Debugf("path matched global excludes: %s", file.RelPath)
|
||||
// mark it as processed and continue to the next
|
||||
f.processedCh <- file
|
||||
continue
|
||||
}
|
||||
|
||||
// check if any formatters are interested in this file
|
||||
var matches []*format.Formatter
|
||||
for _, formatter := range f.formatters {
|
||||
if formatter.Wants(file) {
|
||||
@ -398,11 +406,13 @@ func (f *Format) applyFormatters(ctx context.Context) func() error {
|
||||
}
|
||||
}
|
||||
|
||||
// see if any formatters matched
|
||||
if len(matches) == 0 {
|
||||
if f.OnUnmatched == log.FatalLevel {
|
||||
return fmt.Errorf("no formatter for path: %s", file.Path)
|
||||
return fmt.Errorf("no formatter for path: %s", file.RelPath)
|
||||
}
|
||||
log.Logf(f.OnUnmatched, "no formatter for path: %s", file.Path)
|
||||
log.Logf(f.OnUnmatched, "no formatter for path: %s", file.RelPath)
|
||||
// mark it as processed and continue to the next
|
||||
f.processedCh <- file
|
||||
} else {
|
||||
// record the match
|
||||
|
@ -39,21 +39,22 @@ func TestOnUnmatched(t *testing.T) {
|
||||
paths := []string{
|
||||
"go/go.mod",
|
||||
"haskell/haskell.cabal",
|
||||
"haskell/treefmt.toml",
|
||||
"html/scripts/.gitkeep",
|
||||
"nixpkgs.toml",
|
||||
"python/requirements.txt",
|
||||
"rust/Cargo.toml",
|
||||
"touch.toml",
|
||||
"treefmt.toml",
|
||||
// these should not be reported as they're in the global excludes
|
||||
// - "nixpkgs.toml"
|
||||
// - "touch.toml"
|
||||
// - "treefmt.toml"
|
||||
// - "rust/Cargo.toml"
|
||||
// - "haskell/treefmt.toml"
|
||||
}
|
||||
|
||||
out, err := cmd(t, "-C", tempDir, "--allow-missing-formatter", "--on-unmatched", "fatal")
|
||||
as.ErrorContains(err, fmt.Sprintf("no formatter for path: %s/%s", tempDir, paths[0]))
|
||||
as.ErrorContains(err, fmt.Sprintf("no formatter for path: %s", paths[0]))
|
||||
|
||||
checkOutput := func(level string, output []byte) {
|
||||
for _, p := range paths {
|
||||
as.Contains(string(output), fmt.Sprintf("%s format: no formatter for path: %s/%s", level, tempDir, p))
|
||||
as.Contains(string(output), fmt.Sprintf("%s format: no formatter for path: %s", level, p))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,8 @@ func TestReadConfigFile(t *testing.T) {
|
||||
|
||||
as.NotNil(cfg)
|
||||
|
||||
as.Equal([]string{"*.toml"}, cfg.Global.Excludes)
|
||||
|
||||
// python
|
||||
python, ok := cfg.Formatters["python"]
|
||||
as.True(ok, "python formatter not found")
|
||||
|
@ -100,7 +100,6 @@ func NewFormatter(
|
||||
name string,
|
||||
treeRoot string,
|
||||
cfg *config.Formatter,
|
||||
globalExcludes []glob.Glob,
|
||||
) (*Formatter, error) {
|
||||
var err error
|
||||
|
||||
@ -136,7 +135,6 @@ func NewFormatter(
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compile formatter '%v' excludes: %w", f.name, err)
|
||||
}
|
||||
f.excludes = append(f.excludes, globalExcludes...)
|
||||
|
||||
return &f, nil
|
||||
}
|
||||
|
@ -22,7 +22,16 @@
|
||||
statix.enable = true;
|
||||
};
|
||||
|
||||
settings.formatter = {
|
||||
settings = {
|
||||
global.excludes = [
|
||||
"LICENSE"
|
||||
# let's not mess with the test folder
|
||||
"test/**"
|
||||
# unsupported extensions
|
||||
"*.{gif,png,svg,tape,mts,lock,mod,sum,toml,env,envrc,gitignore}"
|
||||
];
|
||||
|
||||
formatter = {
|
||||
deadnix = {
|
||||
priority = 1;
|
||||
};
|
||||
@ -37,18 +46,8 @@
|
||||
|
||||
prettier = {
|
||||
options = ["--tab-width" "4"];
|
||||
includes = [
|
||||
"*.css"
|
||||
"*.html"
|
||||
"*.js"
|
||||
"*.json"
|
||||
"*.jsx"
|
||||
"*.md"
|
||||
"*.mdx"
|
||||
"*.scss"
|
||||
"*.ts"
|
||||
"*.yaml"
|
||||
];
|
||||
includes = ["*.{css,html,js,json,jsx,md,mdx,scss,ts,yaml}"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,8 @@
|
||||
# One CLI to format the code tree - https://git.numtide.com/numtide/treefmt
|
||||
|
||||
[global]
|
||||
excludes = ["*.toml"]
|
||||
|
||||
[formatter.python]
|
||||
command = "black"
|
||||
includes = ["*.py"]
|
||||
|
Loading…
Reference in New Issue
Block a user