Skip to content

Commit 445f876

Browse files
amitksingh1490forge-code-agentlaststylebender14
authored
refactor(config-reader): cache base path resolution (#3038)
Co-authored-by: ForgeCode <noreply@forgecode.dev> Co-authored-by: laststylebender <43403528+laststylebender14@users.noreply.github.com>
1 parent d6f6b58 commit 445f876

2 files changed

Lines changed: 25 additions & 38 deletions

File tree

crates/forge_config/src/reader.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ static LOAD_DOT_ENV: LazyLock<()> = LazyLock::new(|| {
3030
}
3131
});
3232

33+
/// Caches base-path resolution for the process lifetime.
34+
static BASE_PATH: LazyLock<PathBuf> = LazyLock::new(ConfigReader::resolve_base_path);
35+
3336
/// Merges [`ForgeConfig`] from layered sources using a builder pattern.
3437
#[derive(Default)]
3538
pub struct ConfigReader {
@@ -58,6 +61,10 @@ impl ConfigReader {
5861
/// existing directory without disruption.
5962
/// 3. `~/.forge` as the default path.
6063
pub fn base_path() -> PathBuf {
64+
BASE_PATH.clone()
65+
}
66+
67+
fn resolve_base_path() -> PathBuf {
6168
if let Ok(path) = std::env::var("FORGE_CONFIG") {
6269
return PathBuf::from(path);
6370
}
@@ -199,7 +206,7 @@ mod tests {
199206
#[test]
200207
fn test_base_path_uses_forge_config_env_var() {
201208
let _guard = EnvGuard::set(&[("FORGE_CONFIG", "/custom/forge/dir")]);
202-
let actual = ConfigReader::base_path();
209+
let actual = ConfigReader::resolve_base_path();
203210
let expected = PathBuf::from("/custom/forge/dir");
204211
assert_eq!(actual, expected);
205212
}
@@ -210,7 +217,7 @@ mod tests {
210217
// cannot race with test_base_path_uses_forge_config_env_var.
211218
let _guard = EnvGuard::set_and_remove(&[], &["FORGE_CONFIG"]);
212219

213-
let actual = ConfigReader::base_path();
220+
let actual = ConfigReader::resolve_base_path();
214221
// Without FORGE_CONFIG set the path must be either "forge" (legacy,
215222
// preferred when ~/forge exists) or ".forge" (default new path).
216223
let name = actual.file_name().unwrap();

crates/forge_infra/src/env.rs

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -158,43 +158,12 @@ impl EnvironmentInfra for ForgeEnvironmentInfra {
158158
#[cfg(test)]
159159
mod tests {
160160
use std::path::PathBuf;
161-
use std::sync::{Mutex, MutexGuard};
162161

163162
use forge_config::ForgeConfig;
164163
use pretty_assertions::assert_eq;
165164

166165
use super::*;
167166

168-
/// Serializes tests that mutate environment variables to prevent races.
169-
static ENV_MUTEX: Mutex<()> = Mutex::new(());
170-
171-
/// Holds env vars set for a test's duration and removes them on drop,
172-
/// while holding [`ENV_MUTEX`].
173-
struct EnvGuard {
174-
keys: Vec<&'static str>,
175-
_lock: MutexGuard<'static, ()>,
176-
}
177-
178-
impl EnvGuard {
179-
#[must_use]
180-
fn set(pairs: &[(&'static str, &str)]) -> Self {
181-
let lock = ENV_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
182-
let keys = pairs.iter().map(|(k, _)| *k).collect();
183-
for (key, value) in pairs {
184-
unsafe { std::env::set_var(key, value) };
185-
}
186-
Self { keys, _lock: lock }
187-
}
188-
}
189-
190-
impl Drop for EnvGuard {
191-
fn drop(&mut self) {
192-
for key in &self.keys {
193-
unsafe { std::env::remove_var(key) };
194-
}
195-
}
196-
}
197-
198167
#[test]
199168
fn test_to_environment_sets_cwd() {
200169
let fixture_cwd = PathBuf::from("/test/cwd");
@@ -203,11 +172,22 @@ mod tests {
203172
}
204173

205174
#[test]
206-
fn test_to_environment_uses_forge_config_env_var() {
207-
let _guard = EnvGuard::set(&[("FORGE_CONFIG", "/custom/config/dir")]);
208-
let actual = to_environment(PathBuf::from("/any/cwd"));
209-
let expected = PathBuf::from("/custom/config/dir");
210-
assert_eq!(actual.base_path, expected);
175+
fn test_to_environment_base_path_is_stable_after_env_var_change() {
176+
let fixture_cwd = PathBuf::from("/any/cwd");
177+
let expected = to_environment(fixture_cwd.clone()).base_path;
178+
179+
let previous = std::env::var("FORGE_CONFIG").ok();
180+
unsafe { std::env::set_var("FORGE_CONFIG", "/custom/config/dir") };
181+
182+
let actual = to_environment(fixture_cwd).base_path;
183+
184+
if let Some(value) = previous {
185+
unsafe { std::env::set_var("FORGE_CONFIG", value) };
186+
} else {
187+
unsafe { std::env::remove_var("FORGE_CONFIG") };
188+
}
189+
190+
assert_eq!(actual, expected);
211191
}
212192

213193
#[test]

0 commit comments

Comments
 (0)