@@ -62,67 +62,32 @@ func evaluateAndFlatten(val cty.Value) []cty.Value {
6262 return values
6363}
6464
65- // getBlueprintValues retrieves a cty.Value from blueprint variables by name,
66- // evaluates it and returns the flattened values and the path to use for errors.
67- func getBlueprintValues (bp config.Blueprint , varName string ) ([]cty.Value , config.Path , error ) {
68- var nilPath config.Path
69-
70- if ! bp .Vars .Has (varName ) {
71- return nil , nilPath , fmt .Errorf ("variable %q not found in blueprint vars" , varName )
72- }
73- val := bp .Vars .Get (varName )
74- if evaledVal , err := bp .Eval (val ); err == nil {
75- val = evaledVal
76- }
77- values := evaluateAndFlatten (val )
78- return values , config .Root .Vars .Dot (varName ), nil
79- }
80-
8165// getModuleSettingValues retrieves a cty.Value from module settings using a dot-separated path,
8266// evaluates expressions via bp.Eval and returns flattened slice + path for errors.
8367func getModuleSettingValues (bp config.Blueprint , group config.Group , modIdx int , mod config.Module , settingName string ) ([]cty.Value , config.Path , error ) {
8468 var nilPath config.Path
8569
86- val , found := getNestedValue (mod .Settings , settingName )
87- if ! found {
88- return nil , nilPath , fmt .Errorf ("setting %q not found in module %q settings" , settingName , mod .ID )
89- }
90- if evaledVal , err := bp .Eval (val ); err == nil {
91- val = evaledVal
92- }
93- values := evaluateAndFlatten (val )
94-
70+ // Determine canonical path for this module.setting in the blueprint.
9571 groupIndex := bp .GroupIndex (group .Name )
9672 path := config .Root .Groups .At (groupIndex ).Modules .At (modIdx ).Settings .Dot (settingName )
9773
98- return values , path , nil
99- }
74+ // If YAML context exists and the path is not present in the user's YAML,
75+ // treat the setting as absent so validators skip it (honoring optional:true).
10076
101- // valuesEqualBlueprint returns true when the provided flattened module values are
102- // equal to the flattened blueprint var with the same name. Comparison is only done
103- // for string values; non-comparable types return false.
104- func valuesEqualBlueprint (bp config.Blueprint , varName string , moduleValues []cty.Value ) bool {
105- if ! bp .Vars .Has (varName ) {
106- return false
107- }
108- bpVal := bp .Vars .Get (varName )
109- if evaledBp , err := bp .Eval (bpVal ); err == nil {
110- bpVal = evaledBp
77+ if bp .YamlCtx != nil {
78+ if _ , ok := bp .YamlCtx .Pos (path ); ! ok {
79+ return nil , nilPath , fmt .Errorf ("setting %q not present in blueprint YAML for module %q" , settingName , mod .ID )
80+ }
11181 }
112- bpVals := evaluateAndFlatten (bpVal )
11382
114- if len (bpVals ) != len (moduleValues ) {
115- return false
116- }
117- for i := range bpVals {
118- if bpVals [i ].Type () != cty .String || moduleValues [i ].Type () != cty .String {
119- return false
120- }
121- if bpVals [i ].AsString () != moduleValues [i ].AsString () {
122- return false
123- }
83+ val , _ := getNestedValue (mod .Settings , settingName )
84+
85+ if evaledVal , err := bp .Eval (val ); err == nil {
86+ val = evaledVal
12487 }
125- return true
88+ values := evaluateAndFlatten (val )
89+
90+ return values , path , nil
12691}
12792
12893// parseStringList normalizes an input that may be a single string, []interface{} or nil into []string.
@@ -179,42 +144,6 @@ func processModuleSettings(bp config.Blueprint, mod config.Module, group config.
179144 return nil
180145}
181146
182- // processVarsAsBlueprint processes a list of names as blueprint vars.
183- func processVarsAsBlueprint (bp config.Blueprint , list []string , optional bool , handler func (Target ) error ) error {
184- for _ , name := range list {
185- values , path , err := getBlueprintValues (bp , name )
186- if err != nil {
187- if optional {
188- continue
189- }
190- // legacy behavior: skip when missing blueprint var even if optional == false
191- continue
192- }
193- if err := handler (Target {Name : name , Values : values , Path : path , IsBlueprint : true }); err != nil {
194- return err
195- }
196- }
197- return nil
198- }
199-
200- // processVarsPreferModuleSetting prefers module.setting for each name; skips if module.setting absent.
201- func processVarsPreferModuleSetting (bp config.Blueprint , mod config.Module , group config.Group , modIdx int , list []string , handler func (Target ) error ) error {
202- for _ , vname := range list {
203- if val , ok := getNestedValue (mod .Settings , vname ); ok {
204- if evaled , err := bp .Eval (val ); err == nil {
205- val = evaled
206- }
207- values := evaluateAndFlatten (val )
208- path := config .Root .Groups .At (bp .GroupIndex (group .Name )).Modules .At (modIdx ).Settings .Dot (vname )
209- if err := handler (Target {Name : vname , Values : values , Path : path , IsBlueprint : false }); err != nil {
210- return err
211- }
212- }
213- // else: skip (do not fallback to blueprint var)
214- }
215- return nil
216- }
217-
218147// IterateRuleTargets resolves vars/settings from a validation rule according to scope and optional semantics,
219148// and calls the provided handler for each resolved Target. The handler may return an error to stop iteration.
220149func IterateRuleTargets (
@@ -226,32 +155,16 @@ func IterateRuleTargets(
226155 handler func (Target ) error ,
227156) error {
228157
158+ // Only support `vars:` in module metadata validators (each treated as a module.setting name).
159+ // `settings:` support has been removed to enforce a single convention.
229160 varsList , _ := parseStringList (rule .Inputs ["vars" ])
230- settingsList , _ := parseStringList (rule .Inputs ["settings" ])
231- scope , _ := rule .Inputs ["scope" ].(string )
232161 optional := true
233162 if v , ok := rule .Inputs ["optional" ]; ok {
234163 if b , ok := v .(bool ); ok {
235164 optional = b
236165 }
237166 }
238167
239- switch scope {
240- case "module" :
241- if len (settingsList ) > 0 {
242- return processModuleSettings (bp , mod , group , modIdx , settingsList , optional , handler )
243- }
244- return processModuleSettings (bp , mod , group , modIdx , varsList , optional , handler )
245-
246- case "blueprint" :
247- return processVarsAsBlueprint (bp , varsList , optional , handler )
248-
249- default :
250- if len (settingsList ) > 0 {
251- if err := processModuleSettings (bp , mod , group , modIdx , settingsList , optional , handler ); err != nil {
252- return err
253- }
254- }
255- return processVarsPreferModuleSetting (bp , mod , group , modIdx , varsList , handler )
256- }
168+ // Interpret each var name as module.settings.<name>
169+ return processModuleSettings (bp , mod , group , modIdx , varsList , optional , handler )
257170}
0 commit comments