diff --git a/.github/workflows/deploy_remote_tests.yml b/.github/workflows/deploy_remote_tests.yml index c690add3..45bcf9f8 100644 --- a/.github/workflows/deploy_remote_tests.yml +++ b/.github/workflows/deploy_remote_tests.yml @@ -15,7 +15,7 @@ jobs: uses: ./.github/workflows/testing.yml with: pytest_markexpr: 'remote' - os_list: '["macos-13","macos-latest","ubuntu-latest"]' + os_list: '["windows-2022","windows-latest","macos-15-intel","macos-latest","ubuntu-latest"]' python_list: '["3.13"]' secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/src/nwb2bids/_command_line_interface/_main.py b/src/nwb2bids/_command_line_interface/_main.py index 4b5f7930..b299ff36 100644 --- a/src/nwb2bids/_command_line_interface/_main.py +++ b/src/nwb2bids/_command_line_interface/_main.py @@ -5,6 +5,7 @@ from .._converters._run_config import RunConfig from .._core._convert_nwb_dataset import convert_nwb_dataset +from .._inspection._inspection_result import Severity from .._tools._pluralize import _pluralize @@ -121,3 +122,9 @@ def _run_convert_nwb_dataset( if console_notification != "" and not silent: rich_click.echo(message=console_notification) + + not_any_failures = not any(notification.severity == Severity.ERROR for notification in notifications) + if not_any_failures and not silent: + text = "BIDS dataset was successfully created!" + console_notification = rich_click.style(text=text, fg="green") + rich_click.echo(message=console_notification) diff --git a/src/nwb2bids/bids_models/_bids_session_metadata.py b/src/nwb2bids/bids_models/_bids_session_metadata.py index d54f46c0..37dc253f 100644 --- a/src/nwb2bids/bids_models/_bids_session_metadata.py +++ b/src/nwb2bids/bids_models/_bids_session_metadata.py @@ -71,14 +71,15 @@ def _check_fields(self, file_paths: list[pathlib.Path] | list[pydantic.HttpUrl]) title="Invalid session ID", reason=( "The session ID contains invalid characters. " - "BIDS allows only dashes to be used as separators in session entity label. " - "Underscores, spaces, slashes, and special characters (including #) are expressly forbidden." + "BIDS allows only the plus sign to be used as a separator in the subject entity label. " + "Underscores, dashes, spaces, slashes, and other special characters (including #) are " + "expressly forbidden." ), - solution="Rename the session without using spaces or underscores.", + solution="Rename the session without using any special characters except for `+`.", examples=[ - "`ses_01` -> `ses-01`", - "`session #2` -> `session-2`", - "`id 2 from 9/1/25` -> `id-2-9-1-25`", + "`ses_01` -> `ses+01`", + "`session #2` -> `session+2`", + "`id 2 from 9/1/25` -> `id+2+9+1+25`", ], field="nwbfile.session_id", source_file_paths=file_paths, diff --git a/src/nwb2bids/bids_models/_model_globals.py b/src/nwb2bids/bids_models/_model_globals.py index 584871e2..d8fbb32b 100644 --- a/src/nwb2bids/bids_models/_model_globals.py +++ b/src/nwb2bids/bids_models/_model_globals.py @@ -1,4 +1,4 @@ -_VALID_ID_REGEX = r"^[A-Za-z0-9]+" +_VALID_ID_REGEX = r"^[A-Za-z0-9+]+" _VALID_SPECIES_REGEX = r"([A-Z][a-z]* [a-z]+)|(http://purl.obolibrary.org/obo/NCBITaxon_\d+)" _VALID_BIDS_SEXES = { value: True diff --git a/src/nwb2bids/bids_models/_participant.py b/src/nwb2bids/bids_models/_participant.py index abcb71e5..e52288c9 100644 --- a/src/nwb2bids/bids_models/_participant.py +++ b/src/nwb2bids/bids_models/_participant.py @@ -100,14 +100,15 @@ def _check_fields(self, file_paths: list[pathlib.Path] | list[pydantic.HttpUrl]) title="Invalid participant ID", reason=( "The participant ID contains invalid characters. " - "BIDS allows only dashes to be used as separators in subject entity label. " - "Underscores, spaces, slashes, and special characters (including #) are expressly forbidden." + "BIDS allows only the plus sign to be used as a separator in the subject entity label. " + "Underscores, dashes, spaces, slashes, and other special characters (including #) are " + "expressly forbidden." ), - solution="Rename the subject without using spaces or underscores.", + solution="Rename the subject without using any special characters except for `+`.", examples=[ - "`ab_01` -> `ab-01`", - "`subject #2` -> `subject-2`", - "`id 2 from 9/1/25` -> `id-2-9-1-25`", + "`ab_01` -> `ab+01`", + "`subject #2` -> `subject+2`", + "`id 2 from 9/1/25` -> `id+2+9+1+25`", ], field="nwbfile.subject.subject_id", source_file_paths=file_paths, diff --git a/tests/integration/test_messages.py b/tests/integration/test_messages.py index 4055b052..9f2d40ab 100644 --- a/tests/integration/test_messages.py +++ b/tests/integration/test_messages.py @@ -38,12 +38,12 @@ def test_messages_1(problematic_nwbfile_path_1: pathlib.Path, temporary_bids_dir nwb2bids.InspectionResult( title="Invalid participant ID", reason=( - "The participant ID contains invalid characters. BIDS allows only dashes to be used as separators in " - "subject entity label. Underscores, spaces, slashes, and special characters (including #) are " - "expressly forbidden." + "The participant ID contains invalid characters. BIDS allows only the plus sign to be used as a " + "separator in the subject entity label. Underscores, dashes, spaces, slashes, and other special " + "characters (including #) are expressly forbidden." ), - solution="Rename the subject without using spaces or underscores.", - examples=["`ab_01` -> `ab-01`", "`subject #2` -> `subject-2`", "`id 2 from 9/1/25` -> `id-2-9-1-25`"], + solution="Rename the subject without using any special characters except for `+`.", + examples=["`ab_01` -> `ab+01`", "`subject #2` -> `subject+2`", "`id 2 from 9/1/25` -> `id+2+9+1+25`"], field="nwbfile.subject.subject_id", source_file_paths=nwb_paths, data_standards=[nwb2bids.DataStandard.BIDS, nwb2bids.DataStandard.DANDI], @@ -118,12 +118,12 @@ def test_messages_2(problematic_nwbfile_path_2: pathlib.Path, temporary_bids_dir nwb2bids.InspectionResult( title="Invalid participant ID", reason=( - "The participant ID contains invalid characters. BIDS allows only dashes to be used as separators in " - "subject entity label. Underscores, spaces, slashes, and special characters (including #) are " - "expressly forbidden." + "The participant ID contains invalid characters. BIDS allows only the plus sign to be used as a " + "separator in the subject entity label. Underscores, dashes, spaces, slashes, and other special " + "characters (including #) are expressly forbidden." ), - solution="Rename the subject without using spaces or underscores.", - examples=["`ab_01` -> `ab-01`", "`subject #2` -> `subject-2`", "`id 2 from 9/1/25` -> `id-2-9-1-25`"], + solution="Rename the subject without using any special characters except for `+`.", + examples=["`ab_01` -> `ab+01`", "`subject #2` -> `subject+2`", "`id 2 from 9/1/25` -> `id+2+9+1+25`"], field="nwbfile.subject.subject_id", source_file_paths=nwb_paths, target_file_paths=None, @@ -135,14 +135,15 @@ def test_messages_2(problematic_nwbfile_path_2: pathlib.Path, temporary_bids_dir title="Invalid session ID", reason=( "The session ID contains invalid characters. " - "BIDS allows only dashes to be used as separators in session entity label. " - "Underscores, spaces, slashes, and special characters (including #) are expressly forbidden." + "BIDS allows only the plus sign to be used as a separator in the subject entity label. " + "Underscores, dashes, spaces, slashes, and other special characters " + "(including #) are expressly forbidden." ), - solution="Rename the session without using spaces or underscores.", + solution="Rename the session without using any special characters except for `+`.", examples=[ - "`ses_01` -> `ses-01`", - "`session #2` -> `session-2`", - "`id 2 from 9/1/25` -> `id-2-9-1-25`", + "`ses_01` -> `ses+01`", + "`session #2` -> `session+2`", + "`id 2 from 9/1/25` -> `id+2+9+1+25`", ], field="nwbfile.session_id", source_file_paths=nwb_paths,