Skip to main content

Crate pmpx_plugin

Crate pmpx_plugin 

Source
Expand description

§pmpx-plugin

The pmpx plugin contract: one trait plus a stable C ABI that carries the trait safely across the dlopen boundary.

A plugin author only implements PackageManager and then uses the one-line export! to generate the whole C ABI shell:

ⓘ
pub fn create() -> Box<dyn PackageManager> { Box::new(CargoPlugin) }
pmpx_plugin::export!(create);

§What a plugin may and may not do

PackageManager::command should only map from its inputs: it does not read files (including anything under project_root), does not write files, does not read environment variables, does not spawn child processes, and does not make network requests. That keeps command() completely pure (unit tests need no fixture directory at all) and stops a plugin from using file reads to probe things it should not know – “what the project looks like” is decided by the host’s detect layer and handed to the plugin through matched, a declarative, auditable allowlist. Data crossing abi is always #[repr(C)] POD, so the two sides need not share a rustc; see the module docs of abi.

Modules§

abi
The wire format across the dlopen boundary.

Macros§

export
Generate the plugin’s entire C ABI shell: the entry symbol, plus the name / family / command / free_* shims.

Structs§

CommandSpec
One command waiting to be executed, pure data – a plugin only describes “what to run” and the actual spawn is done by the host, so stdio, environment, and exit-code handling have exactly one implementation. Construction is a consuming chain (self -> Self), so it can produce a value directly:
Context
The context the host passes to the plugin. Read-only.
Family
Ecosystem family. Decides the grouping headers of the host’s plugin ls, the scope of plugin set, and the key names of [plugin] <family> = "..." in a project’s .pmpx.toml. An open type rather than a closed enum: known ecosystems have constants, unknown ones extend via Family::new, and comparison and ordering go by string – a third-party plugin supporting a new ecosystem needs neither a change to this crate nor a host release.

Enums§

PluginError
The errors a plugin can report. Deliberately only three – because the host only needs to distinguish three: the verb is not supported (so it can degrade to passing through verbatim), the arguments are wrong, and everything else. The human-readable description goes in the payload and the host prints it to stderr as-is.
Verb
The verbs pmpx recognizes. A closed set – this is all the command line has. The numbers correspond one-to-one with the VERB_* constants in abi, and the order must not change (changing it requires abi::ABI_VERSION + 1); a test in the abi module pins this down.

Traits§

PackageManager
An implementation of one package manager backend, a purely synchronous interface: no async, no callbacks, no I/O – passing a Future across the dlopen boundary is the most fragile part of this approach. It should only do mapping; see the crate docs for the constraints.