def concretize()

in lib/ramble/ramble/workspace/workspace.py [0:0]


    def concretize(self, force=False, quiet=False):
        """Concretize software definitions for defined experiments

        Extract suggested software for experiments defined in a workspace, and
        ensure the software environments are defined properly.

        Args:
            force (bool): Whether to overwrite conflicting definitions of named packages or not
            quiet (bool): Whether to silently ignore conflicts or not


        """
        full_software_dict = self.get_software_dict()

        if (
            namespace.packages not in full_software_dict
            or not full_software_dict[namespace.packages]
        ):
            full_software_dict[namespace.packages] = syaml.syaml_dict()
        if (
            namespace.environments not in full_software_dict
            or not full_software_dict[namespace.environments]
        ):
            full_software_dict[namespace.environments] = syaml.syaml_dict()

        packages_dict = full_software_dict[namespace.packages]
        environments_dict = full_software_dict[namespace.environments]

        self.software_environments = ramble.software_environments.SoftwareEnvironments(self)

        experiment_set = self.build_experiment_set(die_on_validate_error=False)

        for _, app_inst, _ in experiment_set.all_experiments():
            app_inst.build_modifier_instances()
            app_inst.add_expand_vars(self)
            env_name_str = app_inst.expander.expansion_str(ramble.keywords.keywords.env_name)
            env_name = app_inst.expander.expand_var(env_name_str)

            if app_inst.package_manager is None:
                continue

            compiler_dicts = [app_inst.compilers]
            for mod_inst in app_inst._modifier_instances:
                compiler_dicts.append(mod_inst.compilers)

            for compiler_dict in compiler_dicts:
                for comp, info in compiler_dict.items():
                    keep_comp = app_inst.expander.satisfies(
                        info["when"], variant_set=app_inst.object_variants
                    )
                    if keep_comp:
                        if comp not in packages_dict or force:
                            packages_dict[comp] = syaml.syaml_dict()
                            packages_dict[comp]["pkg_spec"] = info["pkg_spec"]
                            ramble.config.add(
                                f'software:packages:{comp}:pkg_spec:{info["pkg_spec"]}',
                                scope=self.ws_file_config_scope_name(),
                            )
                            if "compiler_spec" in info and info["compiler_spec"]:
                                packages_dict[comp]["compiler_spec"] = info["compiler_spec"]
                                config_path = (
                                    f"software:packages:{comp}:"
                                    + f'compiler_spec:{info["compiler_spec"]}'
                                )
                                ramble.config.add(
                                    config_path, scope=self.ws_file_config_scope_name()
                                )
                            if "compiler" in info and info["compiler"]:
                                packages_dict[comp]["compiler"] = info["compiler"]
                                config_path = (
                                    f"software:packages:{comp}:" + f'compiler:{info["compiler"]}'
                                )
                                ramble.config.add(
                                    config_path, scope=self.ws_file_config_scope_name()
                                )
                        elif not quiet and not specs_equiv(info, packages_dict[comp]):
                            logger.debug(f"  Spec 1: {str(info)}")
                            logger.debug(f"  Spec 2: {str(packages_dict[comp])}")
                            raise RambleConflictingDefinitionError(
                                f"Compiler {comp} would be defined " "in multiple conflicting ways"
                            )

            logger.debug(f"Trying to define packages for {env_name}")
            app_packages = []
            if env_name in environments_dict:
                if namespace.packages in environments_dict[env_name]:
                    app_packages = environments_dict[env_name][namespace.packages].copy()

            software_dicts = [app_inst.software_specs]
            for mod_inst in app_inst._modifier_instances:
                software_dicts.append(mod_inst.software_specs)

            for software_dict in software_dicts:
                for spec_name, info in software_dict.items():
                    keep_pkg = app_inst.expander.satisfies(
                        info["when"], variant_set=app_inst.object_variants
                    )
                    if keep_pkg:
                        logger.debug(f"    Found spec: {spec_name}")
                        if spec_name not in packages_dict or force:
                            packages_dict[spec_name] = syaml.syaml_dict()
                            packages_dict[spec_name]["pkg_spec"] = info["pkg_spec"]
                            if "compiler_spec" in info and info["compiler_spec"]:
                                packages_dict[spec_name]["compiler_spec"] = info["compiler_spec"]
                            if "compiler" in info and info["compiler"]:
                                packages_dict[spec_name]["compiler"] = info["compiler"]

                        elif not quiet and not specs_equiv(info, packages_dict[spec_name]):
                            logger.debug(f"  Spec 1: {str(info)}")
                            logger.debug(f"  Spec 2: {str(packages_dict[spec_name])}")
                            raise RambleConflictingDefinitionError(
                                f"Package {spec_name} would be defined in multiple "
                                "conflicting ways"
                            )

                        if spec_name not in app_packages:
                            app_packages.append(spec_name)

            if app_packages:
                if env_name not in environments_dict:
                    environments_dict[env_name] = syaml.syaml_dict()

                environments_dict[env_name][namespace.packages] = app_packages.copy()

        ramble.config.config.update_config(
            "software", full_software_dict, scope=self.ws_file_config_scope_name()
        )

        return