Skip to content

Commit ca8ce95

Browse files
committed
refactor: centralize environment variable access
- Add util::env_var module with wrapper functions - Replace direct std::env calls throughout codebase - Preserve all defaults: bash, vi, same logic for all env vars - Fix recursive calls in system_info functions
1 parent a275492 commit ca8ce95

File tree

14 files changed

+135
-21
lines changed

14 files changed

+135
-21
lines changed

crates/chat-cli/src/auth/builder_id.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
//! - RETURNS: [PollCreateToken]
1919
//! 4. (Repeat) Tokens SHOULD be refreshed if expired and a refresh token is available.
2020
//! - Code: [BuilderIdToken::refresh_token]
21+
22+
use crate::util::env_var::is_sigv4_enabled;
2123
//! - Calls [Client::create_token]
2224
//! - RETURNS: [BuilderIdToken]
2325
@@ -545,7 +547,7 @@ pub async fn poll_create_token(
545547

546548
pub async fn is_logged_in(database: &mut Database) -> bool {
547549
// Check for BuilderId if not using Sigv4
548-
if std::env::var("AMAZON_Q_SIGV4").is_ok_and(|v| !v.is_empty()) {
550+
if is_sigv4_enabled() {
549551
debug!("logged in using sigv4 credentials");
550552
return true;
551553
}

crates/chat-cli/src/cli/chat/cli/editor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::cli::chat::{
1111
ChatState,
1212
};
1313
use crate::theme::StyledText;
14+
use crate::util::env_var::get_editor;
1415

1516
#[deny(missing_docs)]
1617
#[derive(Debug, PartialEq, Args)]
@@ -86,7 +87,7 @@ impl EditorArgs {
8687
/// Launch the user's preferred editor with the given file path
8788
fn launch_editor(file_path: &std::path::Path) -> Result<(), ChatError> {
8889
// Get the editor from environment variable or use a default
89-
let editor_cmd = std::env::var("EDITOR").unwrap_or_else(|_| "vi".to_string());
90+
let editor_cmd = get_editor();
9091

9192
// Parse the editor command to handle arguments
9293
let mut parts =

crates/chat-cli/src/cli/chat/tools/delegate.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use crossterm::{
1313
style,
1414
};
1515
use eyre::{
16+
17+
use crate::util::env_var::get_all_env_vars;
1618
Result,
1719
bail,
1820
};
@@ -333,7 +335,7 @@ pub async fn spawn_agent_process(os: &Os, agent: &str, task: &str) -> Result<Age
333335
cmd.stdout(std::process::Stdio::piped());
334336
cmd.stderr(std::process::Stdio::piped());
335337
cmd.stdin(std::process::Stdio::null()); // No user input
336-
cmd.envs(std::env::vars());
338+
cmd.envs(get_all_env_vars());
337339

338340
#[cfg(not(windows))]
339341
cmd.process_group(0);

crates/chat-cli/src/cli/chat/tools/execute/unix.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use tokio::io::AsyncBufReadExt;
1010
use tokio::select;
1111
use tracing::error;
1212

13+
use crate::util::env_var::get_chat_shell;
1314
use super::{
1415
CommandResult,
1516
env_vars_with_user_agent,
@@ -30,7 +31,7 @@ pub async fn run_command<W: Write>(
3031
max_result_size: usize,
3132
mut updates: Option<W>,
3233
) -> Result<CommandResult> {
33-
let shell = std::env::var("AMAZON_Q_CHAT_SHELL").unwrap_or("bash".to_string());
34+
let shell = get_chat_shell();
3435

3536
// Set up environment variables with user agent metadata for CloudTrail tracking
3637
let env_vars = env_vars_with_user_agent(os);

crates/chat-cli/src/cli/chat/util/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use aws_smithy_types::{
1414
};
1515
use eyre::Result;
1616

17+
use crate::util::env_var::get_term;
18+
1719
use super::ChatError;
1820
use super::token_counter::TokenCounter;
1921

@@ -119,7 +121,7 @@ pub fn play_notification_bell(requires_confirmation: bool) {
119121
/// Determine if we should play the bell based on terminal type
120122
fn should_play_bell() -> bool {
121123
// Get the TERM environment variable
122-
if let Ok(term) = std::env::var("TERM") {
124+
if let Some(term) = get_term() {
123125
// List of terminals known to handle bell character well
124126
let bell_compatible_terms = [
125127
"xterm",

crates/chat-cli/src/cli/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::theme::StyledText;
2+
use crate::util::env_var::{is_log_stdout_enabled, get_var};
23
mod agent;
34
pub mod chat;
45
mod debug;
@@ -231,7 +232,7 @@ impl Cli {
231232
),
232233
false => None,
233234
},
234-
log_to_stdout: std::env::var_os("Q_LOG_STDOUT").is_some() || self.verbose > 0,
235+
log_to_stdout: is_log_stdout_enabled() || self.verbose > 0,
235236
log_file_path: match subcommand {
236237
RootSubcommand::Chat { .. } => Some(logs_dir().expect("home dir must be set").join("qchat.log")),
237238
_ => None,
@@ -240,7 +241,7 @@ impl Cli {
240241
});
241242

242243
// Check for region support.
243-
if let Ok(region) = std::env::var("AWS_REGION") {
244+
if let Ok(region) = get_var("AWS_REGION") {
244245
if GOV_REGIONS.contains(&region.as_str()) {
245246
bail!("AWS GovCloud ({region}) is not supported.")
246247
}

crates/chat-cli/src/logging.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use tracing_subscriber::{
1414
fmt,
1515
};
1616

17-
use crate::util::env_var::Q_LOG_LEVEL;
17+
use crate::util::env_var::get_log_level;
1818

1919
const MAX_FILE_SIZE: u64 = 10 * 1024 * 1024;
2020
const DEFAULT_FILTER: LevelFilter = LevelFilter::ERROR;
@@ -196,7 +196,7 @@ pub fn get_log_level() -> String {
196196
.lock()
197197
.unwrap()
198198
.clone()
199-
.unwrap_or_else(|| std::env::var(Q_LOG_LEVEL).unwrap_or_else(|_| DEFAULT_FILTER.to_string()))
199+
.unwrap_or_else(|| get_log_level().unwrap_or_else(|_| DEFAULT_FILTER.to_string()))
200200
}
201201

202202
/// Set the log level to the given level.
@@ -247,7 +247,7 @@ fn create_filter_layer() -> EnvFilter {
247247
.lock()
248248
.unwrap()
249249
.clone()
250-
.or_else(|| std::env::var(Q_LOG_LEVEL).ok());
250+
.or_else(|| get_log_level().ok());
251251

252252
match log_level {
253253
Some(level) => EnvFilter::builder()

crates/chat-cli/src/mcp_client/client.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use rmcp::model::{
1313
Implementation,
1414
InitializeRequestParam,
1515
ListPromptsResult,
16+
17+
use crate::util::env_var::get_all_env_vars;
1618
ListToolsResult,
1719
LoggingLevel,
1820
LoggingMessageNotificationParam,
@@ -431,7 +433,7 @@ impl McpClientService {
431433
process_env_vars(envs, &os.env);
432434
cmd.envs(envs);
433435
}
434-
cmd.envs(std::env::vars()).args(args);
436+
cmd.envs(get_all_env_vars()).args(args);
435437

436438
#[cfg(not(windows))]
437439
cmd.process_group(0);

crates/chat-cli/src/telemetry/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub use crate::telemetry::core::{
7474
QProfileSwitchIntent,
7575
TelemetryResult,
7676
};
77-
use crate::util::env_var::Q_CLI_CLIENT_APPLICATION;
77+
use crate::util::env_var::get_cli_client_application;
7878
use crate::util::system_info::os_version;
7979

8080
#[derive(thiserror::Error, Debug)]
@@ -484,7 +484,7 @@ async fn set_event_metadata(database: &Database, event: &mut Event) {
484484
}
485485

486486
// Set the client application from environment variable
487-
if let Ok(client_app) = std::env::var(Q_CLI_CLIENT_APPLICATION) {
487+
if let Some(client_app) = get_cli_client_application() {
488488
event.set_client_application(client_app);
489489
}
490490
}

crates/chat-cli/src/util/directories.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use thiserror::Error;
1212

1313
use crate::cli::DEFAULT_AGENT_NAME;
1414
use crate::os::Os;
15+
use crate::util::env_var::{get_home_dir, get_tmpdir, get_xdg_runtime_dir, get_var_os};
1516

1617
#[derive(Debug, Error)]
1718
pub enum DirectoryError {
@@ -123,7 +124,7 @@ fn macos_tempdir() -> Result<PathBuf> {
123124
#[cfg(unix)]
124125
pub fn runtime_dir() -> Result<PathBuf> {
125126
let mut dir = dirs::runtime_dir();
126-
dir = dir.or_else(|| std::env::var_os("TMPDIR").map(PathBuf::from));
127+
dir = dir.or_else(|| get_var_os("TMPDIR").map(PathBuf::from));
127128

128129
cfg_if::cfg_if! {
129130
if #[cfg(target_os = "macos")] {
@@ -422,15 +423,15 @@ mod tests {
422423
fn sanitized_directory_path(path: Result<PathBuf>) -> String {
423424
let mut path = path.unwrap().into_os_string().into_string().unwrap();
424425

425-
if let Ok(home) = std::env::var("HOME") {
426+
if let Some(home) = get_home_dir() {
426427
let home = home.strip_suffix('/').unwrap_or(&home);
427428
path = path.replace(home, "$HOME");
428429
}
429430

430431
let user = whoami::username();
431432
path = path.replace(&user, "$USER");
432433

433-
if let Ok(tmpdir) = std::env::var("TMPDIR") {
434+
if let Some(tmpdir) = get_tmpdir() {
434435
let tmpdir = tmpdir.strip_suffix('/').unwrap_or(&tmpdir);
435436
path = path.replace(tmpdir, "$TMPDIR");
436437
}
@@ -444,7 +445,7 @@ mod tests {
444445
};
445446
}
446447

447-
if let Ok(xdg_runtime_dir) = std::env::var("XDG_RUNTIME_DIR") {
448+
if let Some(xdg_runtime_dir) = get_xdg_runtime_dir() {
448449
let xdg_runtime_dir = xdg_runtime_dir.strip_suffix('/').unwrap_or(&xdg_runtime_dir);
449450
path = path.replace(xdg_runtime_dir, "$XDG_RUNTIME_DIR");
450451
}

0 commit comments

Comments
 (0)