blob: dc18e3e39a3dbb96833ed7575f0ee0f833a8573c [file] [log] [blame] [view]
# Advanced Plugin Internals
This page is intended for developers who want to understand FFX's plugin system
better. FFX is built on top of the [argh](https://docs.rs/argh/0.1.3/argh/)
crate. This crate imposes the Google standard for CLI parameters. The structure
that argh expects to define the CLI parameters is required at compile time.
Therefore, this rules out any runtime plugin systems as Rust structs cannot be
edited after compile time.
It also means that any dynamic ability to add plugins must come before compile
time. To accomplish this, FFX uses GN build rules to generate the final argh
structure from the supplied plugin dependencies. You can see that code
[here](https://fuchsia.googlesource.com/fuchsia/+/HEAD/src/developer/ffx/build/ffx.gni#35).
Internal libraries to FFX require access to top level CLI flags and parameters.
For example, the config library needs access to the "--config" flag:
```sh
$fx ffx --config "config-test=runtime" config get --name config-test
```
These internal libraries are available for use in the plugins. For example, the
config library supplies configuration management for plugins. More about that
can be read on the [config](config.md) page.
This means that the final argh structure generated needs to be supplied to these
internal libraries. And in turn, the config libraries need to be supplied to the
plugins.
This is why there are two libraries generated by the ffx_plugin template.
The Rust attributes that developers decorate their code with generates some code
at compile time as well.
The "ffx_command" attribute just creates the following code in the "_args"
library:
```rust
pub type FfxPluginCommand = <Your Command>;
```
This provides a known entry point into this library that can used by FFX while
allowing the developer to name their command whatever they want.
The "ffx_plugin" attribute does something similar.
```rust
pub async fn ffx_plugin_impl(<Your methods inputs>) -> Result<(), Error> {
<Your method name>(<Your parameter names>).await
}
```
The ffx_plugin template requires enough dependencies to allow for the code
generated via the Rust attributes to compile. Therefore the ffx_plugin template
gets the following
[dependencies](https://fuchsia.googlesource.com/fuchsia/+/refs/hea%20ds/HEAD/src/developer/ffx/build/ffx_plugin.gni#99)
for free:
+ //sdk/fidl/fuchsia.developer.remotecontrol:fuchsia.developer.remotecontrol-rustc
+ //src/connectivity/overnet/lib/hoist
+ //src/developer/ffx/core:lib
+ //src/developer/ffx:command_lib
+ //src/developer/ffx/config:lib
+ //src/lib/fidl/rust/fidl
+ //third_party/rust_crates:anyhow
+ "//third_party/rust_crates:argh
+ "//third_party/rust_crates:futures
+ "//third_party/rust_crates:log