How to write a plugin
This guide shows you how to create a plugin that contributes a CliCommand to the Cli operation.
Goal
A plugin that adds a greet command to the CLI.
Steps
1. Create a crate
sh
cargo new --lib my-greet-pluginAdd dependencies:
toml
[dependencies]
handl-platform = { path = "../crates/platform" }
handl-ext-cli = { path = "../crates/ext-cli" }
serde_json = "1"2. Implement Plugin
rust
use handl_ext_cli::{Cli, CliCommand};
use handl_platform::{ContributionContext, PlatformError, Plugin};
use serde_json::json;
pub struct GreetPlugin;
impl Plugin for GreetPlugin {
fn id(&self) -> &str { "my-greet" }
fn version(&self) -> &str { "0.1.0" }
fn metadata(&self) -> serde_json::Value { serde_json::Value::Null }
fn contribute(&self, ctx: &mut ContributionContext) -> Result<(), PlatformError> {
ctx.contribute::<Cli>(CliCommand {
name: "greet".to_string(),
about: "Greet someone".to_string(),
run: Box::new(|host, matches| {
let name = matches
.get_one::<String>("name")
.cloned()
.unwrap_or_else(|| "world".to_string());
host.execute(
&"eval".into(),
json!({"expr": format!("\"Hello, {}!\"", name)}),
)
}),
})?;
Ok(())
}
}3. Register the plugin in a host
rust
use my_greet_plugin::GreetPlugin;
host.register_plugin(GreetPlugin);
host.load()?;4. Run the command
sh
./target/debug/my-host greet AliceCommon cases
If you are contributing to a different operation, change the RuleAcceptor:
contribute::<Linter>(...)for lint rules.contribute::<Formatter>(...)for format rules.contribute::<Options>(...)for option schemas.contribute::<DataTypes>(...)for data types.
Each call is type-checked at compile time against the RuleAcceptor::Rule associated type.