support formatter ordering #20
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -66,8 +67,7 @@ func (f *Format) Run() error {
|
|||||||
|
|
||||||
formatters := make(map[string]*format.Formatter)
|
formatters := make(map[string]*format.Formatter)
|
||||||
|
|
||||||
// detect dependency cycles and broken dependencies
|
// detect broken dependencies
|
||||||
// todo dependency cycle detection
|
|
||||||
for name, config := range cfg.Formatters {
|
for name, config := range cfg.Formatters {
|
||||||
before := config.Before
|
before := config.Before
|
||||||
if before != "" {
|
if before != "" {
|
||||||
@ -79,6 +79,30 @@ func (f *Format) Run() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dependency cycle detection
|
||||||
|
for name, config := range cfg.Formatters {
|
||||||
|
var ok bool
|
||||||
|
var history []string
|
||||||
|
childName := name
|
||||||
|
for {
|
||||||
|
// add to history
|
||||||
|
history = append(history, childName)
|
||||||
|
|
||||||
|
if config.Before == "" {
|
||||||
|
break
|
||||||
|
} else if config.Before == name {
|
||||||
|
return fmt.Errorf("formatter cycle detected %v", strings.Join(history, " -> "))
|
||||||
|
}
|
||||||
|
|
||||||
|
// load child config
|
||||||
|
childName = config.Before
|
||||||
|
config, ok = cfg.Formatters[config.Before]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("formatter not found: %v", config.Before)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// init formatters
|
// init formatters
|
||||||
for name, config := range cfg.Formatters {
|
for name, config := range cfg.Formatters {
|
||||||
if !includeFormatter(name) {
|
if !includeFormatter(name) {
|
||||||
|
@ -39,6 +39,27 @@ func TestAllowMissingFormatter(t *testing.T) {
|
|||||||
as.NoError(err)
|
as.NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDependencyCycle(t *testing.T) {
|
||||||
|
as := require.New(t)
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
configPath := tempDir + "/treefmt.toml"
|
||||||
|
|
||||||
|
test.WriteConfig(t, configPath, format.Config{
|
||||||
|
Formatters: map[string]*format.FormatterConfig{
|
||||||
|
"a": {Command: "echo", Before: "b"},
|
||||||
|
"b": {Command: "echo", Before: "c"},
|
||||||
|
"c": {Command: "echo", Before: "a"},
|
||||||
|
"d": {Command: "echo", Before: "e"},
|
||||||
|
"e": {Command: "echo", Before: "f"},
|
||||||
|
"f": {Command: "echo"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := cmd(t, "--config-file", configPath, "--tree-root", tempDir)
|
||||||
|
as.ErrorContains(err, "formatter cycle detected a -> b -> c")
|
||||||
|
}
|
||||||
|
|
||||||
func TestSpecifyingFormatters(t *testing.T) {
|
func TestSpecifyingFormatters(t *testing.T) {
|
||||||
as := require.New(t)
|
as := require.New(t)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user