use crate::{
commands::global,
config::locator::{self},
env_vars,
print::Print,
};
use clap::Parser;
#[allow(clippy::doc_markdown)]
#[derive(Debug, Parser)]
pub struct Cmd {
#[arg()]
pub name: Option<String>,
#[command(flatten)]
pub config_locator: locator::Args,
}
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Locator(#[from] locator::Error),
}
impl Cmd {
pub fn run(&self, global_args: &global::Args) -> Result<(), Error> {
let print = Print::new(global_args.quiet);
let mut vars: Vec<EnvVar> = Vec::new();
let supported = env_vars::prefixed("STELLAR");
for key in supported {
if let Some(v) = EnvVar::get(&key) {
vars.push(v);
}
}
if let Some(name) = &self.name {
if env_vars::is_concealed(name) {
if let Some(v) = vars.iter().find(|v| &v.key == name) {
println!("{}", v.value);
}
}
return Ok(());
}
if vars.is_empty() {
print.warnln("No defaults or environment variables set".to_string());
return Ok(());
}
let max_len = vars.iter().map(|v| v.str().len()).max().unwrap_or(0);
vars.sort();
for v in vars {
println!("{:max_len$} # {}", v.str(), v.source);
}
Ok(())
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct EnvVar {
key: String,
value: String,
source: String,
}
impl EnvVar {
fn get(key: &str) -> Option<Self> {
let source = std::env::var(format!("{key}_SOURCE"))
.ok()
.unwrap_or("env".to_string());
if let Ok(value) = std::env::var(key) {
return Some(EnvVar {
key: key.to_string(),
value,
source,
});
}
None
}
fn str(&self) -> String {
if env_vars::is_concealed(&self.key) {
format!("{}={}", self.key, self.value)
} else {
format!("# {}=<concealed>", self.key)
}
}
}