2828class ConfigProcessor (object ):
2929
3030 def process (self , cwd = None , path = None , filters = (), exclude_keys = (), enclosing_key = None , remove_enclosing_key = None , output_format = "yaml" ,
31- print_data = False , output_file = None , skip_interpolations = False , skip_interpolation_validation = False , skip_secrets = False , multi_line_string = False ):
31+ print_data = False , output_file = None , skip_interpolations = False , skip_interpolation_validation = False , skip_secrets = False , multi_line_string = False ,
32+ type_strategies = [(list , ["append" ]), (dict , ["merge" ])], fallback_strategies = ["override" ], type_conflict_strategies = ["override" ]):
3233
3334 path = self .get_relative_path (path )
3435
@@ -41,7 +42,7 @@ def process(self, cwd=None, path=None, filters=(), exclude_keys=(), enclosing_ke
4142 if cwd is None :
4243 cwd = os .getcwd ()
4344
44- generator = ConfigGenerator (cwd , path , multi_line_string )
45+ generator = ConfigGenerator (cwd , path , multi_line_string , type_strategies , fallback_strategies , type_conflict_strategies )
4546 generator .generate_hierarchy ()
4647 generator .process_hierarchy ()
4748
@@ -120,13 +121,15 @@ class ConfigGenerator(object):
120121 will contain merged data on each layer.
121122 """
122123
123- def __init__ (self , cwd , path , multi_line_string ):
124+ def __init__ (self , cwd , path , multi_line_string , type_strategies , fallback_strategies , type_conflict_strategies ):
124125 self .cwd = cwd
125126 self .path = path
126127 self .hierarchy = self .generate_hierarchy ()
127128 self .generated_data = OrderedDict ()
128129 self .interpolation_validator = InterpolationValidator ()
129-
130+ self .type_strategies = type_strategies
131+ self .fallback_strategies = fallback_strategies
132+ self .type_conflict_strategies = type_conflict_strategies
130133 if multi_line_string is True :
131134 yaml .representer .BaseRepresenter .represent_scalar = ConfigGenerator .custom_represent_scalar
132135
@@ -176,22 +179,22 @@ def yaml_get_content(yaml_file):
176179 return content if content else {}
177180
178181 @staticmethod
179- def merge_value (reference , new_value ):
180- merger = Merger ([( list , [ "append" ]), ( dict , [ "merge" ])], [ "override" ], [ "override" ] )
182+ def merge_value (reference , new_value , type_strategies , fallback_strategies , type_conflict_strategies ):
183+ merger = Merger (type_strategies , fallback_strategies , type_conflict_strategies )
181184 if isinstance (new_value , (list , set , dict )):
182185 new_reference = merger .merge (reference , new_value )
183186 else :
184187 raise TypeError ("Cannot handle merge_value of type {}" .format (type (new_value )))
185188 return new_reference
186189
187190 @staticmethod
188- def merge_yamls (values , yaml_content ):
191+ def merge_yamls (values , yaml_content , type_strategies , fallback_strategies , type_conflict_strategies ):
189192 for key , value in iteritems (yaml_content ):
190193 if key in values and type (values [key ]) != type (value ):
191194 raise Exception ("Failed to merge key '{}', because of mismatch in type: {} vs {}"
192195 .format (key , type (values [key ]), type (value )))
193196 if key in values and not isinstance (value , primitive_types ):
194- values [key ] = ConfigGenerator .merge_value (values [key ], value )
197+ values [key ] = ConfigGenerator .merge_value (values [key ], value , type_strategies , fallback_strategies , type_conflict_strategies )
195198 else :
196199 values [key ] = value
197200
@@ -224,7 +227,7 @@ def process_hierarchy(self):
224227 for yaml_files in self .hierarchy :
225228 for yaml_file in yaml_files :
226229 yaml_content = self .yaml_get_content (yaml_file )
227- self .merge_yamls (merged_values , yaml_content )
230+ self .merge_yamls (merged_values , yaml_content , self . type_strategies , self . fallback_strategies , self . type_conflict_strategies )
228231 self .resolve_simple_interpolations (merged_values , yaml_file )
229232 self .generated_data = merged_values
230233
0 commit comments