Skip to content

Commit 8ff6db8

Browse files
authored
refactor: centralize environment variable access (#3315)
* Shim layer for env variable access
1 parent 4e7974b commit 8ff6db8

File tree

23 files changed

+238
-61
lines changed

23 files changed

+238
-61
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl ApiClient {
138138
model_cache: Arc::new(RwLock::new(None)),
139139
};
140140

141-
if let Ok(json) = env.get("Q_MOCK_CHAT_RESPONSE") {
141+
if let Some(json) = crate::util::env_var::get_mock_chat_response(env) {
142142
this.set_mock_output(serde_json::from_str(fs.read_to_string(json).await.unwrap().as_str()).unwrap());
143143
}
144144

@@ -148,7 +148,7 @@ impl ApiClient {
148148
// If SIGV4_AUTH_ENABLED is true, use Q developer client
149149
let mut streaming_client = None;
150150
let mut sigv4_streaming_client = None;
151-
match env.get("AMAZON_Q_SIGV4").is_ok() {
151+
match crate::util::env_var::is_sigv4_enabled(env) {
152152
true => {
153153
let credentials_chain = CredentialsChain::new().await;
154154
if let Err(err) = credentials_chain.provide_credentials().await {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ use crate::database::{
6363
Database,
6464
Secret,
6565
};
66+
use crate::os::Env;
67+
use crate::util::env_var::is_sigv4_enabled;
6668

6769
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
6870
pub enum OAuthFlow {
@@ -589,7 +591,7 @@ pub async fn poll_create_token(
589591

590592
pub async fn is_logged_in(database: &mut Database) -> bool {
591593
// Check for BuilderId if not using Sigv4
592-
if std::env::var("AMAZON_Q_SIGV4").is_ok_and(|v| !v.is_empty()) {
594+
if is_sigv4_enabled(&Env::new()) {
593595
debug!("logged in using sigv4 credentials");
594596
return true;
595597
}

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/cli/usage/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use clap::Args;
22

33
use crate::cli::chat::token_counter::TokenCount;
4-
use crate::cli::chat::{ChatError, ChatSession, ChatState};
4+
use crate::cli::chat::{
5+
ChatError,
6+
ChatSession,
7+
ChatState,
8+
};
59
use crate::os::Os;
610

711
pub mod usage_data_provider;
@@ -32,6 +36,8 @@ impl UsageArgs {
3236
pub async fn execute(self, os: &Os, session: &mut ChatSession) -> Result<ChatState, ChatError> {
3337
let usage_data = usage_data_provider::get_detailed_usage_data(session, os).await?;
3438
usage_renderer::render_context_window(&usage_data, session).await?;
35-
Ok(ChatState::PromptUser { skip_printing_tools: true })
39+
Ok(ChatState::PromptUser {
40+
skip_printing_tools: true,
41+
})
3642
}
37-
}
43+
}

crates/chat-cli/src/cli/chat/cli/usage/usage_data_provider.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
use crate::cli::chat::cli::model::context_window_tokens;
2-
use crate::cli::chat::token_counter::{CharCount, TokenCount};
3-
use crate::cli::chat::{ChatError, ChatSession};
2+
use crate::cli::chat::token_counter::{
3+
CharCount,
4+
TokenCount,
5+
};
6+
use crate::cli::chat::{
7+
ChatError,
8+
ChatSession,
9+
};
410
use crate::os::Os;
511

612
/// Get detailed usage data for context window analysis
7-
pub(super) async fn get_detailed_usage_data(session: &mut ChatSession, os: &Os) -> Result<super::DetailedUsageData, ChatError> {
13+
pub(super) async fn get_detailed_usage_data(
14+
session: &mut ChatSession,
15+
os: &Os,
16+
) -> Result<super::DetailedUsageData, ChatError> {
817
let context_window_size = context_window_tokens(session.conversation.model_info.as_ref());
918

1019
let state = session

crates/chat-cli/src/cli/chat/cli/usage/usage_renderer.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
use crossterm::style::Attribute;
2-
use crossterm::{execute, queue, style};
2+
use crossterm::{
3+
execute,
4+
queue,
5+
style,
6+
};
37

48
use crate::cli::chat::token_counter::TokenCount;
5-
use crate::cli::chat::{ChatError, ChatSession};
9+
use crate::cli::chat::{
10+
ChatError,
11+
ChatSession,
12+
};
613
use crate::theme::StyledText;
714

815
/// Calculate usage percentage from token counts (private utility)
@@ -11,7 +18,10 @@ fn calculate_usage_percentage(tokens: TokenCount, context_window_size: usize) ->
1118
}
1219

1320
/// Render context window information section
14-
pub async fn render_context_window(usage_data: &super::DetailedUsageData, session: &mut ChatSession) -> Result<(), ChatError> {
21+
pub async fn render_context_window(
22+
usage_data: &super::DetailedUsageData,
23+
session: &mut ChatSession,
24+
) -> Result<(), ChatError> {
1525
if !usage_data.dropped_context_files.is_empty() {
1626
execute!(
1727
session.stderr,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use crate::cli::{
4141
};
4242
use crate::os::Os;
4343
use crate::theme::StyledText;
44+
use crate::util::env_var::get_all_env_vars;
4445
use crate::util::paths::PathResolver;
4546

4647
/// Launch and manage async agent processes. Delegate tasks to agents that run independently in
@@ -334,7 +335,7 @@ pub async fn spawn_agent_process(os: &Os, agent: &str, task: &str) -> Result<Age
334335
cmd.stdout(std::process::Stdio::piped());
335336
cmd.stderr(std::process::Stdio::piped());
336337
cmd.stdin(std::process::Stdio::null()); // No user input
337-
cmd.envs(std::env::vars());
338+
cmd.envs(get_all_env_vars());
338339

339340
#[cfg(not(windows))]
340341
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
@@ -16,6 +16,7 @@ use super::{
1616
format_output,
1717
};
1818
use crate::os::Os;
19+
use crate::util::env_var::get_chat_shell;
1920

2021
/// Run a bash command on Unix systems.
2122
/// # Arguments
@@ -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/tools/fs_write.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,11 @@ impl FsWrite {
311311
let relative_path = format_path(cwd, &path);
312312
let prev = if os.fs.exists(&path) {
313313
let file = os.fs.read_to_string_sync(&path)?;
314-
stylize_output_if_able(os, &path, &file)
314+
stylize_output_if_able(&path, &file)
315315
} else {
316316
Default::default()
317317
};
318-
let new = stylize_output_if_able(os, &relative_path, &file_text);
318+
let new = stylize_output_if_able(&relative_path, &file_text);
319319
print_diff(output, &prev, &new, 1)?;
320320

321321
// Display summary as purpose if available after the diff
@@ -343,8 +343,8 @@ impl FsWrite {
343343
let old = [prefix, insert_line_content, suffix].join("");
344344
let new = [prefix, insert_line_content, new_str, suffix].join("");
345345

346-
let old = stylize_output_if_able(os, &relative_path, &old);
347-
let new = stylize_output_if_able(os, &relative_path, &new);
346+
let old = stylize_output_if_able(&relative_path, &old);
347+
let new = stylize_output_if_able(&relative_path, &new);
348348
print_diff(output, &old, &new, start_line)?;
349349

350350
// Display summary as purpose if available after the diff
@@ -362,8 +362,8 @@ impl FsWrite {
362362
Some((start_line, end_line)) => (start_line, end_line),
363363
_ => (0, 0),
364364
};
365-
let old_str = stylize_output_if_able(os, &relative_path, old_str);
366-
let new_str = stylize_output_if_able(os, &relative_path, new_str);
365+
let old_str = stylize_output_if_able(&relative_path, old_str);
366+
let new_str = stylize_output_if_able(&relative_path, new_str);
367367
print_diff(output, &old_str, &new_str, start_line)?;
368368

369369
// Display summary as purpose if available after the diff
@@ -375,7 +375,7 @@ impl FsWrite {
375375
let path = sanitize_path_tool_arg(os, path);
376376
let relative_path = format_path(cwd, &path);
377377
let start_line = os.fs.read_to_string_sync(&path)?.lines().count() + 1;
378-
let file = stylize_output_if_able(os, &relative_path, new_str);
378+
let file = stylize_output_if_able(&relative_path, new_str);
379379
print_diff(output, &Default::default(), &file, start_line)?;
380380

381381
// Display summary as purpose if available after the diff
@@ -763,8 +763,8 @@ fn terminal_width_required_for_line_count(line_count: usize) -> usize {
763763
line_count.to_string().chars().count()
764764
}
765765

766-
fn stylize_output_if_able(os: &Os, path: impl AsRef<Path>, file_text: &str) -> StylizedFile {
767-
if supports_truecolor(os) {
766+
fn stylize_output_if_able(path: impl AsRef<Path>, file_text: &str) -> StylizedFile {
767+
if supports_truecolor() {
768768
match stylized_file(path, file_text) {
769769
Ok(s) => return s,
770770
Err(err) => {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,9 @@ fn format_path(cwd: impl AsRef<Path>, path: impl AsRef<Path>) -> String {
444444
.unwrap_or(path.as_ref().to_string_lossy().to_string())
445445
}
446446

447-
fn supports_truecolor(os: &Os) -> bool {
447+
fn supports_truecolor() -> bool {
448448
// Simple override to disable truecolor since shell_color doesn't use Context.
449-
!os.env.get("Q_DISABLE_TRUECOLOR").is_ok_and(|s| !s.is_empty())
449+
!crate::util::env_var::is_truecolor_disabled()
450450
&& shell_color::get_color_support().contains(shell_color::ColorSupport::TERM24BIT)
451451
}
452452

@@ -514,7 +514,7 @@ pub fn queue_function_result(result: &str, updates: &mut impl Write, is_error: b
514514

515515
/// Helper function to set up environment variables with user agent metadata for CloudTrail tracking
516516
pub fn env_vars_with_user_agent(os: &Os) -> std::collections::HashMap<String, String> {
517-
let mut env_vars: std::collections::HashMap<String, String> = std::env::vars().collect();
517+
let mut env_vars: std::collections::HashMap<String, String> = crate::util::env_var::get_all_env_vars().collect();
518518

519519
// Set up additional metadata for the AWS CLI user agent
520520
let user_agent_metadata_value = format!(

0 commit comments

Comments
 (0)