diff --git a/rocrate/cli.py b/rocrate/cli.py index 9e63e54..8ff4e88 100644 --- a/rocrate/cli.py +++ b/rocrate/cli.py @@ -69,6 +69,36 @@ def add(): pass +@add.command() +@click.argument('path', type=click.Path(exists=True, dir_okay=False)) +@OPTION_CRATE_PATH +def file(crate_dir, path): + crate = ROCrate(crate_dir, init=False, gen_preview=False) + source = Path(path).resolve(strict=True) + try: + dest_path = source.relative_to(crate_dir) + except ValueError: + # For now, only support adding an existing file to the metadata + raise ValueError(f"{source} is not in the crate dir {crate_dir}") + crate.add_file(source, dest_path) + crate.metadata.write(crate_dir) + + +@add.command() +@click.argument('path', type=click.Path(exists=True, file_okay=False)) +@OPTION_CRATE_PATH +def dataset(crate_dir, path): + crate = ROCrate(crate_dir, init=False, gen_preview=False) + source = Path(path).resolve(strict=True) + try: + dest_path = source.relative_to(crate_dir) + except ValueError: + # For now, only support adding an existing directory to the metadata + raise ValueError(f"{source} is not in the crate dir {crate_dir}") + crate.add_dataset(source, dest_path) + crate.metadata.write(crate_dir) + + @add.command() @click.argument('path', type=click.Path(exists=True)) @click.option('-l', '--language', type=click.Choice(LANG_CHOICES), default="cwl") diff --git a/test/test_cli.py b/test/test_cli.py index 12e97ba..b6b8b69 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -20,6 +20,7 @@ import click from click.testing import CliRunner import pytest +import shutil from rocrate.cli import cli from rocrate.model import File @@ -132,6 +133,58 @@ def test_cli_init_exclude(test_data_dir, helpers): assert not e.id.startswith("test") +@pytest.mark.parametrize("cwd", [False, True]) +def test_cli_add_file(tmpdir, test_data_dir, helpers, monkeypatch, cwd): + # init + crate_dir = tmpdir / "crate" + crate_dir.mkdir() + runner = CliRunner() + assert runner.invoke(cli, ["init", "-c", str(crate_dir)]).exit_code == 0 + json_entities = helpers.read_json_entities(crate_dir) + assert set(json_entities) == {"./", "ro-crate-metadata.json"} + # add + shutil.copy(test_data_dir / "sample_file.txt", crate_dir) + file_path = crate_dir / "sample_file.txt" + args = ["add", "file"] + if cwd: + monkeypatch.chdir(str(crate_dir)) + file_path = file_path.relative_to(crate_dir) + else: + args.extend(["-c", str(crate_dir)]) + args.append(str(file_path)) + result = runner.invoke(cli, args) + assert result.exit_code == 0 + json_entities = helpers.read_json_entities(crate_dir) + assert "sample_file.txt" in json_entities + assert json_entities["sample_file.txt"]["@type"] == "File" + + +@pytest.mark.parametrize("cwd", [False, True]) +def test_cli_add_dataset(tmpdir, test_data_dir, helpers, monkeypatch, cwd): + # init + crate_dir = tmpdir / "crate" + crate_dir.mkdir() + runner = CliRunner() + assert runner.invoke(cli, ["init", "-c", str(crate_dir)]).exit_code == 0 + json_entities = helpers.read_json_entities(crate_dir) + assert set(json_entities) == {"./", "ro-crate-metadata.json"} + # add + dataset_path = crate_dir / "test_add_dir" + shutil.copytree(test_data_dir / "test_add_dir", dataset_path) + args = ["add", "dataset"] + if cwd: + monkeypatch.chdir(str(crate_dir)) + dataset_path = dataset_path.relative_to(crate_dir) + else: + args.extend(["-c", str(crate_dir)]) + args.append(str(dataset_path)) + result = runner.invoke(cli, args) + assert result.exit_code == 0 + json_entities = helpers.read_json_entities(crate_dir) + assert "test_add_dir/" in json_entities + assert json_entities["test_add_dir/"]["@type"] == "Dataset" + + @pytest.mark.parametrize("cwd", [False, True]) def test_cli_add_workflow(test_data_dir, helpers, monkeypatch, cwd): # init