def transform(self, config, meta_config=None): """Return a config and a list of changes, if any.""" checker = CompulsoryChecker() problem_list = checker.validate(config, meta_config) missing_sect_opts = [] for report in problem_list: if report.info != checker.WARNING_COMPULSORY_USER_IGNORED: missing_sect_opts.append((report.section, report.option)) missing_sect_opts.sort() missing_sect_opts.sort(lambda x, y: cmp(x[1], y[1])) for sect, opt in missing_sect_opts: if opt is None: config.set([sect]) self.add_report(sect, opt, None, self.ADD_COMPULSORY_SECT) problem_list = checker.validate(config, meta_config) missing_sect_opts = [] for report in problem_list: if report.info != checker.WARNING_COMPULSORY_USER_IGNORED: missing_sect_opts.append((report.section, report.option)) missing_sect_opts.sort() missing_sect_opts.sort(lambda x, y: cmp(x[1], y[1])) for sect, opt in missing_sect_opts: if opt is None: continue var_id = self._get_id_from_section_option(sect, opt) metadata = rose.macro.get_metadata_for_config_id( var_id, meta_config) value = rose.variable.get_value_from_metadata(metadata) config.set([sect, opt], value) self.add_report(sect, opt, value, self.ADD_COMPULSORY_OPT) return config, self.reports
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration.""" section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if config.get([section, option]) is not None: if forced: return self.change_setting(config, keys, value, state, comments, info) return False if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def pretty_format_config(config): """Improve configuration prettiness.""" for section in config.value.keys(): keylist = [section] scheme = keylist[0] if ":" in scheme: scheme = scheme.split(":", 1)[0] try: scheme_module = getattr(rose.formats, scheme) pretty_format_keys = getattr(scheme_module, "pretty_format_keys") pretty_format_value = getattr(scheme_module, "pretty_format_value") except AttributeError: continue new_keylist = pretty_format_keys(keylist) if new_keylist != keylist: node = config.get(keylist) config.unset(keylist) config.set(new_keylist, node.value, node.state, node.comments) section = new_keylist[0] for keylist, node in list(config.walk([section])): values = rose.variable.array_split(node.value, ",") node.value = pretty_format_value(values) new_keylist = pretty_format_keys(keylist) if new_keylist != keylist: config.unset(keylist) config.set(new_keylist, node.value, node.state, node.comments)
def transform(self, config, meta_config=None): """Return a config and a list of changes, if any.""" checker = CompulsoryChecker() problem_list = checker.validate(config, meta_config) missing_sect_opts = [] for report in problem_list: if report.info != checker.WARNING_COMPULSORY_USER_IGNORED: missing_sect_opts.append((report.section, report.option)) missing_sect_opts.sort() missing_sect_opts.sort(lambda x, y: cmp(x[1], y[1])) for sect, opt in missing_sect_opts: if opt is None: config.set([sect]) self.add_report(sect, opt, None, self.ADD_COMPULSORY_SECT) problem_list = checker.validate(config, meta_config) missing_sect_opts = [] for report in problem_list: if report.info != checker.WARNING_COMPULSORY_USER_IGNORED: missing_sect_opts.append((report.section, report.option)) missing_sect_opts.sort() missing_sect_opts.sort(lambda x, y: cmp(x[1], y[1])) for sect, opt in missing_sect_opts: if opt is None: continue var_id = self._get_id_from_section_option(sect, opt) metadata = rose.macro.get_metadata_for_config_id( var_id, meta_config) value = rose.variable.get_value_from_metadata(metadata) config.set([sect, opt], value) self.add_report(sect, opt, value, self.ADD_COMPULSORY_OPT) return config, self.reports
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration.""" section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if config.get([section, option]) is not None: if forced: return self.change_setting_value(config, keys, value, state, comments, info) return False if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration.""" section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) # Search for existing conflicting settings. found_setting = False if config.get([section, option]) is None: strip_dupl = rose.macro.REC_ID_STRIP for keys, node in config.walk(): existing_section = keys[0] existing_base_section = rose.macro.REC_ID_STRIP.sub("", existing_section) if len(keys) == 1: existing_option = None existing_base_option = None else: existing_option = keys[1] existing_base_option = rose.macro.REC_ID_STRIP_DUPL.sub("", existing_option) if option is None: # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'. if existing_section == section or existing_base_section == section: found_setting = True break # For option 'foo', look for 'foo', 'foo(1)'. elif existing_section == section and (existing_option == option or existing_base_option == option): found_setting = True break else: found_setting = True # If already added, quit, unless "forced". if found_setting: if forced: # If forced, override the existing properties. return self.change_setting_value(config, keys, value, state, comments, info) return False # Add parent section if missing. if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) # Set (add) the section/option. config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def store_password(self): """Store the authentication information for self.prefix.""" if self.username and self.username_orig != self.username: user_rose_conf_path = os.path.join(ResourceLocator.USER_CONF_PATH, ResourceLocator.ROSE_CONF) if os.access(user_rose_conf_path, os.F_OK | os.R_OK | os.W_OK): config = rose.config.load(user_rose_conf_path) config.set(["rosie-id", "prefix-username." + self.prefix], self.username) rose.config.dump(config, user_rose_conf_path) if (self.password_store is not None and self.password and self.password_orig != self.password): self.password_store.store_password( self.scheme, self.host, self.username, self.password)
def store_password(self): """Store the authentication information for self.prefix.""" if self.username and self.username_orig != self.username: user_rose_conf_path = os.path.join(ResourceLocator.USER_CONF_PATH, ResourceLocator.ROSE_CONF) if os.access(user_rose_conf_path, os.F_OK | os.R_OK | os.W_OK): config = rose.config.load(user_rose_conf_path) else: config = rose.config.ConfigNode() config.set(["rosie-id", "prefix-username." + self.prefix], self.username) rose.config.dump(config, user_rose_conf_path) if (self.password_store is not None and self.password and self.password_orig != self.password): self.password_store.store_password(self.scheme, self.host, self.username, self.password)
def run_impl_prep(self, config, opts, args, uuid, work_files): """Prepare to run the application.""" if opts.new_mode: conf_dir = opts.conf_dir if not conf_dir or os.path.abspath(conf_dir) == os.getcwd(): raise NewModeError(os.getcwd()) for p in os.listdir("."): self.fs_util.delete(p) # Dump the actual configuration as rose-app-run.conf rose.config.dump(config, "rose-app-run.conf") # Environment variables: PATH conf_dir = opts.conf_dir if conf_dir is None: conf_dir = os.getcwd() conf_bin_dir = os.path.join(conf_dir, "bin") if os.path.isdir(conf_bin_dir): value = conf_bin_dir + os.pathsep + os.getenv("PATH") config.set(["env", "PATH"], value) else: config.set(["env", "PATH"], os.getenv("PATH")) # Free format files not defined in the configuration file # TODO: review location conf_file_dir = os.path.join(conf_dir, rose.SUB_CONFIG_FILE_DIR) file_section_prefix = self.config_pm.get_processor("file").PREFIX if os.path.isdir(conf_file_dir): dirs = [] files = [] for dirpath, dirnames, filenames in os.walk(conf_file_dir): for dirname in dirnames: if dirname.startswith("."): dirnames.remove(dirname) dir = dirpath[len(conf_file_dir) + 1 :] files += [os.path.join(dir, filename) for filename in filenames] if dirpath != conf_file_dir: dirs.append(dir) for target in dirs: section = file_section_prefix + target if config.get([section], no_ignore=True) is None: config.set([section, "mode"], "mkdir") for target in files: section = file_section_prefix + target if config.get([section], no_ignore=True) is None: source = os.path.join(conf_file_dir, target) config.set([section, "source"], source) # Process Environment Variables self.config_pm(config, "env") # Process Files self.config_pm(config, "file", no_overwrite_mode=opts.no_overwrite_mode)
def get_meta_upgrade_module(meta_key): """Import and return the versions.py module for a given meta_key. The meta_key should not contain a version, just the category. For example, it should be 'my-command' rather than 'my-command/vn9.1'. """ config = rose.config.ConfigNode() config.set([rose.CONFIG_SECT_TOP, rose.CONFIG_OPT_META_TYPE], meta_key) meta_path, warning = rose.macro.load_meta_path(config, is_upgrade=True) if meta_path is None: return None meta_path = os.path.abspath(meta_path) print meta_path if not os.path.isfile(os.path.join(meta_path, MACRO_UPGRADE_MODULE_PATH)): return None sys.path.insert(0, os.path.abspath(meta_path)) version_module = __import__(MACRO_UPGRADE_MODULE) sys.path.pop(0) return version_module
def transform(self, config, meta_config=None): """Return a config and a list of changes, if any.""" checker = CompulsoryChecker() problem_list = checker.validate(config, meta_config) missing_sect_opts = [] for report in problem_list: if report.info != checker.WARNING_COMPULSORY_USER_IGNORED: missing_sect_opts.append((report.section, report.option)) missing_sect_opts.sort() missing_sect_opts.sort(lambda x, y: cmp(x[1], y[1])) for sect, opt in missing_sect_opts: if opt is None: config.set([sect]) self.add_report(sect, opt, None, self.ADD_COMPULSORY_SECT) continue if config.get([sect]) is None: config.set([sect]) self.add_report(sect, None, None, self.ADD_MISSING_SECT) var_id = self._get_id_from_section_option(sect, opt) metadata = {} for key, node in meta_config.get([var_id]).value.items(): if node.is_ignored(): continue metadata.update({key: node.value}) value = rose.variable.get_value_from_metadata(metadata) config.set([sect, opt], value) self.add_report(sect, opt, value, self.ADD_COMPULSORY_OPT) return config, self.reports
def get_meta_upgrade_module(meta_key): """Import and return the versions.py module for a given meta_key. The meta_key should not contain a version, just the category. For example, it should be 'my-command' rather than 'my-command/vn9.1'. """ config = rose.config.ConfigNode() config.set([rose.CONFIG_SECT_TOP, rose.CONFIG_OPT_META_TYPE], meta_key) meta_path, warning = rose.macro.load_meta_path(config, is_upgrade=True) if meta_path is None: return None meta_path = os.path.abspath(meta_path) print meta_path if not os.path.isfile(os.path.join(meta_path, MACRO_UPGRADE_MODULE_PATH)): return None sys.path.insert(0, os.path.abspath(meta_path)) version_module = __import__(MACRO_UPGRADE_MODULE) sys.path.pop(0) return version_module
def namelist_dump(args=None, output_file=None, case_mode=None): """Convert Fortran namelist file to a Rose configuration.""" # Input and output options if not args: args = [STD_FILE_ARG] if output_file is None or output_file == STD_FILE_ARG: output_file = sys.stdout else: output_file = open(output_file, "w") # Config: file: sections config = rose.config.ConfigNode() files = [] for arg in args: if arg == STD_FILE_ARG: files.append(sys.stdin) config.set(["file:STDIN"], {}) else: files.append(open(arg, "r")) config.set(["file:" + arg], {}) # Parse files into a list of NamelistGroup objects groups = rose.formats.namelist.parse(files) # Count group in files and group groups_in_file = {} groups_by_name = {} index_of_group = {} for group in groups: name = group.name.lower() if name not in groups_by_name: groups_by_name[name] = [] groups_by_name[name].append(group) index_of_group[group] = len(groups_by_name[name]) if group.file_ not in groups_in_file: groups_in_file[group.file_] = [] groups_in_file[group.file_].append(group) # Add contents to relevant file: sections for file_, groups in groups_in_file.items(): section = "file:" + file_ if file_ == sys.stdin.name: section = "file:STDIN" group_sections = [] for group in groups: group_section = "namelist:" + tr_case(group.name, case_mode) if len(groups_by_name[group.name.lower()]) > 1: group_section += "(" + str(index_of_group[group]) + ")" group_sections.append(group_section) config.set([section, "source"], " ".join(group_sections)) # Add namelist: sections for name, groups in groups_by_name.items(): for group in groups: section = "namelist:" + tr_case(group.name, case_mode) if len(groups) > 1: section += "(" + str(index_of_group[group]) + ")" config.set([section], {}) for obj in group.objects: lhs = tr_case(obj.lhs, case_mode) config.set([section, lhs], obj.get_rhs_as_string()) # Config: write results rose.config.dump(config, output_file, sort_sections=_sort_config_key, sort_option_items=_sort_config_key, env_escape_ok=True) output_file.close()
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration. Args: config (rose.config.ConfigNode): The application configuration. keys (list): A list defining a hierarchy of node.value 'keys'. A section will be a list of one keys, an option will have two. value (string - optional): String denoting the new setting value. Required for options but not for settings. forced (bool - optional) If True override value if the setting already exists. state (str - optional): The state of the new setting - should be one of the ``rose.config.ConfigNode`` states e.g. ``rose.config.ConfigNode.STATE_USER_IGNORED``. Defaults to ``rose.config.ConfigNode.STATE_NORMAL``. comments (list - optional): List of comment lines (strings) for the new setting or ``None``. info (string - optional): A short string containing no new lines, describing the addition of the setting. Returns: None """ section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) # Search for existing conflicting settings. conflict_id = None found_setting = False if config.get([section, option]) is None: for key in config.get_value(): existing_section = key if not existing_section.startswith(section): continue existing_base_section = (rose.macro.REC_ID_STRIP.sub( "", existing_section)) if option is None: # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'. found_setting = (existing_section == section or existing_base_section == section) else: # For 'foo=bar', don't allow sections 'foo(1)', 'foo{bar}'. found_setting = (existing_section != section and existing_base_section == section) if found_setting: conflict_id = existing_section break if option is not None: for keys, _ in config.walk([existing_section]): existing_option = keys[1] existing_base_option = ( rose.macro.REC_ID_STRIP_DUPL.sub( "", existing_option)) # For option 'foo', look for 'foo', 'foo(1)'. if (existing_section == section and (existing_option == option or existing_base_option == option)): found_setting = True conflict_id = self._get_id_from_section_option( existing_section, existing_option) break if found_setting: break else: found_setting = True conflict_id = None # If already added, quit, unless "forced". if found_setting: if forced and (conflict_id is None or id_ == conflict_id): # If forced, override settings for an identical id. return self.change_setting_value(config, keys, value, state, comments, info) if conflict_id: self.add_report(section, option, value, self.WARNING_ADD_CLASH.format( id_, conflict_id), is_warning=True) return False # Add parent section if missing. if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) # Set (add) the section/option. config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration.""" section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) # Search for existing conflicting settings. conflict_id = None found_setting = False if config.get([section, option]) is None: strip_dupl = rose.macro.REC_ID_STRIP for key in config.get_value(): existing_section = key if not existing_section.startswith(section): continue existing_base_section = (rose.macro.REC_ID_STRIP.sub( "", existing_section)) if option is None: # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'. found_setting = (existing_section == section or existing_base_section == section) else: # For 'foo=bar', don't allow sections 'foo(1)', 'foo{bar}'. found_setting = (existing_section != section and existing_base_section == section) if found_setting: conflict_id = existing_section break if option is not None: for keys, node in config.walk([existing_section]): existing_option = keys[1] existing_base_option = ( rose.macro.REC_ID_STRIP_DUPL.sub( "", existing_option)) # For option 'foo', look for 'foo', 'foo(1)'. if (existing_section == section and (existing_option == option or existing_base_option == option)): found_setting = True conflict_id = self._get_id_from_section_option( existing_section, existing_option) break if found_setting: break else: found_setting = True conflict_id = None # If already added, quit, unless "forced". if found_setting: if forced and (conflict_id is None or id_ == conflict_id): # If forced, override settings for an identical id. return self.change_setting_value(config, keys, value, state, comments, info) if conflict_id: self.add_report(section, option, value, self.WARNING_ADD_CLASH.format( id_, conflict_id), is_warning=True) return False # Add parent section if missing. if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) # Set (add) the section/option. config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration.""" section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) # Search for existing conflicting settings. conflict_id = None found_setting = False if config.get([section, option]) is None: strip_dupl = rose.macro.REC_ID_STRIP for key in config.get_value(): existing_section = key if not existing_section.startswith(section): continue existing_base_section = ( rose.macro.REC_ID_STRIP.sub("", existing_section)) if option is None: # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'. found_setting = (existing_section == section or existing_base_section == section) else: # For 'foo=bar', don't allow sections 'foo(1)', 'foo{bar}'. found_setting = (existing_section != section and existing_base_section == section) if found_setting: conflict_id = existing_section break if option is not None: for keys, node in config.walk([existing_section]): existing_option = keys[1] existing_base_option = ( rose.macro.REC_ID_STRIP_DUPL.sub( "", existing_option) ) # For option 'foo', look for 'foo', 'foo(1)'. if (existing_section == section and (existing_option == option or existing_base_option == option)): found_setting = True conflict_id = self._get_id_from_section_option( existing_section, existing_option) break if found_setting: break else: found_setting = True conflict_id = None # If already added, quit, unless "forced". if found_setting: if forced and (conflict_id is None or id_ == conflict_id): # If forced, override settings for an identical id. return self.change_setting_value( config, keys, value, state, comments, info) if conflict_id: self.add_report( section, option, value, self.WARNING_ADD_CLASH.format(id_, conflict_id), is_warning=True ) return False # Add parent section if missing. if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) # Set (add) the section/option. config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def namelist_dump(args=None, output_file=None, case_mode=None): # Input and output options if not args: args = [STD_FILE_ARG] if output_file is None or output_file == STD_FILE_ARG: output_file = sys.stdout else: output_file = open(output_file, "w") # Config: file: sections config = rose.config.ConfigNode() files = [] for arg in args: if arg == STD_FILE_ARG: files.append(sys.stdin) config.set(["file:STDIN"], {}) else: files.append(open(arg, "r")) config.set(["file:" + arg], {}) # Parse files into a list of NamelistGroup objects groups = rose.formats.namelist.parse(files) # Count group in files and group groups_in_file = {} groups_by_name = {} index_of_group = {} for group in groups: name = group.name.lower() if name not in groups_by_name: groups_by_name[name] = [] groups_by_name[name].append(group) index_of_group[group] = len(groups_by_name[name]) if group.file not in groups_in_file: groups_in_file[group.file] = [] groups_in_file[group.file].append(group) # Add contents to relevant file: sections for file, groups in groups_in_file.items(): section = "file:" + file if file == sys.stdin.name: section = "file:STDIN" group_sections = [] for group in groups: group_section = "namelist:" + tr_case(group.name, case_mode) if len(groups_by_name[group.name.lower()]) > 1: group_section += "(" + str(index_of_group[group]) + ")" group_sections.append(group_section) config.set([section, "source"], " ".join(group_sections)) # Add namelist: sections for name, groups in groups_by_name.items(): for group in groups: section = "namelist:" + tr_case(group.name, case_mode) if len(groups) > 1: section += "(" + str(index_of_group[group]) + ")" config.set([section], {}) for object in group.objects: lhs = tr_case(object.lhs, case_mode) config.set([section, lhs], object.get_rhs_as_string()) # Config: write results rose.config.dump(config, output_file, sort_sections=_sort_config_key, sort_option_items=_sort_config_key, env_escape_ok=True) output_file.close()
def write_config(self, filename, tasks): """Write an analysis config file based on a list of tasks provided""" config = rose.config.ConfigNode() for task in tasks: sectionname = task.name if task.resultfileconfig: config.set([sectionname, "resultfile"], task.resultfileconfig) for i in range(1, task.numkgofiles + 1): origvar = "kgo" + str(i) + "fileconfig" valvar = "kgo" + str(i) + "file" if hasattr(task, origvar): config.set([sectionname, valvar], getattr(task, origvar)) if task.extract: config.set([sectionname, "extract"], task.extract) if task.subextract: config.set([sectionname, "extract"], task.extract + ":" + task.subextract) if task.comparison: config.set([sectionname, "comparison"], task.comparison) if task.tolerance: config.set([sectionname, "tolerance"], task.tolerance) if task.warnonfail: config.set([sectionname, "warnonfail"], "true") rose.config.dump(config, filename)
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration.""" section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) # Search for existing conflicting settings. found_setting = False if config.get([section, option]) is None: strip_dupl = rose.macro.REC_ID_STRIP for keys, node in config.walk(): existing_section = keys[0] existing_base_section = (rose.macro.REC_ID_STRIP.sub( "", existing_section)) if len(keys) == 1: existing_option = None existing_base_option = None else: existing_option = keys[1] existing_base_option = (rose.macro.REC_ID_STRIP_DUPL.sub( "", existing_option)) if option is None: # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'. if (existing_section == section or existing_base_section == section): found_setting = True break # For option 'foo', look for 'foo', 'foo(1)'. elif (existing_section == section and (existing_option == option or existing_base_option == option)): found_setting = True break else: found_setting = True # If already added, quit, unless "forced". if found_setting: if forced: # If forced, override the existing properties. return self.change_setting_value(config, keys, value, state, comments, info) return False # Add parent section if missing. if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if value is not None and not isinstance(value, basestring): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) # Set (add) the section/option. config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)
def write_config(self, filename, tasks): """Write an analysis config file based on a list of tasks provided""" config = rose.config.ConfigNode() for task in tasks: sectionname = task.name if task.resultfileconfig: config.set([sectionname, "resultfile"], task.resultfileconfig) for i in range(1, task.numkgofiles + 1): origvar = "kgo" + str(i) + "fileconfig" valvar = "kgo" + str(i) + "file" if hasattr(task, origvar): config.set([sectionname, valvar], getattr(task, origvar)) if task.extract: config.set([sectionname, "extract"], task.extract) if task.subextract: config.set([sectionname, "extract"], task.extract + ":" + task.subextract) if task.comparison: config.set([sectionname, "comparison"], task.comparison) if task.tolerance: config.set([sectionname, "tolerance"], task.tolerance) if task.warnonfail: config.set([sectionname, "warnonfail"], "true") rose.config.dump(config, filename)
def add_setting(self, config, keys, value=None, forced=False, state=None, comments=None, info=None): """Add a setting to the configuration. Args: config (rose.config.ConfigNode): The application configuration. keys (list): A list defining a hierarchy of node.value 'keys'. A section will be a list of one keys, an option will have two. value (string - optional): String denoting the new setting value. Required for options but not for settings. forced (bool - optional) If True override value if the setting already exists. state (str - optional): The state of the new setting - should be one of the ``rose.config.ConfigNode`` states e.g. ``rose.config.ConfigNode.STATE_USER_IGNORED``. Defaults to ``rose.config.ConfigNode.STATE_NORMAL``. comments (list - optional): List of comment lines (strings) for the new setting or ``None``. info (string - optional): A short string containing no new lines, describing the addition of the setting. Returns: None """ section, option = self._get_section_option_from_keys(keys) id_ = self._get_id_from_section_option(section, option) if option is not None and value is None: value = "" if info is None: if option is None: info = self.INFO_ADDED_SECT else: info = self.INFO_ADDED_VAR.format(repr(value)) # Search for existing conflicting settings. conflict_id = None found_setting = False if config.get([section, option]) is None: for key in config.get_value(): existing_section = key if not existing_section.startswith(section): continue existing_base_section = ( rose.macro.REC_ID_STRIP.sub("", existing_section)) if option is None: # For section 'foo', look for 'foo', 'foo{bar}', 'foo(1)'. found_setting = (existing_section == section or existing_base_section == section) else: # For 'foo=bar', don't allow sections 'foo(1)', 'foo{bar}'. found_setting = (existing_section != section and existing_base_section == section) if found_setting: conflict_id = existing_section break if option is not None: for keys, _ in config.walk([existing_section]): existing_option = keys[1] existing_base_option = ( rose.macro.REC_ID_STRIP_DUPL.sub( "", existing_option) ) # For option 'foo', look for 'foo', 'foo(1)'. if (existing_section == section and (existing_option == option or existing_base_option == option)): found_setting = True conflict_id = self._get_id_from_section_option( existing_section, existing_option) break if found_setting: break else: found_setting = True conflict_id = None # If already added, quit, unless "forced". if found_setting: if forced and (conflict_id is None or id_ == conflict_id): # If forced, override settings for an identical id. return self.change_setting_value( config, keys, value, state, comments, info) if conflict_id: self.add_report( section, option, value, self.WARNING_ADD_CLASH.format(id_, conflict_id), is_warning=True ) return False # Add parent section if missing. if option is not None and config.get([section]) is None: self.add_setting(config, [section]) if value is not None and not isinstance(value, str): text = "New value {0} for {1} is not a string" raise ValueError(text.format(repr(value), id_)) # Set (add) the section/option. config.set([section, option], value=value, state=state, comments=comments) self.add_report(section, option, value, info)