1919from structkit .utils import get_current_repo
2020
2121
22+ class TemplateVariableError (ValueError ):
23+ """Raised when a template variable is missing or fails validation."""
24+
25+
2226class TemplateRenderer :
2327 def __init__ (self , config_variables , input_store , non_interactive , mappings = None ):
2428 self .config_variables = config_variables
@@ -147,8 +151,15 @@ def prompt_for_missing_vars(self, content, vars):
147151 self .logger .debug (f"Default values from config: { default_values } " )
148152
149153 for var in undeclared_variables :
154+ conf = schema .get (var , {})
155+ if var in vars :
156+ if conf :
157+ coerced = self ._coerce_and_validate (var , vars [var ], conf )
158+ self .input_store .set_value (var , coerced )
159+ vars [var ] = coerced
160+ continue
161+
150162 if var not in vars :
151- conf = schema .get (var , {})
152163 required = conf .get ('required' , False )
153164 default = self .input_data .get (var , default_values .get (var , "" ))
154165 if self .non_interactive :
@@ -190,7 +201,7 @@ def prompt_for_missing_vars(self, content, vars):
190201 user_input = raw
191202 else :
192203 # For invalid enum input, raise immediately instead of re-prompting
193- raise ValueError ( f"Variable ' { var } ' must be one of { enum } , got: { raw } " )
204+ raise self . _enum_value_error ( var , raw , enum )
194205 else :
195206 if description :
196207 print (f"{ icon } { BOLD } { var } { RESET } : { description } " )
@@ -223,12 +234,12 @@ def _coerce_and_validate(self, name, value, conf):
223234 else :
224235 coerced = '' if value is None else str (value )
225236 except Exception :
226- raise ValueError (f"Variable '{ name } ' could not be coerced to { vtype } (value: { original } )" )
237+ raise TemplateVariableError (f"Variable '{ name } ' could not be coerced to { vtype } (value: { original } )" )
227238
228239 # Enum validation
229240 enum = conf .get ('enum' )
230241 if enum is not None and coerced not in enum :
231- raise ValueError ( f"Variable ' { name } ' must be one of { enum } , got: { coerced } " )
242+ raise self . _enum_value_error ( name , coerced , enum )
232243
233244 # Regex validation (only for strings)
234245 pattern = conf .get ('regex' ) or conf .get ('pattern' )
@@ -255,3 +266,14 @@ def _as_num(x):
255266 raise ValueError (f"Variable '{ name } ' must be <= { maxv } , got { coerced } " )
256267
257268 return coerced
269+
270+ def _enum_value_error (self , name , value , enum ):
271+ allowed_values = ", " .join (str (item ) for item in enum )
272+ if value is None or value == "" :
273+ return TemplateVariableError (
274+ f"Variable '{ name } ' must be set to one of: { allowed_values } . "
275+ f"No value was provided. Pass --vars { name } =<value> or define a default."
276+ )
277+ return TemplateVariableError (
278+ f"Variable '{ name } ' must be one of: { allowed_values } . Got: { value } ."
279+ )
0 commit comments