Skip to content

Commit 22a0459

Browse files
authored
Merge pull request #92 from simleo/rde_properties
Root Data Entity required properties
2 parents 7f24a35 + 6a2ba1d commit 22a0459

File tree

4 files changed

+86
-14
lines changed

4 files changed

+86
-14
lines changed

src/runcrate/cli.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,27 @@ def cli():
5656
type=click.Path(exists=True, dir_okay=False, readable=True, path_type=Path),
5757
help="path to a README file (should be README.md in Markdown format)",
5858
)
59-
def convert(root, output, license, workflow_name, readme):
59+
@click.option(
60+
"-n",
61+
"--crate-name",
62+
metavar="STRING",
63+
help="crate name",
64+
)
65+
@click.option(
66+
"-d",
67+
"--crate-desc",
68+
metavar="STRING",
69+
help="crate description",
70+
)
71+
def convert(root, output, license, workflow_name, readme, crate_name, crate_desc):
6072
"""\
6173
Convert a CWLProv RO bundle into a Workflow Run RO-Crate.
6274
6375
RO_DIR: top-level directory of the CWLProv RO
6476
"""
6577
if not output:
6678
output = Path(f"{root.name}.crate.zip")
67-
builder = ProvCrateBuilder(root, workflow_name, license, readme)
79+
builder = ProvCrateBuilder(root, workflow_name, license, readme, crate_name, crate_desc)
6880
crate = builder.build()
6981
if output.suffix == ".zip":
7082
crate.write_zip(output)

src/runcrate/convert.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161

6262
CWLPROV_NONE = "https://w3id.org/cwl/prov#None"
6363

64+
# https://w3id.org/workflowhub/workflow-ro-crate/1.0
6465
WROC_PROFILE_VERSION = "1.0"
66+
DEFAULT_LICENSE = "notspecified"
6567

6668
DOCKER_IMG_TYPE = "https://w3id.org/ro/terms/workflow-run#DockerImage"
6769

@@ -197,11 +199,14 @@ def get_workflow(wf_path):
197199

198200
class ProvCrateBuilder:
199201

200-
def __init__(self, root, workflow_name=None, license=None, readme=None):
202+
def __init__(self, root, workflow_name=None, license=None, readme=None,
203+
crate_name=None, crate_desc=None):
201204
self.root = Path(root)
202205
self.workflow_name = workflow_name
203-
self.license = license
206+
self.license = license or DEFAULT_LICENSE
204207
self.readme = Path(readme) if readme else readme
208+
self.crate_name = crate_name
209+
self.crate_desc = crate_desc
205210
self.wf_path = self.root / "workflow" / WORKFLOW_BASENAME
206211
self.cwl_defs = get_workflow(self.wf_path)
207212
self.step_maps = self._get_step_maps(self.cwl_defs)
@@ -290,9 +295,9 @@ def get_dict(self, entity):
290295
def build(self):
291296
crate = ROCrate(gen_preview=False)
292297
crate.metadata.extra_contexts.append(TERMS_NAMESPACE)
293-
self.add_root_metadata(crate)
294298
self.add_profiles(crate)
295299
self.add_workflow(crate)
300+
self.add_root_metadata(crate)
296301
self.add_engine_run(crate)
297302
self.add_action(crate, self.workflow_run)
298303
self.patch_workflow_input_collection(crate)
@@ -301,13 +306,16 @@ def build(self):
301306
return crate
302307

303308
def add_root_metadata(self, crate):
304-
if self.license:
305-
crate.root_dataset["license"] = self.license
309+
crate.root_dataset["license"] = self.license
306310
if self.readme:
307311
readme = crate.add_file(self.readme)
308312
readme["about"] = crate.root_dataset
309313
if self.readme.suffix.lower() == ".md":
310314
readme["encodingFormat"] = "text/markdown"
315+
if not self.crate_name:
316+
self.crate_name = f"run of {self.workflow_name}"
317+
crate.root_dataset["name"] = self.crate_name
318+
crate.root_dataset["description"] = self.crate_desc or self.crate_name
311319

312320
def add_profiles(self, crate):
313321
profiles = []
@@ -338,10 +346,11 @@ def add_workflow(self, crate):
338346
lang_version=lang_version, gen_cwl=False, properties=properties
339347
)
340348
cwl_workflow = self.cwl_defs[workflow.id]
341-
wf_name = self.wf_path.name
349+
if not self.workflow_name:
350+
self.workflow_name = self.wf_path.name
342351
if hasattr(cwl_workflow, "label") and cwl_workflow.label:
343-
wf_name = cwl_workflow.label
344-
workflow["name"] = self.workflow_name or wf_name
352+
self.workflow_name = cwl_workflow.label
353+
workflow["name"] = self.workflow_name
345354
if hasattr(cwl_workflow, "doc") and cwl_workflow.doc:
346355
workflow["description"] = cwl_workflow.doc
347356
# cannot convert "intent" to featureList: workflow is not a SoftwareApplication

tests/test_cli.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_cli_convert(data_dir, tmpdir, monkeypatch):
3232
crate_zip = tmpdir / f"{root.name}.crate.zip"
3333
assert crate_zip.is_file()
3434
crate = ROCrate(crate_zip)
35-
assert not crate.root_dataset.get("license")
35+
assert crate.root_dataset.get("license") == "notspecified"
3636
workflow = crate.mainEntity
3737
assert workflow["name"] == "packed.cwl"
3838

@@ -47,7 +47,7 @@ def test_cli_convert_output(data_dir, tmpdir):
4747
assert result.exit_code == 0, result.exception
4848
assert crate_zip.is_file()
4949
crate = ROCrate(crate_zip)
50-
assert not crate.root_dataset.get("license")
50+
assert crate.root_dataset.get("license") == "notspecified"
5151
workflow = crate.mainEntity
5252
assert workflow["name"] == "packed.cwl"
5353
crate_zip.unlink()
@@ -59,7 +59,7 @@ def test_cli_convert_output(data_dir, tmpdir):
5959
assert result.exit_code == 0, result.exception
6060
assert crate_dir.is_dir()
6161
crate = ROCrate(crate_dir)
62-
assert not crate.root_dataset.get("license")
62+
assert crate.root_dataset.get("license") == "notspecified"
6363
workflow = crate.mainEntity
6464
assert workflow["name"] == "packed.cwl"
6565

@@ -102,6 +102,34 @@ def test_cli_convert_workflow_name(data_dir, tmpdir):
102102
assert workflow["name"] == workflow_name
103103

104104

105+
def test_cli_convert_crate_name(data_dir, tmpdir):
106+
root = data_dir / "revsort-run-1"
107+
crate_dir = tmpdir / "revsort-run-1-crate"
108+
workflow_name = "RevSort"
109+
crate_name = "name of the crate"
110+
runner = CliRunner()
111+
args = ["convert", str(root), "-o", str(crate_dir), "-w", workflow_name, "-n", crate_name]
112+
result = runner.invoke(cli, args)
113+
assert result.exit_code == 0, result.exception
114+
crate = ROCrate(crate_dir)
115+
assert crate.root_dataset["name"] == crate_name
116+
assert crate.root_dataset["description"] == crate_name
117+
118+
119+
def test_cli_convert_crate_desc(data_dir, tmpdir):
120+
root = data_dir / "revsort-run-1"
121+
crate_dir = tmpdir / "revsort-run-1-crate"
122+
workflow_name = "RevSort"
123+
crate_desc = "description of the crate"
124+
runner = CliRunner()
125+
args = ["convert", str(root), "-o", str(crate_dir), "-w", workflow_name, "-d", crate_desc]
126+
result = runner.invoke(cli, args)
127+
assert result.exit_code == 0, result.exception
128+
crate = ROCrate(crate_dir)
129+
assert crate.root_dataset["name"] == f"run of {workflow_name}"
130+
assert crate.root_dataset["description"] == crate_desc
131+
132+
105133
def test_cli_convert_readme(data_dir, tmpdir):
106134
root = data_dir / "revsort-run-1"
107135
crate_dir = tmpdir / "revsort-run-1-crate"

tests/test_cwlprov_crate_builder.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ def test_revsort(data_dir, tmpdir):
4747
assert readme_f["about"] is crate.root_dataset
4848
workflow = crate.mainEntity
4949
assert workflow.id == "packed.cwl"
50-
assert workflow["name"] == "RevSort"
50+
assert workflow["name"] == workflow_name
51+
assert crate.root_dataset["name"] == f"run of {workflow_name}"
52+
assert crate.root_dataset["description"] == f"run of {workflow_name}"
5153
tools = workflow["hasPart"]
5254
assert len(tools) == 2
5355
for entity in tools:
@@ -1191,3 +1193,24 @@ def test_agent_no_name(data_dir, tmpdir):
11911193
assert agent.type == "Person"
11921194
assert agent.id == "https://orcid.org/0000-0001-9447-460X"
11931195
assert "name" not in agent
1196+
1197+
1198+
def test_no_license(data_dir):
1199+
root = data_dir / "revsort-run-1"
1200+
builder = ProvCrateBuilder(root)
1201+
crate = builder.build()
1202+
assert crate.root_dataset["license"] == "notspecified"
1203+
1204+
1205+
def test_name_desc(data_dir):
1206+
root = data_dir / "revsort-run-1"
1207+
workflow_name = "RevSort"
1208+
crate_name = "name of the crate"
1209+
builder = ProvCrateBuilder(root, workflow_name=workflow_name, crate_name=crate_name)
1210+
crate = builder.build()
1211+
assert crate.root_dataset["name"] == crate_name
1212+
assert crate.root_dataset["description"] == crate_name
1213+
crate_desc = "description of the crate"
1214+
builder = ProvCrateBuilder(root, workflow_name=workflow_name, crate_name=crate_name, crate_desc=crate_desc)
1215+
crate = builder.build()
1216+
assert crate.root_dataset["description"] == crate_desc

0 commit comments

Comments
 (0)