@@ -675,34 +675,96 @@ def dcnm_get_template_details(module, version, name):
675675
676676
677677def dcnm_update_arg_specs (mspec , arg_specs ):
678+ """
679+ Update argument specifications based on module specification dependencies.
680+
681+ ## Summary
682+
683+ Evaluates boolean dependency expressions to determine if parameters are required.
684+
685+ ## Raises
686+
687+ - None
688+ """
689+ comparison_ops = {
690+ "==" : lambda a , b : a == b ,
691+ "!=" : lambda a , b : a != b ,
692+ ">" : lambda a , b : a > b ,
693+ "<" : lambda a , b : a < b ,
694+ ">=" : lambda a , b : a >= b ,
695+ "<=" : lambda a , b : a <= b ,
696+ }
678697
679698 pat = re .compile (r"(\w+)\s*([<>=!]{1,2})\s*(\w+)" )
680699
681700 for as_key in arg_specs :
682-
683701 item = arg_specs [as_key ]
684702
685703 if item ["required" ] not in [True , False ]:
704+ # Parse the dependency expression
705+ expr = item ["required" ]
706+
707+ # Normalize true/false to boolean values
708+ expr = expr .replace ("true" , "True" ).replace ("false" , "False" )
709+
710+ # Split by && and || operators, tracking which operator was used
711+ parts = []
712+ operators = []
713+
714+ # Split while preserving operator information
715+ if "&&" in expr and "||" in expr :
716+ # Handle mixed operators (would need more complex logic)
717+ # For now, fall back to simple evaluation
718+ pass
719+ elif "&&" in expr :
720+ parts = [p .strip () for p in expr .split ("&&" )]
721+ operators = ["and" ] * (len (parts ) - 1 )
722+ elif "||" in expr :
723+ parts = [p .strip () for p in expr .split ("||" )]
724+ operators = ["or" ] * (len (parts ) - 1 )
725+ else :
726+ parts = [expr .strip ()]
727+
728+ # Evaluate each part
729+ results = []
730+ for part in parts :
731+ part = part .strip ("() " )
732+ match = pat .search (part )
733+
734+ if match :
735+ key = match [1 ]
736+ op = match [2 ]
737+ value_str = match [3 ]
738+
739+ # Convert string "True"/"False" to boolean
740+ if value_str in ("True" , "False" ):
741+ expected_value = value_str == "True"
742+ else :
743+ expected_value = value_str
744+
745+ # Get actual value from mspec
746+ actual_value = mspec .get (key ) if mspec else None
686747
687- # item is a dependent variable. item["required"] includes a string which specifies
688- # the variables it depends on. Parse the string and check the mspec to
689- # derive if required should be True or False.
690- dvars = re .split (r"&& | \|\|" , item ["required" ])
691-
692- for elem in dvars :
693- match = pat .search (elem )
694- key = match [1 ].replace ("(" , "" ).replace (")" , "" )
695-
696- if mspec and mspec .get (key , None ) == bool (match .group (3 )):
697- # Given key is included in the mspec. So mark this a 'true' in the aspec. Final 'eval'
698- # on the item["required"] will yield the desired bool value.
699- item ["required" ] = item ["required" ].replace ("true" , "True" )
700- item ["required" ] = item ["required" ].replace ("false" , "False" )
701- item ["required" ] = eval (item ["required" ].replace (key , "True" ))
748+ # Evaluate the comparison
749+ if op in comparison_ops :
750+ results .append (comparison_ops [op ](actual_value , expected_value ))
751+ else :
752+ results .append (False )
702753 else :
703- item ["required" ] = item ["required" ].replace ("true" , "True" )
704- item ["required" ] = item ["required" ].replace ("false" , "False" )
705- item ["required" ] = eval (item ["required" ].replace (key , "False" ))
754+ # Direct True/False value
755+ results .append (part == "True" )
756+
757+ # Combine results based on operators
758+ if not operators :
759+ item ["required" ] = results [0 ] if results else False
760+ else :
761+ final_result = results [0 ]
762+ for i , op in enumerate (operators ):
763+ if op == "and" :
764+ final_result = final_result and results [i + 1 ]
765+ else : # "or"
766+ final_result = final_result or results [i + 1 ]
767+ item ["required" ] = final_result
706768
707769
708770def dcnm_get_template_specs (module , name , version ):
0 commit comments