# HG changeset patch
# User m2lahtel
# Date 1287668213 -10800
# Node ID d2c80f5cab5334685a088f13224cc68f4028c05a
# Parent 0951727b8815afc65863570d9360d0d44a8a13d6
Updated to version 1.2.14
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/RELEASE.TXT
--- a/configurationengine/RELEASE.TXT Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/RELEASE.TXT Thu Oct 21 16:36:53 2010 +0300
@@ -1,12 +1,26 @@
ConE - the Configuration Engine
- Version cone-1.2.13
- Release Notes, 06.09.2010
+ Version cone-1.2.14
+ Release Notes, 19.10.2010
Release notes:
=============
+== Version Cone-1.2.14 ==
+* Stories
+ * #1129 Remove lxml and jinja from SF, because they are under GPL witch is not compatible with EPL
+ * #1113 Theme generation fails if theme doesn't have .project file
+ * #1104 As a variant engineer I want to use Initvariant in TB10.1 environment
+ * #1086 As a user I want initvariant to update configuration project's root file so that any structural changes are included
+ * #1108 As a ConE Linux user I want to have execution rights in cone.zip file for cone (shell script)
+ * #1003 As a variant engineer I want to export CPF filtered so that content only from the specified layers is included
+ * #1125 ConE support for confml rules extension
+
+* Bug fixes
+ * #1127 Pickling error with sequences
+ * #1126 Content copied too many times in master CPF
+
== Version Cone-1.2.13 ==
* Stories
* #1046 As a product integrator I want to get product specific report containing changed settings so that I can easily compare different configurations
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/build-scripts/export_bat.py
--- a/configurationengine/build-scripts/export_bat.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/build-scripts/export_bat.py Thu Oct 21 16:36:53 2010 +0300
@@ -157,7 +157,7 @@
log.info("Copying library eggs...")
DEP_EGGS_DIR = os.path.normpath(os.path.join(ROOT_PATH, '../dep-eggs'))
assert os.path.isdir(DEP_EGGS_DIR)
- DEPENDENCIES = ['simplejson', 'Jinja2']
+ DEPENDENCIES = ['simplejson']
for dep in DEPENDENCIES:
egg_file_name = find_egg_file(DEP_EGGS_DIR, dep, PYTHON_VERSION)
if egg_file_name is None:
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/build-scripts/install_cone.py
--- a/configurationengine/build-scripts/install_cone.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/build-scripts/install_cone.py Thu Oct 21 16:36:53 2010 +0300
@@ -130,24 +130,17 @@
for egg in eggs:
log.debug(egg)
- if PLATFORM_SUBDIR == 'win':
- command = ['easy_install-%s' % python_version,
- '--allow-hosts None',
- '--find-links install-temp/dep-eggs',
- '--install-dir "%s"' % LIB_DIR,
- '--script-dir "%s"' % SCRIPT_DIR,
- '--site-dirs "%s"' % LIB_DIR,
- '--always-copy',
- '--always-unzip']
- else:
- command = ['easy_install-%s' % python_version,
- '--allow-hosts None',
- '--find-links install-temp/dep-eggs',
- '--install-dir "%s"' % LIB_DIR,
- '--script-dir "%s"' % SCRIPT_DIR,
- '--site-dirs "%s"' % LIB_DIR,
- '--always-unzip']
-
+ command = ['easy_install-%s' % python_version,
+ '--find-links install-temp/dep-eggs',
+ '--install-dir "%s"' % LIB_DIR,
+ '--script-dir "%s"' % SCRIPT_DIR,
+ '--site-dirs "%s"' % LIB_DIR,
+ '--always-unzip']
+
+ if PLATFORM_SUBDIR == 'win':
+ # Use --always-copy on Windows to copy all needed libraries
+ command.append('--always-copy')
+
command.append('"' + egg + '"')
command = ' '.join(command)
@@ -165,12 +158,11 @@
for source_path in source_paths:
os.chdir(source_path)
command = ['%s setup.py develop' % python_executable,
- '--allow-hosts None',
'--find-links "%s"' % os.path.normpath(os.path.join(ROOT_PATH, 'install-temp/dep-eggs')),
'--install-dir "%s"' % LIB_DIR,
'--script-dir "%s"' % SCRIPT_DIR,
'--site-dirs "%s"' % LIB_DIR,
- '--always-copy']
+ ]
command = ' '.join(command)
log.debug(command)
ok = utils.run_command(command, env_overrides={'PYTHONPATH': LIB_DIR})
@@ -188,6 +180,21 @@
# Retrieve dependencies to the correct location
retrieve_dep_eggs(plugin_package)
+ # Install the dependencies locally using either local copies or downloading from PyPi
+ deps = ['Jinja2', 'lxml']
+ for dep in deps:
+ command = ['easy_install-%s' % python_version,
+ '--find-links install-temp/dep-eggs']
+
+ command.append(dep)
+ command = ' '.join(command)
+ log.debug(command)
+ ok = utils.run_command(command)
+ if not ok:
+ print "Warning: failed to run easy_install to install %s." % dep
+
+
+
# Find paths to the sources to install
source_paths = find_cone_egg_sources(plugin_package)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/build.xml
--- a/configurationengine/build.xml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/build.xml Thu Oct 21 16:36:53 2010 +0300
@@ -8,10 +8,9 @@
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -441,27 +470,30 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Zip package located at ${zip_abs}.
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Zip package located at ${zip_abs}.
+
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/common.properties
--- a/configurationengine/common.properties Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/common.properties Thu Oct 21 16:36:53 2010 +0300
@@ -4,7 +4,7 @@
****************************************************************************-->
# ConE version that is added to the produced ZIP file
-common.version = 1.2.13
+common.version = 1.2.14
common.build_scripts_dir = build-scripts
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/dep-eggs/Jinja2-2.1.1-py2.5-win32.egg
Binary file configurationengine/dep-eggs/Jinja2-2.1.1-py2.5-win32.egg has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/dep-eggs/Jinja2-2.1.1-py2.6-win32.egg
Binary file configurationengine/dep-eggs/Jinja2-2.1.1-py2.6-win32.egg has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/dep-eggs/lxml-2.2.2-py2.5-win32.egg
Binary file configurationengine/dep-eggs/lxml-2.2.2-py2.5-win32.egg has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/dep-eggs/lxml-2.2.2-py2.6-win32.egg
Binary file configurationengine/dep-eggs/lxml-2.2.2-py2.6-win32.egg has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/dep-eggs/readme.txt
--- a/configurationengine/dep-eggs/readme.txt Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/dep-eggs/readme.txt Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,14 @@
This directory contains all library dependencies needed by ConE as egg files.
+In addition to these libraries, ConE also depends on Jinja2 and lxml. Use the
+following commands to install these libraries into your Python environment:
+
+easy_install Jinja2
+easy_install lxml
+
+Note: If you need to use a HTTP proxy to access the Internet, you need to set
+HTTP_PROXY enviroment variable before running the above commands.
+
Note that if a plug-in requires a library not used in ConE core, the egg
should not be added here, but in source/plugins//dep-eggs/.
This way the egg will not be installed unless the plug-in package requiring
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/doc/conf.py
--- a/configurationengine/doc/conf.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/doc/conf.py Thu Oct 21 16:36:53 2010 +0300
@@ -59,7 +59,7 @@
# The short X.Y version.
version = '1.2'
# The full version, including alpha/beta/rc tags.
-release = '1.2.13'
+release = '1.2.14'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/doc/xsd/confml2.xsd
--- a/configurationengine/doc/xsd/confml2.xsd Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/doc/xsd/confml2.xsd Thu Oct 21 16:36:53 2010 +0300
@@ -1,274 +1,405 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/__init__.py
--- a/configurationengine/source/cone/__init__.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/__init__.py Thu Oct 21 16:36:53 2010 +0300
@@ -13,5 +13,5 @@
#
# Description:
#
-__version__ = "1.2.13"
+__version__ = "1.2.14"
_svnrevision = ""
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/model.py
--- a/configurationengine/source/cone/confml/model.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/confml/model.py Thu Oct 21 16:36:53 2010 +0300
@@ -76,6 +76,8 @@
self.meta = kwargs.get('meta')
if kwargs.get('desc'):
self.desc = kwargs.get('desc')
+ if kwargs.get('extensions'):
+ self.extensions = kwargs.get('extensions')
def _view_class(self):
return ConfmlView
@@ -129,6 +131,28 @@
""" The meta element as a property """
meta = property(get_meta,set_meta,del_meta)
+
+ def get_extensions(self):
+ """
+ @return: The extension element of the Configuration.
+ """
+ try:
+ extensions = getattr(self,ConfmlExtensions.refname)
+ return extensions
+ except AttributeError:
+ return None
+
+ def set_extensions(self,value):
+ self._add(ConfmlExtensions(value))
+
+ def del_extensions(self):
+ try:
+ self._remove(ConfmlExtensions.refname)
+ except exceptions.NotFound:
+ pass
+
+ """ The extensions element as a property """
+ extensions = property(get_extensions,set_extensions,del_extensions)
class ConfmlSettingAttributes(ConfmlElement):
"""
@@ -429,6 +453,7 @@
'selection']
def __init__(self, ref,**kwargs):
super(ConfmlSetting,self).__init__(ref,**kwargs)
+ self.extensionAttributes = []
self.type = kwargs.get('type',None)
def get_value_cast(self, value, attr=None):
@@ -496,7 +521,15 @@
return 'true'
else:
return 'false'
-
+
+ def set_extension_attributes(self, attributes):
+ self.extensionAttributes = attributes
+
+ def get_extension_attributes(self):
+ return self.extensionAttributes
+
+ def add_extension_attribute(self, attribute):
+ self.extensionAttributes.append(attribute)
class ConfmlStringSetting(ConfmlSetting):
"""
@@ -1128,3 +1161,51 @@
mapmodule = __import__('cone.confml.mapping')
return mapmodule.confml.mapping.MAPPERS[modelname]()
+class ConfmlExtensions(api.Base):
+ """
+ Confml extensions element
+ """
+ refname = "_extensions"
+ def __init__(self, **kwargs):
+ super(ConfmlExtensions,self).__init__(self.refname)
+
+
+class ConfmlExtension(api.Base):
+ """
+ Confml generic subelement of extensions element
+ """
+ refname = "_extension"
+ def __init__(self, tag, value = None, ns = None, **kwargs):
+ """
+ """
+ super(ConfmlExtension,self).__init__(self.refname)
+ self.tag = tag
+ self.value = value
+ self.ns = ns
+ self.attrs = dict(kwargs.get('attrs') or {})
+
+
+ def __cmp__(self, other):
+ try:
+ if self.tag != other.tag or self.value != other.value\
+ or self.ns != other.ns or self.attrs != other.attrs:
+ return 1
+ except:
+ return 1
+ return 0
+
+ def __str__(self):
+ return "Tag: %s Value: %s Namespace: %s Attributes: % s" % (self.tag, self.value, self.ns, repr(self.attrs))
+
+class ConfmlExtensionAttribute():
+ """
+ Confml generic extension attribute
+ """
+ def __init__(self, name, value = None, ns = None, **kwargs):
+ """
+ """
+ self.name = name
+ self.value = value
+ self.ns = ns
+ self.attrs = dict(kwargs.get('attrs') or {})
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/persistentconfml.py
--- a/configurationengine/source/cone/confml/persistentconfml.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/confml/persistentconfml.py Thu Oct 21 16:36:53 2010 +0300
@@ -16,6 +16,7 @@
import os
import re
import logging
+
try:
from cElementTree import ElementTree
except ImportError:
@@ -35,7 +36,15 @@
INCLUDE_NAMESPACES = ["http://www.w3.org/2001/XInclude","http://www.w3.org/2001/xinclude"]
XLINK_NAMESPACES = ["http://www.w3.org/1999/xlink"]
SCHEMA_NAMESPACES = ["http://www.w3.org/2001/XMLSchema"]
+RULEML_NAMESPACES = ["http://www.s60.com/xml/ruleml/3"]
+RULEML_NAMESPACE = {"http://www.s60.com/xml/ruleml/3" : "ruleml"}
CV_NAMESPACE = {"http://www.nokia.com/xml/cpf-id/1": "cv"}
+KNOWN_NAMESPACES = []
+KNOWN_NAMESPACES.extend(CONFIGURATION_NAMESPACES)
+KNOWN_NAMESPACES.extend(INCLUDE_NAMESPACES)
+KNOWN_NAMESPACES.extend(XLINK_NAMESPACES)
+KNOWN_NAMESPACES.extend(SCHEMA_NAMESPACES)
+KNOWN_NAMESPACES.extend(CV_NAMESPACE)
MODEL = model
def dumps(obj, indent=True):
@@ -365,6 +374,9 @@
elem.set('relevant', obj.get_relevant())
if obj.get_constraint() != None:
elem.set('constraint', obj.get_constraint())
+
+ dump_extension_attributes(obj, elem)
+
for child in obj._objects():
""" Make sure that the object is mapped to an object in this model """
mobj = child._get_mapper('confml').map_object(child)
@@ -408,14 +420,17 @@
feature.set_constraint(elem.get('constraint'))
feature.set_type(type)
feature.lineno = utils.etree.get_lineno(elem)
+
+ load_extension_attributes(elem, feature)
+
for elem in elem.getchildren():
# At the moment we ignore the namespace of elements
- (namespace,elemname) = get_elemname(elem.tag)
+ (_,elemname) = get_elemname(elem.tag)
try:
reader = get_reader_for_elem(elemname)
obj = reader.loads(elem)
feature.add(obj)
- except exceptions.ConePersistenceError,e:
+ except exceptions.ConePersistenceError:
add_unknown_element_warning(elem)
continue
return feature
@@ -446,6 +461,13 @@
if obj.display_name is not None: objdict['displayName'] = obj.display_name
if obj.map_value is not None: objdict['mapValue'] = obj.map_value
+ if hasattr(obj,'extensionAttributes') and obj.extensionAttributes is not None and obj.extensionAttributes != []:
+ for ext_attribute in obj.extensionAttributes:
+ if ext_attribute.ns != None and ext_attribute.ns != "":
+ objdict["{%s}%s" % (ext_attribute.ns, ext_attribute.name)] = str(ext_attribute.value)
+ else:
+ objdict[ext_attribute.name] = str(ext_attribute.value)
+
elem = ElementTree.Element('option', objdict)
return elem
@@ -482,6 +504,14 @@
map_value=elem.get('mapValue'),
display_name=elem.get('displayName'))
option.lineno = utils.etree.get_lineno(elem)
+
+ #Add extension attributes
+ for attribute in elem.attrib:
+ (ns,attname) = get_elemname(attribute)
+ if ns != None and ns != "":
+ if not ns in KNOWN_NAMESPACES:
+ option.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))
+
return option
@@ -905,6 +935,13 @@
if hasattr(obj,'displayName') and obj.displayName is not None:
elem.set('displayName', str(obj.displayName))
+ if getattr(obj, 'extensionAttributes', None):
+ for ext_attribute in obj.extensionAttributes:
+ if ext_attribute.ns:
+ elem.set(("{%s}%s" % (ext_attribute.ns, ext_attribute.name)), str(ext_attribute.value))
+ else:
+ elem.set(ext_attribute.name, str(ext_attribute.value))
+
for child in obj._objects():
""" Make sure that the object is mapped to an object in this model """
mobj = child._get_mapper('confml').map_object(child)
@@ -966,13 +1003,12 @@
feature = model.ConfmlDurationSetting(elem.get('ref'))
elif typedef == 'hexBinary':
feature = model.ConfmlHexBinarySetting(elem.get('ref'))
-
-
else:
# Handle the default setting as int type
feature = model.ConfmlSetting(elem.get('ref'), type=typedef)
feature.lineno = utils.etree.get_lineno(elem)
self._get_setting_properties(elem, feature)
+
return feature
def _get_setting_properties(self, elem, feature):
@@ -996,12 +1032,20 @@
if elem.get('relevant'):
feature.relevant = elem.get('relevant')
+ #Add extension attributes
+ for attribute in elem.attrib:
+ (ns,attname) = get_elemname(attribute)
+ if ns != None and ns != "":
+ if not ns in KNOWN_NAMESPACES:
+ feature.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))
+
for elem in elem.getchildren():
# At the moment we ignore the namespace of elements
(namespace,elemname) = get_elemname(elem.tag)
try:
reader = get_reader_for_elem(elemname)
obj = reader.loads(elem)
+
if obj != None:
feature.add(obj,container.APPEND)
else:
@@ -1171,7 +1215,155 @@
def dumps(self, obj):
return None
+class ExtensionsWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="ConfmlExtensions":
+ return True
+ else:
+ return False
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+
+ elem = ElementTree.Element("extensions")
+ for extension in obj._objects():
+ if isinstance(extension, api.RulemlEvalGlobals):
+ writer = EvalGlobalsWriter()
+ childelem = writer.dumps(extension)
+ if childelem != None:
+ elem.append(childelem)
+ else:
+ if extension.ns != None and extension.ns != "":
+ childelem = ElementTree.Element("{%s}%s" % (extension.ns, extension.tag))
+ else:
+ childelem = ElementTree.Element(extension.tag)
+ if extension.value != None:
+ childelem.text = extension.value
+ for attr in extension.attrs:
+ childelem.set(attr, extension.attrs[attr])
+
+ childs = self._dump_childen(extension._objects())
+ for ch in childs:
+ childelem.append(ch)
+
+ elem.append(childelem)
+ return elem
+
+ def _dump_childen(self, obj):
+ childs = []
+
+ for child in obj:
+ if child.ns != None and child.ns != "":
+ childelem = ElementTree.Element("{%s}%s" % (child.ns, child.tag))
+ else:
+ childelem = ElementTree.Element(child.tag)
+ if child.value != None:
+ childelem.text = child.value
+ for attr in child.attrs:
+ childelem.set(attr, child.attrs[attr])
+
+
+ chds = self._dump_childen(child._objects())
+ for ch in chds:
+ childelem.append(ch)
+
+ childs.append(childelem)
+
+ return childs
+#import xml.sax.expatreader
+
+class ExtensionsReader(ConfmlReader):
+
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="extensions":
+ return True
+ else:
+ return False
+
+ def loads(self,etree):
+ extensionselem = model.ConfmlExtensions()
+ extensionselem.lineno = utils.etree.get_lineno(etree)
+ for elem in etree.getchildren():
+ try:
+ (_,elemname) = utils.xml.split_tag_namespace(elem.tag)
+ reader = get_reader_for_elem(elemname, 'extensions')
+ except exceptions.ConePersistenceError:
+ extensionselem._add(self._load_children(elem, etree), policy=container.APPEND)
+ else:
+ obj = reader.loads(elem)
+ if obj != None:
+ extensionselem._add(obj, policy=container.APPEND)
+ return extensionselem
+
+ def _load_children(self, elem, etree):
+ (namespace,elemname) = get_elemname(elem.tag)
+ attributes = {}
+ for key in elem.keys():
+ attributes[key] = elem.get(key)
+
+ extension = model.ConfmlExtension(elemname, elem.text, namespace, attrs=attributes)
+
+ for childelem in elem.getchildren():
+ extension._add(self._load_children(childelem, etree), policy=container.APPEND)
+
+ return extension
+
+
+class EvalGlobalsWriter(ConfmlWriter):
+ @classmethod
+ def supported_class(cls, classname):
+ """
+ Class method to determine if this ConfmlWriter supports writing
+ of the given class name
+ """
+ if classname=="RulemlEvalGlobals":
+ return True
+ else:
+ return False
+
+ def dumps(self, obj):
+ """
+ @param obj: The Configuration object
+ """
+
+ elem = ElementTree.Element("{%s}eval_globals" % (RULEML_NAMESPACES[0]))
+
+ if obj.value != None:
+ elem.text = obj.value
+ if obj.file != None:
+ elem.set('file', obj.file)
+
+ return elem
+
+class EvalGlobalsReader(ConfmlReader):
+
+ @classmethod
+ def supported_elem(cls, elemname, parent=None):
+ """
+ Class method to determine if this ConfmlWriter supports reading
+ of the given elem name
+ """
+ if elemname=="eval_globals":
+ return True
+ else:
+ return False
+
+ def loads(self,etree):
+ eval_globals = api.RulemlEvalGlobals(etree.text, etree.get("file", None))
+
+ return eval_globals
class RfsReader(ConfmlReader):
"""
@@ -1255,7 +1447,6 @@
return (namespace,elemname)
else:
raise exceptions.ParseError("Could not parse tag %s" % tag)
-
def get_reader_for_elem(elemname, parent=None):
for reader in utils.all_subclasses(ConfmlReader):
@@ -1268,3 +1459,18 @@
if writer.supported_class(classname):
return writer ()
raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
+
+def dump_extension_attributes(obj, elem):
+ if hasattr(obj,'extensionAttributes') and obj.extensionAttributes is not None and obj.extensionAttributes != []:
+ for ext_attribute in obj.extensionAttributes:
+ if ext_attribute.ns != None and ext_attribute.ns != "":
+ elem.set(("{%s}%s" % (ext_attribute.ns, ext_attribute.name)), unicode(ext_attribute.value))
+ else:
+ elem.set(ext_attribute.name, unicode(ext_attribute.value))
+
+def load_extension_attributes(elem, obj):
+ for attribute in elem.attrib:
+ (ns,attname) = get_elemname(attribute)
+ if ns != None and ns != "":
+ if not ns in KNOWN_NAMESPACES:
+ obj.add_extension_attribute(model.ConfmlExtensionAttribute(attname, elem.attrib[attribute], ns))
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/tests/testdata/pickle_unpickle/config_root.confml
--- a/configurationengine/source/cone/confml/tests/testdata/pickle_unpickle/config_root.confml Wed Sep 08 12:20:56 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-
-
-
-
-
-
- Version1
- Platform1
- Date1
- Release1
- Editor1
-
-Description1
-
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/tests/testdata/read_write/extensions.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/extensions.confml Thu Oct 21 16:36:53 2010 +0300
@@ -0,0 +1,14 @@
+
+
+
+
+
+ This is the description for the feature. It can be used for display purposes.
+
+
+ foo
+
+ The first setting
+
+
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/tests/testdata/read_write/extensions2.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/extensions2.confml Thu Oct 21 16:36:53 2010 +0300
@@ -0,0 +1,40 @@
+
+
+
+
+ bar
+
+ bar2
+
+
+ ${Feature/Boolean} == true
+
+
+def is_foobar(value):
+ if value.lower() == "foobar":
+ return True
+ else:
+ return False
+
+
+
+ This is the description for the feature. It can be used for display purposes.
+
+
+
+ bar
+
+
+
+ The first setting
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/tests/unittest_model.py
--- a/configurationengine/source/cone/confml/tests/unittest_model.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/confml/tests/unittest_model.py Thu Oct 21 16:36:53 2010 +0300
@@ -16,7 +16,7 @@
import unittest
import sys
-from cone.public import api, exceptions
+from cone.public import api, exceptions, container
from cone.confml import model
@@ -1376,7 +1376,6 @@
self.assertEquals(subconfig.get_full_path(),'test/foo/sub/jee.confml')
self.assertTrue(isinstance(subconfig,model.ConfmlConfiguration))
-
class TestConfmlView(unittest.TestCase):
def test_create_view(self):
view = model.ConfmlView("test", id="test")
@@ -1471,6 +1470,11 @@
self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').minExclusive, 0)
self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').maxExclusive, 10)
self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').options['1'].name,'opt1')
-
+
+class TestConfmlExtensions(unittest.TestCase):
+ def test_create_extensions(self):
+ extensionselem = model.ConfmlExtensions()
+ self.assertEquals(str(extensionselem),"ConfmlExtensions({'ref': '_extensions'})")
+
if __name__ == '__main__':
unittest.main()
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/confml/tests/unittest_persistentconfml.py
--- a/configurationengine/source/cone/confml/tests/unittest_persistentconfml.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/confml/tests/unittest_persistentconfml.py Thu Oct 21 16:36:53 2010 +0300
@@ -29,6 +29,7 @@
from testautomation.base_testcase import BaseTestCase
import pickle
+
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
ElementTree = utils.etree
@@ -1745,6 +1746,44 @@
os.path.join(self.TEMP_DIR, FILE_NAME),
os.path.join(self.EXPECTED_DIR, 'complex_seq_with_nones.confml'))
+class TestExtensions(unittest.TestCase):
+ def test_get_reader_for_extensions(self):
+ reader = persistentconfml.get_reader_for_elem("extensions")
+ self.assertTrue(isinstance(reader, persistentconfml.ExtensionsReader))
+
+ def test_parse_extensions_elem(self):
+ reader = persistentconfml.get_reader_for_elem("extensions")
+ elem = ElementTree.Element('extension')
+ owner = ElementTree.Element('owner')
+ owner.text = 'Testing owner'
+ origin = ElementTree.Element('origin')
+ origin.text = 'just origin'
+ target = ElementTree.Element('target')
+ target.text = 'target hw'
+ elem.append(owner)
+ elem.append(origin)
+ elem.append(target)
+ data = reader.loads(elem)
+ exts = data._get('_extension')
+ self.assertTrue(isinstance(exts, list))
+ self.assertEquals(exts[0].tag, 'owner')
+ self.assertEquals(exts[0].value, 'Testing owner')
+ self.assertEquals(exts[1].tag, 'origin')
+ self.assertEquals(exts[1].value, 'just origin')
+ self.assertEquals(exts[2].tag, 'target')
+ self.assertEquals(exts[2].value, 'target hw')
+
+ def test_write_extensions_elem(self):
+ writer = persistentconfml.get_writer_for_class("ConfmlExtensions")
+ celem = model.ConfmlExtensions()
+ celem._add([model.ConfmlExtension('test', 123),
+ model.ConfmlExtension('owner', "some ownername"),
+ model.ConfmlExtension('target', "hw")])
+ etree = writer.dumps(celem)
+ self.assertEquals(etree.find('test').text,123)
+ self.assertEquals(etree.find('owner').text,'some ownername')
+ self.assertEquals(etree.find('target').text,'hw')
+
class TestReadWriteConfml(BaseTestCase):
"""
Test case for ensuring that reading in a ConfML file and then writing
@@ -1862,6 +1901,7 @@
finally: f.close()
model = persistentconfml.loads(original_data)
+ model.get_default_view()#verify that dump works also after get_default_view is called
PATH_ORIGINAL = os.path.join(output_dir, 'original_pickled', file_name)
PATH_DUMPED = os.path.join(output_dir, 'pickled', file_name)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/core/tests/testdata/test_project.cpf
Binary file configurationengine/source/cone/core/tests/testdata/test_project.cpf has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/core/tests/unittest_configuration.py
--- a/configurationengine/source/cone/core/tests/unittest_configuration.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/core/tests/unittest_configuration.py Thu Oct 21 16:36:53 2010 +0300
@@ -184,7 +184,7 @@
config = p.get_configuration('root5.confml')
view = config.get_default_view()
print "Fealist %s." % len(view.list_all_features())
- self.assertEquals(len(view.list_all_features()), 99)
+ self.assertEquals(len(view.list_all_features()), 102)
for feaname in view.list_all_features():
fea = view.get_feature(feaname)
if fea.get_type() == 'sequence':
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/core/tests/unittest_configuration_project_export.py
--- a/configurationengine/source/cone/core/tests/unittest_configuration_project_export.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_export.py Thu Oct 21 16:36:53 2010 +0300
@@ -65,6 +65,110 @@
self.assertEquals(files1[i],files2[i])
os.unlink(export_zip)
+ def test_export_with_include_content_filter(self):
+ include_content_filter = ".*layer4.*"
+ include_filters = {'content':include_content_filter}
+ test_project_dir = os.path.join(temp_dir, "test_project_1")
+ unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
+
+ export_zip = os.path.join(temp_dir, "configexport.zip")
+
+ fs = FileStorage(test_project_dir)
+ p = api.Project(fs)
+ conf = p.get_configuration('root5.confml')
+ zs = ZipStorage(export_zip,"w")
+ zp = api.Project(zs)
+ p.export_configuration(conf,zs,include_filters = include_filters)
+ zp.close()
+
+ zs = ZipStorage(export_zip,"r")
+ zp = api.Project(zs)
+ conf = zp.get_configuration('root5.confml')
+ rel = conf.get_layer().list_all_related()
+
+ exp = ['Layer1/implml/bitmask_test_12341002.crml',
+ 'Layer1/implml/feature1_12341000.crml',
+ 'Layer1/implml/feature1_12341001.crml',
+ 'Layer1/implml/feature1_sequence.gcfml',
+ 'Layer1/implml/feature2_ABCD0000.crml',
+ 'Layer1/implml/time_types_test_12341003.crml',
+ 'Layer4/content/seq/layer4_file.txt']
+ zs.close()
+ self.assertEquals(exp,rel)
+ os.unlink(export_zip)
+
+ def test_export_with_exclude_content_filter(self):
+ exclude_content_filter = ".*(layer1|layer2).*"
+ exclude_filters = {'content':exclude_content_filter}
+ test_project_dir = os.path.join(temp_dir, "test_project_1")
+ unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
+
+ export_zip = os.path.join(temp_dir, "configexport.zip")
+
+ fs = FileStorage(test_project_dir)
+ p = api.Project(fs)
+ conf = p.get_configuration('root5.confml')
+ zs = ZipStorage(export_zip,"w")
+ zp = api.Project(zs)
+ p.export_configuration(conf,zs,exclude_filters = exclude_filters)
+ zp.close()
+
+ zs = ZipStorage(export_zip,"r")
+ zp = api.Project(zs)
+ conf = zp.get_configuration('root5.confml')
+ rel = conf.get_layer().list_all_related()
+
+ exp = ['Layer1/implml/bitmask_test_12341002.crml',
+ 'Layer1/implml/feature1_12341000.crml',
+ 'Layer1/implml/feature1_12341001.crml',
+ 'Layer1/implml/feature1_sequence.gcfml',
+ 'Layer1/implml/feature2_ABCD0000.crml',
+ 'Layer1/implml/time_types_test_12341003.crml',
+ 'Layer3/content/seq/layer3_file.txt',
+ 'Layer4/content/seq/layer4_file.txt',
+ 'Layer5/content/content.txt',
+ 'Layer5/content/folder/abc.txt']
+ zs.close()
+ self.assertEquals(exp,rel)
+ os.unlink(export_zip)
+
+ def test_export_with_include_exclude_content_filters(self):
+ exclude_content_filter = ".*def.+\.txt"
+ include_content_filter = ".*layer5.*"
+ exclude_filters = {'content':exclude_content_filter}
+ include_filters = {'content':include_content_filter}
+ test_project_dir = os.path.join(temp_dir, "test_project_1")
+ unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
+
+ export_zip = os.path.join(temp_dir, "configexport.zip")
+
+ fs = FileStorage(test_project_dir)
+ p = api.Project(fs)
+ conf = p.get_configuration('root5.confml')
+ zs = ZipStorage(export_zip,"w")
+ zp = api.Project(zs)
+ p.export_configuration(conf,zs,exclude_filters = exclude_filters,
+ include_filters = include_filters)
+ zp.close()
+
+ zs = ZipStorage(export_zip,"r")
+ zp = api.Project(zs)
+ conf = zp.get_configuration('root5.confml')
+ rel = conf.get_layer().list_all_related()
+
+ exp = ['Layer1/implml/bitmask_test_12341002.crml',
+ 'Layer1/implml/feature1_12341000.crml',
+ 'Layer1/implml/feature1_12341001.crml',
+ 'Layer1/implml/feature1_sequence.gcfml',
+ 'Layer1/implml/feature2_ABCD0000.crml',
+ 'Layer1/implml/time_types_test_12341003.crml',
+ 'Layer5/content/content.txt',
+ 'Layer5/content/folder/abc.txt']
+
+ zs.close()
+ self.assertEquals(exp,rel)
+ os.unlink(export_zip)
+
def test_export_from_files_to_zipstorage_add(self):
test_project_dir = os.path.join(temp_dir, "test_project_1")
unzip_file.unzip_file(test_cpf, test_project_dir, delete_if_exists=True)
@@ -158,29 +262,6 @@
r.close()
self.assertTrue(os.path.exists(output_dir))
- # Temporarly hacked to pass, because feature is not supported
-# def test_export_to_zipstorage_multiple_configurations(self):
-# try:
-# fs = FileStorage(datafolder)
-# p = api.Project(fs)
-# zs = ZipStorage(tempzip,"w")
-# zp = api.Project(zs)
-# conf = p.get_configuration('morestuff.confml')
-# conf_files = conf.list_resources()
-# p.export_configuration(conf,zs)
-# conf = p.get_configuration('prodX.confml')
-# conf_files2 = conf.list_resources()
-# conf_files.extend(conf_files2)
-# conf_files = utils.distinct_array(conf_files)
-# p.export_configuration(conf,zs)
-# zp.close()
-# self.assertTrue(os.path.exists(tempzip))
-# zfile = zipfile.ZipFile(tempzip,"r")
-# files = zfile.namelist()
-# files.remove('.metadata')
-# self.assertEquals(sorted(conf_files),sorted(files))
-# except exceptions.NotSupportedException:
-# pass
def _test_export_to_filestorage_multiple_configurations(self):
fs = FileStorage(datafolder)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/public/_etree_wrapper.py
--- a/configurationengine/source/cone/public/_etree_wrapper.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/public/_etree_wrapper.py Thu Oct 21 16:36:53 2010 +0300
@@ -238,6 +238,7 @@
for backend_id in self.DEFAULT_BACKEND_IMPORT_ORDER:
try:
self.set_backend_id(backend_id)
+ #break
except ImportError:
pass
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/public/api.py
--- a/configurationengine/source/cone/public/api.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/public/api.py Thu Oct 21 16:36:53 2010 +0300
@@ -614,12 +614,44 @@
for child in configuration._traverse(type=Configuration):
export_storage.unload(child.get_full_path(),child)
+ ruleml_eval_globals_files = []
+ for child in configuration._traverse(type=RulemlEvalGlobals):
+ if child.file != None:
+ ruleml_eval_globals_files.append(RulemlEvalGlobals.get_script_file_full_path(child))
+
#If the configuration is not in the root of the project adding the path
#to final exporting source path.
#l = []
+ empty_folders = kwargs.get('empty_folders',False)
+ layer = configuration.get_layer()
+ all_resources = []
+ layer_content = layer.list_content(empty_folders)
+ layer_doc = layer.list_doc(empty_folders)
+ layer_implml = layer.list_implml(empty_folders)
+
+ include_filters = kwargs.get('include_filters',{})
+ exclude_filters = kwargs.get('exclude_filters',{})
+
+ include_content_filter = include_filters.get('content')
+ exclude_content_filter = exclude_filters.get('content')
+
+ # perform filtering of content files
+ if exclude_content_filter:
+ f = lambda x: not re.search(exclude_content_filter, x, re.IGNORECASE)
+ layer_content = filter(f,layer_content)
+
+ if include_content_filter:
+ f = lambda x: re.search(include_content_filter, x, re.IGNORECASE)
+ layer_content = filter(f,layer_content)
+
+ all_resources.extend(layer_content)
+ all_resources.extend(layer_doc)
+ all_resources.extend(layer_implml)
+
cpath = utils.resourceref.get_path(configuration.get_path())
resr = [utils.resourceref.join_refs([cpath,related]) \
- for related in configuration.get_layer().list_all_related(**kwargs)]
+ for related in all_resources]
+ resr.extend(ruleml_eval_globals_files)
self.storage.export_resources(resr ,export_storage, kwargs.get("empty_folders", False))
return
@@ -909,6 +941,15 @@
super(Configuration, self).__init__(utils.resourceref.to_objref(self.path), **kwargs)
self.container = True
+ def __getstate__(self):
+ state = self.__dict__.copy()
+ if state.has_key('_children'):
+ childs = state.get('_children')
+ if childs.has_key('?default_view'):
+ childs.pop('?default_view')
+ state['_children'] = childs
+ return state
+
def _default_object(self, name):
return self._default_class()(name)
@@ -1645,6 +1686,7 @@
self.relevant = kwargs.get('relevant', None)
self.constraint = kwargs.get('constraint', None)
self._dataproxy = None
+ self.extensionAttributes = []
def __copy__(self):
dict = {}
@@ -2185,6 +2227,14 @@
else: value_list = value_subsetting.get_original_value()
return value_list[key_list.index(mapping_key)]
+ def set_extension_attributes(self, attributes):
+ self.extensionAttributes = attributes
+
+ def get_extension_attributes(self):
+ return self.extensionAttributes
+
+ def add_extension_attribute(self, attribute):
+ self.extensionAttributes.append(attribute)
class FeatureSequence(Feature):
POLICY_REPLACE = 0
@@ -3274,6 +3324,7 @@
self.relevant = kwargs.get('relevant', None)
self.map_value = kwargs.get('map_value', None)
self.display_name = kwargs.get('display_name', None)
+ self.extensionAttributes = []
@classmethod
def to_optref(cls, value, map):
@@ -3306,6 +3357,14 @@
else:
return 1
+ def set_extension_attributes(self, attributes):
+ self.extensionAttributes = attributes
+
+ def get_extension_attributes(self):
+ return self.extensionAttributes
+
+ def add_extension_attribute(self, attribute):
+ self.extensionAttributes.append(attribute)
class Storage(object):
"""
@@ -3950,33 +4009,33 @@
lres.append(utils.resourceref.join_refs([layerpath, respath]))
return lres
- def list_implml(self):
+ def list_implml(self,empty_folders=False):
"""
@return: array of implml file references.
"""
lres = []
for layerpath in self.list_layers():
- for respath in self.get_layer(layerpath).list_implml():
+ for respath in self.get_layer(layerpath).list_implml(empty_folders):
lres.append(utils.resourceref.join_refs([layerpath, respath]))
return lres
- def list_content(self):
+ def list_content(self,empty_folders=False):
"""
@return: array of content file references.
"""
lres = []
for layerpath in self.list_layers():
- for respath in self.get_layer(layerpath).list_content():
+ for respath in self.get_layer(layerpath).list_content(empty_folders):
lres.append(utils.resourceref.join_refs([layerpath, respath]))
return lres
- def list_doc(self):
+ def list_doc(self,empty_folders=False):
"""
@return: array of document file references.
"""
lres = []
for layerpath in self.list_layers():
- for respath in self.get_layer(layerpath).list_doc():
+ for respath in self.get_layer(layerpath).list_doc(empty_folders):
lres.append(utils.resourceref.join_refs([layerpath, respath]))
return lres
@@ -4056,28 +4115,28 @@
res += super(Layer, self).list_confml()
return res
- def list_implml(self):
+ def list_implml(self,empty_folders=False):
"""
@return: array of implml file references.
"""
- res = self.list_resources(self.predefined['implml_path'], recurse=True)
- res += super(Layer, self).list_implml()
+ res = self.list_resources(self.predefined['implml_path'], recurse=True,empty_folders=empty_folders)
+ res += super(Layer, self).list_implml(empty_folders)
return res
- def list_content(self):
+ def list_content(self,empty_folders=False):
"""
@return: array of content file references.
"""
- res = self.list_resources(self.predefined['content_path'], recurse=True)
- res += super(Layer, self).list_content()
+ res = self.list_resources(self.predefined['content_path'], recurse=True,empty_folders=empty_folders)
+ res += super(Layer, self).list_content(empty_folders)
return res
- def list_doc(self):
+ def list_doc(self,empty_folders=False):
"""
@return: array of document file references.
"""
- res = self.list_resources(self.predefined['doc_path'], recurse=True)
- res += super(Layer, self).list_doc()
+ res = self.list_resources(self.predefined['doc_path'], recurse=True,empty_folders=empty_folders)
+ res += super(Layer, self).list_doc(empty_folders)
return res
def confml_folder(self):
@@ -4186,6 +4245,25 @@
mapmodule = __import__('cone.public.mapping')
return mapmodule.public.mapping.BaseMapper()
+class RulemlEvalGlobals(Base):
+ """
+ Ruleml subelement of extensions element
+ """
+ refname = "_extension"
+ def __init__(self, value = None, file = None, **kwargs):
+ """
+ """
+ super(RulemlEvalGlobals,self).__init__(self.refname)
+ self.value = value
+ self.file = file
+
+ @classmethod
+ def get_script_file_full_path(self, child):
+ parent_config = child._find_parent(type=Configuration)
+ cpath = parent_config.get_full_path()
+ cpath = utils.resourceref.psplit_ref(cpath)[0]
+ path = utils.resourceref.join_refs([cpath, child.file])
+ return path
class Problem(object):
SEVERITY_ERROR = "error"
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/public/tests/unittest_configuration.py
--- a/configurationengine/source/cone/public/tests/unittest_configuration.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/public/tests/unittest_configuration.py Thu Oct 21 16:36:53 2010 +0300
@@ -19,7 +19,7 @@
"""
import unittest
import os
-import pickle
+import pickle
from cone.public import api,exceptions
from cone.storage import persistentdictionary
@@ -774,6 +774,28 @@
['foo1','foo2','foo3']])
self.assertEquals(conf.list_all_datas(),['feature1', 'feature1.child1', 'feature1.child2', 'feature1.child3', 'feature1', 'feature1.child1', 'feature1.child2', 'feature1.child3'])
+ def test_create_layers_add_featuresequence_and_add_data_via_features_pickle(self):
+
+ conf = api.Configuration("foo/foo.confml")
+ conf.add_feature(api.FeatureSequence('feature1'))
+ conf.add_feature(api.Feature('child1'),'feature1')
+ conf.add_feature(api.Feature('child2'),'feature1')
+ conf.add_feature(api.Feature('child3'),'feature1')
+
+ pickle.dumps(conf)
+
+ conf.feature1.add_sequence(['foo1','foo2','foo3'])
+ pickle.dumps(conf)
+
+ conf.feature1.add_sequence()
+ pickle.dumps(conf)
+
+ conf.feature1.get_data()[1][0].set_value('test1')
+ conf.feature1.get_data()[1][1].set_value('test2')
+ conf.feature1.get_data()[1][2].set_value('test3')
+ conf.feature1.add_sequence(['bar1','bar2','bar3'])
+
+
def test_create_featuresequence_and_get_empty_data(self):
conf = api.Configuration("foo/foo.confml")
conf.add_feature(api.FeatureSequence('feature1'))
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/public/tests/unittest_feature.py
--- a/configurationengine/source/cone/public/tests/unittest_feature.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/public/tests/unittest_feature.py Thu Oct 21 16:36:53 2010 +0300
@@ -232,6 +232,7 @@
self.assertEquals(fea._dict(), {'ref': 'foo',
'type': 'int',
'name': None,
+ 'extensionAttributes': [],
'relevant': None,
'constraint': None })
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/public/tests/unittest_utils.py
--- a/configurationengine/source/cone/public/tests/unittest_utils.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/public/tests/unittest_utils.py Thu Oct 21 16:36:53 2010 +0300
@@ -648,6 +648,16 @@
def test_prepend_list_with_string(self):
self.assertEquals(utils.prepend_list(['bar','test'], 'foo'), ['foo','bar','test'])
+class TestFlattenList(unittest.TestCase):
+ def test_flatten_list(self):
+ self.assertEquals(utils.flatten_list([]), [])
+ self.assertEquals(utils.flatten_list([[[[]]]]), [])
+ self.assertEquals(utils.flatten_list([1]), [1])
+ self.assertEquals(utils.flatten_list([[[[1]]]]), [1])
+ self.assertEquals(utils.flatten_list([1, 2, 3]), [1, 2, 3])
+ self.assertEquals(utils.flatten_list([1, [2, [3, [4, 5], 6], 7]]), [1, 2, 3, 4, 5, 6, 7])
+ self.assertEquals(utils.flatten_list(((1, 2), [3, 4])), [1, 2, 3, 4])
+
from cone.confml import model as confmlmodel
class TestModelGetters(unittest.TestCase):
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/public/utils.py
--- a/configurationengine/source/cone/public/utils.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/public/utils.py Thu Oct 21 16:36:53 2010 +0300
@@ -569,6 +569,25 @@
retlist.insert(0, prepend)
return retlist
+def iter_flatten(iterable):
+ for item in iterable:
+ if isinstance(item, (list, tuple)):
+ for subitem in flatten_list(item):
+ yield subitem
+ else:
+ yield item
+
+def flatten_list(lst):
+ """
+ Flatten a list or tuple.
+ @param lst: The list of tuple to flatten.
+ @return: The flattened list.
+
+ >>> flatten_list([1, 2, [3, [4, 5]], [6]])
+ [1, 2, 3, 4, 5, 6]
+ """
+ return [item for item in iter_flatten(lst)]
+
def is_list(elem):
return isinstance(elem, list)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/storage/filestorage.py
--- a/configurationengine/source/cone/storage/filestorage.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/storage/filestorage.py Thu Oct 21 16:36:53 2010 +0300
@@ -224,8 +224,9 @@
# when we can just write the file directly into the ZIP
if isinstance(storage, zipstorage.ZipStorage):
source_abspath = os.path.join(self.rootpath, path)
- logging.getLogger("cone").debug("Exporting directly from file to ZIP: %r -> %r" % (source_abspath, path))
- storage.zipfile.write(source_abspath, path)
+ logging.getLogger("cone").debug("Pre-caching: %r -> %r" % (source_abspath, path))
+ storage.cache[path] = source_abspath
+ storage.modified = True
else:
wres = storage.open_resource(path,'wb')
res = self.open_resource(path,"rb")
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py
--- a/configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py Thu Oct 21 16:36:53 2010 +0300
@@ -169,16 +169,17 @@
target_storage = self.get_temp_file_storage('z2f/ef_target', empty=True),
empty_folders = True)
- def test_export_file_to_zip(self):
- self._run_test_storage_to_storage(
- source_storage = self.get_temp_file_storage('f2z/source'),
- target_storage = self.get_temp_zip_storage('f2z/target.zip', empty=True),
- empty_folders = False)
-
- self._run_test_storage_to_storage(
- source_storage = self.get_temp_file_storage('f2z/ef_source'),
- target_storage = self.get_temp_zip_storage('f2z/ef_target.zip', empty=True),
- empty_folders = True)
+ #def test_export_file_to_zip(self):
+ # Currently fails, because zip storage will only contain exported file resources after closing
+ # self._run_test_storage_to_storage(
+ # source_storage = self.get_temp_file_storage('f2z/source'),
+ # target_storage = self.get_temp_zip_storage('f2z/target.zip', empty=True),
+ # empty_folders = False)
+ #
+ # self._run_test_storage_to_storage(
+ # source_storage = self.get_temp_file_storage('f2z/ef_source'),
+ # target_storage = self.get_temp_zip_storage('f2z/ef_target.zip', empty=True),
+ # empty_folders = True)
if __name__ == '__main__':
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/storage/zipstorage.py
--- a/configurationengine/source/cone/storage/zipstorage.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/storage/zipstorage.py Thu Oct 21 16:36:53 2010 +0300
@@ -55,6 +55,7 @@
self.persistentmodule = persistentconfml
self.compression = zipfile.ZIP_DEFLATED
self.modified = False
+ self.cache = {}
self.logger = logging.getLogger('cone')
self.logger.debug("ZipStorage path %s open in mode %s" % (path,self.mode))
try:
@@ -284,23 +285,31 @@
self.zipfile.close()
# Recreate the zip file if the zip has been modified to make a zip without
# duplicate local file entries
- if self.modified:
- oldfile = None
- newzipfile = None
- fh, tmp_path = tempfile.mkstemp(suffix='.zip')
- shutil.move(self.path, tmp_path)
- oldfile = zipfile.ZipFile(tmp_path,"r")
- newzipfile = zipfile.ZipFile(self.path,"w",self.compression)
- for fileinfo in oldfile.infolist():
- newzipfile.writestr(fileinfo, oldfile.read(fileinfo.filename))
- if oldfile: oldfile.close()
- if newzipfile: newzipfile.close()
- os.close(fh)
- os.unlink(tmp_path)
- self.zipfile = None
else:
raise exceptions.StorageException('Storage %s has been already closed!' % self.path)
+ if self.modified or self.cache:
+ logging.getLogger('cone').debug("Recreating the ZIP output file")
+ oldfile = None
+ newzipfile = None
+ fh, tmp_path = tempfile.mkstemp(suffix='.zip')
+ shutil.move(self.path, tmp_path)
+ oldfile = zipfile.ZipFile(tmp_path,"r")
+ newzipfile = zipfile.ZipFile(self.path,"w",self.compression)
+ for fileinfo in oldfile.infolist():
+ if fileinfo.filename not in self.cache.keys():
+ newzipfile.writestr(fileinfo, oldfile.read(fileinfo.filename))
+ for filename in sorted(self.cache.keys()):
+ logging.getLogger('cone').debug("Adding pre-cached file %s." % filename)
+ newzipfile.write(self.cache[filename], arcname=filename)
+ if oldfile: oldfile.close()
+ if newzipfile: newzipfile.close()
+ os.close(fh)
+ os.unlink(tmp_path)
+ logging.getLogger('cone').debug("Recreating the ZIP output file completed.")
+
+ self.zipfile = None
+
def unload(self, path, object):
"""
Dump a given object to the storage (reference is fetched from the object)
@@ -383,4 +392,4 @@
if self.content_info == None:
self.content_info = api.make_content_info(self, self.handle.getvalue())
- return self.content_info
\ No newline at end of file
+ return self.content_info
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/confml_xsd/confml2.xsd
--- a/configurationengine/source/cone/validation/confml_xsd/confml2.xsd Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/confml_xsd/confml2.xsd Thu Oct 21 16:36:53 2010 +0300
@@ -1,272 +1,406 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/basic_setting_types_test.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/basic_setting_types_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/basic_setting_types_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
Feature with basic setting types (ConfML v2.0)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/file_folder_test.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/file_folder_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/file_folder_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
Feature with file and folder setting types
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/name_id_mapping_test.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/name_id_mapping_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/name_id_mapping_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/product_root.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/product_root.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/product_root.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/relevant_feature_test.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/relevant_feature_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/relevant_feature_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -2,7 +2,7 @@
+ name="Relevant feature test" version="2.91.0">
Feature for testing attribute 'relevant' in a feature.
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/sequence_setting_test.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/sequence_setting_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/sequence_setting_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
Feature with a sequence setting (ConfML v2.0)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/time_types_test.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/time_types_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/time_types_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
Feature with date-time etc. setting types
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/view.confml
--- a/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/view.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/view.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
Testing view located on layer 1.
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py Thu Oct 21 16:36:53 2010 +0300
@@ -202,6 +202,8 @@
if input_dir == None:
self.logger.warning("Input dir is none!")
+ files = utils.flatten_list(files)
+ self.logger.info("Files: %s" % files)
if files != []:
for f in files:
@@ -212,8 +214,7 @@
if files != []:
- filesfunc = lambda x: x.lower() in [f.lower() for f in files]
- contentfiles = filter(filesfunc, contentfiles)
+ contentfiles = files
if include_filter != "":
filter_regexp = include_filter
filter_regexp = filter_regexp.replace('.','\.')
@@ -226,7 +227,7 @@
filter_regexp = filter_regexp.replace('*','.*')
self.logger.info("filtering with exclude %s" % filter_regexp)
contentfiles = utils.resourceref.neg_filter_resources(contentfiles,filter_regexp)
- for outfile in contentfiles:
+ for (index, outfile) in enumerate(contentfiles):
sourcefile = ""
targetfile = ""
@@ -235,24 +236,34 @@
else: input_dir_check = input_dir
if input_dir != None and (input_dir == outfile or outfile.startswith(input_dir_check)):
- sourcefile = datacontainer.get_value(outfile)
- if flatten:
- targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(outfile)])
- targetfile = utils.resourceref.norm(targetfile)
+ try:
+ sourcefile = datacontainer.get_value(outfile)
+ except KeyError:
+ self.logger.info("Input file not found: %s" % outfile)
else:
- targetfile = utils.resourceref.replace_dir(outfile,input_dir,output_dir)
+ if flatten:
+ targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(outfile)])
+ targetfile = utils.resourceref.norm(targetfile)
+ else:
+ targetfile = utils.resourceref.replace_dir(outfile,input_dir,output_dir)
elif external:
#External inputs
- sourcefile = utils.resourceref.norm(datacontainer.get_value(outfile))
-
- if flatten:
- targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(sourcefile)])
- targetfile = utils.resourceref.norm(targetfile)
+ try:
+ sourcefile = utils.resourceref.norm(datacontainer.get_value(outfile))
+ except KeyError:
+ self.logger.info("Input file not found: %s" % outfile)
else:
- fulldir = os.path.abspath(os.path.join(self.configuration.get_project().get_storage().get_path(),input_dir))
- targetfile = utils.resourceref.replace_dir(sourcefile,fulldir,output_dir)
-
- if output_file:
+ if flatten:
+ targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(sourcefile)])
+ targetfile = utils.resourceref.norm(targetfile)
+ else:
+ fulldir = os.path.abspath(os.path.join(self.configuration.get_project().get_storage().get_path(),input_dir))
+ targetfile = utils.resourceref.replace_dir(sourcefile,fulldir,output_dir)
+
+ if isinstance(output_file,list):
+ #Renaming output if defined
+ targetfile = targetfile.replace(os.path.basename(targetfile), output_file[index])
+ elif output_file:
#Renaming output if defined
targetfile = targetfile.replace(os.path.basename(targetfile), output_file)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py Thu Oct 21 16:36:53 2010 +0300
@@ -60,10 +60,16 @@
self.configuration = configuration
def path_convert(self, path):
- match = re.match('([a-zA-Z]:)(.*)', path)
- if match:
- path = match.group(2)
- return path.lstrip('\\/')
+ if isinstance(path,list):
+ converted_paths = []
+ for path_item in path:
+ converted_paths.append(self.path_convert(path_item))
+ return converted_paths
+ else:
+ match = re.match('([a-zA-Z]:)(.*)', path)
+ if match:
+ path = match.group(2)
+ return path.lstrip('\\/')
def get_dir(self):
if self.configuration and ConfmlRefs.is_confml_ref(self._dir):
@@ -92,6 +98,28 @@
parts[index] = self.path_convert(parts[index])
else:
parts[index] = part
+ #sequence tester
+ has_sequence = False
+ seq_indexes = []
+ for (index,single_part) in enumerate(parts):
+ if isinstance(single_part,list):
+ has_sequence= True
+ seq_indexes.append(index)
+ break
+
+ if has_sequence:
+ final_list = []
+ list_index = 0
+ while len(parts[seq_indexes[0]]) > list_index:
+ tmp_list = []
+ for tmp_part in parts:
+ if isinstance(tmp_part,list):
+ tmp_list.append(tmp_part[list_index])
+ else:
+ tmp_list.append(tmp_part)
+ final_list.append((os.sep).join(tmp_list))
+ list_index = list_index + 1
+ return final_list
return (os.sep).join(parts)
else:
return self._file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/wallpapers.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/wallpapers.confml Thu Oct 21 16:36:53 2010 +0300
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/multiple_input_from_sequence_with_flatten.content
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/multiple_input_from_sequence_with_flatten.content Thu Oct 21 16:36:53 2010 +0300
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/root.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/root.confml has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/confml/data.confml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/confml/data.confml Thu Oct 21 16:36:53 2010 +0300
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+ wallpapers/wallpaper1.png
+ 1_wallpaper1.png
+
+
+
+
+ wallpapers/wallpaper2.png
+ 2_wallpaper2.png
+
+
+
+
+ wallpapers/wallpaper3.png
+ 3_wallpaper3.png
+
+
+
+
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/wallpapers/wallpaper1.png
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/wallpapers/wallpaper1.png has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/wallpapers/wallpaper2.png
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/wallpapers/wallpaper2.png has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/wallpapers/wallpaper3.png
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/wallpapers/wallpaper3.png has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/root.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/root.confml has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/product.confml
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/product.confml has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py Thu Oct 21 16:36:53 2010 +0300
@@ -317,6 +317,17 @@
self.assertEquals(conout.path_convert('/test/foo/bar.txt'), 'test/foo/bar.txt')
self.assertEquals(conout.path_convert('foo/bar.txt'), 'foo/bar.txt')
+ def test_path_convert_with_sequence_input(self):
+ conout = contentmlparser.ContentOutput()
+ self.assertEquals(conout.path_convert(['z:\\test\\foo\\bar.txt',
+ 'z:/test/foo/bar.txt',
+ '/test/foo/bar.txt',
+ 'foo/bar.txt']),
+ ['test\\foo\\bar.txt',
+ 'test/foo/bar.txt',
+ 'test/foo/bar.txt',
+ 'foo/bar.txt'])
+
class TestContentInput(unittest.TestCase):
def test_content_input_dir(self):
conin = contentmlparser.ContentInput(dir='foobar/test')
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py Thu Oct 21 16:36:53 2010 +0300
@@ -176,7 +176,10 @@
'content/test/shout.txt',
'content/test/override.txt',
'content/test/s60.txt',
- 'content/test/test_CAP_letters.txt']
+ 'content/test/test_CAP_letters.txt',
+ 'content/wallpapers/wallpaper1.png',
+ 'content/wallpapers/wallpaper2.png',
+ 'content/wallpapers/wallpaper3.png']
actual = impl.list_output_files()
self.assertEquals(sorted(actual), sorted(expected))
@@ -273,5 +276,24 @@
# There should be nothing in the copy list
self.assertEquals(copylist, [])
+ def test_get_copy_list_with_multiple_includes_from_sequence(self):
+ impl = self.load_impl('assets/s60/implml/multiple_input_includes_from_sequence.content')
+ copylist = impl.get_full_copy_list()
+ self.assertEquals(sorted(copylist),
+ sorted(
+ [('assets/s60/content/test/foo.txt', 'widget/temp/foo.txt', False),
+ ('assets/s60/content/test/bar.txt', 'widget/temp/bar.txt', False),
+ ('assets/s60/content/test/baz.txt', 'widget/temp/baz.txt', False),
+ ('assets/s60/content/test/s60.txt', 'widget/temp/s60.txt', False)]))
+
+ def test_get_copy_list_with_multiple_input_from_sequence_with_flatten(self):
+ impl = self.load_impl('assets/s60/implml/multiple_input_from_sequence_with_flatten.content')
+ copylist = impl.get_full_copy_list()
+ self.assertEquals(sorted(copylist),
+ sorted(
+ [('family/product/content/wallpapers/wallpaper1.png', 'content/wallpapers/1_wallpaper1.png', False),
+ ('family/product/content/wallpapers/wallpaper2.png', 'content/wallpapers/2_wallpaper2.png', False),
+ ('family/product/content/wallpapers/wallpaper3.png', 'content/wallpapers/3_wallpaper3.png', False)]))
+
if __name__ == '__main__':
unittest.main()
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/common/ConeTemplatePlugin/Jinja2-2.1.1-py2.5-win32.egg
Binary file configurationengine/source/plugins/common/ConeTemplatePlugin/Jinja2-2.1.1-py2.5-win32.egg has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py Thu Oct 21 16:36:53 2010 +0300
@@ -141,10 +141,10 @@
name_tdf = os.path.join(name_tdf,name_tdf+".tdf")
input_tdf = os.path.join(zip_output,name_tdf)
- command_line = "makepackage -input " + input_tdf + " -output " + output_path
+ command_line = "makepackage -input \"%s\" -output \"%s\"" % (input_tdf, output_path)
if len(theme_version) != 0:
- command_line = command_line + " -ver "+ theme_version
+ command_line = "%s -ver %s" % (command_line, theme_version)
if theme.get_uid() != None:
command_line = command_line + " -uid " + theme.get_uid()
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_function.py
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_function.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_function.py Thu Oct 21 16:36:53 2010 +0300
@@ -28,6 +28,7 @@
import os
import logging
+import re
def convert_hexa_to_decimal(hexa_number):
"""
@@ -61,14 +62,21 @@
This method takes the name of the tdf file from the .project file
"""
- path = os.path.join(path,".project")
- etree = ElementTree.parse(path)
-
- el_name = etree.find("name")
- if el_name != None:
- return el_name.text
+ prj_file_path = os.path.join(path,".project")
+ if os.path.exists(prj_file_path):
+ etree = ElementTree.parse(prj_file_path)
+
+ el_name = etree.find("name")
+ if el_name != None:
+ return el_name.text
+ else:
+ logging.getLogger('cone.thememl').error("The element name is not in %s" % prj_file_path)
else:
- logging.getLogger('cone.thememl').error("The element name is not in %s" % path)
+ logging.getLogger('cone.thememl').info("No .project file found. Trying to find tdf file.")
+ for root,dirs,files in os.walk(path):
+ for f in files:
+ if f.endswith('tdf'):
+ return re.sub('\.tdf', '', os.path.join(root, f))
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/unzip.py
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/unzip.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/unzip.py Thu Oct 21 16:36:53 2010 +0300
@@ -22,17 +22,19 @@
if (os.path.exists(dir) is not True):
os.mkdir(dir, 0777)
-
zfobj = zipfile.ZipFile(file)
for name in zfobj.namelist():
filePath = dir + name
if name.endswith('/'):
- os.mkdir(filePath)
+ if not os.path.exists(filePath):
+ createEmtyResource(filePath)
+ #os.mkdir(filePath)
else:
- createEmtyResource(filePath)
- outfile = open(dir+ name, 'wb')
- outfile.write(zfobj.read(name))
- outfile.close()
+ if not os.path.exists(filePath):
+ createEmtyResource(filePath)
+ outfile = open(dir+ name, 'wb')
+ outfile.write(zfobj.read(name))
+ outfile.close()
def createEmtyResource(path):
splitdrive = os.path.splitdrive(path)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/plugins/symbian/integration-test/unittest_generate.py
--- a/configurationengine/source/plugins/symbian/integration-test/unittest_generate.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/plugins/symbian/integration-test/unittest_generate.py Thu Oct 21 16:36:53 2010 +0300
@@ -76,7 +76,7 @@
project = project_dir,
expected = os.path.join(ROOT_PATH, 'testdata/generate/expected_last_layer'),
args = '--layer -1',
- linux_ignores = ['anim1.mbm', 'anim2.mif', '20000000.txt', '10207114', 'themepackage.mbm', 'themepackage.mif', '12340001', '12340002'])
+ linux_ignores = ['anim1.mbm', 'anim2.mif', '20000000.txt', '10207114', 'themepackage.mbm', 'themepackage.mif', '12340001', '12340002', 'resource'])
def test_generate_all_impls_target_rofs2_file_storage(self):
project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
@@ -101,7 +101,7 @@
project = project_zip,
expected = os.path.join(ROOT_PATH, 'testdata/generate/expected_last_layer'),
args = '--layer -1',
- linux_ignores = ['anim1.mbm', 'anim2.mif', '20000000.txt', '10207114', 'themepackage.mbm', 'themepackage.mif', '12340001', '12340002' ])
+ linux_ignores = ['anim1.mbm', 'anim2.mif', '20000000.txt', '10207114', 'themepackage.mbm', 'themepackage.mif', '12340001', '12340002', 'resource' ])
def _run_test_generate_all_impls_on_last_layer(self, workdir, project, expected, args='', linux_ignores=[]):
# Create a temp workdir and go there to run the test
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/cone_tool.py
--- a/configurationengine/source/scripts/cone_tool.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/cone_tool.py Thu Oct 21 16:36:53 2010 +0300
@@ -32,6 +32,18 @@
print("Officially supported versions are 2.5 and 2.6")
sys.exit(1)
+try:
+ import jinja2
+except:
+ print "ERROR: Jinja2 library is not installed - please install it by running 'easy_install Jinja2'"
+ sys.exit(1)
+
+try:
+ import lxml
+except:
+ print "ERROR: Python LXML library is not installed - please install it by running 'easy_install lxml'"
+ sys.exit(1)
+
import os
import fnmatch
import re
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/conesub_export.py
--- a/configurationengine/source/scripts/conesub_export.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/conesub_export.py Thu Oct 21 16:36:53 2010 +0300
@@ -138,6 +138,14 @@
"Filters out all files with extension sis, sisx, wgz or wgt.",
default=None)
+ group.add_option("--include-content-filter",
+ dest="include_content_filter",
+ help="Filters out files and folders from content folder which don't match with "\
+ "the given regular expression. Matching is case-insensitive. "\
+ "Example --include-content-filter=\".*(manual|configurator).*\" "\
+ "Filters out all content files which don't have manual or configurator in their path.",
+ default=None)
+
parser.add_option_group(group)
(options, args) = parser.parse_args()
@@ -201,6 +209,7 @@
added_layers = options.added,
empty_folders = not options.exclude_empty_folders,
exclude_filters = {"content": options.exclude_content_filter},
+ include_filters = {"content": options.include_content_filter},
options = options)
else:
_export_to_storage(project = project,
@@ -209,10 +218,11 @@
added_layers = options.added,
empty_folders = not options.exclude_empty_folders,
exclude_filters = {"content": options.exclude_content_filter},
+ include_filters = {"content": options.include_content_filter},
options = options)
-def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders, exclude_filters, options):
+def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders, exclude_filters, include_filters, options):
assert len(configs) > 0
# If the remote storage is not given, determine it automatically based
@@ -240,7 +250,8 @@
project.export_configuration(config,
remote_project.storage,
empty_folders = empty_folders,
- exclude_filters = exclude_filters)
+ exclude_filters = exclude_filters,
+ include_filters = include_filters)
print "Export %s to %s done!" % (config_path, remote_project_location)
# Setting first as active configuration if there are more than one configuration defined.
@@ -254,9 +265,9 @@
remote_project.save()
remote_project.close()
- _add_layers(project, remote_project_location, added_layers, empty_folders, exclude_filters, options)
+ _add_layers(project, remote_project_location, added_layers, empty_folders, exclude_filters, include_filters, options)
-def _add_layers(source_project, remote_project_location, added_configs, empty_folders, exclude_filters, options):
+def _add_layers(source_project, remote_project_location, added_configs, empty_folders, exclude_filters, include_filters, options):
"""
Add new configuration layers from source_project into
"""
@@ -278,7 +289,8 @@
source_project.export_configuration(existing_config,
target_project.storage,
empty_folders = empty_folders,
- exclude_filters = exclude_filters)
+ exclude_filters = exclude_filters,
+ include_filters = include_filters)
else:
# The given configuration does not exist in the source project,
# create a new empty layer
@@ -292,7 +304,7 @@
target_project.save()
target_project.close()
-def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders, exclude_filters, options):
+def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders, exclude_filters, include_filters, options):
if not os.path.exists(export_dir):
os.makedirs(export_dir)
@@ -304,7 +316,7 @@
remote_name += '/'
remote_name = os.path.join(export_dir, remote_name)
- _export_to_storage(project, remote_name, [config], added_layers, empty_folders, exclude_filters, options)
+ _export_to_storage(project, remote_name, [config], added_layers, empty_folders, exclude_filters, include_filters, options)
if __name__ == "__main__":
main()
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/conesub_initvariant.py
--- a/configurationengine/source/scripts/conesub_initvariant.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/conesub_initvariant.py Thu Oct 21 16:36:53 2010 +0300
@@ -160,8 +160,25 @@
print >>sys.stderr, "Are you sure the given based-on-configuration is valid?"
sys.exit(2)
- path = coreplat_name + '/' + product
-
+ path = coreplat_name + '/' + product
+
+ # the new way (product)
+ if (os.path.exists(os.path.join(options.project, product, "root.confml"))):
+ path = product
+ # the old way (coreplat/product)
+ elif (os.path.exists(os.path.join(options.project, coreplat_name, product, "root.confml"))):
+ path = coreplat_name + '/' + product
+ # any other way, product root somewhere else (?/?/product/root.confml)
+ else:
+ for root, dirs, files in os.walk(os.path.abspath(options.project)):
+ if os.path.exists(os.path.join(root, product, "root.confml")):
+ fullpath = os.path.abspath(os.path.join(root, product, "root.confml"))
+ m = re.search(r'%s[\\/](.*)[\\/]root.confml' % re.escape(os.path.abspath(options.project)), fullpath)
+ if m:
+ path = m.group(1)
+ path = re.sub(r'\\','/', path)
+ break
+
temp_cpf_folder = tempfile.mkdtemp()
export_options = ExportOptions()
@@ -174,6 +191,7 @@
export_options.config_regexes = None
export_options.export_dir = None
export_options.exclude_content_filter = None
+ export_options.include_content_filter = None
export_options.added = [path + '/customer/custvariant/manual/root.confml',
path + '/customer/custvariant/configurator/root.confml']
export_options.exclude_empty_folders = False
@@ -241,7 +259,8 @@
source_config = options.sourceconfiguration,
target_config = target_config,
layer_finder_func = find_layers,
- merge_policy = MergePolicy.OVERWRITE_LAYER)
+ merge_policy = MergePolicy.OVERWRITE_LAYER,
+ find_pattern = options.find_pattern)
if options.set_active_root:
target_project.get_storage().set_active_configuration(target_config)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/conesub_merge.py
--- a/configurationengine/source/scripts/conesub_merge.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/conesub_merge.py Thu Oct 21 16:36:53 2010 +0300
@@ -16,6 +16,7 @@
import sys
import logging
+import re
from optparse import OptionParser, OptionGroup
import cone_common
@@ -184,7 +185,8 @@
def merge_config_root_to_config_root(source_project, target_project,
source_config, target_config,
layer_finder_func,
- merge_policy):
+ merge_policy,
+ find_pattern=None):
"""
Merge the source configuration root to the target configuration root.
@@ -197,6 +199,10 @@
configuration and target_layer_root the one in the target
configuration.
@param merge_policy: The used merge policy.
+ @param find_pattern: Layers found with this pattern will be used from
+ the source configuration. If the configuration project has a root
+ configuration which has the same ctr code as the source config,
+ the other layers are taken from the found root config.
"""
target_root = get_active_root_if_necessary(target_project, target_config, 'target')
source_root = get_active_root_if_necessary(source_project, source_config, 'source')
@@ -209,22 +215,77 @@
except exceptions.NotFound:
raise MergeFailedException("Configuration root '%s' not found in source project" % source_root)
-
+
+ def get_matching_config_in_target_project(target_prj, src_config):
+
+ def get_based_on_ctr(meta):
+ if meta:
+ for prop in meta.array:
+ if 'name' in prop.attrs and 'value' in prop.attrs:
+ name = prop.attrs['name']
+ if name == 'based_on_ctr':
+ ctr_codes = prop.attrs['value'].split(',')
+ return [ctr.strip() for ctr in ctr_codes]
+ return []
+
+ root_configs = target_prj.list_configurations()
+ based_on_ctr_s = sorted(get_based_on_ctr(src_config.meta))
+ for c in root_configs:
+ based_on_ctr_c = sorted(get_based_on_ctr(target_prj.get_configuration(c).meta))
+ if based_on_ctr_c and based_on_ctr_s:
+ # if only one ctr code specified in source config, try to find root config that has that code
+ # (and maybe some others)
+ if len(based_on_ctr_s) == 1:
+ if based_on_ctr_s[0] in based_on_ctr_c:
+ return c
+ # otherwise try to find a config that has all the same ctr codes
+ elif based_on_ctr_c == based_on_ctr_s:
+ return c
+ return None
+
+
# Create or get the target configuration root
try:
target_config = target_project.get_configuration(target_root)
except exceptions.NotFound:
logger.info('Creating new root configuration %s' % (target_config))
target_config = target_project.create_configuration(target_config)
- for sourcelayer_path in source_config.list_configurations():
- sourcelayer = source_config.get_configuration(sourcelayer_path)
- sourcelayer_path = sourcelayer.path
- if target_config.get_storage().is_resource(sourcelayer.path):
- logger.info('Including layer %s to root %s' % (sourcelayer_path, target_config.path))
- target_config.include_configuration(sourcelayer_path)
- else:
- logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path))
- target_config.create_configuration(sourcelayer_path)
+ # try to find a matching configuration in target project (based_on_ctr)
+ cmp_config_in_target_prj = get_matching_config_in_target_project(target_project, source_config)
+ #cmp_config_in_target_prj = None
+ if cmp_config_in_target_prj:
+ logger.info('Found root %s with the same ctr code(s) from target project.' % cmp_config_in_target_prj)
+ cmp_configurations = target_project.get_configuration(cmp_config_in_target_prj).list_configurations()
+ p = re.compile(find_pattern)
+ for cmp_layer_path in cmp_configurations:
+ if not p.search(cmp_layer_path):
+ if target_config.get_storage().is_resource(cmp_layer_path):
+ logger.info('Including layer %s to root %s' % (cmp_layer_path, target_config.path))
+ target_config.include_configuration(cmp_layer_path)
+ else:
+ logger.info('Creating new layer %s to root %s' % (cmp_layer_path, target_config.path))
+ target_config.create_configuration(cmp_layer_path)
+
+ for sourcelayer_path in source_config.list_configurations():
+ sourcelayer = source_config.get_configuration(sourcelayer_path)
+ sourcelayer_path = sourcelayer.path
+ if p.search(sourcelayer_path):
+ if target_config.get_storage().is_resource(sourcelayer.path):
+ logger.info('Including layer %s to root %s' % (sourcelayer_path, target_config.path))
+ target_config.include_configuration(sourcelayer_path)
+ else:
+ logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path))
+ target_config.create_configuration(sourcelayer_path)
+ else:
+ for sourcelayer_path in source_config.list_configurations():
+ sourcelayer = source_config.get_configuration(sourcelayer_path)
+ sourcelayer_path = sourcelayer.path
+ if target_config.get_storage().is_resource(sourcelayer.path):
+ logger.info('Including layer %s to root %s' % (sourcelayer_path, target_config.path))
+ target_config.include_configuration(sourcelayer_path)
+ else:
+ logger.info('Creating new layer %s to root %s' % (sourcelayer_path, target_config.path))
+ target_config.create_configuration(sourcelayer_path)
# Collect a correctly sorted list of all layer paths to merge
layers_to_merge = layer_finder_func(source_config, target_config)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/expected.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/expected2.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected2.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/expected3.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected3.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/expected4.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected4.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/expected5.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected5.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/expected6.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected6.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/project4.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/project4.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/test_project.cpf
Binary file configurationengine/source/scripts/tests/testdata/initvariant/test_project.cpf has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/initvariant/test_project2.zip
Binary file configurationengine/source/scripts/tests/testdata/initvariant/test_project2.zip has changed
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/expected/invalid_config_report.txt
--- a/configurationengine/source/scripts/tests/testdata/validate/expected/invalid_config_report.txt Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/invalid_config_report.txt Thu Oct 21 16:36:53 2010 +0300
@@ -8,7 +8,7 @@
File: assets/invalid/confml/invalid_element.confml
Line: 8
Type: schema.confml
-Msg: Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive ).
+Msg: Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}pattern, {http://www.w3.org/2001/XMLSchema}minInclusive ).
File: assets/invalid/confml/invalid_type.confml
Line: 4
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/expected/report.xml
--- a/configurationengine/source/scripts/tests/testdata/validate/expected/report.xml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report.xml Thu Oct 21 16:36:53 2010 +0300
@@ -7,7 +7,7 @@
-
+
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/expected/report_only_confml.txt
--- a/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_confml.txt Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_confml.txt Thu Oct 21 16:36:53 2010 +0300
@@ -8,7 +8,7 @@
File: assets/invalid/confml/invalid_element.confml
Line: 8
Type: schema.confml
-Msg: Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive ).
+Msg: Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}pattern, {http://www.w3.org/2001/XMLSchema}minInclusive ).
File: assets/invalid/confml/invalid_type.confml
Line: 4
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/expected/report_only_schema.txt
--- a/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_schema.txt Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_schema.txt Thu Oct 21 16:36:53 2010 +0300
@@ -3,7 +3,7 @@
File: assets/invalid/confml/invalid_element.confml
Line: 8
Type: schema.confml
-Msg: Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive ).
+Msg: Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}pattern, {http://www.w3.org/2001/XMLSchema}minInclusive ).
File: assets/invalid/confml/invalid_type.confml
Line: 4
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/confml/basic_setting_types_test.confml
--- a/configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/confml/basic_setting_types_test.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/confml/basic_setting_types_test.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,5 +1,5 @@
-
+
Feature with basic setting types (ConfML v2.0)
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/root.confml
--- a/configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/root.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/root.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/project/errors_root.confml
--- a/configurationengine/source/scripts/tests/testdata/validate/project/errors_root.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/errors_root.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/testdata/validate/project/no_errors_root.confml
--- a/configurationengine/source/scripts/tests/testdata/validate/project/no_errors_root.confml Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/no_errors_root.confml Thu Oct 21 16:36:53 2010 +0300
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/unittest_export.py
--- a/configurationengine/source/scripts/tests/unittest_export.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/unittest_export.py Thu Oct 21 16:36:53 2010 +0300
@@ -134,6 +134,14 @@
self.fail("Entry '%s' not in zip file '%s'." % (path, zipfile))
finally:
zf.close()
+
+ def assert_zip_entry_exists_not(self, zip_file, path):
+ zf = zipfile.ZipFile(zip_file, "r")
+ try:
+ if path in zf.namelist():
+ self.fail("Entry '%s' in zip file '%s'." % (path, zipfile))
+ finally:
+ zf.close()
def _run_test_export_project_to_project(self,
@@ -397,7 +405,55 @@
expected_cpfs = [('root1.cpf', 'root1.confml'),
('root4.cpf', 'root4.confml')])
+ def test_export_with_include_content_filter_help(self):
+ # test help update
+ cmd = '%s -h' % get_cmd('export')
+ out = self.run_command(cmd)
+ lines = out.split(os.linesep)
+ self.assertTrue(' --include-content-filter=INCLUDE_CONTENT_FILTER' in lines)
+
+ def test_export_with_include_content_filter_project_to_cpf(self):
+ # test cpf export
+ source = os.path.join(TEMP_DIR, "layers")
+ remote = os.path.join(TEMP_DIR, 'layers.cpf')
+ self.remove_if_exists(remote)
+
+ unzip_file(EXPORT_TEST_PROJECT, source, delete_if_exists=True)
+
+ cmd = '%s -p "%s" -c "root4.confml" -r "%s" --include-content-filter="%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote,".*layer1.*")
+ out = self.run_command(cmd)
+
+ # layer1 content
+ self.assert_zip_entry_exists(remote, "root4.confml")
+ self.assert_zip_entry_exists(remote, "Layer1/content/default_file.txt")
+ self.assert_zip_entry_exists(remote, "Layer1/content/seq/def1_file.txt")
+
+ # filtered content
+ self.assert_zip_entry_exists_not(remote, "Layer2/content/layer2_file.txt")
+ self.assert_zip_entry_exists_not(remote, "Layer3/content/seq/layer3_file.txt")
+ self.assert_zip_entry_exists_not(remote, "Layer4/content/seq/layer4_file.txt")
+
+ def test_export_with_include_content_filter_cpf_to_cpf(self):
+ # test cpf export
+ remote = os.path.join(TEMP_DIR, 'layers2.cpf')
+ self.remove_if_exists(remote)
+
+
+
+ cmd = '%s -p "%s" -c "root4.confml" -r "%s" --include-content-filter="%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote,".*layer2.*")
+ out = self.run_command(cmd)
+
+ # layer1 content
+ self.assert_zip_entry_exists(remote, "root4.confml")
+ self.assert_zip_entry_exists(remote, "Layer2/content/layer2_file.txt")
+
+ # filtered content
+ self.assert_zip_entry_exists_not(remote, "Layer1/content/default_file.txt")
+ self.assert_zip_entry_exists_not(remote, "Layer3/content/seq/layer3_file.txt")
+ self.assert_zip_entry_exists_not(remote, "Layer4/content/seq/layer4_file.txt")
+
+
class TestExportInvalidArgs(BaseTestCase):
def _run_test_invalid_args(self, args, expected_msg):
diff -r 0951727b8815 -r d2c80f5cab53 configurationengine/source/scripts/tests/unittest_initvariant.py
--- a/configurationengine/source/scripts/tests/unittest_initvariant.py Wed Sep 08 12:20:56 2010 +0300
+++ b/configurationengine/source/scripts/tests/unittest_initvariant.py Thu Oct 21 16:36:53 2010 +0300
@@ -34,7 +34,7 @@
class TestInitVariant(BaseTestCase):
- def _prepare_workdir(self, subdir, expected_zip):
+ def _prepare_workdir(self, subdir, project_zip, expected_zip):
WORKDIR = os.path.join(TEMP_DIR, subdir)
PROJECT_DIR = os.path.join(WORKDIR, 'project')
EXPECTED_DIR = os.path.join(WORKDIR, 'expected')
@@ -42,7 +42,7 @@
self.remove_if_exists(WORKDIR)
unzip_file.unzip_file(
- os.path.join(TESTDATA_DIR, 'test_project.zip'),
+ os.path.join(TESTDATA_DIR, project_zip),
PROJECT_DIR)
unzip_file.unzip_file(
os.path.join(TESTDATA_DIR, expected_zip),
@@ -57,8 +57,8 @@
p.close()
return active_root
- def test_initvariant(self):
- PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var1', 'expected.zip')
+ def test_initvariant_set_active_root(self):
+ PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var1', 'test_project.zip', 'expected.zip')
self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
@@ -70,8 +70,8 @@
'testprod_custvariant_123_foo_root.confml')
- def test_initvariant_2(self):
- PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var2', 'expected2.zip')
+ def test_initvariant_do_not_set_active_root(self):
+ PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var2', 'test_project.zip', 'expected2.zip')
self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
@@ -83,17 +83,54 @@
def test_initvariant_based_on_configuration(self):
- PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var3', 'expected3.zip')
+ PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var3', 'test_project.zip', 'expected3.zip')
self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
cmd = '%s -p "%s" -c foovariant.confml --variant-id=123 -b testprod_custvariant_root.confml' % (get_cmd('initvariant'), PROJECT_DIR)
-
+ self.run_command(cmd)
+
+ self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
+ self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+
+ def test_initvariant_based_on_configuration_on_dcp_structure(self):
+ # variant dir is project/product/customer/variant instead of project/coreplat/product/customer/variant
+ PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var4', 'project4.zip', 'expected4.zip')
+
+ cmd = '%s -p "%s" -c foovariant.confml --variant-id=123 -b testprod_custvariant_root.confml' % (get_cmd('initvariant'), PROJECT_DIR)
+ self.run_command(cmd)
+
+ self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
+ self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+
+ # test that when root config in cpf has multiple ctr codes defined and a matching updated
+ # root config with all the same ctr codes is found, the target root config is created
+ # accordingly
+ def test_initvariant_with_updated_root_in_target_project(self):
+ PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var5', 'test_project2.zip', 'expected5.zip')
+ TEST_CPF = os.path.join(TESTDATA_DIR, 'test_project.cpf')
+ ROOT_CONFIG = 'testprod_custvariant_03_root.confml'
+ FIND_LAYER_REGEXP = r'.*custvar[^/].*|.*/configurator/.*|.*/manual/.*'
+
+ cmd = '%s -p "%s" -s %s -c foovariant.confml --variant-id=123 -r %s --find-layer-regexp=\"%s\"' % (get_cmd('initvariant'), PROJECT_DIR, ROOT_CONFIG, TEST_CPF, FIND_LAYER_REGEXP)
+ self.run_command(cmd)
+
+ self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
+ self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+
+ # test that when root config in cpf has ONE ctr code defined, a matching updated root config is
+ # found from target project and the target root config is created accordingly
+ def test_initvariant_with_one_matching_ctr_code(self):
+ PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var6', 'test_project2.zip', 'expected6.zip')
+ TEST_CPF = os.path.join(TESTDATA_DIR, 'test_project.cpf')
+ ROOT_CONFIG = 'testprod_custvariant_04_root.confml'
+ FIND_LAYER_REGEXP = r'.*custvar[^/].*|.*/configurator/.*|.*/manual/.*'
+
+ cmd = '%s -p "%s" -s %s -c foovariant.confml --variant-id=123 -r %s --find-layer-regexp=\"%s\"' % (get_cmd('initvariant'), PROJECT_DIR, ROOT_CONFIG, TEST_CPF, FIND_LAYER_REGEXP)
self.run_command(cmd)
self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
-
if __name__ == '__main__':
unittest.main()