diff --git a/qualibrate_config/core/project/model.py b/qualibrate_config/core/project/model.py index 6863d76..73e5e02 100644 --- a/qualibrate_config/core/project/model.py +++ b/qualibrate_config/core/project/model.py @@ -13,6 +13,7 @@ class Project(BaseModel): created_at: AwareDatetime last_modified_at: AwareDatetime updates: Annotated[Mapping[str, Any], Field(default_factory=dict)] + config: Annotated[Mapping[str, Any] | None, Field(default=None)] @field_serializer("created_at", "last_modified_at") def dt_serializer(self, dt: AwareDatetime) -> str: diff --git a/qualibrate_config/core/project/p_list.py b/qualibrate_config/core/project/p_list.py index f316ff9..2fe5a92 100644 --- a/qualibrate_config/core/project/p_list.py +++ b/qualibrate_config/core/project/p_list.py @@ -86,7 +86,10 @@ def _project_stat_dir( def project_stat( - qualibrate_path: Path, project: str, config_path: Path + qualibrate_path: Path, + project: str, + config_path: Path, + with_config: bool = False, ) -> Project: project_path = get_project_path(qualibrate_path, project) @@ -117,6 +120,7 @@ def project_stat( created_at=created_at.astimezone(), last_modified_at=last_modified_at.astimezone(), updates=project_config, + config=config_dict if with_config else None, ) @@ -139,7 +143,9 @@ def verbose_list_projects( ) -> dict[str, Project]: qualibrate_path = config_path.parent return { - p_name: project_stat(qualibrate_path, p_name, config_path) + p_name: project_stat( + qualibrate_path, p_name, config_path, with_config=True + ) for p_name in list_projects(qualibrate_path) } diff --git a/tests/unit/test_core/test_project/test_p_list.py b/tests/unit/test_core/test_project/test_p_list.py index da9b98b..7523e99 100644 --- a/tests/unit/test_core/test_project/test_p_list.py +++ b/tests/unit/test_core/test_project/test_p_list.py @@ -219,6 +219,65 @@ def test_project_stat_with_no_storage_defined(mocker, tmp_path): assert isinstance(project_obj.last_modified_at, datetime) +def test_project_stat_with_config_includes_full_config(mocker, tmp_path): + project = "proj" + project_path = tmp_path / project + project_path.mkdir() + config_path = tmp_path / "config.toml" + config_dict = {"qualibrate": {"project": project, "storage": {}}} + project_config = {"qualibrate": {"project": project}} + now = datetime.now().astimezone() + + mocker.patch( + "qualibrate_config.core.project.p_list.get_project_path", + return_value=project_path, + ) + mocker.patch( + "qualibrate_config.core.project.p_list.read_config_file", + return_value=config_dict, + ) + mocker.patch( + "qualibrate_config.core.project.p_list.read_project_config_file", + return_value=project_config, + ) + mocker.patch( + "qualibrate_config.core.project.p_list._project_stat_dir", + return_value=(0, now, now), + ) + + project_obj = p_list.project_stat( + tmp_path, project, config_path, with_config=True + ) + + assert project_obj.config == config_dict + assert project_obj.updates == project_config + + +def test_verbose_list_projects_requests_config(mocker, tmp_path): + config_path = tmp_path / "config.toml" + now = datetime.now().astimezone() + + mocker.patch( + "qualibrate_config.core.project.p_list.list_projects", + return_value=["p1"], + ) + project_stat = mocker.patch( + "qualibrate_config.core.project.p_list.project_stat", + return_value=p_list.Project( + name="p1", + nodes_number=1, + created_at=now, + last_modified_at=now, + ), + ) + + p_list.verbose_list_projects(config_path) + + project_stat.assert_called_once_with( + config_path.parent, "p1", config_path, with_config=True + ) + + def test_list_projects_not_exists(mocker, tmp_path): projects = tmp_path / "p1" mock_path = mocker.patch(