Write a generated client extension module into `path` as a managed block. * * The module is generated from the tool registry rather than shipped (see * src/cli/client_adapter.h), and it goes in as a MARKED BLOCK rather than a * whole-file write: the directory is auto-loaded by the client, so a user may * legitimately keep their own module there, and clobbering it would be the * install routi
| 8056 | * than a skip, because a silently absent extension is exactly the failure mode |
| 8057 | * that left #616 a no-op for six weeks. */ |
| 8058 | static void install_generated_client_extension(const char *label, const char *path, |
| 8059 | const char *binary_path, |
| 8060 | char *(*generate)(const char *), bool dry_run) { |
| 8061 | if (g_install_plan) { |
| 8062 | plan_record(label, "extension", path); |
| 8063 | return; |
| 8064 | } |
| 8065 | char *content = generate(binary_path); |
| 8066 | if (!content) { |
| 8067 | record_agent_config_error(false, label, "extension_generate", path); |
| 8068 | return; |
| 8069 | } |
| 8070 | bool installed = true; |
| 8071 | if (!dry_run && (!prepare_config_parent(path) || |
| 8072 | cbm_text_upsert_managed_block(path, CBM_ADAPTER_MARKER_START, |
| 8073 | CBM_ADAPTER_MARKER_END, content) != 0)) { |
| 8074 | installed = false; |
| 8075 | record_agent_config_error(false, label, "extension_install", path); |
| 8076 | } |
| 8077 | free(content); |
| 8078 | if (installed) { |
| 8079 | printf(" extension: %s\n", path); |
| 8080 | } |
| 8081 | } |
| 8082 | |
| 8083 | /* Remove only OUR marked block, never the file: a user's own module may share |
| 8084 | * it, and owned removal is the convention every other uninstall path here |
no test coverage detected