diff --git a/src/main.rs b/src/main.rs
index 4e202bf..3fa23bc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -201,8 +201,8 @@ fn main() -> Result<(), Error> {
KeepModes::List => modes::list::mode_list(&mut cmd, &settings, ids, tags, &mut conn, data_path),
KeepModes::Delete => modes::delete::mode_delete(&mut cmd, &settings, &settings, ids, tags, &mut conn, data_path),
KeepModes::Info => modes::info::mode_info(&mut cmd, &settings, ids, tags, &mut conn, data_path),
- KeepModes::Status => modes::status::mode_status(&mut cmd, &settings, data_path, db_path, false),
- KeepModes::StatusPlugins => modes::status::mode_status(&mut cmd, &settings, data_path, db_path, true),
+ KeepModes::Status => modes::status::mode_status(&mut cmd, &settings, data_path, db_path),
+ KeepModes::StatusPlugins => modes::status_plugins::mode_status_plugins(&mut cmd, &settings, data_path, db_path),
KeepModes::Server => modes::server::mode_server(&mut cmd, &settings, &mut conn, data_path),
KeepModes::GenerateConfig => modes::generate_config::mode_generate_config(&mut cmd, &settings),
KeepModes::Unknown => unreachable!(),
diff --git a/src/modes/mod.rs b/src/modes/mod.rs
index f9f30a9..5fac735 100644
--- a/src/modes/mod.rs
+++ b/src/modes/mod.rs
@@ -8,3 +8,4 @@ pub mod list;
pub mod save;
pub mod server;
pub mod status;
+pub mod status_plugins;
diff --git a/src/modes/status.rs b/src/modes/status.rs
index 71546f0..9aa6e52 100644
--- a/src/modes/status.rs
+++ b/src/modes/status.rs
@@ -343,7 +343,6 @@ pub fn mode_status(
settings: &config::Settings,
data_path: PathBuf,
db_path: PathBuf,
- plugins_only: bool,
) -> Result<(), anyhow::Error> {
debug!("STATUS: Starting mode_status function");
@@ -355,73 +354,25 @@ pub fn mode_status(
match output_format {
OutputFormat::Table => {
- if plugins_only {
- println!("META PLUGINS AVAILABLE:");
- build_meta_plugin_table(&status_info.meta_plugins).printstd();
- println!();
+ println!("CONFIG:");
+ build_config_table(settings).printstd();
+ println!();
+
+ println!("PATHS:");
+ build_path_table(&status_info.paths).printstd();
+ println!();
- // Always try to print META PLUGINS CONFIGURED section
- if let Some(meta_plugins_table) = build_meta_plugins_configured_table(settings) {
- println!("META PLUGINS CONFIGURED:");
- meta_plugins_table.printstd();
- println!();
- } else {
- println!("META PLUGINS CONFIGURED:");
- println!("No plugins configured");
- println!();
- }
- } else {
- println!("CONFIG:");
- build_config_table(settings).printstd();
- println!();
-
- println!("PATHS:");
- build_path_table(&status_info.paths).printstd();
- println!();
-
- println!("COMPRESSION:");
- build_compression_table(&status_info.compression).printstd();
- println!();
- }
+ println!("COMPRESSION:");
+ build_compression_table(&status_info.compression).printstd();
+ println!();
Ok(())
},
OutputFormat::Json => {
- if plugins_only {
- // Create a subset for plugins only
- let plugins_info = serde_json::json!({
- "meta_plugins_available": status_info.meta_plugins,
- "meta_plugins_configured": settings.meta_plugins
- });
- println!("{}", serde_json::to_string_pretty(&plugins_info)?);
- } else {
- println!("{}", serde_json::to_string_pretty(&status_info)?);
- }
+ println!("{}", serde_json::to_string_pretty(&status_info)?);
Ok(())
},
OutputFormat::Yaml => {
- if plugins_only {
- // Create a proper structure for plugins info
- use serde_yaml::Mapping;
- let mut plugins_mapping = Mapping::new();
-
- // Add available plugins
- plugins_mapping.insert(
- serde_yaml::Value::String("meta_plugins_available".to_string()),
- serde_yaml::to_value(&status_info.meta_plugins)?,
- );
-
- // Add configured plugins if they exist
- if let Some(configured_plugins) = &settings.meta_plugins {
- plugins_mapping.insert(
- serde_yaml::Value::String("meta_plugins_configured".to_string()),
- serde_yaml::to_value(configured_plugins)?,
- );
- }
-
- println!("{}", serde_yaml::to_string(&plugins_mapping)?);
- } else {
- println!("{}", serde_yaml::to_string(&status_info)?);
- }
+ println!("{}", serde_yaml::to_string(&status_info)?);
Ok(())
}
}
diff --git a/src/modes/status_plugins.rs b/src/modes/status_plugins.rs
index e69de29..bb8330e 100644
--- a/src/modes/status_plugins.rs
+++ b/src/modes/status_plugins.rs
@@ -0,0 +1,290 @@
+use clap::*;
+use is_terminal::IsTerminal;
+use std::path::PathBuf;
+use log::debug;
+
+use crate::modes::common::{get_format_box_chars_no_border_line_separator, OutputFormat};
+use crate::config;
+use prettytable::color;
+use serde_json;
+use serde_yaml;
+use prettytable::row;
+use prettytable::{Attr, Cell, Row, Table};
+use prettytable::format::consts::{FORMAT_BOX_CHARS, FORMAT_NO_BORDER_LINE_SEPARATOR};
+
+use crate::meta_plugin::{MetaPluginType, get_meta_plugin};
+use crate::common::status::{MetaPluginInfo};
+
+fn build_meta_plugins_configured_table(settings: &config::Settings) -> Option
{
+ let meta_plugins = settings.meta_plugins.as_ref()?;
+ if meta_plugins.is_empty() {
+ return None;
+ }
+
+ // Sort meta plugins by name
+ let mut sorted_meta_plugins = meta_plugins.clone();
+ sorted_meta_plugins.sort_by(|a, b| a.name.cmp(&b.name));
+
+ let mut table = Table::new();
+ if std::io::stdout().is_terminal() {
+ table.set_format(*FORMAT_BOX_CHARS);
+ } else {
+ table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR);
+ }
+
+ table.set_titles(Row::new(vec![
+ Cell::new("Plugin Name").with_style(Attr::Bold),
+ Cell::new("Options").with_style(Attr::Bold),
+ Cell::new("Outputs").with_style(Attr::Bold),
+ ]));
+
+ for plugin_config in sorted_meta_plugins {
+ // Create the plugin to get its default options
+ let meta_plugin_type = match MetaPluginType::from_str(&plugin_config.name) {
+ Ok(plugin_type) => plugin_type,
+ Err(_) => continue,
+ };
+
+ // First, create a default plugin to get its default options
+ let default_plugin = get_meta_plugin(
+ meta_plugin_type.clone(),
+ None,
+ None,
+ );
+
+ // Start with the default options
+ let mut effective_options = default_plugin.options().clone();
+
+ // Merge with the configured options
+ for (key, value) in &plugin_config.options {
+ effective_options.insert(key.clone(), value.clone());
+ }
+
+ // Convert outputs from HashMap to HashMap
+ let outputs_converted: std::collections::HashMap = plugin_config.outputs
+ .iter()
+ .map(|(k, v)| (k.clone(), serde_yaml::Value::String(v.clone())))
+ .collect();
+
+ // Create the actual plugin with merged options - the constructor will handle setting up outputs
+ let actual_plugin = get_meta_plugin(
+ meta_plugin_type.clone(),
+ Some(effective_options.clone()),
+ Some(outputs_converted),
+ );
+
+ // Get the default plugin to see its default options
+ let default_plugin = get_meta_plugin(
+ meta_plugin_type.clone(),
+ None,
+ None,
+ );
+
+ // Start with the default options
+ let mut all_options = default_plugin.options().clone();
+ // Merge with the configured options
+ for (key, value) in &effective_options {
+ all_options.insert(key.clone(), value.clone());
+ }
+
+ // Sort options by key and convert to a YAML string
+ let mut sorted_options: Vec<_> = all_options.iter().collect();
+ sorted_options.sort_by(|a, b| a.0.cmp(b.0));
+ let sorted_options_map: std::collections::BTreeMap<_, _> = sorted_options.into_iter().collect();
+
+ let options_str = if sorted_options_map.is_empty() {
+ "{}".to_string()
+ } else {
+ serde_yaml::to_string(&sorted_options_map)
+ .unwrap_or_else(|_| "Unable to serialize options".to_string())
+ .trim()
+ .to_string()
+ };
+
+ // Show only non-null outputs from the plugin
+ // Collect and sort outputs by their string representation
+ let mut enabled_output_pairs = Vec::new();
+ for (key, value) in actual_plugin.outputs() {
+ // Skip null values (disabled outputs)
+ if value.is_null() {
+ continue;
+ }
+
+ // Convert serde_yaml::Value to a string representation
+ let value_str = match value {
+ serde_yaml::Value::String(s) => s.clone(),
+ serde_yaml::Value::Number(n) => n.to_string(),
+ serde_yaml::Value::Bool(b) => b.to_string(),
+ serde_yaml::Value::Null => "null".to_string(),
+ serde_yaml::Value::Sequence(_) => {
+ serde_yaml::to_string(value).unwrap_or_else(|_| "[]".to_string())
+ }
+ serde_yaml::Value::Mapping(_) => {
+ serde_yaml::to_string(value).unwrap_or_else(|_| "{}".to_string())
+ }
+ serde_yaml::Value::Tagged(_) => {
+ serde_yaml::to_string(value).unwrap_or_else(|_| "tagged".to_string())
+ }
+ };
+ // Trim any extra whitespace from the serialized values
+ let value_str = value_str.trim().to_string();
+ if key == &value_str {
+ enabled_output_pairs.push((key.clone(), key.clone()));
+ } else {
+ enabled_output_pairs.push((key.clone(), format!("{}->{}", key, value_str)));
+ }
+ }
+
+ // Sort outputs by their display value (second element of the tuple)
+ enabled_output_pairs.sort_by(|a, b| a.1.cmp(&b.1));
+
+ // Join each output on a new line
+ let outputs_str = if enabled_output_pairs.is_empty() {
+ "{}".to_string()
+ } else {
+ enabled_output_pairs.into_iter()
+ .map(|(_, display)| display)
+ .collect::>()
+ .join("\n")
+ };
+
+ table.add_row(Row::new(vec![
+ Cell::new(&plugin_config.name),
+ Cell::new(&options_str),
+ Cell::new(&outputs_str),
+ ]));
+ }
+
+ Some(table)
+}
+
+fn build_meta_plugin_table(meta_plugin_info: &std::collections::HashMap) -> Table {
+ let mut meta_plugin_table = Table::new();
+ if std::io::stdout().is_terminal() {
+ meta_plugin_table.set_format(*FORMAT_BOX_CHARS);
+ } else {
+ meta_plugin_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR);
+ }
+
+ meta_plugin_table.set_titles(row!(
+ b->"Plugin Name",
+ b->"Options",
+ b->"Outputs"));
+
+ // Sort meta plugin info by plugin name
+ let mut sorted_meta_plugin_info: Vec<&MetaPluginInfo> = meta_plugin_info.values().collect();
+ sorted_meta_plugin_info.sort_by(|a, b| a.meta_name.cmp(&b.meta_name));
+
+ for info in sorted_meta_plugin_info {
+ // Get default options for the meta plugin
+ let meta_plugin_type = match MetaPluginType::from_str(&info.meta_name) {
+ Ok(plugin_type) => plugin_type,
+ Err(_) => continue,
+ };
+
+ // Create a default plugin to get its default options
+ let default_plugin = get_meta_plugin(
+ meta_plugin_type.clone(),
+ None,
+ None,
+ );
+
+ // Get and sort options
+ let mut options: Vec<_> = default_plugin.options().iter().collect();
+ options.sort_by(|a, b| a.0.cmp(b.0));
+
+ // Format options as YAML string, each on a new line
+ let options_str = if options.is_empty() {
+ "{}".to_string()
+ } else {
+ let options_map: std::collections::BTreeMap<_, _> = options.into_iter().collect();
+ serde_yaml::to_string(&options_map)
+ .unwrap_or_else(|_| "Unable to serialize options".to_string())
+ .trim()
+ .to_string()
+ };
+
+ // Get and sort output keys
+ let mut output_keys: Vec = info.outputs.keys().map(|k| k.to_string()).collect();
+ output_keys.sort();
+ let outputs_display = if output_keys.is_empty() {
+ "{}".to_string()
+ } else {
+ output_keys.join("\n")
+ };
+
+ meta_plugin_table.add_row(Row::new(vec![
+ Cell::new(&info.meta_name),
+ Cell::new(&options_str),
+ Cell::new(&outputs_display),
+ ]));
+ }
+
+ meta_plugin_table
+}
+
+pub fn mode_status_plugins(
+ cmd: &mut Command,
+ settings: &config::Settings,
+ data_path: PathBuf,
+ db_path: PathBuf,
+) -> Result<(), anyhow::Error> {
+ debug!("STATUS_PLUGINS: Starting mode_status_plugins function");
+
+ let status_service = crate::services::status_service::StatusService::new();
+ let output_format = crate::modes::common::settings_output_format(settings);
+ debug!("STATUS_PLUGINS: About to generate status info");
+ let status_info = status_service.generate_status(cmd, settings, data_path, db_path);
+ debug!("STATUS_PLUGINS: Status info generated successfully");
+
+ match output_format {
+ OutputFormat::Table => {
+ println!("META PLUGINS AVAILABLE:");
+ build_meta_plugin_table(&status_info.meta_plugins).printstd();
+ println!();
+
+ // Always try to print META PLUGINS CONFIGURED section
+ if let Some(meta_plugins_table) = build_meta_plugins_configured_table(settings) {
+ println!("META PLUGINS CONFIGURED:");
+ meta_plugins_table.printstd();
+ println!();
+ } else {
+ println!("META PLUGINS CONFIGURED:");
+ println!("No plugins configured");
+ println!();
+ }
+ Ok(())
+ },
+ OutputFormat::Json => {
+ // Create a subset for plugins only
+ let plugins_info = serde_json::json!({
+ "meta_plugins_available": status_info.meta_plugins,
+ "meta_plugins_configured": settings.meta_plugins
+ });
+ println!("{}", serde_json::to_string_pretty(&plugins_info)?);
+ Ok(())
+ },
+ OutputFormat::Yaml => {
+ // Create a proper structure for plugins info
+ use serde_yaml::Mapping;
+ let mut plugins_mapping = Mapping::new();
+
+ // Add available plugins
+ plugins_mapping.insert(
+ serde_yaml::Value::String("meta_plugins_available".to_string()),
+ serde_yaml::to_value(&status_info.meta_plugins)?,
+ );
+
+ // Add configured plugins if they exist
+ if let Some(configured_plugins) = &settings.meta_plugins {
+ plugins_mapping.insert(
+ serde_yaml::Value::String("meta_plugins_configured".to_string()),
+ serde_yaml::to_value(configured_plugins)?,
+ );
+ }
+
+ println!("{}", serde_yaml::to_string(&plugins_mapping)?);
+ Ok(())
+ }
+ }
+}