use onerom_cli::plugin::{
PluginRelease, PluginReleasesManifest, PluginType, fetch_plugin_releases,
fetch_plugins_manifest,
};
use onerom_cli::{Error, Options};
use onerom_config::fw::FirmwareVersion;
use crate::args::plugin::PluginArgs;
pub async fn cmd_plugin(options: &Options, args: &PluginArgs) -> Result<(), Error> {
let fw_version = resolve_fw_version(options, args)?;
let manifest = fetch_plugins_manifest().await?;
if manifest.plugins.is_empty() {
println!("No plugins available.");
return Ok(());
}
let plugins: Vec<_> = manifest
.plugins
.iter()
.filter(|p| args.r#type.is_none_or(|t| p.plugin_type == t))
.collect();
if plugins.is_empty() {
println!("No plugins found matching the specified type.");
return Ok(());
}
if options.verbose {
if let Some(fw) = &fw_version {
println!("Firmware version: {}", fw);
} else {
println!("Connect a device or use --fw-version to check compatibility.");
}
}
println!("Available plugins ({}):", plugins.len());
for entry in plugins {
let releases = match fetch_plugin_releases(entry.plugin_type, &entry.name).await {
Ok(r) => r,
Err(e) => {
let short_type = entry.plugin_type.short();
println!(
" {}/{}: failed to fetch releases: {e}",
short_type, entry.name
);
continue;
}
};
println!("---");
print_plugin(
options,
&releases,
entry.plugin_type,
&entry.name,
&fw_version,
args.all_versions,
);
}
Ok(())
}
fn print_plugin(
options: &Options,
releases: &PluginReleasesManifest,
plugin_type: PluginType,
name: &str,
fw_version: &Option<FirmwareVersion>,
all_versions: bool,
) {
println!("{}/{name} - {}", plugin_type.short(), releases.display_name);
println!(" {}", releases.description);
if releases.releases.is_empty() {
println!(" No releases available.");
return;
}
let to_show: Vec<&PluginRelease> = if all_versions {
releases.releases.iter().collect()
} else {
releases.releases.iter().take(1).collect()
};
for release in to_show {
print_release(options, release, fw_version);
}
}
fn print_release(options: &Options, release: &PluginRelease, fw_version: &Option<FirmwareVersion>) {
let compat = match fw_version {
Some(fw) if !release.compatible_with_firmware(fw) => {
" - incompatible with selected firmware"
}
_ => "",
};
let min_fw = if options.verbose {
format!(
" - requires One ROM firmware >= v{}",
release.min_fw_version
)
} else {
"".to_string()
};
println!(" v{}{min_fw}{compat}", release.version);
}
fn resolve_fw_version(
options: &Options,
args: &PluginArgs,
) -> Result<Option<FirmwareVersion>, Error> {
if let Some(v) = &args.fw_version {
return FirmwareVersion::try_from_str(v).map(Some).map_err(|_| {
Error::InvalidArgument(
"--fw-version".to_string(),
format!("Expected format major.minor.patch (e.g. 0.6.6)\n --fw-version '{v}'"),
)
});
}
if let Some(device) = &options.device
&& let Some(onerom) = &device.onerom
&& let Some(flash) = &onerom.flash
{
return Ok(Some(flash.version));
}
Ok(None)
}