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
| 8205 | * than a skip, because a silently absent extension is exactly the failure mode |
| 8206 | * that left #616 a no-op for six weeks. */ |
| 8207 | static void install_generated_client_extension(const char *label, const char *path, |
| 8208 | const char *binary_path, |
| 8209 | char *(*generate)(const char *), bool dry_run) { |
| 8210 | if (g_install_plan) { |
| 8211 | plan_record(label, "extension", path); |
| 8212 | return; |
| 8213 | } |
| 8214 | char *content = generate(binary_path); |
| 8215 | if (!content) { |
| 8216 | record_agent_config_error(false, label, "extension_generate", path); |
| 8217 | return; |
| 8218 | } |
| 8219 | bool installed = true; |
| 8220 | if (!dry_run && (!prepare_config_parent(path) || |
| 8221 | cbm_text_upsert_managed_block(path, CBM_ADAPTER_MARKER_START, |
| 8222 | CBM_ADAPTER_MARKER_END, content) != 0)) { |
| 8223 | installed = false; |
| 8224 | record_agent_config_error(false, label, "extension_install", path); |
| 8225 | } |
| 8226 | free(content); |
| 8227 | if (installed) { |
| 8228 | printf(" extension: %s\n", path); |
| 8229 | } |
| 8230 | } |
| 8231 | |
| 8232 | /* Remove only OUR marked block, never the file: a user's own module may share |
| 8233 | * it, and owned removal is the convention every other uninstall path here |
no test coverage detected