Skip to content

Commit

Permalink
Fix handling of README files with extensions (#1318)
Browse files Browse the repository at this point in the history
* we have a failing test!

* lint fixes

* check for existing README with all allowed extensions and use that one.

* updated whats new

* fix scope

* Update doc/whats_new.rst

Co-authored-by: Daniel McCloy <[email protected]>

* remove extra print command

Co-authored-by: Daniel McCloy <[email protected]>

* do not cast to str

* throw exception when more than one readme is encountered.

* added a test for multiple readmes

---------

Co-authored-by: Daniel McCloy <[email protected]>
  • Loading branch information
thht and drammock authored Oct 11, 2024
1 parent 420686e commit ed75468
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
1 change: 1 addition & 0 deletions doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Detailed list of changes
- Dealing with alphanumeric ``sub`` entity labels is now fixed for :func:`~mne_bids.write_raw_bids`, by `Aaron Earle-Richardson`_ (:gh:`1291`)
- When processing subject_info data that MNE Python imports as numpy arrays with only one item, MNE-BIDS now unpacks these, resulting in a correct participants.tsv, by `Thomas Hartmann`_ (:gh:`1310`)
- Fixed broken links in examples 7 and 8, by `William Turner`_ (:gh:`1316`)
- All valid extensions for ``README`` files are now accepted. This prevents an extra ``README`` file being created, when one with a ``.txt``, ``.md``, or ``.rst`` extension is already present. By `Thomas Hartmann`_ (:gh:`1318`)

⚕️ Code health
^^^^^^^^^^^^^^
Expand Down
59 changes: 57 additions & 2 deletions mne_bids/tests/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import json
import os.path as op
import shutil
from pathlib import Path

import mne
Expand Down Expand Up @@ -38,7 +39,7 @@
)


@pytest.fixture(scope="session")
@pytest.fixture(scope="function")
def _get_bids_test_dir(tmp_path_factory):
"""Return path to a written test BIDS dir."""
bids_root = str(tmp_path_factory.mktemp("mnebids_utils_test_bids_ds"))
Expand Down Expand Up @@ -76,7 +77,7 @@ def _get_bids_test_dir(tmp_path_factory):
return bids_root


@pytest.fixture(scope="session")
@pytest.fixture(scope="function")
def _get_sidecar_json_update_file(_get_bids_test_dir):
"""Return path to a sidecar JSON updating file."""
bids_root = _get_bids_test_dir
Expand Down Expand Up @@ -292,3 +293,57 @@ def test_update_anat_landmarks(tmp_path):
assert np.allclose(
mri_json["AnatomicalLandmarkCoordinates"][landmark], expected_coords
)


@testing.requires_testing_data
@pytest.mark.parametrize("extension", [None, ".txt", ".rst", ".md"])
def test_readme_conflicts(extension, _get_bids_test_dir):
"""Test that exisiting README files are respected with any extension."""
bids_root = _get_bids_test_dir
assert Path(bids_root, "README").exists()
all_readmes = Path(bids_root).rglob("README*")
assert len(list(all_readmes)) == 1
if extension is not None:
shutil.move(Path(bids_root, "README"), Path(bids_root, f"README{extension}"))

bids_path = BIDSPath(
subject="02",
session=session_id,
run=1,
acquisition=acq,
task=task,
suffix="meg",
root=_get_bids_test_dir,
)

raw_fname = op.join(data_path, "MEG", "sample", "sample_audvis_trunc_raw.fif")
raw = mne.io.read_raw_fif(raw_fname)

write_raw_bids(raw, bids_path, overwrite=False)
all_readmes = Path(bids_root).rglob("README*")
assert len(list(all_readmes)) == 1
shutil.rmtree(bids_root)


@testing.requires_testing_data
def test_multiple_readmes_invalid(_get_bids_test_dir):
"""Test that multiple README files are not allowed."""
bids_root = _get_bids_test_dir
assert Path(bids_root, "README").exists()
shutil.copy(Path(bids_root, "README"), Path(bids_root, "README.md"))
bids_path = BIDSPath(
subject="02",
session=session_id,
run=1,
acquisition=acq,
task=task,
suffix="meg",
root=_get_bids_test_dir,
)

raw_fname = op.join(data_path, "MEG", "sample", "sample_audvis_trunc_raw.fif")
raw = mne.io.read_raw_fif(raw_fname)

with pytest.raises(RuntimeError, match="Multiple README files found"):
write_raw_bids(raw, bids_path, overwrite=False)
shutil.rmtree(bids_root)
13 changes: 12 additions & 1 deletion mne_bids/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,18 @@ def write_raw_bids(
)

# For the remaining files, we can use BIDSPath to alter.
readme_fname = op.join(bids_path.root, "README")
readme_suffixes = ("", ".md", ".rst", ".txt")
found_readmes = sorted(
filter(lambda x: x.suffix in readme_suffixes, bids_path.root.glob("README*"))
)
if len(found_readmes) > 1:
raise RuntimeError(
"Multiple README files found in the BIDS root folder. "
"This violates the BIDS specifications. "
"Please ensure there is only one README file."
)
readme_fname = str((found_readmes or [bids_path.root / "README"])[0])

participants_tsv_fname = op.join(bids_path.root, "participants.tsv")
participants_json_fname = participants_tsv_fname.replace(".tsv", ".json")

Expand Down

0 comments on commit ed75468

Please sign in to comment.