configurationengine/source/scripts/conesub_merge.py
author terytkon
Sat, 06 Nov 2010 16:59:14 +0200
changeset 9 63964d875993
parent 5 d2c80f5cab53
permissions -rw-r--r--
Merge changes to system model generator to SF tip.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     1
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     2
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     3
# All rights reserved.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     4
# This component and the accompanying materials are made available
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     5
# under the terms of "Eclipse Public License v1.0"
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     6
# which accompanies this distribution, and is available
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     7
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     8
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
     9
# Initial Contributors:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    10
# Nokia Corporation - initial contribution.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    11
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    12
# Contributors:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    13
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    14
# Description: 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    15
#
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    16
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    17
import sys
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    18
import logging
5
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
    19
import re
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    20
from optparse import OptionParser, OptionGroup
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    21
import cone_common
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    22
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    23
from cone.public import api, utils, exceptions
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    24
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    25
VERSION = '1.0'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    26
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    27
logger    = logging.getLogger('cone')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    28
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    29
class MergeFailedException(Exception):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    30
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    31
    Exception raised if the merge failed for some reason.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    32
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    33
    pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    34
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    35
class MergePolicy(object):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    36
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    37
    Merge policy constants.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    38
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    39
    #: Replace/add files from the source layer into the
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    40
    #: target layer, preserving files in the target layer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    41
    #: that do not exist in the source layer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    42
    REPLACE_ADD = 'replace-add'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    43
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    44
    #: Overwrite the entire target layer, so that it contains
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    45
    #: only the contents of the source layer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    46
    OVERWRITE_LAYER = 'overwrite-layer'
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    47
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    48
    ALL = (REPLACE_ADD, OVERWRITE_LAYER)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    49
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    50
    @classmethod
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    51
    def is_valid(cls, policy):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    52
        return policy in cls.ALL
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    53
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    54
def get_new_layer_name(oldname,rootconfig):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    55
    newpath = utils.resourceref.get_path(oldname)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    56
    newpath+= "_" + utils.resourceref.remove_ext(utils.resourceref.get_filename(rootconfig))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    57
    newpath+= "/" + utils.resourceref.get_filename(oldname)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    58
    return newpath
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    59
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    60
def merge_configuration_layer(sourceconfig, targetconfig, merge_policy):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    61
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    62
    Merge the contents of the source layer into the target layer.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    63
    @param sourceconfig: Source layer root configuration object.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    64
    @param targetconfig: Target layer root configuration object.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    65
    @param merge_policy: The used layer merge policy.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    66
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    67
    # If policy tells to entirely overwrite the layer, remove all
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    68
    # resources from the layer first
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    69
    if merge_policy == MergePolicy.OVERWRITE_LAYER:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    70
        # Remove configurations from the layer root
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    71
        confs = targetconfig.list_configurations()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    72
        for conf in confs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    73
            targetconfig.remove_configuration(conf)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    74
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    75
        # Remove all related resources
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    76
        layerobj = targetconfig.get_layer()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    77
        # Round one: remove all files
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    78
        resources = layerobj.list_all_related(empty_folders=False)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    79
        for res in resources: layerobj.delete_resource(res)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    80
        # Round two: remove any remaining empty directories
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    81
        resources = layerobj.list_all_related(empty_folders=True)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    82
        for res in resources: layerobj.delete_folder(res)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    83
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    84
    # Find all ConfML files
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    85
    confml_resources = sourceconfig.list_configurations()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    86
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    87
    # Find all other related files and folders (content/, doc/ etc.)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    88
    layerobj = sourceconfig.get_layer()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    89
    targetobj = targetconfig.get_layer()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    90
    other_resources = layerobj.list_all_related(empty_folders=True)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    91
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    92
    # Copy the resources to the target configuration
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    93
    for res_path in confml_resources + other_resources:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    94
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    95
            rres = layerobj.open_resource(res_path,"rb")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    96
            wres = targetobj.open_resource(res_path,"wb")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    97
            print "Copying %s" % rres.path
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    98
            logger.info('Copying layer resource %s to %s' % (rres.path, wres.path))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
    99
            wres.write(rres.read())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   100
            wres.close()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   101
            rres.close()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   102
        except exceptions.NotResource:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   103
            # If it isn't a resource (file), it's a folder
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   104
            targetobj.create_folder(res_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   105
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   106
    # Remove all configurations from the target layer root
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   107
    already_included = targetconfig.list_configurations()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   108
    for confml_path in already_included:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   109
        targetconfig.remove_configuration(confml_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   110
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   111
    # Include them back
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   112
    for confml_path in already_included:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   113
        targetconfig.include_configuration(confml_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   114
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   115
    # Include all added configurations
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   116
    for confml_path in confml_resources:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   117
        if confml_path not in already_included:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   118
            print "Including %s in layer root %s" % (confml_path, targetconfig.path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   119
            targetconfig.include_configuration(confml_path)
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   120
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   121
    merge_metadata(sourceconfig, targetconfig)
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   122
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   123
def find_layers_to_merge(layer_indices, rename, sourceconfig, targetconfig):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   124
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   125
    Return a list of layers to merge.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   126
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   127
    @param layer_indices: List of layer indices to merge, can also be
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   128
        None to indicate that all layers are to be merged.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   129
    @param rename: True if the layers should be renamed in the target
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   130
        config, False if not.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   131
    @return: A list of tuples (layer_root, target_layer_root), where
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   132
        layer_root is the path to the layer root in the source
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   133
        configuration and target_layer_root the one in the target
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   134
        configuration.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   135
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   136
    # Get a list of all configurations to merge
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   137
    if layer_indices is None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   138
        mergeconfigs = sourceconfig.list_configurations()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   139
    else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   140
        mergeconfigs = sort_mergeconfigs(layer_indices, sourceconfig.list_configurations())
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   141
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   142
    result = []
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   143
    if rename:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   144
        for source_path in mergeconfigs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   145
            target_path = get_new_layer_name(source_path, targetconfig.path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   146
            result.append((source_path, target_path))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   147
    else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   148
        for source_path in mergeconfigs:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   149
            result.append((source_path, source_path))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   150
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   151
    return result
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   152
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   153
def sort_mergeconfigs(layers, sourceconfigs):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   154
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   155
    Return a correctly sorted list of source configuration layers.
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   156
    @param layers: List of the indices of the layers to merge. Can be None, in
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   157
        which case all layers are returned.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   158
    @param sourceconfigs: List of all configuration layer root paths in the
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   159
        source project.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   160
    @return: List of configuration layer root paths.
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   161
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   162
    sorted_configs = [None for _ in xrange(len(sourceconfigs))]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   163
    for layer in layers:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   164
        sorted_configs[layer]=sourceconfigs[layer]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   165
    sorted_configs = filter(lambda x: x != None, sorted_configs)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   166
    return sorted_configs
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   167
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   168
def merge_metadata(source_config, target_config):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   169
    # Merge (well, replace) configuration meta-data
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   170
    if source_config.meta:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   171
        target_config.meta = source_config.meta._clone(recursion=True)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   172
    else:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   173
        del target_config.meta
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   174
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   175
def get_active_root_if_necessary(project, configuration, name):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   176
    if configuration:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   177
        return configuration
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   178
    else:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   179
        active_root = project.get_storage().get_active_configuration()
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   180
        if active_root == "":
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   181
            raise MergeFailedException("No %s configuration given and the project does not have an active root" % name)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   182
        else:
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   183
            return active_root
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   184
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   185
def merge_config_root_to_config_root(source_project, target_project,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   186
                                     source_config, target_config,
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   187
                                     layer_finder_func,
5
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   188
                                     merge_policy,
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   189
                                     find_pattern=None):
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   190
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   191
    Merge the source configuration root to the target configuration root.
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   192
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   193
    @param source_config: Name of the source configuration.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   194
    @param target_config: Name of the target configuration.
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   195
    @param layer_finder_func: Function for finding the layers that are to be
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   196
        merged. It should take source and target configuration objects as
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   197
        arguments and return a list of tuples (layer_root, target_layer_root),
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   198
        where layer_root is the path to the layer root in the source
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   199
        configuration and target_layer_root the one in the target
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   200
        configuration.
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   201
    @param merge_policy: The used merge policy.
5
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   202
    @param find_pattern: Layers found with this pattern will be used from 
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   203
        the source configuration. If the configuration project has a root
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   204
        configuration which has the same ctr code as the source config,
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   205
        the other layers are taken from the found root config.
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   206
    """
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   207
    target_root = get_active_root_if_necessary(target_project, target_config, 'target')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   208
    source_root = get_active_root_if_necessary(source_project, source_config, 'source')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   209
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   210
    print "Target config:  %s" % target_root
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   211
    print "Source config:  %s" % source_root
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   212
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   213
    try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   214
        source_config = source_project.get_configuration(source_root)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   215
    except exceptions.NotFound:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   216
        raise MergeFailedException("Configuration root '%s' not found in source project" % source_root)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   217
    
5
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   218
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   219
    def get_matching_config_in_target_project(target_prj, src_config):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   220
        
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   221
        def get_based_on_ctr(meta):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   222
            if meta:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   223
                for prop in meta.array:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   224
                    if 'name' in prop.attrs and 'value' in prop.attrs:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   225
                        name = prop.attrs['name']
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   226
                        if name == 'based_on_ctr':
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   227
                            ctr_codes = prop.attrs['value'].split(',')
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   228
                            return [ctr.strip() for ctr in ctr_codes]
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   229
            return []
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   230
        
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   231
        root_configs = target_prj.list_configurations()
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   232
        based_on_ctr_s = sorted(get_based_on_ctr(src_config.meta))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   233
        for c in root_configs:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   234
            based_on_ctr_c = sorted(get_based_on_ctr(target_prj.get_configuration(c).meta))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   235
            if based_on_ctr_c and based_on_ctr_s:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   236
                # if only one ctr code specified in source config, try to find root config that has that code
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   237
                # (and maybe some others)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   238
                if len(based_on_ctr_s) == 1:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   239
                    if based_on_ctr_s[0] in based_on_ctr_c:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   240
                        return c
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   241
                # otherwise try to find a config that has all the same ctr codes
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   242
                elif based_on_ctr_c == based_on_ctr_s:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   243
                    return c
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   244
        return None
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   245
        
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   246
        
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   247
    # Create or get the target configuration root
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   248
    try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   249
        target_config = target_project.get_configuration(target_root)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   250
    except exceptions.NotFound:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   251
        logger.info('Creating new root configuration %s' % (target_config))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   252
        target_config  = target_project.create_configuration(target_config)
5
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   253
        # try to find a matching configuration in target project (based_on_ctr)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   254
        cmp_config_in_target_prj = get_matching_config_in_target_project(target_project, source_config)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   255
        #cmp_config_in_target_prj = None
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   256
        if cmp_config_in_target_prj:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   257
            logger.info('Found root %s with the same ctr code(s) from target project.' % cmp_config_in_target_prj)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   258
            cmp_configurations = target_project.get_configuration(cmp_config_in_target_prj).list_configurations()
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   259
            p = re.compile(find_pattern)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   260
            for cmp_layer_path in cmp_configurations:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   261
                if not p.search(cmp_layer_path):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   262
                    if target_config.get_storage().is_resource(cmp_layer_path):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   263
                        logger.info('Including layer %s to root %s' % (cmp_layer_path, target_config.path))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   264
                        target_config.include_configuration(cmp_layer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   265
                    else:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   266
                        logger.info('Creating new layer %s to root %s' % (cmp_layer_path, target_config.path))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   267
                        target_config.create_configuration(cmp_layer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   268
        
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   269
            for sourcelayer_path in source_config.list_configurations():
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   270
                sourcelayer = source_config.get_configuration(sourcelayer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   271
                sourcelayer_path = sourcelayer.path
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   272
                if p.search(sourcelayer_path):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   273
                    if target_config.get_storage().is_resource(sourcelayer.path):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   274
                        logger.info('Including layer %s to root %s' % (sourcelayer_path, target_config.path))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   275
                        target_config.include_configuration(sourcelayer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   276
                    else:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   277
                        logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   278
                        target_config.create_configuration(sourcelayer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   279
        else:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   280
            for sourcelayer_path in source_config.list_configurations():
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   281
                sourcelayer = source_config.get_configuration(sourcelayer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   282
                sourcelayer_path = sourcelayer.path
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   283
                if target_config.get_storage().is_resource(sourcelayer.path):
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   284
                    logger.info('Including layer %s to root %s' % (sourcelayer_path, target_config.path))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   285
                    target_config.include_configuration(sourcelayer_path)
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   286
                else:
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   287
                    logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path))
d2c80f5cab53 Updated to version 1.2.14
m2lahtel
parents: 3
diff changeset
   288
                    target_config.create_configuration(sourcelayer_path)
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   289
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   290
    # Collect a correctly sorted list of all layer paths to merge
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   291
    layers_to_merge = layer_finder_func(source_config, target_config)
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   292
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   293
    print "Merging %d layer(s)..." % len(layers_to_merge)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   294
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   295
    # Merge the layers
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   296
    for source_path, target_path in layers_to_merge:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   297
        print "Merging %s -> %s" % (source_path, target_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   298
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   299
        source_layer = source_project.get_configuration(source_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   300
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   301
        if source_path != target_path:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   302
            try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   303
                target_config.remove_configuration(source_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   304
            except exceptions.NotFound:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   305
                pass
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   306
            target_config.create_configuration(target_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   307
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   308
        # Get or create the target configuration layer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   309
        try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   310
            target_layer = target_config.get_configuration(target_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   311
        except exceptions.NotFound:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   312
            logger.info('Creating new layer configuration %s' % (target_path))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   313
            target_layer = target_config.create_configuration(target_path)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   314
        
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   315
        merge_configuration_layer(source_layer, target_layer, merge_policy)
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   316
    
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   317
    merge_metadata(source_config, target_config)
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   318
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   319
def main(argv=sys.argv):
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   320
    """ Merge a configuration/layer to the project. """
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   321
    parser = OptionParser(version="%%prog %s" % VERSION)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   322
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   323
    parser.add_options(cone_common.COMMON_OPTIONS)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   324
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   325
    parser.add_option("-c", "--configuration",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   326
                        dest="configuration",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   327
                        help="defines the name of the target configuration for the action",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   328
                        metavar="CONFIG")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   329
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   330
    parser.add_option("-p", "--project",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   331
                       dest="project",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   332
                       help="defines the location of current project. Default is the current working directory.",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   333
                       default=".",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   334
                       metavar="STORAGE")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   335
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   336
    group = OptionGroup(parser, 'Merge options',
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   337
                        'The merge functionality is meant to merge configurations/layers '
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   338
                        'from a remote project (defined with -r) to the current project (defined with -p). '
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   339
                        'Default value for the current project is the currently working directory. '
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   340
                        'A project can be either a folder or a cpf/zip file. There are two ways to '
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   341
                        'use merge: merge configuration roots (multiple layers), or specific layers. '
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   342
                        'See the ConE documentation for details and examples.')
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   343
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   344
    group.add_option("-r", "--remote",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   345
                   dest="remote",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   346
                   help="defines the location of remote storage",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   347
                   metavar="STORAGE")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   348
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   349
    group.add_option("-s", "--sourceconfiguration",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   350
                        dest="sourceconfiguration",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   351
                        help="defines the name of the remote configuration inside the remote storage for the merge action. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   352
                             "Default is the active root of the remote project.",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   353
                        metavar="CONFIG")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   354
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   355
    group.add_option("--sourcelayer",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   356
                     help="Defines a specific layer to use as the layer to merge "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   357
                          "from the remote project. Must be the layer root (ConfML file)."\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   358
                          "For example: --sourcelayer assets/somelayer/root.confml",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   359
                     metavar="LAYER_ROOT",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   360
                     default=None)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   361
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   362
    group.add_option("--targetlayer",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   363
                     help="Defines a specific layer (root) to use as the layer to merge "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   364
                          "into the target project. Must be the layer root (ConfML file)."\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   365
                          "For example: --targetlayer assets/somelayer/root.confml",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   366
                     metavar="LAYER_ROOT",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   367
                     default=None)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   368
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   369
    group.add_option("--rename",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   370
                        action="store_true", 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   371
                        dest="rename",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   372
                        help="defines that the merged layers need to be renamed",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   373
                        default=False)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   374
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   375
    group.add_option("--all",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   376
                        action="store_true", 
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   377
                        dest="all",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   378
                        help="Defines that the entire configuration (all layers) needs to be merged. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   379
                             "This has no effect when merging layers directly using --sourcelayer and --targetlayer.",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   380
                        default=False)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   381
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   382
    group.add_option("-l", "--layer",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   383
                   dest="layers",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   384
                   type="int",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   385
                   action="append",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   386
                   help="Define the layers of the source configuration that are included to merge action. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   387
                        "The layer operation can be used several times in a single command. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   388
                        "Note that this can only be used when merging configuration roots, not "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   389
                        "specific layers using --sourcelayer and --targetlayer. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   390
                        "Example -l -1 --layer=-2, which would append a layers -1 and -2 to the layers => layers = -1,-2",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   391
                   metavar="LAYERS",\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   392
                   default=None)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   393
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   394
    group.add_option("--merge-policy",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   395
                     help="Specifies the merge policy to use when merging layers. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   396
                          "Possible values:                                                         "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   397
                          "replace-add - Add/replace files from source layer, but leave other files in the target as they are. "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   398
                          "                                                         "\
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   399
                          "overwrite-layer - Overwrite the entire layer (remove all previous content).",
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   400
                     default=MergePolicy.REPLACE_ADD)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   401
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   402
    parser.add_option_group(group)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   403
    (options, _) = parser.parse_args(argv)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   404
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   405
    cone_common.handle_common_options(options)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   406
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   407
    # Check the passed options
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   408
    if not MergePolicy.is_valid(options.merge_policy):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   409
        parser.error("Invalid merge policy: %s\nMust be one of %s" % (options.merge_policy, '\n'.join(MergePolicy.ALL)))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   410
    if not options.remote: parser.error("Remote project must be given")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   411
    if options.layers and (options.sourcelayer or options.targetlayer):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   412
        parser.error("Specifying layer indices using --layer is not supported when using --sourcelayer or --targetlayer!")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   413
    if options.sourcelayer and not options.targetlayer:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   414
        parser.error("Merging a layer into a configuration is not supported at the moment!")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   415
    if options.sourcelayer and not options.sourcelayer.lower().endswith('.confml'):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   416
        parser.error("Source layer root should be a .confml file")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   417
    if options.targetlayer and not options.targetlayer.lower().endswith('.confml'):
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   418
        parser.error("Target layer root should be a .confml file")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   419
    if not options.sourcelayer and options.targetlayer:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   420
        parser.error("Cannot merge a configuration into a layer!")
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   421
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   422
    # If layers for configuration root merging are not specifically given,
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   423
    # the default is the last layer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   424
    if options.layers is None:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   425
        options.layers = [-1]
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   426
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   427
    target_project = api.Project(api.Storage.open(options.project,"a", username=options.username, password=options.password))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   428
    source_project = api.Project(api.Storage.open(options.remote,"r", username=options.username, password=options.password))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   429
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   430
    print "Target project: %s" % options.project
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   431
    print "Source project: %s" % options.remote
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   432
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   433
    target_config = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   434
    try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   435
        if options.sourcelayer and options.targetlayer:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   436
            print "Target layer:   %s" % options.targetlayer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   437
            print "Source layer:   %s" % options.sourcelayer
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   438
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   439
            try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   440
                source_config = source_project.get_configuration(options.sourcelayer)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   441
            except exceptions.NotFound:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   442
                raise MergeFailedException("Layer root '%s' not found in source project" % options.sourcelayer)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   443
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   444
            try:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   445
                target_config = target_project.get_configuration(options.targetlayer)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   446
            except exceptions.NotFound:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   447
                logger.info('Creating new layer %s' % (options.targetlayer))
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   448
                target_config  = target_project.create_configuration(options.targetlayer)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   449
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   450
            print "Merging layers..."
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   451
            merge_configuration_layer(source_config, target_config, options.merge_policy)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   452
        else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   453
            # Merging a configuration root into a configuration root
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   454
            
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   455
            if options.all: layer_indices = None
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   456
            else:           layer_indices = utils.distinct_array(options.layers)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   457
            
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   458
            def find_layers(source_config, target_config):
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   459
                return find_layers_to_merge(
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   460
                    layer_indices   = layer_indices,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   461
                    rename          = options.rename,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   462
                    sourceconfig    = source_config,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   463
                    targetconfig    = target_config)
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   464
            
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   465
            merge_config_root_to_config_root(
3
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   466
                source_project      = source_project,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   467
                target_project      = target_project,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   468
                source_config       = options.sourceconfiguration,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   469
                target_config       = options.configuration,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   470
                layer_finder_func   = find_layers,
e7e0ae78773e ConE 1.2.11 release
m2lahtel
parents: 0
diff changeset
   471
                merge_policy        = options.merge_policy)
0
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   472
    except MergeFailedException, e:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   473
        print "Could not merge: %s" % e
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   474
        sys.exit(2)
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   475
    else:
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   476
        # Merge successful, so save the target configuration and project
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   477
        # to persist the changes
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   478
        if target_config: target_config.save()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   479
        target_project.save()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   480
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   481
    target_project.close()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   482
    source_project.close()
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   483
    
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   484
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   485
if __name__ == "__main__":
2e8eeb919028 Adding EPL version of configurationengine.
terytkon
parents:
diff changeset
   486
    main()