diff options
Diffstat (limited to 'internal/engine')
| -rw-r--r-- | internal/engine/engine.go | 5 | ||||
| -rw-r--r-- | internal/engine/engine_test.go | 38 |
2 files changed, 43 insertions, 0 deletions
diff --git a/internal/engine/engine.go b/internal/engine/engine.go index 00a249d..958e4f9 100644 --- a/internal/engine/engine.go +++ b/internal/engine/engine.go @@ -177,6 +177,11 @@ func Load(mainFile string, names ...string) (*Engine, []*config.Diag) { func checkCaptures(file string, r *config.Rule, c *cond.Cond) *config.Diag { groups := c.NameGroups() for _, a := range r.Actions { + if err := plan.CheckTemplate(a.Arg); err != nil { + // A placeholder that could never expand is a config error, not a + // step skipped at plan time (plan 12). + return &config.Diag{File: file, Pos: a.Pos, Msg: fmt.Sprintf("rule %q: %v", r.Name, err)} + } n, err := plan.MaxIndex(a.Arg) if err != nil || n == 0 { continue diff --git a/internal/engine/engine_test.go b/internal/engine/engine_test.go index 9de3ea4..4af8f79 100644 --- a/internal/engine/engine_test.go +++ b/internal/engine/engine_test.go @@ -256,3 +256,41 @@ func TestLoadAcceptsDuplicateWithMove(t *testing.T) { } } } + +// TestLoadRefusesBadPlaceholders: a copy or move destination or a rename +// name whose placeholders could never expand is a config error at load, so +// krino check reports it at the action's position instead of a run skipping +// the step (plan 12). +func TestLoadRefusesBadPlaceholders(t *testing.T) { + for _, c := range []struct { + action, want string + }{ + {`(move "Out/{foo}")`, "unknown placeholder {foo}"}, + {`(move "Out/{mtime}")`, "unknown placeholder {mtime}"}, + {`(move "Out/{now}")`, "unknown placeholder {now}"}, + {`(move "Out/{mtime:%B}")`, "%B"}, + {`(rename "{0}-x")`, "numbered from 1"}, + {`(copy "Out/{10}")`, "unknown placeholder {10}"}, + {`(move "Out/{name")`, "unclosed placeholder"}, + } { + h := sandbox(t) + os.MkdirAll(filepath.Join(h, "dl"), 0o755) + main := writeConfig(t, h, `(include "dl")`, map[string]string{"dl": "(path \"~/dl\")\n(rule \"r\" (when (name \"^(a)\")) " + c.action + ")\n"}) + _, errs := Load(main) + found := false + for _, e := range errs { + if strings.Contains(e.Error(), c.want) && strings.Contains(e.Error(), "dl.conf:2:") { + found = true + } + } + if !found { + t.Errorf("%s: errors %v; want %q at line 2", c.action, errs, c.want) + } + } + h := sandbox(t) + os.MkdirAll(filepath.Join(h, "dl"), 0o755) + main := writeConfig(t, h, `(include "dl")`, map[string]string{"dl": "(path \"~/dl\")\n(rule \"r\" (when (name \"^(a)\")) (rename \"{1}-{stem}{ext}\") (move \"Out/{mtime:%Y/%m}/{{x}}/{now:%j}\"))\n"}) + if _, errs := Load(main); len(errs) > 0 { + t.Errorf("valid placeholders refused: %v", errs) + } +} |
