Co-authored-by: aider (openai/andrew/openrouter/deepseek/deepseek-chat-v3.1) <aider@aider.chat>
267 lines
9.3 KiB
Rust
267 lines
9.3 KiB
Rust
use clap::*;
|
|
use is_terminal::IsTerminal;
|
|
use std::path::PathBuf;
|
|
use std::str::FromStr;
|
|
use log::debug;
|
|
|
|
use crate::modes::common::OutputFormat;
|
|
use crate::config;
|
|
use crate::common::status::StatusInfo;
|
|
use serde_json;
|
|
use serde_yaml;
|
|
use comfy_table::{Table, ContentArrangement, Cell, Attribute};
|
|
use comfy_table::presets::UTF8_FULL;
|
|
use comfy_table::modifiers::UTF8_ROUND_CORNERS;
|
|
|
|
use crate::common::status::PathInfo;
|
|
use crate::meta_plugin::MetaPluginType;
|
|
use crate::meta_plugin::get_meta_plugin;
|
|
|
|
fn build_path_table(path_info: &PathInfo) -> Table {
|
|
let mut path_table = Table::new();
|
|
|
|
if std::io::stdout().is_terminal() {
|
|
path_table
|
|
.load_preset(UTF8_FULL)
|
|
.apply_modifier(UTF8_ROUND_CORNERS);
|
|
} else {
|
|
path_table.set_content_arrangement(ContentArrangement::Dynamic);
|
|
}
|
|
|
|
path_table.set_header(vec![
|
|
Cell::new("Type").add_attribute(Attribute::Bold),
|
|
Cell::new("Path").add_attribute(Attribute::Bold),
|
|
]);
|
|
|
|
path_table.add_row(vec!["Data", &path_info.data]);
|
|
path_table.add_row(vec!["Database", &path_info.database]);
|
|
|
|
path_table
|
|
}
|
|
|
|
|
|
fn build_config_table(settings: &config::Settings) -> Table {
|
|
let mut config_table = Table::new();
|
|
if std::io::stdout().is_terminal() {
|
|
config_table
|
|
.load_preset(UTF8_FULL)
|
|
.apply_modifier(UTF8_ROUND_CORNERS);
|
|
} else {
|
|
config_table.set_content_arrangement(ContentArrangement::Dynamic);
|
|
}
|
|
|
|
config_table.set_header(vec![
|
|
Cell::new("Setting").add_attribute(Attribute::Bold),
|
|
Cell::new("Value").add_attribute(Attribute::Bold),
|
|
]);
|
|
|
|
// Add relevant configuration settings
|
|
config_table.add_row(vec!["Directory", &settings.dir.to_string_lossy()]);
|
|
config_table.add_row(vec!["Human Readable", &settings.human_readable.to_string()]);
|
|
config_table.add_row(vec!["Quiet", &settings.quiet.to_string()]);
|
|
|
|
if let Some(output_format) = &settings.output_format {
|
|
config_table.add_row(vec!["Output Format", output_format]);
|
|
}
|
|
|
|
if let Some(compression) = settings.compression() {
|
|
config_table.add_row(vec!["Compression", &compression]);
|
|
}
|
|
|
|
config_table
|
|
}
|
|
|
|
fn build_meta_plugins_configured_table(status_info: &StatusInfo) -> Option<Table> {
|
|
let meta_plugins = status_info.configured_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
|
|
.load_preset(UTF8_FULL)
|
|
.apply_modifier(UTF8_ROUND_CORNERS);
|
|
} else {
|
|
table.set_content_arrangement(ContentArrangement::Dynamic);
|
|
}
|
|
|
|
table.set_header(vec![
|
|
Cell::new("Plugin Name").add_attribute(Attribute::Bold),
|
|
Cell::new("Options").add_attribute(Attribute::Bold),
|
|
Cell::new("Outputs").add_attribute(Attribute::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<String, String> to HashMap<String, serde_yaml::Value>
|
|
let outputs_converted: std::collections::HashMap<String, serde_yaml::Value> = 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::<Vec<_>>()
|
|
.join("\n")
|
|
};
|
|
|
|
table.add_row(vec![
|
|
plugin_config.name.clone(),
|
|
options_str,
|
|
outputs_str,
|
|
]);
|
|
}
|
|
|
|
Some(table)
|
|
}
|
|
|
|
|
|
pub fn mode_status(
|
|
cmd: &mut Command,
|
|
settings: &config::Settings,
|
|
data_path: PathBuf,
|
|
db_path: PathBuf,
|
|
) -> Result<(), anyhow::Error> {
|
|
debug!("STATUS: Starting mode_status function");
|
|
|
|
let status_service = crate::services::status_service::StatusService::new();
|
|
let output_format = crate::modes::common::settings_output_format(settings);
|
|
debug!("STATUS: About to generate status info");
|
|
let status_info = status_service.generate_status(cmd, settings, data_path, db_path);
|
|
debug!("STATUS: Status info generated successfully");
|
|
|
|
match output_format {
|
|
OutputFormat::Table => {
|
|
println!("CONFIG:");
|
|
println!("{}", build_config_table(settings));
|
|
println!();
|
|
|
|
println!("PATHS:");
|
|
println!("{}", build_path_table(&status_info.paths));
|
|
println!();
|
|
|
|
// Always try to print META PLUGINS CONFIGURED section using status_info
|
|
if let Some(meta_plugins_table) = build_meta_plugins_configured_table(&status_info) {
|
|
println!("META PLUGINS CONFIGURED:");
|
|
println!("{}", meta_plugins_table);
|
|
println!();
|
|
} else {
|
|
println!("META PLUGINS CONFIGURED:");
|
|
println!("No plugins configured");
|
|
println!();
|
|
}
|
|
Ok(())
|
|
},
|
|
OutputFormat::Json => {
|
|
// Create a subset for status info that includes everything
|
|
println!("{}", serde_json::to_string_pretty(&status_info)?);
|
|
Ok(())
|
|
},
|
|
OutputFormat::Yaml => {
|
|
println!("{}", serde_yaml::to_string(&status_info)?);
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|