def test_create_generator_with_extraparams(self): prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject"))) config = prj.get_configuration('product.confml') dview = config.get_default_view() impl = impl_from_resource('variant/implml/startupmif_animation_with_version.imageml', config) # 1st impl self.assertEquals(impl.generators[0].extraparams, '/V3') # Assert the the extraparams is actually used in the command command_obj = impl.generators[0].get_command() cmd = command_obj.get_command(command_obj._get_filtered_input_files()) self.assertEquals(len(cmd), 6) self.assertEquals(cmd[2], r'/V3') # 2nd impl self.assertEquals(impl.generators[1].extraparams, '${StartupSettings.PluginTimeout}') self.assertEquals(utils.expand_refs_by_default_view(impl.generators[1].extraparams, dview), '30000') # Assert the the extraparams is actually used in the command command_obj = impl.generators[1].get_command() cmd = command_obj.get_command(command_obj._get_filtered_input_files()) self.assertEquals(len(cmd), 6) self.assertEquals(cmd[2], r'30000') # 3rd impl self.assertEquals(impl.generators[2].extraparams, '${StartupSettings.PluginTimeout}') self.assertEquals(utils.expand_refs_by_default_view(impl.generators[1].extraparams, dview), '30000') # Assert the the extraparams is actually used in the command command_obj = impl.generators[2].get_command() cmd = command_obj.get_command(command_obj._get_filtered_input_files()) self.assertEquals(len(cmd), 4) self.assertEquals(cmd[1], r'30000')
def extraparams(self): if self._generator.extraparams and self._generator.configuration: dview = self._generator.configuration.get_default_view() return utils.expand_refs_by_default_view( self._generator.extraparams, dview) else: return self._generator.extraparams or ''
def create_feature(self, config): """ Add a feature based on this temp feature definition to the given configuration. """ if '.' in self.ref: pos = self.ref.rfind('.') ref = self.ref[pos + 1:] namespace = self.ref[:pos] else: ref = self.ref namespace = '' mapping = { 'string': cone.confml.model.ConfmlStringSetting, 'int': cone.confml.model.ConfmlIntSetting, 'real': cone.confml.model.ConfmlRealSetting, 'boolean': cone.confml.model.ConfmlBooleanSetting } # Create temp variables always name being also the ref feature = mapping[self.type](ref, name=ref) setattr(feature, TEMP_FEATURE_MARKER_VARNAME, True) config.add_feature(feature, namespace) value = utils.expand_refs_by_default_view(self.value, config.get_default_view()) config.add_data(api.Data(fqr=self.ref, value=value))
def get_output_file(self, output_dir, config): """ Return the path of the output file specified by this output object. """ # Expand ConfML references file = utils.expand_refs_by_default_view(self.file, config.get_default_view()) return os.path.normpath(os.path.join(output_dir, file))
def parse_filters(self, etree): filters = [] filter_elems = etree.findall("{%s}filter" % self.namespaces[0]) for filter_elem in filter_elems: if filter_elem != None: filter = Filter() if filter_elem.get('name') != None: name = filter_elem.get('name') if self.configuration != None: name = utils.expand_refs_by_default_view( name, self.configuration.get_default_view()) filter.set_name(name) if filter_elem.get('file') != None: file = filter_elem.get('file') if self.configuration != None: file = utils.expand_refs_by_default_view( file, self.configuration.get_default_view()) filter.set_path(file) if filter_elem.text != None: filter.set_code(filter_elem.text) if filter_elem.get('file') != None: logging.getLogger('cone.templateml').warning( "In filter element file attribute and text defined. Using filter found from file attribute." ) filters.append(filter) filters_elems = etree.findall("{%s}filters" % self.namespaces[0]) for filters_elem in filters_elems: if filters_elem != None: filter = Filter() if filters_elem.get('file') != None: file = filters_elem.get('file') if self.configuration != None: file = utils.expand_refs_by_default_view( file, self.configuration.get_default_view()) filter.set_path(file) if filters_elem.text != None: filter.set_code(filters_elem.text) if filters_elem.get('file') != None: logging.getLogger('cone.templateml').warning( "In filters element file attribute and text defined. Using filters found from file attribute." ) filters.append(filter) return filters
def __solve_ref(self, inputstr): """ Internal function to solve whether input is ref or just normal input string. For refs actual ConfML value is resolved and returned. Non-refs are returned as such. """ if inputstr and isinstance(inputstr, types.StringType): return utils.expand_refs_by_default_view(inputstr, self.dview) else: return inputstr
def expand_output_refs_by_default_view(self): for output in self.outputs: if output.encoding: if self.configuration != None: output.set_encoding( utils.expand_refs_by_default_view( output.encoding, self.configuration.get_default_view())) try: codecs.lookup(output.encoding) except LookupError: raise exceptions.ParseError("Invalid output encoding: %s" % output.encoding) if output.filename: if self.configuration != None: output.set_filename( utils.expand_refs_by_default_view( output.filename, self.configuration.get_default_view())) if output.path: if self.configuration != None: output.set_path( utils.expand_refs_by_default_view( output.path, self.configuration.get_default_view())) if output.newline: newline = output.newline if self.configuration != None: newline = utils.expand_refs_by_default_view( output.newline, self.configuration.get_default_view()) if newline.lower() in self.NEWLINE_WIN_PARSE_OPTIONS: output.set_newline(OutputFile.NEWLINE_WIN) if output.bom: bom = output.bom if self.configuration != None: bom = utils.expand_refs_by_default_view( output.bom, self.configuration.get_default_view()) output.bom = bom.lower() in ('1', 'true', 't', 'yes', 'y') if output.fearef: if self.configuration != None: fea = self.configuration.get_default_view().get_feature( output.fearef) output.set_filename(fea.value)
def write_to_file(self, output_dir, context): """ Write the text file specified by this output object to the given output directory. """ # Get the actual output path and encoding file_path = self.get_output_file(output_dir, context.configuration) encoding = utils.expand_refs_by_default_view( self.encoding, context.configuration.get_default_view()) # Generate the binary data to write text = utils.expand_refs_by_default_view( self.text, context.configuration.get_default_view()) data = text.encode(encoding) # Write the file. f = context.create_file(file_path, mode="wb") try: f.write(data) finally: f.close()
def test_expand_refs_by_default_view(self): VALUES = { 'Test.Color': 'brown', 'Test.Animal1': 'fox', 'Test.Animal2': 'dog' } class DummyFeature(object): def __init__(self, ref): self.ref = ref def get_original_value(self): return VALUES[self.ref] class DummyDefaultView(object): def get_feature(self, ref): if ref in VALUES: return DummyFeature(ref) else: raise exceptions.NotFound() dview = DummyDefaultView() result = utils.expand_refs_by_default_view( "The quick ${Test.Color} ${Test.Animal1} jumps over the lazy ${Test.Animal2}.", dview) self.assertEquals(result, "The quick brown fox jumps over the lazy dog.") # Test expanding with a non-existent ref result = utils.expand_refs_by_default_view( "The quick ${Test.Color} ${Test.Foo} jumps over the lazy ${Test.Animal2}.", dview) self.assertEquals(result, "The quick brown jumps over the lazy dog.") # Test expanding with a non-existent ref and a custom default value result = utils.expand_refs_by_default_view( "The quick ${Test.Color} ${Test.Foo} jumps over the lazy ${Test.Animal2}.", dview, default_value_for_missing='giraffe') self.assertEquals(result, "The quick brown giraffe jumps over the lazy dog.")
def solve_ref(self, inputdata): """ Internal function to solve whether input is ref or just normal input string. For refs actual ConfML value is resolved and returned. Non-refs are returned as such. """ dview = self.source_configuration.get_default_view() if inputdata and isinstance(inputdata, types.StringType): return utils.expand_refs_by_default_view(inputdata, dview) elif inputdata and isinstance(inputdata, types.DictType): retDict = {} for key in inputdata: retDict[self.solve_ref(key)] = self.solve_ref(inputdata[key]) return retDict else: return inputdata
def validate(self): for output in self.impl.output_objects: encoding = None try: encoding = utils.expand_refs_by_default_view( output.encoding, self.context.configuration.get_default_view(), catch_not_found=False) except exceptions.NotFound: # Ignore invalid setting references, they are validated # in another validator continue if encoding is not None: # Check the encoding try: codecs.lookup(encoding) except LookupError: prob = api.Problem(msg=u"Invalid encoding '%s'" % encoding, type=self.PROBLEM_TYPES[0], line=output.lineno, file=self.impl.ref) self.context.problems.append(prob)
def _expand_refs(text, config): if config is not None: return utils.expand_refs_by_default_view(text, config.get_default_view()) else: return text
def depth(self): if self._depth and self.configuration: dview = self.configuration.get_default_view() return utils.expand_refs_by_default_view(self._depth, dview) else: return self._depth or ''
def main(argv=sys.argv): """ Initialize a variant from a cpf. """ parser = OptionParser(version="%%prog %s" % VERSION) parser.add_options(cone_common.COMMON_OPTIONS) parser.add_option("-p", "--project", dest="project", help="Defines the location of current project. Default is the current working directory.", default=".", metavar="STORAGE") group = OptionGroup(parser, 'Initvariant options', 'The initvariant action is intended for merging a variant CPF back into the ' 'configuration project, or creating a new empty variant based on an existing ' 'configuration. It merges all customer variant layers (layers with ' 'custvariant* in their path name) and renames them based on the variant ID ' 'and variant name ("custvariant_<id>_<name>").') group.add_option("-c", "--configuration", dest="configuration", help="Defines the name of the target configuration. By default the " "configuration file name is composed of product name, variant ID " "and variant name like this: <product>_custvariant_<id>_<name>_root.confml", metavar="CONFIG") group.add_option("-r", "--remote", dest="remote", help="Defines the location of remote storage (CPF)", metavar="STORAGE") group.add_option("-s", "--sourceconfiguration", dest="sourceconfiguration", help="Defines the name of the remote configuration inside the remote storage. " "Default is the active root of the remote project.", metavar="CONFIG") group.add_option("--variant-id", help="Variant ID, mandatory.") group.add_option("--variant-name", help="Variant name, optional.") group.add_option("--product-name", help="Product name, taken from the configuration data by default " "(i.e. defaults to '${imakerapi.productname}')", default="${imakerapi.productname}") group.add_option("--set-active-root", action="store_true", help="Set the newly created (or update) configuration root as the " "project's active root after the merge is done.") group.add_option("-b","--based-on-configuration", dest="boconfig", help="Defines the configuration root which is used as a base " "configuration for the new empty variant.") group.add_option("--find-layer-regexp", dest="find_pattern", default='.*/manual/.*|.*/configurator/.*', help="Defines the pattern which is used to find the layers " "from source configuration that will be merged" "Default: '.*/manual/.*|.*/configurator/.*' " ) parser.add_option_group(group) (options, _) = parser.parse_args(argv) cone_common.handle_common_options(options) # Check the passed options if not options.remote and not options.boconfig: parser.error("Remote project or based-on-configuration must be given") if options.remote and options.boconfig: parser.error("Only either remote project or based-on-configuration can be given, but not both") if not options.variant_id: parser.error("Variant ID must be given") temp_cpf_folder = None if options.boconfig: class ExportOptions(object): pass path = '' coreplat_name = '' product = '' project = api.Project(api.Storage.open(options.project,"a", username=options.username, password=options.password)) config = project.get_configuration(options.boconfig) meta = config.meta if meta: for prop in meta.array: if 'name' in prop.attrs and 'value' in prop.attrs: name = prop.attrs['name'] if name == 'coreplat_name': coreplat_name = prop.attrs['value'] if name == 'product_name': product = prop.attrs['value'] if not coreplat_name or not product: print >>sys.stderr, "Could not find coreplat_name or product_name from meta data." print >>sys.stderr, "Are you sure the given based-on-configuration is valid?" sys.exit(2) 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() export_options.project = options.project export_options.remote = os.path.join(temp_cpf_folder, 'temp.cpf') export_options.configs = [options.boconfig] export_options.username = options.username export_options.password = options.password export_options.config_wildcards = None 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 export_options.action = None options.remote = export_options.remote print "Exporting variant CPF to a temporary directory" run_export(export_options) target_project = api.Project(api.Storage.open(options.project,"a", username=options.username, password=options.password)) source_project = api.Project(api.Storage.open(options.remote,"r", username=options.username, password=options.password)) print "Target project: %s" % options.project print "Source project: %s" % options.remote replace_dict = {"VAR_ID": options.variant_id, "VAR_NAME": options.variant_name} try: # Open the source configuration source_config = get_active_root_if_necessary(source_project, options.sourceconfiguration, 'source') source_config = source_project.get_configuration(source_config) # Determine the new name of the layer part (replaces 'custvariant[^/]*') if options.variant_name: new_name = "custvariant_%s_%s" % (options.variant_id, options.variant_name) else: new_name = "custvariant_%s" % options.variant_id # Determine the target configuration if options.configuration: target_config = options.configuration else: # Target configuration not given explicitly, automatically # determine the name based on the product name and the new # layer name try: product_name = utils.expand_refs_by_default_view( options.product_name, source_config.get_default_view(), catch_not_found = False) except Exception, e: print "Could not determine product name: %s" % e sys.exit(2) print "Product name: %s" % product_name target_config = "%s_%s_root.confml" % (product_name, new_name) def find_layers(source_config, target_config): ret_list = [] layers = find_variant_layers_to_merge(source_config, target_config, options.find_pattern) p = re.compile(r'custvariant[^/]*') for layer in layers: tgt_layer = p.sub(new_name, layer) ret_list.append((layer, tgt_layer)) return ret_list # Perform the merge merge_config_root_to_config_root( source_project = source_project, target_project = target_project, source_config = options.sourceconfiguration, target_config = target_config, layer_finder_func = find_layers, merge_policy = MergePolicy.OVERWRITE_LAYER, find_pattern = options.find_pattern) if options.set_active_root: target_project.get_storage().set_active_configuration(target_config)