Skip to content

Commit d1bd513

Browse files
committed
fix: $HOME detection on windows
1 parent 02c4659 commit d1bd513

File tree

7 files changed

+59
-16
lines changed

7 files changed

+59
-16
lines changed

cargo-smart-release/src/crates_index.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn default_path() -> PathBuf {
3636
.or_else(|| {
3737
std::env::var_os("CARGO_HOME")
3838
.map(PathBuf::from)
39-
.or_else(|| std::env::var_os("HOME").map(|dir| Path::new(&dir).join(".cargo")))
39+
.or_else(|| home::home_dir().map(|dir| Path::new(&dir).join(".cargo")))
4040
})
4141
.expect("one of these paths works")
4242
.join("registry/index")

gix-config/src/file/init/comfort.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::path::PathBuf;
22

3+
use gix_path::home;
4+
35
use crate::{
46
file::{init, Metadata},
57
path, source, File, Source,
@@ -30,7 +32,7 @@ impl File<'static> {
3032
.flat_map(|kind| kind.sources())
3133
.filter_map(|source| {
3234
let path = source
33-
.storage_location(&mut |name| std::env::var_os(name))
35+
.storage_location(&mut crate::env_var)
3436
.and_then(|p| p.is_file().then_some(p))
3537
.map(|p| p.into_owned());
3638

@@ -43,7 +45,7 @@ impl File<'static> {
4345
.into()
4446
});
4547

46-
let home = std::env::var("HOME").ok().map(PathBuf::from);
48+
let home = home();
4749
let options = init::Options {
4850
includes: init::includes::Options::follow_without_conditional(home.as_deref()),
4951
..Default::default()
@@ -59,7 +61,7 @@ impl File<'static> {
5961
///
6062
/// [`gix-config`'s documentation]: https://git-scm.com/docs/gix-config#Documentation/gix-config.txt-GITCONFIGCOUNT
6163
pub fn from_environment_overrides() -> Result<File<'static>, init::from_env::Error> {
62-
let home = std::env::var("HOME").ok().map(PathBuf::from);
64+
let home = home();
6365
let options = init::Options {
6466
includes: init::includes::Options::follow_without_conditional(home.as_deref()),
6567
..Default::default()
@@ -88,7 +90,7 @@ impl File<'static> {
8890
let mut path = dir.into();
8991
path.push(
9092
source
91-
.storage_location(&mut |n| std::env::var_os(n))
93+
.storage_location(&mut crate::env_var)
9294
.expect("location available for local"),
9395
);
9496
let local = Self::from_path_no_includes(&path, source)?;
@@ -101,7 +103,7 @@ impl File<'static> {
101103
let source = Source::Worktree;
102104
let path = git_dir.join(
103105
source
104-
.storage_location(&mut |n| std::env::var_os(n))
106+
.storage_location(&mut crate::env_var)
105107
.expect("location available for worktree"),
106108
);
107109
Self::from_path_no_includes(path, source)
@@ -110,7 +112,7 @@ impl File<'static> {
110112
}
111113
.transpose()?;
112114

113-
let home = std::env::var("HOME").ok().map(PathBuf::from);
115+
let home = home();
114116
let options = init::Options {
115117
includes: init::includes::Options::follow(
116118
path::interpolate::Context {

gix-config/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,21 @@ pub mod lookup;
4444
pub mod parse;
4545
///
4646
pub mod value;
47+
use std::ffi::OsString;
48+
4749
pub use gix_config_value::{color, integer, path, Boolean, Color, Integer, Path};
4850

4951
mod types;
5052
pub use types::{File, Source};
5153
///
5254
pub mod source;
55+
56+
/// Returns the contents of an eviorment variable with some specical handeling
57+
/// for certain enviorment variables (like $HOME) for platform compatability
58+
pub fn env_var(var: &str) -> Option<OsString> {
59+
if var == "HOME" {
60+
gix_path::home().map(|home| home.into_os_string())
61+
} else {
62+
std::env::var_os(var)
63+
}
64+
}

gix-path/src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
pub struct Spec(bstr::BString);
5757

5858
mod convert;
59+
use std::env::var_os;
60+
use std::path::PathBuf;
61+
5962
pub use convert::*;
6063

6164
mod util;
@@ -66,3 +69,32 @@ mod spec;
6669
///
6770
pub mod realpath;
6871
pub use realpath::function::{realpath, realpath_opts};
72+
73+
/// Returns a platform independent home directory
74+
/// On unix this simply returns $HOME on windows this uses %HOMEDRIVE%\%HOMEPATH% or %USERPROFILE%
75+
pub fn home() -> Option<PathBuf> {
76+
if let Some(home) = var_os("HOME") {
77+
return Some(home.into());
78+
}
79+
80+
// TODO cache env access on windows? git does this by setting HOME but
81+
// setting enviorment variables is a *really* bad idea in library
82+
83+
// FIXME: technically we should also check HOMESHARE in case HOME is a UNC path
84+
// but git doesn't do this either so probably best to wait for an upstream fix
85+
#[cfg(windows)]
86+
if let Some(homedrive) = var_os("HOMEDRIVE") {
87+
if let Some(home_path) = var_os("HOMEPATH") {
88+
let home = PathBuf::from(homedrive).join(home_path);
89+
if home.metadata().map_or(false, |home| home.is_dir()) {
90+
return Some(home);
91+
}
92+
}
93+
}
94+
#[cfg(windows)]
95+
if let Some(userprofile) = var_os("USERPROFILE") {
96+
return Some(userprofile.into());
97+
}
98+
99+
None
100+
}

gix/src/config/cache/access.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use std::{borrow::Cow, path::PathBuf, time::Duration};
33

44
use gix_lock::acquire::Fail;
5+
use gix_path::home;
56

67
use crate::{
78
bstr::BStr,
@@ -203,10 +204,9 @@ impl Cache {
203204
std::env::var_os("XDG_CONFIG_HOME")
204205
.map(|path| (PathBuf::from(path), &self.xdg_config_home_env))
205206
.or_else(|| {
206-
std::env::var_os("HOME").map(|path| {
207+
home().map(|mut p| {
207208
(
208209
{
209-
let mut p = PathBuf::from(path);
210210
p.push(".config");
211211
p
212212
},
@@ -226,8 +226,6 @@ impl Cache {
226226
/// We never fail for here even if the permission is set to deny as we `gix-config` will fail later
227227
/// if it actually wants to use the home directory - we don't want to fail prematurely.
228228
pub(crate) fn home_dir(&self) -> Option<PathBuf> {
229-
std::env::var_os("HOME")
230-
.map(PathBuf::from)
231-
.and_then(|path| self.home_env.check_opt(path))
229+
home().and_then(|path| self.home_env.check_opt(path))
232230
}
233231
}

gix/src/config/cache/init.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl Cache {
9595
"HOME" => Some(home_env),
9696
_ => None,
9797
}
98-
.and_then(|perm| perm.check_opt(name).and_then(std::env::var_os))
98+
.and_then(|perm| perm.check_opt(name).and_then(gix_config::env_var))
9999
})
100100
.map(|p| (source, p.into_owned()))
101101
})

gix/src/open/repository.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use std::{borrow::Cow, path::PathBuf};
33

44
use gix_features::threading::OwnShared;
5+
use gix_path::home;
56

67
use super::{Error, Options};
78
use crate::{
@@ -180,9 +181,7 @@ impl ThreadSafeRepository {
180181
};
181182
let head = refs.find("HEAD").ok();
182183
let git_install_dir = crate::path::install_dir().ok();
183-
let home = std::env::var_os("HOME")
184-
.map(PathBuf::from)
185-
.and_then(|home| env.home.check_opt(home));
184+
let home = home().and_then(|home| env.home.check_opt(home));
186185

187186
let mut filter_config_section = filter_config_section.unwrap_or(config::section::is_trusted);
188187
let config = config::Cache::from_stage_one(

0 commit comments

Comments
 (0)