Skip to content

Commit

Permalink
feat: allow missing formatters (#6)
Browse files Browse the repository at this point in the history
Closes #3

Reviewed-on: https://git.numtide.com/numtide/treefmt/pulls/6
Co-authored-by: Brian McGee <[email protected]>
Co-committed-by: Brian McGee <[email protected]>
  • Loading branch information
brianmcgee authored and Brian McGee committed Dec 23, 2023
1 parent 298e5ac commit 4c45d2a
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 8 deletions.
3 changes: 3 additions & 0 deletions internal/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ func Open(treeRoot string, clean bool) (err error) {
}

func Close() error {
if db == nil {
return nil
}
return db.Close()
}

Expand Down
9 changes: 5 additions & 4 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import "github.com/charmbracelet/log"
var Cli = Options{}

type Options struct {
Verbosity int `name:"verbose" short:"v" type:"counter" default:"0" env:"LOG_LEVEL" help:"Set the verbosity of logs e.g. -vv"`
ConfigFile string `type:"existingfile" default:"./treefmt.toml"`
TreeRoot string `type:"existingdir" default:"."`
ClearCache bool `short:"c" help:"Reset the evaluation cache. Use in case the cache is not precise enough"`
AllowMissingFormatter bool `default:"false" help:"Do not exit with error if a configured formatter is missing"`
ClearCache bool `short:"c" help:"Reset the evaluation cache. Use in case the cache is not precise enough"`
ConfigFile string `type:"existingfile" default:"./treefmt.toml"`
TreeRoot string `type:"existingdir" default:"."`
Verbosity int `name:"verbose" short:"v" type:"counter" default:"0" env:"LOG_LEVEL" help:"Set the verbosity of logs e.g. -vv"`

Format Format `cmd:"" default:"."`
}
Expand Down
9 changes: 8 additions & 1 deletion internal/cli/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ func (f *Format) Run() error {

// init formatters
for name, formatter := range cfg.Formatters {
if err = formatter.Init(name); err != nil {
err = formatter.Init(name)
if err == format.ErrFormatterNotFound && Cli.AllowMissingFormatter {
l.Debugf("formatter not found: %v", name)
// remove this formatter
delete(cfg.Formatters, name)
} else if err != nil {
return errors.Annotatef(err, "failed to initialise formatter: %v", name)
}
}
Expand Down Expand Up @@ -155,5 +160,7 @@ func (f *Format) Run() error {
return cache.ChangeSet(ctx, Cli.TreeRoot, pathsCh)
})

// shutdown.Listen(syscall.SIGINT, syscall.SIGTERM)

return eg.Wait()
}
68 changes: 68 additions & 0 deletions internal/cli/format_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package cli

import (
"os"
"testing"

"git.numtide.com/numtide/treefmt/internal/format"
"github.com/BurntSushi/toml"
"github.com/alecthomas/kong"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func writeConfig(t *testing.T, path string, cfg format.Config) {
t.Helper()
f, err := os.Create(path)
if err != nil {
t.Fatalf("failed to create a new config file: %v", err)
}
encoder := toml.NewEncoder(f)
if err = encoder.Encode(cfg); err != nil {
t.Fatalf("failed to write to config file: %v", err)
}
}

func newKong(t *testing.T, cli interface{}, options ...kong.Option) *kong.Kong {
t.Helper()
options = append([]kong.Option{
kong.Name("test"),
kong.Exit(func(int) {
t.Helper()
t.Fatalf("unexpected exit()")
}),
}, options...)
parser, err := kong.New(cli, options...)
assert.NoError(t, err)
return parser
}

func newCli(t *testing.T, args ...string) (*kong.Context, error) {
t.Helper()
p := newKong(t, &Cli)
return p.Parse(args)
}

func TestAllowMissingFormatter(t *testing.T) {
as := require.New(t)

tempDir := t.TempDir()
configPath := tempDir + "/treefmt.toml"

writeConfig(t, configPath, format.Config{
Formatters: map[string]*format.Formatter{
"foo-fmt": {
Command: "foo-fmt",
},
},
})

ctx, err := newCli(t, "--config-file", configPath, "--tree-root", tempDir)
as.NoError(err)
as.Error(ctx.Run(), format.ErrFormatterNotFound)

ctx, err = newCli(t, "--config-file", configPath, "--tree-root", tempDir, "--allow-missing-formatter")
as.NoError(err)

as.NoError(ctx.Run())
}
7 changes: 6 additions & 1 deletion internal/format/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/stretchr/testify/require"
)

func TestConfig(t *testing.T) {
func TestReadConfigFile(t *testing.T) {
as := require.New(t)

cfg, err := ReadConfigFile("../../test/treefmt.toml")
Expand Down Expand Up @@ -119,4 +119,9 @@ shfmt -i 2 -s -w "$@"
as.Equal([]string{"fmt"}, terraform.Options)
as.Equal([]string{"*.tf"}, terraform.Includes)
as.Nil(terraform.Excludes)

// missing
foo, ok := cfg.Formatters["foo-fmt"]
as.True(ok, "foo formatter not found")
as.Equal("foo-fmt", foo.Command)
}
11 changes: 10 additions & 1 deletion internal/format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (
"github.com/juju/errors"
)

const (
ErrFormatterNotFound = errors.ConstError("formatter not found")
)

type Formatter struct {
Name string
Command string
Expand All @@ -32,8 +36,13 @@ type Formatter struct {

func (f *Formatter) Init(name string) error {
f.Name = name
f.log = log.WithPrefix("format | " + name)

// test if the formatter is available
if err := exec.Command(f.Command, "--help").Run(); err != nil {
return ErrFormatterNotFound
}

f.log = log.WithPrefix("format | " + name)
f.inbox = make(chan string, 1024)

f.batchSize = 1024
Expand Down
5 changes: 4 additions & 1 deletion test/treefmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,7 @@ includes = ["*.sh"]
# see https://github.com/numtide/treefmt/issues/97
command = "terraform"
options = ["fmt"]
includes = ["*.tf"]
includes = ["*.tf"]

[formatter.foo-fmt]
command = "foo-fmt"

0 comments on commit 4c45d2a

Please sign in to comment.