Skip to content

Commit 9e916fe

Browse files
authored
Merge pull request #3 from softwarepub/feature/new-data-model
Make the plugin ready for the new data model
2 parents d076672 + d958359 commit 9e916fe

4 files changed

Lines changed: 64 additions & 23 deletions

File tree

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ SPDX-License-Identifier: CC-BY-4.0
99

1010
HERMES curation plugin using the Software CaRD framework.
1111

12+
Install it:
13+
14+
``` bash
15+
pip install git+https://github.com/softwarepub/hermes-plugin-software-card.git
16+
```
17+
18+
Configure it in `hermes.toml`:
19+
20+
``` toml
21+
[curate]
22+
plugin = "software_card"
23+
```
24+
1225
## Development
1326

1427
```bash

hermes.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
sources = ["cff"]
88

99
[curate]
10-
method = "software_card"
10+
plugin = "software_card"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ classifiers = [
2828
]
2929
requires-python = ">=3.11"
3030
dependencies = [
31-
"hermes @ git+https://github.com/softwarepub/hermes.git@develop",
31+
"hermes >= 0.10.0",
3232
"software-card-policies @ git+https://github.com/softwarepub/software-card-policies.git",
3333
]
3434

src/hermes_plugin_software_card/curate.py

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
"""Module containing the Software CaRD curation plugin for HERMES."""
77

88
import json
9-
from pathlib import Path
9+
from io import StringIO
1010

11-
from hermes.commands.curate.base import BaseCuratePlugin
11+
from hermes.commands.curate.base import HermesCurateCommand, HermesCuratePlugin
12+
from hermes.model import SoftwareMetadata
13+
from hermes.model.hermes_cache import HermesCacheManager
1214
from software_card_policies.config import Config
1315
from software_card_policies.data_model import (
1416
make_shacl_graph,
@@ -20,17 +22,16 @@
2022
from hermes_plugin_software_card import environment
2123

2224

23-
class SoftwareCaRDCuratePlugin(BaseCuratePlugin):
25+
class SoftwareCaRDCuratePlugin(HermesCuratePlugin):
2426
"""Software CaRD curation plugin."""
2527

26-
def __init__(self, command, ctx):
28+
def __init__(self):
2729
"""Initialize the plugin."""
28-
super().__init__(command, ctx)
30+
super().__init__()
2931
self._data_graph = None
3032
self._shacl_graph = None
3133
self._conforms = False
3234
self._validation_graph = None
33-
self._report = None
3435

3536
self._environment = environment.get()
3637
self._app_base_url = "https://software-metadata.pub/software-card/"
@@ -65,25 +66,59 @@ def __init__(self, command, ctx):
6566
}
6667
}
6768

68-
def prepare(self):
69+
def __call__(
70+
self,
71+
command: HermesCurateCommand, # noqa: ARG002
72+
metadata: SoftwareMetadata,
73+
) -> SoftwareMetadata:
74+
"""Entry point of the callable.
75+
76+
This method runs the main logic of the plugin. It calls the other methods of the
77+
object in the correct order. Depending on the result of
78+
``is_publication_approved`` either the valid metadata or a new, empty
79+
``SoftwareMetadata`` object is returned.
80+
"""
81+
self.prepare(metadata)
82+
self.validate()
83+
self.create_report()
84+
85+
if not self.is_publication_approved():
86+
return SoftwareMetadata()
87+
88+
return metadata
89+
90+
def prepare(self, metadata: SoftwareMetadata):
6991
"""Prepare the validation.
7092
71-
The metadata given in the context is parsed as an RDF graph and then validated
72-
using the Software CaRD validation.
93+
The metadata given in ``metadata`` is parsed as an RDF graph for validation.
7394
"""
74-
text = json.dumps(self.ctx.get_data()["curate"])
75-
self._data_graph = read_rdf_resource(format="json-ld", data=text)
95+
self._data_graph = read_rdf_resource(
96+
format="json-ld", data=json.dumps(metadata.ld_value)
97+
)
7698
self._shacl_graph = make_shacl_graph(Config.from_dict(self._validation_config))
7799

78100
def validate(self):
79-
"""Run Software CaRD validation."""
101+
"""Run Software CaRD validation on the given software metadata."""
80102
conforms, validation_graph = validate_graph(self._data_graph, self._shacl_graph)
81103
self._conforms = conforms
82104
self._validation_graph = validation_graph
83105

84106
def create_report(self):
85-
"""Create basic text report."""
86-
self._report = create_report(self._validation_graph)
107+
"""Create validation report.
108+
109+
This creates the report both as a machine-readble JSON-LD file, and prints a
110+
human-readable report, and the URL to the Software CaRD web app to the screen.
111+
"""
112+
ctx = HermesCacheManager()
113+
ctx.prepare_step("curate")
114+
with ctx["result"] as cache:
115+
graph_io = StringIO()
116+
self._validation_graph.print(format="json-ld", out=graph_io)
117+
cache["validation"] = json.loads(graph_io.getvalue())
118+
graph_io.close()
119+
ctx.finalize_step("curate")
120+
121+
print(create_report(self._validation_graph), end="\n\n")
87122
if self._environment is None:
88123
print("Software CaRD plugin not running in CI environment.")
89124
else:
@@ -95,10 +130,3 @@ def create_report(self):
95130
def is_publication_approved(self) -> bool:
96131
"""Decide whether the publication of the software is approved."""
97132
return self._conforms
98-
99-
def process_decision_positive(self):
100-
"""Write the given metadata into the curate directory."""
101-
curate_output = Path(self.ctx.get_cache("curate", self.ctx.hermes_name))
102-
Path.mkdir(curate_output.parent)
103-
with open(curate_output, "w") as curate_output_fh:
104-
json.dump(self.ctx.get_data(), curate_output_fh)

0 commit comments

Comments
 (0)