From 867fa5140b0cf213715a0bf188e53374e6b2f096 Mon Sep 17 00:00:00 2001 From: Qubasa Date: Tue, 14 Oct 2025 18:54:22 +0200 Subject: [PATCH] clan_lib: Add get_service_readmes api function Returns the README.md for one or multiple clan services, needed for the clan ai feature --- pkgs/clan-cli/clan_lib/services/modules.py | 35 +++++++++++++++++++ .../clan_lib/services/modules_test.py | 22 ++++++++++++ 2 files changed, 57 insertions(+) diff --git a/pkgs/clan-cli/clan_lib/services/modules.py b/pkgs/clan-cli/clan_lib/services/modules.py index 8869b5a10..82fe8a9c9 100644 --- a/pkgs/clan-cli/clan_lib/services/modules.py +++ b/pkgs/clan-cli/clan_lib/services/modules.py @@ -210,6 +210,41 @@ def find_instance_refs_for_module( return res +type ServiceName = str +type Readme = str | None +type ServiceReadmes = dict[ServiceName, Readme] +type InputName = str | None + + +@dataclass(frozen=True) +class ServiceReadmeCollection: + input_name: str | None + readmes: ServiceReadmes + + +@API.register +def get_service_readmes( + input_name: InputName, + service_names: list[ServiceName], + flake: Flake, +) -> ServiceReadmeCollection: + """Get the README content for a service module""" + query_param = "modulesPerSource" + + if input_name is None: + query_param = "staticModules" + + service_queries = "{" + ",".join(service_names) + "}" + + query = ( + f"clanInternals.inventoryClass.{query_param}.{service_queries}.manifest.readme" + ) + + readmes = flake.select(query) + + return ServiceReadmeCollection(input_name=input_name, readmes=readmes) + + @API.register def list_service_modules(flake: Flake) -> ClanModules: """Show information about a module""" diff --git a/pkgs/clan-cli/clan_lib/services/modules_test.py b/pkgs/clan-cli/clan_lib/services/modules_test.py index 27a32f70c..ea0511a29 100644 --- a/pkgs/clan-cli/clan_lib/services/modules_test.py +++ b/pkgs/clan-cli/clan_lib/services/modules_test.py @@ -6,6 +6,7 @@ from clan_cli.tests.fixtures_flakes import nested_dict from clan_lib.errors import ClanError from clan_lib.flake.flake import Flake from clan_lib.services.modules import ( + get_service_readmes, list_service_instances, list_service_modules, set_service_instance, @@ -70,6 +71,27 @@ def test_list_service_instances( assert borgbackup_service.info.roles["server"].description is not None +@pytest.mark.with_core +def test_get_service_readmes( + clan_flake: Callable[..., Flake], +) -> None: + clan_config: Clan = {"inventory": {}} + flake = clan_flake(clan_config) + + service_modules = list_service_modules(flake) + service_names = [m.usage_ref["name"] for m in service_modules.modules] + + collection = get_service_readmes( + input_name=None, + service_names=service_names, + flake=flake, + ) + + assert collection.input_name is None + assert collection.readmes["borgbackup"] + assert len(collection.readmes["borgbackup"]) > 10 + + @pytest.mark.with_core def test_list_service_modules( clan_flake: Callable[..., Flake],