Bug 1725134 - Handle XDG_CONFIG_HOME in crashreporter r=afranchuk

Differential Revision: https://phabricator.services.mozilla.com/D122358
This commit is contained in:
Alexandre Lissy
2025-04-03 16:10:43 +00:00
parent d471649fe2
commit 04094ced84
2 changed files with 77 additions and 9 deletions

View File

@@ -17,6 +17,48 @@ const MINIDUMP_PRUNE_SAVE_COUNT: usize = 10;
#[cfg(test)]
pub mod test {
pub const MINIDUMP_PRUNE_SAVE_COUNT: usize = super::MINIDUMP_PRUNE_SAVE_COUNT;
cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {
use crate::std::{mock, env};
fn cfg_get_data_dir_root() -> crate::std::path::PathBuf {
let cfg = super::Config::new();
cfg.get_data_dir_root("vendor").unwrap()
}
#[test]
fn data_dir_root_xdg_default() {
mock::builder()
.set(env::MockHomeDir, "home_dir".into())
.run(|| {
let path = cfg_get_data_dir_root();
assert_eq!(path, crate::std::path::PathBuf::from("home_dir/.config/vendor"));
});
}
#[test]
fn data_dir_root_xdg_home() {
mock::builder()
.set(env::MockEnv("XDG_CONFIG_HOME".into()), "home_dir/xdg/config".into())
.run(|| {
let path = cfg_get_data_dir_root();
assert_eq!(path, crate::std::path::PathBuf::from("home_dir/xdg/config/vendor"));
});
}
#[test]
fn data_dir_root_legacy_force() {
mock::builder()
.set(env::MockHomeDir, "home_dir".into())
.set(env::MockEnv("MOZ_LEGACY_HOME".into()), "1".into())
.run(|| {
let path = cfg_get_data_dir_root();
assert_eq!(path, crate::std::path::PathBuf::from("home_dir/.vendor"));
});
}
}
}
}
mod buildid_section {
@@ -428,6 +470,22 @@ impl Config {
}
}
#[cfg(target_os = "linux")]
fn get_data_dir_root(&self, vendor: &str) -> anyhow::Result<PathBuf> {
// home_dir is deprecated due to incorrect behavior on windows, but we only use it on linux
#[allow(deprecated)]
let data_path = if std::env::var_os("MOZ_LEGACY_HOME").is_some() {
std::env::home_dir().map(|h| h.join(format!(".{}", vendor.to_lowercase())))
} else {
std::env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.or_else(|| std::env::home_dir().map(|home| home.join(".config")))
.map(|h| h.join(format!("{}", vendor.to_lowercase())))
}
.with_context(|| self.string("crashreporter-error-no-home-dir"))?;
Ok(data_path)
}
cfg_if::cfg_if! {
if #[cfg(mock)] {
fn get_data_dir(&self, vendor: &str, product: &str) -> anyhow::Result<PathBuf> {
@@ -439,11 +497,7 @@ impl Config {
}
} else if #[cfg(target_os = "linux")] {
fn get_data_dir(&self, vendor: &str, product: &str) -> anyhow::Result<PathBuf> {
// home_dir is deprecated due to incorrect behavior on windows, but we only use it on linux
#[allow(deprecated)]
let mut data_path =
std::env::home_dir().with_context(|| self.string("crashreporter-error-no-home-dir"))?;
data_path.push(format!(".{}", vendor.to_lowercase()));
let mut data_path = self.get_data_dir_root(vendor)?;
data_path.push(product.to_lowercase());
data_path.push("Crash Reports");
Ok(data_path)

View File

@@ -10,6 +10,14 @@ mock_key! {
pub struct MockCurrentExe => std::path::PathBuf
}
mock_key! {
pub struct MockEnv(pub OsString) => String
}
mock_key! {
pub struct MockHomeDir => super::path::PathBuf
}
pub struct ArgsOs {
argv0: Option<OsString>,
}
@@ -26,12 +34,14 @@ impl Iterator for ArgsOs {
}
}
pub fn var<K: AsRef<OsStr>>(_key: K) -> Result<String, VarError> {
unimplemented!("no var access in tests")
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
MockEnv(key.as_ref().to_os_string())
.try_get(|value| value.clone())
.ok_or(VarError::NotPresent)
}
pub fn var_os<K: AsRef<OsStr>>(_key: K) -> Option<OsString> {
unimplemented!("no var access in tests")
pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
MockEnv(key.as_ref().to_os_string()).try_get(|value| value.clone().into())
}
pub fn args_os() -> ArgsOs {
@@ -40,6 +50,10 @@ pub fn args_os() -> ArgsOs {
})
}
pub fn home_dir() -> Option<super::path::PathBuf> {
MockHomeDir.try_get(|p| p.clone())
}
#[allow(unused)]
pub fn current_exe() -> std::io::Result<super::path::PathBuf> {
Ok(MockCurrentExe.get(|r| r.clone().into()))