114 # Include all added configurations |
114 # Include all added configurations |
115 for confml_path in confml_resources: |
115 for confml_path in confml_resources: |
116 if confml_path not in already_included: |
116 if confml_path not in already_included: |
117 print "Including %s in layer root %s" % (confml_path, targetconfig.path) |
117 print "Including %s in layer root %s" % (confml_path, targetconfig.path) |
118 targetconfig.include_configuration(confml_path) |
118 targetconfig.include_configuration(confml_path) |
|
119 |
|
120 merge_metadata(sourceconfig, targetconfig) |
119 |
121 |
120 def find_layers_to_merge(layer_indices, rename, sourceconfig, targetconfig): |
122 def find_layers_to_merge(layer_indices, rename, sourceconfig, targetconfig): |
121 """ |
123 """ |
122 Return a list of layers to merge. |
124 Return a list of layers to merge. |
123 |
125 |
148 return result |
150 return result |
149 |
151 |
150 def sort_mergeconfigs(layers, sourceconfigs): |
152 def sort_mergeconfigs(layers, sourceconfigs): |
151 """ |
153 """ |
152 Return a correctly sorted list of source configuration layers. |
154 Return a correctly sorted list of source configuration layers. |
153 @param layers: List of the indices of the layers to merg. Can be None, in |
155 @param layers: List of the indices of the layers to merge. Can be None, in |
154 which case all layers are returned. |
156 which case all layers are returned. |
155 @param sourceconfigs: List of all configuration layer root paths in the |
157 @param sourceconfigs: List of all configuration layer root paths in the |
156 source project. |
158 source project. |
157 @return: List of configuration layer root paths. |
159 @return: List of configuration layer root paths. |
158 """ |
160 """ |
160 for layer in layers: |
162 for layer in layers: |
161 sorted_configs[layer]=sourceconfigs[layer] |
163 sorted_configs[layer]=sourceconfigs[layer] |
162 sorted_configs = filter(lambda x: x != None, sorted_configs) |
164 sorted_configs = filter(lambda x: x != None, sorted_configs) |
163 return sorted_configs |
165 return sorted_configs |
164 |
166 |
|
167 def merge_metadata(source_config, target_config): |
|
168 # Merge (well, replace) configuration meta-data |
|
169 if source_config.meta: |
|
170 target_config.meta = source_config.meta._clone(recursion=True) |
|
171 else: |
|
172 del target_config.meta |
|
173 |
|
174 def get_active_root_if_necessary(project, configuration, name): |
|
175 if configuration: |
|
176 return configuration |
|
177 else: |
|
178 active_root = project.get_storage().get_active_configuration() |
|
179 if active_root == "": |
|
180 raise MergeFailedException("No %s configuration given and the project does not have an active root" % name) |
|
181 else: |
|
182 return active_root |
|
183 |
165 def merge_config_root_to_config_root(source_project, target_project, |
184 def merge_config_root_to_config_root(source_project, target_project, |
166 source_config, target_config, |
185 source_config, target_config, |
167 layer_indices, rename, |
186 layer_finder_func, |
168 merge_policy): |
187 merge_policy): |
169 """ |
188 """ |
170 Merge the source configuration root to the target configuration root. |
189 Merge the source configuration root to the target configuration root. |
171 @param layer_indices: List of layer indices to specify the layers |
190 |
172 to merge, can be None. |
191 @param source_config: Name of the source configuration. |
173 @param rename: If True, the merged layers are renamed based on the |
192 @param target_config: Name of the target configuration. |
174 name of the target configuration root. |
193 @param layer_finder_func: Function for finding the layers that are to be |
|
194 merged. It should take source and target configuration objects as |
|
195 arguments and return a list of tuples (layer_root, target_layer_root), |
|
196 where layer_root is the path to the layer root in the source |
|
197 configuration and target_layer_root the one in the target |
|
198 configuration. |
175 @param merge_policy: The used merge policy. |
199 @param merge_policy: The used merge policy. |
176 """ |
200 """ |
177 |
|
178 def get_active_root_if_necessary(project, configuration, name): |
|
179 if configuration: |
|
180 return configuration |
|
181 else: |
|
182 active_root = project.get_storage().get_active_configuration() |
|
183 if active_root == "": |
|
184 raise MergeFailedException("No %s configuration given and the project does not have an active root" % name) |
|
185 else: |
|
186 return active_root |
|
187 |
|
188 target_root = get_active_root_if_necessary(target_project, target_config, 'target') |
201 target_root = get_active_root_if_necessary(target_project, target_config, 'target') |
189 source_root = get_active_root_if_necessary(source_project, source_config, 'source') |
202 source_root = get_active_root_if_necessary(source_project, source_config, 'source') |
190 |
203 |
191 print "Target config: %s" % target_root |
204 print "Target config: %s" % target_root |
192 print "Source config: %s" % source_root |
205 print "Source config: %s" % source_root |
212 else: |
225 else: |
213 logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path)) |
226 logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path)) |
214 target_config.create_configuration(sourcelayer_path) |
227 target_config.create_configuration(sourcelayer_path) |
215 |
228 |
216 # Collect a correctly sorted list of all layer paths to merge |
229 # Collect a correctly sorted list of all layer paths to merge |
217 layers_to_merge = find_layers_to_merge( |
230 layers_to_merge = layer_finder_func(source_config, target_config) |
218 layer_indices = layer_indices, |
|
219 rename = rename, |
|
220 sourceconfig = source_config, |
|
221 targetconfig = target_config) |
|
222 |
231 |
223 print "Merging %d layer(s)..." % len(layers_to_merge) |
232 print "Merging %d layer(s)..." % len(layers_to_merge) |
224 |
233 |
225 # Merge the layers |
234 # Merge the layers |
226 for source_path, target_path in layers_to_merge: |
235 for source_path, target_path in layers_to_merge: |
241 except exceptions.NotFound: |
250 except exceptions.NotFound: |
242 logger.info('Creating new layer configuration %s' % (target_path)) |
251 logger.info('Creating new layer configuration %s' % (target_path)) |
243 target_layer = target_config.create_configuration(target_path) |
252 target_layer = target_config.create_configuration(target_path) |
244 |
253 |
245 merge_configuration_layer(source_layer, target_layer, merge_policy) |
254 merge_configuration_layer(source_layer, target_layer, merge_policy) |
246 |
255 |
247 |
256 merge_metadata(source_config, target_config) |
248 |
257 |
249 def main(argv=sys.argv): |
258 def main(argv=sys.argv): |
|
259 """ Merge a configuration/layer to the project. """ |
250 parser = OptionParser(version="%%prog %s" % VERSION) |
260 parser = OptionParser(version="%%prog %s" % VERSION) |
251 |
261 |
252 parser.add_options(cone_common.COMMON_OPTIONS) |
262 parser.add_options(cone_common.COMMON_OPTIONS) |
253 |
263 |
254 parser.add_option("-c", "--configuration",\ |
264 parser.add_option("-c", "--configuration",\ |
382 # Merging a configuration root into a configuration root |
392 # Merging a configuration root into a configuration root |
383 |
393 |
384 if options.all: layer_indices = None |
394 if options.all: layer_indices = None |
385 else: layer_indices = utils.distinct_array(options.layers) |
395 else: layer_indices = utils.distinct_array(options.layers) |
386 |
396 |
|
397 def find_layers(source_config, target_config): |
|
398 return find_layers_to_merge( |
|
399 layer_indices = layer_indices, |
|
400 rename = options.rename, |
|
401 sourceconfig = source_config, |
|
402 targetconfig = target_config) |
|
403 |
387 merge_config_root_to_config_root( |
404 merge_config_root_to_config_root( |
388 source_project = source_project, |
405 source_project = source_project, |
389 target_project = target_project, |
406 target_project = target_project, |
390 source_config = options.sourceconfiguration, |
407 source_config = options.sourceconfiguration, |
391 target_config = options.configuration, |
408 target_config = options.configuration, |
392 layer_indices = layer_indices, |
409 layer_finder_func = find_layers, |
393 rename = options.rename, |
410 merge_policy = options.merge_policy) |
394 merge_policy = options.merge_policy) |
|
395 except MergeFailedException, e: |
411 except MergeFailedException, e: |
396 print "Could not merge: %s" % e |
412 print "Could not merge: %s" % e |
397 sys.exit(2) |
413 sys.exit(2) |
398 else: |
414 else: |
399 # Merge successful, so save the target configuration and project |
415 # Merge successful, so save the target configuration and project |