Skip to content

Commit 9d86602

Browse files
✨ Schema validation (#1467)
This is the implementation of the discussion #1451 and a follow-up on #1441. The PR adds schema validation to Sphinx-Needs that supports local validation and network validation. The Sphinx-Needs internal data type representation is not changed yet, all types are still strings. This will come shortly after merge. Users can already try out the new interface and provide feedback. Differences to PR 1441: - Aligning with standards in JSON schema for re-using subschemas via `$defs` and `$ref` - Fully typed implementation including runtime checks of valid schema user input - Auto inject the default string type if not given - Replace `trigger_schema` with `select` which aligns with query language terminology - Replace `trigger_schema_id` with the mentioned `$ref` mechanism - New schemas root key `validate` with sub-keys `local` and `network` for the 2 validation types - Network validation items does not allow the `select` key anymore as the selection happens by linking target needs. This cleans up an ambiguity in the other PR. - Network validation errors now bubble up to the root json schema and are displayed to see exactly why the chain fails - More network rule types for better control over debug schema output - Rewrite test cases to use a declarative definition as yaml, so all pieces can be given in one place: - conf.py - ubproject.toml - index.rst - schemas.json - expected ontology warnings - Simplified the code logic - String patterns (regex) are constrained to a basic subset that works across engines - Added docs - Examples and explanations - Comparison with `needs_warnings` and `needs_constraints` and migration path - Many more test cases - `items` with `minItems` and `maxItems` and `contains` with `minContains` and `maxContains` are now semantically equivalent to JSON schema spec --------- Co-authored-by: Chris Sewell <[email protected]>
1 parent 9824a37 commit 9d86602

39 files changed

+8651
-36
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ repos:
2929
- types-docutils==0.20.0.20240201
3030
- types-jsonschema
3131
- types-requests
32+
- typeguard
3233

3334
# TODO this does not work on pre-commit.ci
3435
# - repo: https://github.com/astral-sh/uv-pre-commit

docs/configuration.rst

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,3 +2316,195 @@ needs_debug_filters
23162316

23172317
If set to ``True``, all calls to :ref:`filter processing <filter>` will be logged to a ``debug_filters.jsonl`` file in the build output directory,
23182318
appending a single-line JSON for each filter call.
2319+
2320+
.. _`needs_schema_definitions`:
2321+
2322+
needs_schema_definitions
2323+
~~~~~~~~~~~~~~~~~~~~~~~~
2324+
2325+
.. versionadded:: 6.0.0
2326+
2327+
Defines validation schemas for needs using a definition format derived from JSON Schema.
2328+
Schemas can be used to validate need fields, enforce constraints, and ensure data consistency.
2329+
2330+
Default value: ``{}``
2331+
2332+
.. code-block:: python
2333+
2334+
needs_schema_definitions = {
2335+
"$defs": {
2336+
"type-spec": {
2337+
"properties": {"type": {"const": "spec"}}
2338+
},
2339+
"safe-need": {
2340+
"properties": {"asil": {"enum": ["A", "B", "C", "D"]}},
2341+
"required": ["asil"]
2342+
}
2343+
},
2344+
"schemas": [
2345+
{
2346+
"id": "unique-id-validation",
2347+
"severity": "warning",
2348+
"message": "ID must be uppercase",
2349+
"validate": {
2350+
"local": {
2351+
"properties": {
2352+
"id": {"pattern": "^[A-Z0-9_]+$"}
2353+
}
2354+
}
2355+
}
2356+
},
2357+
{
2358+
"id": "safe-spec",
2359+
"validate": {
2360+
"local": {
2361+
"allOf": [
2362+
{"$ref": "#/$defs/type-spec"},
2363+
{"$ref": "#/$defs/safe-need"}
2364+
]
2365+
}
2366+
}
2367+
}
2368+
]
2369+
}
2370+
2371+
See :ref:`schema_validation` for detailed documentation.
2372+
2373+
.. _`needs_schema_definitions_from_json`:
2374+
2375+
needs_schema_definitions_from_json
2376+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2377+
2378+
.. versionadded:: 6.0.0
2379+
2380+
Path to a JSON file containing schema definitions. This is the recommended approach for
2381+
defining schemas as it provides better IDE support and maintainability.
2382+
2383+
Default value: ``None``
2384+
2385+
.. code-block:: python
2386+
2387+
needs_schema_definitions_from_json = "schemas.json"
2388+
2389+
The JSON file should contain the same structure as :ref:`needs_schema_definitions`:
2390+
2391+
.. _`needs_schema_severity`:
2392+
2393+
needs_schema_severity
2394+
~~~~~~~~~~~~~~~~~~~~~
2395+
2396+
.. versionadded:: 6.0.0
2397+
2398+
Minimum severity level for schema validation reporting.
2399+
Extra option and extra link schema errors are always reported as violations.
2400+
For each entry in :ref:`needs_schema_definitions` the severity can be defined by the user.
2401+
2402+
Available severity levels:
2403+
2404+
- ``info``: Informational message (default)
2405+
- ``warning``: Warning message
2406+
- ``violation``: Violation message
2407+
2408+
The levels align with how `SHACL <https://www.w3.org/TR/shacl/#severity>`__ defines severity levels.
2409+
2410+
Default value: ``"info"``
2411+
2412+
.. code-block:: python
2413+
2414+
needs_schema_severity = "warning"
2415+
2416+
.. _`needs_schema_debug_active`:
2417+
2418+
needs_schema_debug_active
2419+
~~~~~~~~~~~~~~~~~~~~~~~~~
2420+
2421+
.. versionadded:: 6.0.0
2422+
2423+
Activates debug mode for schema validation. When enabled, the validation dumps JSON files,
2424+
schema files, and validation messages to help troubleshoot schema validation issues.
2425+
2426+
Default value: ``False``
2427+
2428+
.. code-block:: python
2429+
2430+
needs_schema_debug_active = True
2431+
2432+
Debug files are written to the directory specified by :ref:`needs_schema_debug_path`.
2433+
2434+
.. _`needs_schema_debug_path`:
2435+
2436+
needs_schema_debug_path
2437+
~~~~~~~~~~~~~~~~~~~~~~~
2438+
2439+
.. versionadded:: 6.0.0
2440+
2441+
Directory path where schema debug files are stored when :ref:`needs_schema_debug_active` is
2442+
enabled.
2443+
2444+
If the path is relative, it will be resolved relative to the ``conf.py`` directory.
2445+
2446+
Default value: ``"schema_debug"``
2447+
2448+
.. code-block:: python
2449+
2450+
needs_schema_debug_path = "debug/schemas"
2451+
2452+
.. _`needs_schema_debug_ignore`:
2453+
2454+
needs_schema_debug_ignore
2455+
~~~~~~~~~~~~~~~~~~~~~~~~~
2456+
2457+
.. versionadded:: 6.0.0
2458+
2459+
List of validation scenarios to ignore when dumping debug information. This helps reduce
2460+
noise in debug output by filtering out irrelevant validations.
2461+
2462+
Default value::
2463+
2464+
[
2465+
"extra_option_success",
2466+
"extra_link_success",
2467+
"select_success",
2468+
"select_fail",
2469+
"local_success",
2470+
"network_local_success"
2471+
]
2472+
2473+
.. code-block:: python
2474+
2475+
needs_schema_debug_ignore = [
2476+
"extra_option_success",
2477+
"local_success",
2478+
"network_local_success"
2479+
]
2480+
2481+
To write all scenarios, set it to an empty list: ``[]``.
2482+
2483+
Available scenarios that can be ignored:
2484+
2485+
- ``cfg_schema_error``: The user provided schema is invalid
2486+
- ``extra_option_type_error``: A need extra option cannot be coerced to the type specified in the schema
2487+
- ``extra_option_success``: Global extra option validation was successful
2488+
- ``extra_option_fail``: Global extra option validation failed
2489+
- ``extra_link_success``: Global extra link validations was successful
2490+
- ``extra_link_fail``: Global extra link validation failed
2491+
- ``select_success``: Successful select validation
2492+
- ``select_fail``: Failed select validation
2493+
- ``local_success``: Successful local validation
2494+
- ``local_fail``: Need local validation failed
2495+
- ``network_missing_target``: An outgoing link target cannot be resolved
2496+
- ``network_contains_too_few``: minContains or minItems validation failed for the given link_schema link type
2497+
- ``network_contains_too_many``: maxContains or maxItems validation failed for the given link_schema link type
2498+
- ``network_items_fail``: items validation failed for the given link_schema link type
2499+
- ``network_local_success``: Successful network local validation
2500+
- ``network_local_fail``: Need does not validate against the local schema in a network context
2501+
- ``network_max_nest_level``: The maximum nesting level of network links was exceeded
2502+
2503+
The debug information is written to the directory specified by :ref:`needs_schema_debug_path`.
2504+
The ``_success`` scenarios exist to analyze why a validation was successful and how the
2505+
final need and schema looks like.
2506+
2507+
.. note::
2508+
2509+
For large need counts, the debug output can become very large.
2510+
Writing debug output also affects the validation performance negatively.

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ Contents
208208
services/index
209209
layout_styles
210210
api
211+
schema/index
211212
utils
212213

213214
.. toctree::

docs/schema/01_basic_setup.drawio.png

59 KB
Loading

docs/schema/02_local_check.drawio.png

93.2 KB
Loading
72 KB
Loading

0 commit comments

Comments
 (0)