Skip to content

Commit 3b304fa

Browse files
committed
Extract system_prefix() Windows strategies to helpers
This refactors `gix_path::env::system_prefix()` by extracting the two strategies used to obtain it on Windows to newly created helper functions: `system_prefix_from_exepath_var()` for the `EXEPATH` optimization, and `system_prefix_from_core_dir()` for the fallback. This is to facilitate testing. The new helpers take the functions they call to obtain systemwide information (`EXEPATH` from the environment, or the once-computed `GIT_CORE_DIR`) by dependency injection, so tests can be added that cover the important cases. This is similar to the approach for `ALTERNATIVE_LOCATIONS` of using a `locations_under_program_files()` helper (since GitoxideLabs#1456). The `system_prefix_from_exepath_var()` helper treats its `var_os_func` parameter analogously to how `locations_under_program_files()` treats its `var_os_func` parameter.
1 parent 571ca6e commit 3b304fa

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

gix-path/src/env/mod.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,31 @@ pub fn core_dir() -> Option<&'static Path> {
139139
GIT_CORE_DIR.as_deref()
140140
}
141141

142+
fn system_prefix_from_core_dir<F>(core_dir_func: F) -> Option<PathBuf>
143+
where
144+
F: Fn() -> Option<&'static Path>,
145+
{
146+
let path = core_dir_func()?;
147+
let one_past_prefix = path.components().enumerate().find_map(|(idx, c)| {
148+
matches!(c,std::path::Component::Normal(name) if name.to_str() == Some("libexec")).then_some(idx)
149+
})?;
150+
Some(path.components().take(one_past_prefix.checked_sub(1)?).collect())
151+
}
152+
153+
fn system_prefix_from_exepath_var<F>(var_os_func: F) -> Option<PathBuf>
154+
where
155+
F: Fn(&str) -> Option<OsString>,
156+
{
157+
let root = PathBuf::from(var_os_func("EXEPATH")?);
158+
for candidate in ["mingw64", "mingw32"] {
159+
let candidate = root.join(candidate);
160+
if candidate.is_dir() {
161+
return Some(candidate);
162+
}
163+
}
164+
None
165+
}
166+
142167
/// Returns the platform dependent system prefix or `None` if it cannot be found (right now only on Windows).
143168
///
144169
/// ### Performance
@@ -153,20 +178,8 @@ pub fn core_dir() -> Option<&'static Path> {
153178
pub fn system_prefix() -> Option<&'static Path> {
154179
if cfg!(windows) {
155180
static PREFIX: Lazy<Option<PathBuf>> = Lazy::new(|| {
156-
if let Some(root) = std::env::var_os("EXEPATH").map(PathBuf::from) {
157-
for candidate in ["mingw64", "mingw32"] {
158-
let candidate = root.join(candidate);
159-
if candidate.is_dir() {
160-
return Some(candidate);
161-
}
162-
}
163-
}
164-
165-
let path = GIT_CORE_DIR.as_deref()?;
166-
let one_past_prefix = path.components().enumerate().find_map(|(idx, c)| {
167-
matches!(c,std::path::Component::Normal(name) if name.to_str() == Some("libexec")).then_some(idx)
168-
})?;
169-
Some(path.components().take(one_past_prefix.checked_sub(1)?).collect())
181+
system_prefix_from_exepath_var(|key| std::env::var_os(key))
182+
.or_else(|| system_prefix_from_core_dir(core_dir))
170183
});
171184
PREFIX.as_deref()
172185
} else {

0 commit comments

Comments
 (0)