Skip to main content

soroban_cli/commands/env/
mod.rs

1use crate::{
2    commands::global,
3    config::locator::{self},
4    env_vars,
5    print::Print,
6};
7use clap::Parser;
8
9#[allow(clippy::doc_markdown)]
10#[derive(Debug, Parser)]
11pub struct Cmd {
12    /// Env variable name to get the value of.
13    ///
14    /// E.g.: $ stellar env STELLAR_ACCOUNT
15    #[arg()]
16    pub name: Option<String>,
17
18    #[command(flatten)]
19    pub config_locator: locator::Args,
20}
21
22#[derive(thiserror::Error, Debug)]
23pub enum Error {
24    #[error(transparent)]
25    Locator(#[from] locator::Error),
26}
27
28impl Cmd {
29    pub fn run(&self, global_args: &global::Args) -> Result<(), Error> {
30        let print = Print::new(global_args.quiet);
31        let mut vars: Vec<EnvVar> = Vec::new();
32        let supported = env_vars::prefixed("STELLAR");
33
34        for key in supported {
35            if let Some(v) = EnvVar::get(&key) {
36                vars.push(v);
37            }
38        }
39
40        // If a specific name is given, just print that one value
41        if let Some(name) = &self.name {
42            if env_vars::is_concealed(name) {
43                if let Some(v) = vars.iter().find(|v| &v.key == name) {
44                    println!("{}", v.value);
45                }
46            }
47
48            return Ok(());
49        }
50
51        if vars.is_empty() {
52            print.warnln("No defaults or environment variables set".to_string());
53            return Ok(());
54        }
55
56        let max_len = vars.iter().map(|v| v.str().len()).max().unwrap_or(0);
57
58        vars.sort();
59
60        for v in vars {
61            println!("{:max_len$} # {}", v.str(), v.source);
62        }
63
64        Ok(())
65    }
66}
67
68#[derive(PartialEq, Eq, PartialOrd, Ord)]
69struct EnvVar {
70    key: String,
71    value: String,
72    source: String,
73}
74
75impl EnvVar {
76    fn get(key: &str) -> Option<Self> {
77        // The _SOURCE env var is set from cmd/soroban-cli/src/cli.rs#set_env_value_from_config
78        let source = std::env::var(format!("{key}_SOURCE"))
79            .ok()
80            .unwrap_or("env".to_string());
81
82        if let Ok(value) = std::env::var(key) {
83            return Some(EnvVar {
84                key: key.to_string(),
85                value,
86                source,
87            });
88        }
89
90        None
91    }
92
93    fn str(&self) -> String {
94        if env_vars::is_concealed(&self.key) {
95            format!("{}={}", self.key, self.value)
96        } else {
97            format!("# {}=<concealed>", self.key)
98        }
99    }
100}