diff --git a/.github/scripts/validate_plugins.py b/.github/scripts/validate_plugins.py index 4f5eb44..47ed67f 100644 --- a/.github/scripts/validate_plugins.py +++ b/.github/scripts/validate_plugins.py @@ -6,7 +6,7 @@ * `plugins.yaml` is valid YAML and has the expected top-level structure. * Every plugin entry has the required fields with the correct types. * `name` is unique, uses snake_case (no spaces). -* `category` is one of the standard categories listed in the README. +* `category` is a list containing one or more of the standard categories listed in the README. * `description` is short (<= 100 characters as recommended by the guidelines). * `repository` is a valid public Git URL (http(s) or git@). * `version` is either `latest` or looks like a (semver-ish) tag. @@ -42,11 +42,9 @@ "repository": str, "version": str, "author": str, - "category": str, -} -OPTIONAL_FIELDS: dict[str, type] = { - "tags": list, + "category": list, } +OPTIONAL_FIELDS: dict[str, type] = {} ALLOWED_CATEGORIES = { "PerceptionStrategy", @@ -145,11 +143,6 @@ def validate_entry(idx: int, entry: Any, problems: Problems) -> None: if field in entry and not isinstance(entry[field], expected): problems.error(f"{label}: field `{field}` must be a {expected.__name__}") - if "tags" in entry and isinstance(entry["tags"], list): - for i, tag in enumerate(entry["tags"]): - if not isinstance(tag, str) or not tag.strip(): - problems.error(f"{label}: tags[{i}] must be a non-empty string") - # Name format if isinstance(entry.get("name"), str): if " " in entry["name"]: @@ -170,11 +163,17 @@ def validate_entry(idx: int, entry: Any, problems: Problems) -> None: # Category cat = entry.get("category") - if isinstance(cat, str) and cat not in ALLOWED_CATEGORIES: - problems.error( - f"{label}: category `{cat}` is not one of " - f"{sorted(ALLOWED_CATEGORIES)}" - ) + if isinstance(cat, list): + if not cat: + problems.error(f"{label}: `category` must contain at least one entry") + for i, item in enumerate(cat): + if not isinstance(item, str) or not item.strip(): + problems.error(f"{label}: category[{i}] must be a non-empty string") + elif item not in ALLOWED_CATEGORIES: + problems.error( + f"{label}: category[{i}] `{item}` is not one of " + f"{sorted(ALLOWED_CATEGORIES)}" + ) # Repository URL repo = entry.get("repository") diff --git a/README.md b/README.md index 0ae38de..ec963f3 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,11 @@ A central registry of community-maintained plugins for [AVLite](https://github.c | `repository` | URL (string) | yes | Public Git URL where the plugin source lives (typically a GitHub repository). | | `version` | string | yes | Plugin version. Use a semver tag (e.g. `1.2.0`) or `latest` to track the default branch. | | `author` | string | yes | Author name, GitHub user, or organization that maintains the plugin. | -| `category` | string | yes | Primary category. See [Categories](#categories) below. | -| `tags` | list of strings | no | Free-form tags used for search and filtering (e.g. `lidar`, `ros2`, `simulation`). | +| `category` | list of strings | yes | One or more categories that describe the plugin. See [Categories](#categories) below. | ### Categories -Use one of the following standard categories for `category`. If your plugin doesn't fit, open an issue to propose a new one rather than inventing one ad hoc: +Use one or more of the following standard categories for `category`. If your plugin doesn't fit, open an issue to propose a new one rather than inventing one ad hoc: - `PerceptionStrategy` — sensing, detection, tracking, segmentation, fusion - `LocalizationStrategy` — pose estimation, SLAM-based localization @@ -37,10 +36,8 @@ plugins: repository: https://github.com/your-org/your-plugin-repo version: latest author: your-org - category: PerceptionStrategy - tags: - - perception - - computer-vision + category: + - PerceptionStrategy ``` The authoritative list of registered plugins lives in [`plugins.yaml`](plugins.yaml). Tools and the AVLite runtime consume that file directly. diff --git a/plugins.yaml b/plugins.yaml index 1c8377a..9cd01da 100644 --- a/plugins.yaml +++ b/plugins.yaml @@ -8,4 +8,5 @@ plugins: repository: https://github.com/AV-Lab/sample-avlite-plugin version: latest author: AV-Lab - category: PerceptionStrategy + category: + - PerceptionStrategy