def _load_second_pass()

in src/buildstream/_project.py [0:0]


    def _load_second_pass(self):
        project_conf_second_pass = self._project_conf.clone()
        self._project_includes.process(project_conf_second_pass, process_project_options=False)
        config = self._default_config_node.clone()
        project_conf_second_pass._composite(config)

        self._load_pass(config, self.config)

        self._validate_toplevel_node(config, first_pass=False)

        #
        # Now all YAML composition is done, from here on we just load
        # the values from our loaded configuration dictionary.
        #

        # Load artifact remote specs
        caches = config.get_sequence("artifacts", default=[], allowed_types=[MappingNode])
        for node in caches:
            spec = RemoteSpec.new_from_node(node, self.directory)
            self.artifact_cache_specs.append(spec)

        # Load source cache remote specs
        caches = config.get_sequence("source-caches", default=[], allowed_types=[MappingNode])
        for node in caches:
            spec = RemoteSpec.new_from_node(node, self.directory)
            self.source_cache_specs.append(spec)

        # Load sandbox environment variables
        self.base_environment = config.get_mapping("environment")
        self.base_env_nocache = config.get_str_list("environment-nocache")

        # Load sandbox configuration
        self.sandbox = config.get_mapping("sandbox")

        # Load project split rules
        self.splits = config.get_mapping("split-rules")

        # Support backwards compatibility for fail-on-overlap
        fail_on_overlap = config.get_scalar("fail-on-overlap", None)

        # Deprecation check
        if not fail_on_overlap.is_none():
            self._context.messenger.warn(
                "Use of fail-on-overlap within project.conf "
                + "is deprecated. Consider using fatal-warnings instead.",
            )

            if (CoreWarnings.OVERLAPS not in self._fatal_warnings) and fail_on_overlap.as_bool():
                self._fatal_warnings.append(CoreWarnings.OVERLAPS)

        # Load project.refs if it exists, this may be ignored.
        if self.ref_storage == ProjectRefStorage.PROJECT_REFS:
            self.refs.load(self.options)

        # Parse shell options
        shell_options = config.get_mapping("shell")
        shell_options.validate_keys(["command", "environment", "host-files"])
        self._shell_command = shell_options.get_str_list("command")

        # Perform environment expansion right away
        shell_environment = shell_options.get_mapping("environment", default={})
        for key in shell_environment.keys():
            value = shell_environment.get_str(key)
            self._shell_environment[key] = os.path.expandvars(value)

        # Host files is parsed as a list for convenience
        host_files = shell_options.get_sequence("host-files", default=[])
        for host_file in host_files:
            if isinstance(host_file, ScalarNode):
                mount = _HostMount(host_file.as_str())
            else:
                # Some validation
                host_file.validate_keys(["path", "host_path", "optional"])

                # Parse the host mount
                path = host_file.get_str("path")
                host_path = host_file.get_str("host_path", default=None)
                optional = host_file.get_bool("optional", default=False)
                mount = _HostMount(path, host_path, optional)

            self._shell_host_files.append(mount)