diff --git a/cmd/soroban-cli/src/cli.rs b/cmd/soroban-cli/src/cli.rs index 9183d0e30..76c5c3194 100644 --- a/cmd/soroban-cli/src/cli.rs +++ b/cmd/soroban-cli/src/cli.rs @@ -2,6 +2,7 @@ use clap::CommandFactory; use dotenvy::dotenv; use tracing_subscriber::{fmt, EnvFilter}; +use crate::config::Config; use crate::print::Print; use crate::upgrade_check::upgrade_check; use crate::{commands, Root}; @@ -33,6 +34,8 @@ pub async fn main() { } } + set_env_from_config(); + let mut root = Root::new().unwrap_or_else(|e| match e { commands::Error::Clap(e) => { let mut cmd = Root::command(); @@ -86,3 +89,27 @@ pub async fn main() { std::process::exit(1); } } + +// Load ~/.config/stellar/config.toml defaults as env vars. +fn set_env_from_config() { + if let Ok(config) = Config::new() { + set_env_value_from_config("STELLAR_ACCOUNT", config.defaults.identity); + set_env_value_from_config("STELLAR_NETWORK", config.defaults.network); + } +} + +// Set an env var from a config file if the env var is not already set. +// Additionally, a `$NAME_SOURCE` variant will be set, which allows +// `stellar env` to properly identity the source. +fn set_env_value_from_config(name: &str, value: Option) { + let Some(value) = value else { + return; + }; + + std::env::remove_var(format!("{name}_SOURCE")); + + if std::env::var(name).is_err() { + std::env::set_var(name, value); + std::env::set_var(format!("{name}_SOURCE"), "use"); + } +} diff --git a/cmd/soroban-cli/src/commands/env/mod.rs b/cmd/soroban-cli/src/commands/env/mod.rs index 4d745400c..298cac3d2 100644 --- a/cmd/soroban-cli/src/commands/env/mod.rs +++ b/cmd/soroban-cli/src/commands/env/mod.rs @@ -1,9 +1,6 @@ use crate::{ commands::global, - config::{ - locator::{self}, - Config, - }, + config::locator::{self}, print::Print, }; use clap::Parser; @@ -23,14 +20,13 @@ pub enum Error { impl Cmd { pub fn run(&self, global_args: &global::Args) -> Result<(), Error> { let print = Print::new(global_args.quiet); - let config = Config::new()?; let mut lines: Vec<(String, String)> = Vec::new(); - if let Some(data) = get("STELLAR_NETWORK", config.defaults.network) { + if let Some(data) = get("STELLAR_NETWORK") { lines.push(data); } - if let Some(data) = get("STELLAR_ACCOUNT", config.defaults.identity) { + if let Some(data) = get("STELLAR_ACCOUNT") { lines.push(data); } @@ -51,13 +47,14 @@ impl Cmd { } } -fn get(env_var: &str, default_value: Option) -> Option<(String, String)> { - if let Ok(value) = std::env::var(env_var) { - return Some((format!("{env_var}={value}"), "env".to_string())); - } +fn get(env_var: &str) -> Option<(String, String)> { + // The _SOURCE env var is set from cmd/soroban-cli/src/cli.rs#set_env_value_from_config + let source = std::env::var(format!("{env_var}_SOURCE")) + .ok() + .unwrap_or("env".to_string()); - if let Some(value) = default_value { - return Some((format!("{env_var}={value}"), "default".to_string())); + if let Ok(value) = std::env::var(env_var) { + return Some((format!("{env_var}={value}"), source)); } None