Skip to content

Commit 54716dc

Browse files
committed
Work on cubids mv command.
1 parent edf7a94 commit 54716dc

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

cubids/cli.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,36 @@ def _path_exists(path, parser):
5555
return path.absolute()
5656

5757

58+
def _path_does_not_exist(path, parser):
59+
"""Ensure a given path does not exist.
60+
61+
Parameters
62+
----------
63+
path : str or Path
64+
The path to check.
65+
parser : argparse.ArgumentParser
66+
The argument parser instance to use for error reporting.
67+
68+
Returns
69+
-------
70+
pathlib.Path
71+
The absolute path if it exists.
72+
73+
Raises
74+
------
75+
argparse.ArgumentError
76+
If the path exists.
77+
"""
78+
if path is not None:
79+
path = Path(path)
80+
81+
if path.exists():
82+
raise parser.error(f"Path already exists: <{path.absolute()}>.")
83+
elif path is None:
84+
raise parser.error("Path is None.")
85+
return path.absolute()
86+
87+
5888
def _is_file(path, parser):
5989
"""Ensure a given path exists and it is a file.
6090
@@ -1394,6 +1424,80 @@ def _enter_print_metadata_fields(argv=None):
13941424
workflows.print_metadata_fields(**args)
13951425

13961426

1427+
def _parse_mv():
1428+
"""Create the parser for the `cubids mv` command.
1429+
1430+
This function sets up an argument parser for the `cubids mv` command, which is used
1431+
to move files between directories in a BIDS dataset. It defines the required
1432+
arguments and their types, as well as optional arguments.
1433+
1434+
Parameters
1435+
----------
1436+
None
1437+
1438+
Returns
1439+
-------
1440+
argparse.ArgumentParser
1441+
The argument parser for the `cubids mv` command.
1442+
1443+
Notes
1444+
-----
1445+
The parser includes the following arguments:
1446+
1447+
- bids_dir: The root of a BIDS dataset, which should contain sub-X directories
1448+
and dataset_description.json.
1449+
- source: The path to the file or directory to move.
1450+
- destination: The path to the new location for the file or directory.
1451+
"""
1452+
parser = argparse.ArgumentParser(
1453+
description="Move or rename a file, a directory, or a symlink within a BIDS dataset",
1454+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
1455+
allow_abbrev=False,
1456+
)
1457+
PathExists = partial(_path_exists, parser=parser)
1458+
1459+
parser.add_argument(
1460+
"source",
1461+
type=PathExists,
1462+
action="store",
1463+
help="The path to the file or directory to move.",
1464+
)
1465+
parser.add_argument(
1466+
"destination",
1467+
type=Path,
1468+
action="store",
1469+
help="The path to the new location for the file or directory.",
1470+
)
1471+
parser.add_argument(
1472+
"--use-datalad",
1473+
action="store_true",
1474+
default=False,
1475+
help="Use Datalad to track the move or rename operation.",
1476+
)
1477+
parser.add_argument(
1478+
"--force",
1479+
action="store_true",
1480+
default=False,
1481+
help="Force the move or rename operation.",
1482+
)
1483+
parser.add_argument(
1484+
"-n",
1485+
"--dry-run",
1486+
action="store_true",
1487+
default=False,
1488+
help="Do nothing; only show what would happen.",
1489+
)
1490+
parser.add_argument(
1491+
"-v",
1492+
"--verbose",
1493+
action="store_true",
1494+
default=False,
1495+
help="Report the details of the move or rename operation.",
1496+
)
1497+
1498+
return parser
1499+
1500+
13971501
COMMANDS = [
13981502
("validate", _parse_validate, workflows.validate),
13991503
("bids-version", _parse_bids_version, workflows.bids_version),
@@ -1408,6 +1512,7 @@ def _enter_print_metadata_fields(argv=None):
14081512
("datalad-save", _parse_datalad_save, workflows.datalad_save),
14091513
("print-metadata-fields", _parse_print_metadata_fields, workflows.print_metadata_fields),
14101514
("remove-metadata-fields", _parse_remove_metadata_fields, workflows.remove_metadata_fields),
1515+
("mv", _parse_mv, workflows.mv),
14111516
]
14121517

14131518

cubids/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,3 +1132,11 @@ def get_bidsuri(filename, dataset_root):
11321132
import os
11331133

11341134
return f"bids::{os.path.relpath(filename, dataset_root)}"
1135+
1136+
1137+
class BIDSError(Exception):
1138+
"""Exception raised for errors in BIDS operations."""
1139+
1140+
def __init__(self, message):
1141+
self.message = message
1142+
super().__init__(self.message)

cubids/workflows.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from cubids.cubids import CuBIDS
1717
from cubids.metadata_merge import merge_json_into_json
18+
from cubids.utils import BIDSError
1819
from cubids.validator import (
1920
bids_validator_version,
2021
build_first_subject_path,
@@ -351,6 +352,42 @@ def apply(
351352
)
352353

353354

355+
def mv(source, destination, use_datalad=False, force=False, dry_run=False, verbose=False):
356+
"""Move or rename a file, a directory, or a symlink within a BIDS dataset.
357+
358+
Parameters
359+
----------
360+
source : :obj:`pathlib.Path`
361+
The path to the file or directory to move.
362+
destination : :obj:`pathlib.Path`
363+
The path to the new location for the file or directory.
364+
use_datalad : :obj:`bool`
365+
Use Datalad to track the move or rename operation.
366+
force : :obj:`bool`
367+
Force the move or rename operation.
368+
dry_run : :obj:`bool`
369+
Do nothing; only show what would happen.
370+
verbose : :obj:`bool`
371+
Report the details of the move or rename operation.
372+
"""
373+
# Find the BIDS dataset root. We can do this by looking for the dataset_description.json file.
374+
# Similar to git mv, it should look for the dataset_description.json file in the current directory
375+
# and all parent directories.
376+
bids_dir = None
377+
cwd = Path.cwd()
378+
for path in cwd.parents:
379+
if (path / "dataset_description.json").exists():
380+
bids_dir = path
381+
break
382+
383+
if bids_dir is None:
384+
raise BIDSError("fatal: not a BIDS dataset (or any of the parent directories)")
385+
386+
# Run directly from python using
387+
bod = CuBIDS(data_root=str(bids_dir), use_datalad=use_datalad)
388+
...
389+
390+
354391
def datalad_save(bids_dir, m):
355392
"""Perform datalad save.
356393

0 commit comments

Comments
 (0)