Skip to content

Commit b1d51f1

Browse files
committed
Merge debelop into 74-flatten-7_requested_workflow_runttl-files
2 parents 5273986 + fcd6ff1 commit b1d51f1

141 files changed

Lines changed: 16834 additions & 1637 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ jobs:
6666
steps:
6767
# Access the tag from the first workflow's outputs
6868
- name: ⬇️ Checkout code
69-
uses: actions/checkout@v4
69+
uses: actions/checkout@v6
7070
- name: 🐍 Set up Python
71-
uses: actions/setup-python@v5
71+
uses: actions/setup-python@v6
7272
with:
7373
python-version: "3.x"
7474
- name: 🚧 Set up Python Environment
@@ -92,7 +92,7 @@ jobs:
9292
- name: 🏗️ Build a binary wheel and a source tarball
9393
run: poetry build
9494
- name: 📦 Store the distribution packages
95-
uses: actions/upload-artifact@v4
95+
uses: actions/upload-artifact@v7
9696
with:
9797
name: python-package-distributions
9898
path: |
@@ -111,7 +111,7 @@ jobs:
111111
id-token: write # IMPORTANT: mandatory for trusted publishing
112112
steps:
113113
- name: ⬇️ Download all the distribution packages
114-
uses: actions/download-artifact@v4
114+
uses: actions/download-artifact@v8
115115
with:
116116
name: python-package-distributions
117117
path: dist/
@@ -132,7 +132,7 @@ jobs:
132132
id-token: write # IMPORTANT: mandatory for trusted publishing
133133
steps:
134134
- name: ⬇️ Download all the dists
135-
uses: actions/download-artifact@v4
135+
uses: actions/download-artifact@v8
136136
with:
137137
name: python-package-distributions
138138
path: dist/
@@ -151,18 +151,18 @@ jobs:
151151

152152
steps:
153153
- name: ⬇️ Download all the distribution packages
154-
uses: actions/download-artifact@v4
154+
uses: actions/download-artifact@v8
155155
with:
156156
name: python-package-distributions
157157
path: dist/
158158
- name: 🖊️ Sign the dists with Sigstore
159-
uses: sigstore/gh-action-sigstore-python@v3.0.0
159+
uses: sigstore/gh-action-sigstore-python@v3.3.0
160160
with:
161161
inputs: >-
162162
./dist/*.tar.gz
163163
./dist/*.whl
164164
- name: 📦 Store the signed distribution packages
165-
uses: actions/upload-artifact@v4
165+
uses: actions/upload-artifact@v7
166166
with:
167167
name: python-package-signatures
168168
path: dist/*.json
@@ -177,12 +177,12 @@ jobs:
177177
id-token: write # IMPORTANT: mandatory for sigstore
178178
steps:
179179
- name: ⬇️ Download all the distribution packages
180-
uses: actions/download-artifact@v4
180+
uses: actions/download-artifact@v8
181181
with:
182182
name: python-package-distributions
183183
path: dist/
184184
- name: ⬇️ Download all the distribution signatures
185-
uses: actions/download-artifact@v4
185+
uses: actions/download-artifact@v8
186186
with:
187187
name: python-package-signatures
188188
path: dist/

.github/workflows/testing.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,17 @@ jobs:
4646
steps:
4747
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
4848
- name: ⬇️ Checkout code
49-
uses: actions/checkout@v4
49+
uses: actions/checkout@v6
5050
- name: 🐍 Set up Python v${{ env.PYTHON_VERSION }}
51-
uses: actions/setup-python@v5
51+
uses: actions/setup-python@v6
5252
with:
5353
python-version: ${{ env.PYTHON_VERSION }}
5454
- name: 🔽 Install flake8
5555
run: pip install flake8
5656
- name: ⌛ Lint Python code
5757
run: flake8 -v rocrate_validator tests
5858
- name: ⌛ Spell check code and profiles (covers Python and SHACL)
59-
uses: crate-ci/typos@v1.41.0
59+
uses: crate-ci/typos@v1.47.0
6060

6161
# Runs the tests
6262
test:
@@ -65,9 +65,9 @@ jobs:
6565
needs: [lint]
6666
steps:
6767
- name: ⬇️ Checkout
68-
uses: actions/checkout@v4
68+
uses: actions/checkout@v6
6969
- name: 🐍 Set up Python v${{ env.PYTHON_VERSION }}
70-
uses: actions/setup-python@v5
70+
uses: actions/setup-python@v6
7171
with:
7272
python-version: ${{ env.PYTHON_VERSION }}
7373
- name: 🔄 Upgrade pip

CHANGELOG.md

Lines changed: 832 additions & 0 deletions
Large diffs are not rendered by default.

CITATION.cff

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ authors:
1919
- family-names: Bauer
2020
given-names: Daniel
2121
orcid: https://orcid.org/0000-0001-9447-460X
22+
- family-names: "Wetzels"
23+
given-names: "Florian"
24+
orcid: https://orcid.org/0000-0002-5526-7138
25+
- family-names: "Weil"
26+
given-names: "Heinrich Lukas"
27+
orcid: https://orcid.org/0000-0003-1945-6342
2228
repository-code: "https://github.com/crs4/rocrate-validator"
2329
url: "https://github.com/crs4/rocrate-validator"
2430
keywords:

docs/0_toc.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
..
2-
Copyright (c) 2024 CRS4
2+
Copyright (c) 2024-2026 CRS4
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
2121
2_usage_cli
2222
3_usage_api
2323
4_how_it_works
24+
5_offline_mode
2425

2526
.. toctree::
2627
:maxdepth: 5
@@ -30,3 +31,9 @@
3031
11_writing_a_profile
3132
10_api
3233
genindex
34+
35+
.. toctree::
36+
:maxdepth: 1
37+
:caption: About
38+
39+
ack

docs/10_api.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
..
2-
Copyright (c) 2024 CRS4
2+
Copyright (c) 2024-2026 CRS4
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -135,7 +135,7 @@ Python Check API
135135
======================
136136

137137
Requirement Class
138-
----------
138+
-----------------
139139
.. autoclass:: rocrate_validator.requirements.python.PyRequirement
140140
:members:
141141

docs/11_writing_a_profile.rst

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,154 @@ These instructions assume you are familiar with code development using Python an
9494
#. When your profile & tests are written, open a pull request to contribute
9595
it back to the repository!
9696

97+
Overriding inherited checks
98+
---------------------------
99+
100+
When a profile inherits from another profile (via ``prof:isProfileOf`` /
101+
``prof:isTransitiveProfileOf``), it automatically receives every check
102+
declared by its ancestors. The validator additionally supports
103+
**override-by-name**: a child profile can replace an inherited check by
104+
declaring a new check with the **same name**.
105+
106+
This allows an extension profile to *redefine* the content of an inherited
107+
check — for example, to make a constraint stricter or looser, change its
108+
severity, or, as described in the next section, fully deactivate it.
109+
110+
Override-by-name is enabled by default. It can be disabled via the
111+
``allow_requirement_check_override`` validation setting (CLI / API), which
112+
will raise an error on duplicate check names instead.
113+
114+
SHACL checks
115+
^^^^^^^^^^^^
116+
117+
Each SHACL ``NodeShape`` / ``PropertyShape`` becomes a check whose name is
118+
its ``sh:name``. To override an inherited check, declare a shape in the
119+
extension profile with the **same** ``sh:name`` as the inherited one:
120+
121+
.. code-block:: turtle
122+
123+
# Parent profile
124+
ro:ShapeC
125+
a sh:NodeShape ;
126+
sh:name "The Shape C" ;
127+
sh:targetNode ro:ro-crate-metadata.json ;
128+
sh:property [
129+
a sh:PropertyShape ;
130+
sh:name "Check Metadata File Descriptor entity existence" ;
131+
sh:path rdf:type ;
132+
sh:minCount 1 ;
133+
sh:message "Missing entity" ;
134+
] .
135+
136+
.. code-block:: turtle
137+
138+
# Extension profile — overrides the inherited PropertyShape by sh:name
139+
ro:ShapeC
140+
a sh:NodeShape ;
141+
sh:name "The Shape C" ;
142+
sh:targetNode ro:ro-crate-metadata.json ;
143+
sh:property [
144+
a sh:PropertyShape ;
145+
sh:name "Check Metadata File Descriptor entity existence" ;
146+
sh:path rdf:type ;
147+
sh:minCount 1 ;
148+
sh:maxCount 1 ;
149+
sh:message "Stricter override from extension profile" ;
150+
] .
151+
152+
Both top-level shapes and ``PropertyShape`` entries nested inside a parent
153+
``NodeShape`` (i.e., declared inline, without an absolute IRI) can be
154+
overridden this way.
155+
156+
Python checks
157+
^^^^^^^^^^^^^
158+
159+
Python checks declared via the ``@check`` decorator are matched by their
160+
``name`` argument. To override an inherited Python check, declare a new
161+
function with the same ``name`` in the extension profile:
162+
163+
.. code-block:: python
164+
165+
# In the extension profile's checks module
166+
from rocrate_validator.requirements.python import check
167+
168+
@check(name="Check Metadata File Descriptor entity existence")
169+
def overridden_check(self, ctx):
170+
# New implementation that replaces the inherited one
171+
...
172+
173+
Deactivating inherited checks
174+
-----------------------------
175+
176+
A child profile can also **fully deactivate** a check inherited from one of
177+
its ancestors. A deactivated check is skipped during validation and
178+
reported as such in the validation result. This is useful when an extension
179+
profile relaxes the parent's expectations, or replaces a coarse-grained
180+
check with a more specific one declared elsewhere in the same profile.
181+
182+
SHACL checks
183+
^^^^^^^^^^^^
184+
185+
Two complementary mechanisms are supported, depending on whether the shape
186+
to disable has an absolute IRI of its own.
187+
188+
**Shape with an absolute IRI** (e.g. a top-level ``NodeShape`` or a named
189+
``PropertyShape``): reference the shape by IRI from the extension profile
190+
and mark it as deactivated, without redeclaring it.
191+
192+
.. code-block:: turtle
193+
194+
# Extension profile
195+
<https://parent-profile/ShapeC> sh:deactivated true .
196+
197+
**Nested ``PropertyShape`` without an absolute IRI** (a property declared
198+
inline inside a parent ``NodeShape``): use the override-by-name mechanism
199+
described in the previous section. Declare a new ``PropertyShape`` in the
200+
extension profile with the same ``sh:name`` as the one to disable, and set
201+
``sh:deactivated true`` on it. This overrides the parent's
202+
``PropertyShape``, and the validator reports the resulting check as
203+
deactivated.
204+
205+
.. code-block:: turtle
206+
207+
# Extension profile — disables the inherited PropertyShape by sh:name
208+
ro:ShapeC
209+
a sh:NodeShape ;
210+
sh:name "The Shape C" ;
211+
sh:targetNode ro:ro-crate-metadata.json ;
212+
sh:property [
213+
a sh:PropertyShape ;
214+
sh:name "Check Metadata File Descriptor entity existence" ;
215+
sh:path rdf:type ;
216+
sh:deactivated true ;
217+
] .
218+
219+
.. note::
220+
221+
Cross-profile deactivation is scoped to the shape's transitive
222+
descendants: a ``sh:deactivated true`` triple declared by a profile
223+
that does not inherit (directly or transitively) from the shape's
224+
owning profile is ignored. This prevents unrelated profiles loaded in
225+
the same process from interfering with one another.
226+
227+
Python checks
228+
^^^^^^^^^^^^^
229+
230+
The ``@check`` decorator accepts a ``deactivated`` flag, mirroring SHACL's
231+
``sh:deactivated``. Combined with override-by-name, an extension profile
232+
can disable an inherited Python check by redeclaring it with
233+
``deactivated=True``:
234+
235+
.. code-block:: python
236+
237+
from rocrate_validator.requirements.python import check
238+
239+
@check(name="Check Metadata File Descriptor entity existence",
240+
deactivated=True)
241+
def disabled(self, ctx):
242+
# Body is irrelevant — the check is skipped during validation.
243+
return True
244+
97245
Running validator & tests during profile development
98246
----------------------------------------------------
99247

docs/1_installation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
..
2-
Copyright (c) 2024 CRS4
2+
Copyright (c) 2024-2026 CRS4
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.

docs/2_usage_cli.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
..
2-
Copyright (c) 2024 CRS4
2+
Copyright (c) 2024-2026 CRS4
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -31,3 +31,9 @@ CLI Validation
3131
:parser: myst_parser.sphinx_
3232
:start-line: 93
3333
:end-line: 120
34+
35+
.. seealso::
36+
37+
To validate without network access and manage the HTTP cache from the
38+
command line (the ``--offline`` and ``--no-cache`` flags and the ``cache``
39+
subcommand), see :ref:`offline_mode`.

docs/3_usage_api.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
..
2-
Copyright (c) 2024 CRS4
2+
Copyright (c) 2024-2026 CRS4
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -30,6 +30,12 @@ Programmatic Validation
3030
:start-line: 121
3131
:end-line: 162
3232

33+
.. seealso::
34+
35+
To resolve resources from a local cache or run validation without network
36+
access (the ``offline`` / ``no_cache`` settings of ``ValidationSettings``),
37+
see :ref:`offline_mode`.
38+
3339

3440
Metadata-only Validation
3541
------------------------

0 commit comments

Comments
 (0)