diff mbox series

[RFC,4/5] bitbake-setup: Add an option to validate the schema

Message ID 20251017231444.374436-5-yoann.congal@smile.fr
State New
Headers show
Series Bitbake-setup configuration schema | expand

Commit Message

Yoann Congal Oct. 17, 2025, 11:14 p.m. UTC
From: Yoann Congal <yoann.congal@smile.fr>

This adds a dependency on "jsonschema"[0] (plus recursive dependencies),
but these dependencies are only used is the --validate option is used.

[0]: https://pypi.org/project/jsonschema/

Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
---
 bin/bitbake-setup | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
diff mbox series

Patch

diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 38bb8099f..a96262c10 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -389,6 +389,43 @@  def choose_fragments(possibilities, parameters, non_interactive, skip_selection)
         choices[k] = options_enumerated[option_n][1]
     return choices
 
+def validate_bitbake_setup_schema(bitbake_setup_conf):
+    """
+    Validates a bitbake-setup configuration file.
+
+    Raises jsonschema.exceptions.ValidationError if the configuration file does
+    not match the schema
+    """
+    import jsonschema
+    import jsonschema.validators
+    import referencing
+    import referencing.exceptions
+
+    SCHEMAS_PATH = os.path.join(bindir, "..", "schemas")
+
+    def retrieve_resource(uri):
+        """
+        Retrieve schemas from /schemas/* URIs, reading them from
+        $BITBAKE_DIR/schemas/* files
+        """
+
+        if not uri.startswith("/schemas/"):
+            raise referencing.exceptions.NoSuchResource(uri)
+
+        schema_path = os.path.join(SCHEMAS_PATH, uri.removeprefix("/schemas/"))
+
+        if not os.path.exists(schema_path):
+            raise referencing.exceptions.NoSuchResource(uri)
+
+        with open(schema_path) as f:
+            schema = json.load(f)
+        return referencing.Resource.from_contents(schema)
+
+    registry = referencing.Registry(retrieve=retrieve_resource)
+    with open(os.path.join(SCHEMAS_PATH, "bitbake-setup.schema.json")) as f:
+        bb_setup_schema = json.load(f)
+    jsonschema.validators.validate( bitbake_setup_conf, schema=bb_setup_schema, registry=registry)
+
 def obtain_config(top_dir, settings, args, source_overrides, d):
     if args.config:
         config_id = args.config[0]
@@ -422,6 +459,9 @@  def obtain_config(top_dir, settings, args, source_overrides, d):
         config_parameters = []
         upstream_config = {'type':'registry','registry':settings["default"]["registry"],'name':config_id,'data':json.load(open(get_registry_config(registry_path,config_id)))}
 
+    if args.validate:
+        validate_bitbake_setup_schema(upstream_config['data'])
+
     upstream_config['bitbake-config'] = choose_bitbake_config(upstream_config['data']['bitbake-setup']['configurations'], config_parameters, args.non_interactive)
     upstream_config['bitbake-config']['oe-fragment-choices'] = choose_fragments(upstream_config['bitbake-config'].get('oe-fragments-one-of',{}), config_parameters[1:], args.non_interactive, args.skip_selection)
     upstream_config['non-interactive-cmdline-options'] = [config_id, upstream_config['bitbake-config']['name']] + sorted(upstream_config['bitbake-config']['oe-fragment-choices'].values())
@@ -753,6 +793,7 @@  def main():
     parser.add_argument('--setting', default=[], action='append', dest='cmdline_settings',
                         nargs=3, metavar=('SECTION', 'SETTING', 'VALUE'),
                         help='Modify a setting (for this bitbake-setup invocation only), for example "--setting default top-dir-prefix /path/to/top/dir".')
+    parser.add_argument('--validate', action='store_true', help='Validate configuration files against the schema (need jsonschema)', default=False)
 
     subparsers = parser.add_subparsers()