@@ -11,6 +11,7 @@ import (
1111 "text/template"
1212
1313 "github.com/GoCodeAlone/workflow/config"
14+ "github.com/GoCodeAlone/workflow/schema"
1415 "gopkg.in/yaml.v3"
1516)
1617
@@ -77,6 +78,7 @@ func runTemplateValidate(args []string) error {
7778 configFile := fs2 .String ("config" , "" , "Validate a specific config file instead of templates" )
7879 strict := fs2 .Bool ("strict" , false , "Fail on warnings (not just errors)" )
7980 format := fs2 .String ("format" , "text" , "Output format: text or json" )
81+ pluginDir := fs2 .String ("plugin-dir" , "" , "Directory of installed external plugins; their types are loaded before validation" )
8082 fs2 .Usage = func () {
8183 fmt .Fprintf (fs2 .Output (), `Usage: wfctl template validate [options]
8284
@@ -90,6 +92,14 @@ Options:
9092 return err
9193 }
9294
95+ // Load external plugin types before validation so their module/trigger/workflow
96+ // types are recognised and don't cause false "unknown type" errors.
97+ if * pluginDir != "" {
98+ if err := schema .LoadPluginTypesFromDir (* pluginDir ); err != nil {
99+ return fmt .Errorf ("failed to load plugins from %s: %w" , * pluginDir , err )
100+ }
101+ }
102+
93103 knownModules := KnownModuleTypes ()
94104 knownSteps := KnownStepTypes ()
95105 knownTriggers := KnownTriggerTypes ()
@@ -353,15 +363,23 @@ func validateWorkflowConfig(name string, cfg *config.WorkflowConfig, knownModule
353363 result .Errors = append (result .Errors , fmt .Sprintf ("module %q uses unknown type %q" , mod .Name , mod .Type ))
354364 } else {
355365 result .ModuleValid ++
356- // Warn on unknown config fields
366+ // Warn on unknown config fields (with snake_case hint)
357367 if mod .Config != nil && len (info .ConfigKeys ) > 0 {
358368 knownKeys := make (map [string ]bool )
369+ snakeToCamel := make (map [string ]string )
359370 for _ , k := range info .ConfigKeys {
360371 knownKeys [k ] = true
372+ if snake := schema .CamelToSnake (k ); snake != k {
373+ snakeToCamel [snake ] = k
374+ }
361375 }
362376 for key := range mod .Config {
363377 if ! knownKeys [key ] {
364- result .Warnings = append (result .Warnings , fmt .Sprintf ("module %q (%s) config field %q not in known fields" , mod .Name , mod .Type , key ))
378+ if camel , ok := snakeToCamel [key ]; ok {
379+ result .Warnings = append (result .Warnings , fmt .Sprintf ("module %q (%s) config field %q uses snake_case; use camelCase %q instead" , mod .Name , mod .Type , key , camel ))
380+ } else {
381+ result .Warnings = append (result .Warnings , fmt .Sprintf ("module %q (%s) config field %q not in known fields" , mod .Name , mod .Type , key ))
382+ }
365383 }
366384 }
367385 }
@@ -401,15 +419,23 @@ func validateWorkflowConfig(name string, cfg *config.WorkflowConfig, knownModule
401419 result .Errors = append (result .Errors , fmt .Sprintf ("pipeline %q step uses unknown type %q" , pipelineName , stepType ))
402420 } else {
403421 result .StepValid ++
404- // Config key warnings
422+ // Config key warnings (with snake_case hint)
405423 if stepCfg , ok := stepMap ["config" ].(map [string ]any ); ok && len (stepInfo .ConfigKeys ) > 0 {
406424 knownKeys := make (map [string ]bool )
425+ snakeToCamel := make (map [string ]string )
407426 for _ , k := range stepInfo .ConfigKeys {
408427 knownKeys [k ] = true
428+ if snake := schema .CamelToSnake (k ); snake != k {
429+ snakeToCamel [snake ] = k
430+ }
409431 }
410432 for key := range stepCfg {
411433 if ! knownKeys [key ] {
412- result .Warnings = append (result .Warnings , fmt .Sprintf ("pipeline %q step %q (%s) config field %q not in known fields" , pipelineName , stepMap ["name" ], stepType , key ))
434+ if camel , ok := snakeToCamel [key ]; ok {
435+ result .Warnings = append (result .Warnings , fmt .Sprintf ("pipeline %q step %q (%s) config field %q uses snake_case; use camelCase %q instead" , pipelineName , stepMap ["name" ], stepType , key , camel ))
436+ } else {
437+ result .Warnings = append (result .Warnings , fmt .Sprintf ("pipeline %q step %q (%s) config field %q not in known fields" , pipelineName , stepMap ["name" ], stepType , key ))
438+ }
413439 }
414440 }
415441 }
0 commit comments