Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/meridian/suites/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@

SUITE_FILE = "suite.yaml"
TASKS_DIR = "tasks"
HARBOR_TASK_FILE = "task.toml"


def _looks_like_harbor_tasks(root: Path) -> bool:
"""Harbor keeps task.toml at the dataset root, one level down, or two."""
return any(
candidate.is_file()
for pattern in (HARBOR_TASK_FILE, f"*/{HARBOR_TASK_FILE}", f"*/*/{HARBOR_TASK_FILE}")
for candidate in root.glob(pattern)
)


def _read_yaml(
Expand Down Expand Up @@ -73,12 +83,15 @@ def load_suite(path: str | Path) -> Suite:

suite_file = root / SUITE_FILE
if not suite_file.is_file():
message = f"no {SUITE_FILE} in {root}"
if _looks_like_harbor_tasks(root):
message += "; this looks like Harbor tasks — run `meridian import-harbor` first"
raise SuiteValidationError(
[
ValidationIssue(
code="missing_suite_file",
file=SUITE_FILE,
message=f"no {SUITE_FILE} in {root}",
message=message,
)
]
)
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/test_suite_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,26 @@ def test_missing_suite_file_is_its_own_code(tmp_path: Path) -> None:
assert excinfo.value.codes() == ["missing_suite_file"]


@pytest.mark.unit
def test_a_harbor_dataset_suggests_importing_it_first(tmp_path: Path) -> None:
"""Pointing `run` at a Harbor dataset should name the command that converts it."""
task = tmp_path / "some-harbor-task"
task.mkdir()
(task / "task.toml").write_text("", encoding="utf-8")
with pytest.raises(SuiteValidationError) as excinfo:
load_suite(tmp_path)
assert excinfo.value.codes() == ["missing_suite_file"]
assert "import-harbor" in str(excinfo.value)


@pytest.mark.unit
def test_a_plain_directory_gets_no_harbor_hint(tmp_path: Path) -> None:
(tmp_path / "tasks").mkdir()
with pytest.raises(SuiteValidationError) as excinfo:
load_suite(tmp_path)
assert "import-harbor" not in str(excinfo.value)


@pytest.mark.unit
def test_malformed_yaml_is_reported_as_such(tmp_path: Path) -> None:
shutil.copytree(FIXTURES / "_valid-control", tmp_path / "suite")
Expand Down
Loading