diff --git a/README.md b/README.md index 8d28f37e3f..64a0c80956 100644 --- a/README.md +++ b/README.md @@ -863,7 +863,7 @@ System-level environment variables (usually set automatically): ```bash # .env -FORGE_CONFIG=/custom/config/dir # Base directory for all Forge config files (default: ~/forge) +FORGE_CONFIG=/custom/config/dir # Base directory for all Forge config files (default: ~/.forge) FORGE_MAX_SEARCH_RESULT_BYTES=10240 # Maximum bytes for search results (default: 10240 - 10 KB) FORGE_HISTORY_FILE=/path/to/history # Custom path for Forge history file (default: uses system default location) FORGE_BANNER="Your custom banner text" # Custom banner text to display on startup (default: Forge ASCII art) diff --git a/crates/forge_config/src/reader.rs b/crates/forge_config/src/reader.rs index 6ce724cbda..f0a6534c36 100644 --- a/crates/forge_config/src/reader.rs +++ b/crates/forge_config/src/reader.rs @@ -52,12 +52,26 @@ impl ConfigReader { /// Returns the base directory for all Forge config files. /// /// If the `FORGE_CONFIG` environment variable is set, its value is used - /// directly as the base path. Otherwise defaults to `~/forge`. + /// directly as the base path. Otherwise defaults to `~/.forge`. + /// Falls back to the legacy `~/forge` path if it exists and `~/.forge` + /// does not. pub fn base_path() -> PathBuf { if let Ok(path) = std::env::var("FORGE_CONFIG") { return PathBuf::from(path); } - dirs::home_dir().unwrap_or(PathBuf::from(".")).join("forge") + + let home = dirs::home_dir().unwrap_or(PathBuf::from(".")); + let path = home.join(".forge"); + let legacy_path = home.join("forge"); + + // Prefer the new dotfile path, but fall back to legacy if only it exists + if !path.exists() && legacy_path.exists() { + tracing::info!("Using legacy path"); + return legacy_path; + } + + tracing::info!("Using new path"); + path } /// Adds the provided TOML string as a config source without touching the @@ -181,8 +195,8 @@ mod tests { #[test] fn test_base_path_falls_back_to_home_dir_when_env_var_absent() { let actual = ConfigReader::base_path(); - // Without FORGE_CONFIG set the path must end with "forge" - assert_eq!(actual.file_name().unwrap(), "forge"); + // Without FORGE_CONFIG set the path must end with ".forge" + assert_eq!(actual.file_name().unwrap(), ".forge"); } #[test] diff --git a/crates/forge_infra/src/env.rs b/crates/forge_infra/src/env.rs index cb50e27558..1a89e7c965 100644 --- a/crates/forge_infra/src/env.rs +++ b/crates/forge_infra/src/env.rs @@ -213,8 +213,8 @@ mod tests { #[test] fn test_to_environment_falls_back_to_home_dir_when_env_var_absent() { let actual = to_environment(PathBuf::from("/any/cwd")); - // Without FORGE_CONFIG the base_path must end with "forge" - assert_eq!(actual.base_path.file_name().unwrap(), "forge"); + // Without FORGE_CONFIG the base_path must end with ".forge" + assert_eq!(actual.base_path.file_name().unwrap(), ".forge"); } #[test]