feat: allow missing formatters (#6)

Closes #3

Reviewed-on: #6
Co-authored-by: Brian McGee <brian@bmcgee.ie>
Co-committed-by: Brian McGee <brian@bmcgee.ie>
This commit is contained in:
Brian McGee 2023-12-23 15:00:39 +00:00 committed by Brian McGee
parent 298e5ac217
commit 4c45d2aa7e
7 changed files with 104 additions and 8 deletions

View File

@ -61,6 +61,9 @@ func Open(treeRoot string, clean bool) (err error) {
}
func Close() error {
if db == nil {
return nil
}
return db.Close()
}

View File

@ -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:"."`
}

View File

@ -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)
}
}
@ -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()
}

View File

@ -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())
}

View File

@ -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")
@ -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)
}

View File

@ -10,6 +10,10 @@ import (
"github.com/juju/errors"
)
const (
ErrFormatterNotFound = errors.ConstError("formatter not found")
)
type Formatter struct {
Name string
Command string
@ -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

View File

@ -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"