Skip to content

Commit ccdb659

Browse files
authored
Merge pull request #1741 from dandi/copilot/add-hint-for-dandiset-yaml
Add HINT validation result for dandiset.yaml in both validate and upload commands
2 parents 953923a + 993be94 commit ccdb659

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

dandi/files/bids.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@
1313

1414
from .bases import GenericAsset, LocalFileAsset, NWBAsset
1515
from .zarr import ZarrAsset
16-
from ..consts import ZARR_MIME_TYPE
16+
from ..consts import ZARR_MIME_TYPE, dandiset_metadata_file
1717
from ..metadata.core import add_common_metadata, prepare_metadata
1818
from ..misctypes import Digest
19-
from ..validate_types import ValidationResult
19+
from ..validate_types import (
20+
ORIGIN_VALIDATION_DANDI_LAYOUT,
21+
Scope,
22+
Severity,
23+
ValidationResult,
24+
)
2025

2126
BIDS_ASSET_ERRORS = ("BIDS.NON_BIDS_PATH_PLACEHOLDER",)
2227
BIDS_DATASET_ERRORS = ("BIDS.MANDATORY_FILE_MISSING_PLACEHOLDER",)
@@ -112,7 +117,42 @@ def _validate(self) -> None:
112117

113118
# Obtain BIDS validation results of the entire dataset through the
114119
# deno-compiled BIDS validator
115-
self._dataset_errors = bids_validate(self.bids_root)
120+
v_results = bids_validate(self.bids_root)
121+
122+
# Validation results from the deno BIDS validator with an additional
123+
# hint, represented as a `ValidationResult` object, following
124+
# each `dandiset.yaml` error, suggesting to add the `dandiset.yaml` file
125+
# to `.bidsignore`.
126+
v_results_extended: list[ValidationResult] = []
127+
128+
for result in v_results:
129+
v_results_extended.append(result)
130+
if (
131+
result.path is not None
132+
and result.dataset_path is not None
133+
and result.path.relative_to(result.dataset_path).as_posix()
134+
== dandiset_metadata_file
135+
):
136+
hint = ValidationResult(
137+
id="DANDI.BIDSIGNORE_DANDISET_YAML",
138+
origin=ORIGIN_VALIDATION_DANDI_LAYOUT,
139+
scope=Scope.DATASET,
140+
origin_result=result,
141+
severity=Severity.HINT,
142+
dandiset_path=result.dandiset_path,
143+
dataset_path=result.dataset_path,
144+
path=result.path,
145+
message=(
146+
f"Consider creating or updating a `.bidsignore` file "
147+
f"in the root of your BIDS dataset to ignore "
148+
f"`{dandiset_metadata_file}`. "
149+
f"Add the following line to `.bidsignore`:\n"
150+
f"{dandiset_metadata_file}"
151+
),
152+
)
153+
v_results_extended.append(hint)
154+
155+
self._dataset_errors = v_results_extended
116156

117157
# Categorized validation results related to individual assets by the
118158
# path of the asset in the BIDS dataset

dandi/tests/test_validate.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,18 @@ def mock_bids_validate(*args: Any, **kwargs: Any) -> list[ValidationResult]:
114114
assert err.dataset_path is not None
115115
assert err.path.relative_to(err.dataset_path).as_posix() == dandiset_metadata_file
116116

117-
assert err.message is not None
118-
assert err.message.startswith(
119-
f"The dandiset metadata file, `{dandiset_metadata_file}`, is not a part of "
120-
f"BIDS specification."
121-
)
117+
# === Assert that there is the dandiset.yaml hint ===
118+
i = None
119+
for i, r in enumerate(validation_results):
120+
if r is err:
121+
break
122+
123+
assert i is not None
124+
# There must be at least one more result after the error
125+
assert len(validation_results) > i + 1
126+
# The next result must be the hint re: dandiset.yaml
127+
assert validation_results[i + 1].id == "DANDI.BIDSIGNORE_DANDISET_YAML"
128+
assert validation_results[i + 1].severity == Severity.HINT
122129

123130

124131
def test_validate_bids_onefile(bids_error_examples: Path, tmp_path: Path) -> None:

dandi/validate.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,22 +186,6 @@ def validate(
186186
):
187187
r_id = id(r)
188188
if r_id not in df_result_ids:
189-
# If the error is about the dandiset metadata file, modify
190-
# the message in the validation to give the context of DANDI
191-
if (
192-
r.path is not None
193-
and r.dataset_path is not None
194-
and r.path.relative_to(r.dataset_path).as_posix()
195-
== dandiset_metadata_file
196-
):
197-
r.message = (
198-
f"The dandiset metadata file, `{dandiset_metadata_file}`, "
199-
f"is not a part of BIDS specification. Please include a "
200-
f"`.bidsignore` file with specification to ignore the "
201-
f"metadata file in your dataset. For more details, see "
202-
f"https://github.com/bids-standard/bids-specification/"
203-
f"issues/131#issuecomment-461060166."
204-
)
205189
df_results.append(r)
206190
df_result_ids.add(r_id)
207191
yield r

0 commit comments

Comments
 (0)