use crate::cli::PluginsCommand;
use anyhow::anyhow;
use clap::Parser;
use forc_util::ForcResult;
use std::path::{Path, PathBuf};
use tracing::info;
#[derive(Debug, Parser)]
pub struct Command {
#[clap(long = "paths", short = 'p')]
print_full_path: bool,
#[clap(long = "describe", short = 'd')]
describe: bool,
}
pub(crate) fn exec(command: PluginsCommand) -> ForcResult<()> {
let PluginsCommand {
print_full_path,
describe,
} = command;
info!("Installed Plugins:");
for path in crate::cli::plugin::find_all() {
info!("{}", print_plugin(path, print_full_path, describe)?);
}
Ok(())
}
fn parse_description_for_plugin(plugin: &Path) -> String {
use std::process::Command;
let default_description = "No description found for this plugin.";
let proc = Command::new(plugin)
.arg("-h")
.output()
.expect("Could not get plugin description.");
let stdout = String::from_utf8_lossy(&proc.stdout);
match stdout.split('\n').nth(1) {
Some(x) => {
if x.is_empty() {
default_description.to_owned()
} else {
x.to_owned()
}
}
None => default_description.to_owned(),
}
}
fn format_print_description(
path: PathBuf,
print_full_path: bool,
describe: bool,
) -> ForcResult<String> {
let display = if print_full_path {
path.display().to_string()
} else {
path.file_name()
.expect("Failed to read file name")
.to_str()
.expect("Failed to print file name")
.to_string()
};
let description = parse_description_for_plugin(&path);
if describe {
Ok(format!(" {display} \t\t{description}"))
} else {
Ok(display)
}
}
fn print_plugin(path: PathBuf, print_full_path: bool, describe: bool) -> ForcResult<String> {
format_print_description(path, print_full_path, describe)
.map_err(|e| anyhow!("Could not get plugin info: {}", e.as_ref()).into())
}