Source code for varats.provider.feature.feature_model_provider

"""Module for the :class:`FeatureProvider`."""
import typing as tp
from pathlib import Path

import benchbuild as bb
from benchbuild.project import Project
from benchbuild.source.base import target_prefix

from varats.provider.provider import Provider
from varats.utils.filesystem_util import lock_file


[docs] class FeatureModelNotFound(FileNotFoundError): """Exception raised when the specified feature model could not be found.""" def __init__(self, project: Project, fm_path: tp.Optional[Path]) -> None: err_msg = f"Could not find feature model for project {project.name}!\n" if fm_path: err_msg += f"No file at: {fm_path}." else: err_msg += "Got no feature-model path." super().__init__(err_msg)
[docs] class FeatureModelProvider(Provider): """Provider for accessing project related FeatureModels.""" fm_repository = "https://github.com/se-sic/ConfigurableSystems.git"
[docs] @classmethod def create_provider_for_project( cls, project: tp.Type[Project] ) -> tp.Optional['FeatureModelProvider']: """ Creates a provider instance for the given project if possible. Returns: a provider instance for the given project if possible, otherwise, ``None`` """ return FeatureModelProvider(project)
[docs] @classmethod def create_default_provider( cls, project: tp.Type[Project] ) -> 'FeatureModelProvider': """ Creates a default provider instance that can be used with any project. Returns: a default provider instance """ raise AssertionError( "All usages should be covered by the project specific provider." )
[docs] def get_feature_model_path( self, # Currently, unused until pascals impl is ready revision: str # pylint: disable=W0613 ) -> tp.Optional[Path]: """ Get the path to a feature model for a specific `revision` that describes the features of a project and their relationships. In case that no feature model exists `None` is returned. Args: revision: of the project, specifying for which state of the project the feature model needs to be valid. Returns: a path to the corresponding feature model """ project_name = self.project.NAME.lower() fully_qualified_fm_name = "FeatureModel" for project_dir in self._get_feature_model_repository_path().iterdir(): if project_dir.name.lower() == project_name: for poss_fm_file in project_dir.iterdir(): if poss_fm_file.stem == fully_qualified_fm_name: return poss_fm_file return None
@staticmethod def _get_feature_model_repository_path() -> Path: fm_source = bb.source.Git( remote=FeatureModelProvider.fm_repository, local="ConfigurableSystems", refspec="origin/HEAD", limit=1, ) lock_path = Path(target_prefix()) / "fm_provider.lock" with lock_file(lock_path): fm_source.fetch() return Path(Path(target_prefix()) / fm_source.local)