예제 #1
0
 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(key=lambda x: str(x[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(key=lambda x: x[1])
     for sect, opt in missing_sect_opts:
         if opt is None:
             continue
         var_id = self._get_id_from_section_option(sect, opt)
         metadata = metomi.rose.macro.get_metadata_for_config_id(
             var_id, meta_config)
         value = metomi.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
예제 #2
0
 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 = metomi.rose.config.load(user_rose_conf_path)
         else:
             config = metomi.rose.config.ConfigNode()
         config.set(["rosie-id", "prefix-username." + self.prefix],
                    self.username)
         metomi.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)
예제 #3
0
    def write_config(self, filename, tasks):
        """Write an analysis config file based on a list of tasks provided"""
        config = metomi.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")
        metomi.rose.config.dump(config, filename)
예제 #4
0
파일: upgrade.py 프로젝트: rolinzcy/rose
    def add_setting(self, config, keys, value=None, forced=False,
                    state=None, comments=None, info=None):
        """Add a setting to the configuration.

        Args:
            config (metomi.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 = (
                    metomi.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 = (
                            metomi.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)
예제 #5
0
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 = metomi.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 = metomi.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
    metomi.rose.config.dump(config,
                            output_file,
                            sort_sections=_sort_config_key,
                            sort_option_items=_sort_config_key,
                            env_escape_ok=True)
    output_file.close()