Initial commit: DPM core library, CLI, bundled info module, and tests
This commit is contained in:
119
docs/CONSUMERS.md
Normal file
119
docs/CONSUMERS.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Consuming libdpm-core
|
||||
|
||||
Programs link libdpm-core to operate the package manager directly: build systems, installers, image builders, system tooling, and foreign-language bindings all use the same library the dpm CLI is built on. A program holding a default context is operating the installed package manager itself — system configuration, system module path, system tree, system locking — identically to invoking the installed dpm command.
|
||||
|
||||
## Compiling and linking
|
||||
|
||||
With core installed, include the public header and link the library:
|
||||
|
||||
```
|
||||
#include <dpm/core.h>
|
||||
```
|
||||
|
||||
```
|
||||
g++ myprog.cpp -ldpm-core
|
||||
```
|
||||
|
||||
The header installs to the standard include path and the library to the standard lib path, so no additional flags are required. The interface is a C ABI: every function is extern "C", every type crossing the boundary is a C type, and state passes through opaque handles — callable from C, C++, or any language with C FFI.
|
||||
|
||||
## The context
|
||||
|
||||
All work happens through a context handle:
|
||||
|
||||
```
|
||||
dpm_ctx* ctx = dpm_open(NULL);
|
||||
...
|
||||
dpm_close(ctx);
|
||||
```
|
||||
|
||||
dpm_open(NULL) reads the system configuration (/etc/dpm/conf.d/), resolves the system module path, and targets the root filesystem. dpm_close releases every handle the context issued; all pointers obtained through the context are invalid after it.
|
||||
|
||||
To point a context elsewhere, pass overrides — every field is optional:
|
||||
|
||||
```
|
||||
dpm_open_overrides ov = {
|
||||
"/path/to/conf.d", /* config_dir: NULL = /etc/dpm/conf.d/ */
|
||||
"/path/to/modules", /* module_path: NULL = config, then default */
|
||||
"/path/to/root", /* root: target root for package operations */
|
||||
-1 /* log_level: -1 = from config */
|
||||
};
|
||||
dpm_ctx* ctx = dpm_open(&ov);
|
||||
```
|
||||
|
||||
The root override is what makes chroot builds, image assembly, and sysroot management work: package operations act on the given tree instead of the running system. Multiple simultaneous contexts with different roots are legal.
|
||||
|
||||
## Acquiring and using modules
|
||||
|
||||
**dpm_require** loads a module by name, on demand, with an optional minimum version:
|
||||
|
||||
```
|
||||
dpm_module* mod = dpm_require(ctx, "mymodule", "1.0.0");
|
||||
```
|
||||
|
||||
Core validates the module completely at load; a handle is returned only for a fully valid module. NULL means the module is absent, invalid, or below the minimum — dpm_last_error(ctx) carries the precise reason. Modules load at most once per context; repeated calls return the same handle.
|
||||
|
||||
**dpm_execute** drives a module the way the CLI does — a command name and arguments:
|
||||
|
||||
```
|
||||
int rc = dpm_execute(ctx, mod, "command", argc, argv);
|
||||
```
|
||||
|
||||
**dpm_get_api** returns a module's typed function table for direct calls:
|
||||
|
||||
```
|
||||
const mymodule_api_v1_s* api = (const mymodule_api_v1_s*)dpm_get_api(ctx, mod, "mymodule", 1);
|
||||
```
|
||||
|
||||
The returned table was validated at load and is usable for the life of the context. NULL means the module does not provide that API at that version.
|
||||
|
||||
## Enumerating modules
|
||||
|
||||
```
|
||||
dpm_cursor* cur = dpm_list_modules(ctx);
|
||||
dpm_module_info info;
|
||||
while (dpm_cursor_next(cur, &info) == 0) {
|
||||
/* info.name, info.version, info.description, info.core_min */
|
||||
}
|
||||
dpm_cursor_free(cur);
|
||||
```
|
||||
|
||||
The cursor covers every valid module in the module path; invalid candidates are excluded and logged.
|
||||
|
||||
## Services
|
||||
|
||||
- **dpm_core_version()** — core's version; callable without a context.
|
||||
- **dpm_config_get(ctx, module, section, key)** — a value from a module's configuration namespace, or NULL if unset.
|
||||
- **dpm_log(ctx, level, message)** — writes to the context's configured log targets; levels are DPM_LOG_FATAL through DPM_LOG_DEBUG.
|
||||
- **dpm_module_path(ctx)** — the resolved module directory.
|
||||
- **dpm_last_error(ctx)** — a human-readable description of the most recent failure on the context, or NULL.
|
||||
|
||||
## Ownership and errors
|
||||
|
||||
Strings returned by the library are owned by the context (or by the module that produced them) and remain valid until dpm_close; callers never free them. Functions returning int use 0 for success. Functions returning pointers use NULL for failure, with detail available from dpm_last_error.
|
||||
|
||||
## Complete example
|
||||
|
||||
```
|
||||
#include <dpm/core.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
dpm_ctx* ctx = dpm_open(NULL);
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "failed to initialize\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dpm_module* mod = dpm_require(ctx, "info", NULL);
|
||||
if (!mod) {
|
||||
fprintf(stderr, "%s\n", dpm_last_error(ctx));
|
||||
dpm_close(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc = dpm_execute(ctx, mod, "version", 0, NULL);
|
||||
|
||||
dpm_close(ctx);
|
||||
return rc;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user