Skip to content

Commit bfad0c4

Browse files
committed
feat(daemon): follow XDG_RUNTIME_DIR if set
If XDG_RUNTIME_DIR is set, put the socket file there. If not, default to storing it in our data dir. We cannot default to a path such as /run/user/$UID/ because it does not exist on all systems. Any system running systemd will set this var by default, and ensure that the directory it points to is correctly setup.
1 parent 80d28ea commit bfad0c4

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

crates/atuin-client/src/settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ impl Settings {
667667
let data_dir = atuin_common::utils::data_dir();
668668
let db_path = data_dir.join("history.db");
669669
let record_store_path = data_dir.join("records.db");
670-
let socket_path = data_dir.join("atuin.sock");
670+
let socket_path = atuin_common::utils::runtime_dir().join("atuin.sock");
671671

672672
let key_path = data_dir.join("key");
673673
let session_path = data_dir.join("session");

crates/atuin-common/src/dirs.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use std::path::PathBuf;
2+
3+
// Where do we store things? The following makes sense.
4+
//
5+
// 1. If set by ATUIN_<config>, follow the env.
6+
// 2. If not set, check for existence of XDG_*. Follow if set.
7+
// 3. If not set, platform-specific defaults:
8+
// Linux: XDG spec, as much as it makes sense anyway
9+
// Mac: ~/.atuin/* for everything
10+
//
11+
// Mac is tricky. we can either follow the spec exactly and put things in ~/Library/blah, follow
12+
// the spec for linux which people may expect, or just put it one place so everything is easy to
13+
// find. I'd rather not follow it, than half follow it.
14+
15+
pub fn data_dir() -> PathBuf {
16+
let data_dir = std::env::var("XDG_DATA_HOME")
17+
.map_or_else(|_| home_dir().join(".local").join("share"), PathBuf::from);
18+
19+
data_dir.join("atuin")
20+
}
21+
22+
#[cfg(not(target_os = "windows"))]
23+
pub fn home_dir() -> PathBuf {
24+
let home = std::env::var("HOME").expect("$HOME not found");
25+
PathBuf::from(home)
26+
}
27+
28+
#[cfg(target_os = "windows")]
29+
pub fn home_dir() -> PathBuf {
30+
let home = std::env::var("USERPROFILE").expect("%userprofile% not found");
31+
PathBuf::from(home)
32+
}
33+
34+
pub fn config_dir() -> PathBuf {
35+
let config_dir =
36+
std::env::var("XDG_CONFIG_HOME").map_or_else(|_| home_dir().join(".config"), PathBuf::from);
37+
config_dir.join("atuin")
38+
}
39+
40+
pub fn dotfiles_cache_dir() -> PathBuf {
41+
// In most cases, this will be ~/.local/share/atuin/dotfiles/cache
42+
let data_dir = std::env::var("XDG_DATA_HOME")
43+
.map_or_else(|_| home_dir().join(".local").join("share"), PathBuf::from);
44+
45+
data_dir.join("atuin").join("dotfiles").join("cache")
46+
}
47+
48+
pub fn get_current_dir() -> String {
49+
// Prefer PWD environment variable over cwd if available to better support symbolic links
50+
match std::env::var("PWD") {
51+
Ok(v) => v,
52+
Err(_) => match std::env::current_dir() {
53+
Ok(dir) => dir.display().to_string(),
54+
Err(_) => String::from(""),
55+
},
56+
}
57+
}
58+
59+
#[cfg(test)]
60+
mod tests {
61+
use super::*;
62+
use std::env;
63+
64+
#[cfg(not(windows))]
65+
#[test]
66+
fn test_dirs() {
67+
// these tests need to be run sequentially to prevent race condition
68+
test_config_dir_xdg();
69+
test_config_dir();
70+
test_data_dir_xdg();
71+
test_data_dir();
72+
}
73+
74+
fn test_config_dir_xdg() {
75+
env::remove_var("HOME");
76+
env::set_var("XDG_CONFIG_HOME", "/home/user/custom_config");
77+
assert_eq!(
78+
config_dir(),
79+
PathBuf::from("/home/user/custom_config/atuin")
80+
);
81+
env::remove_var("XDG_CONFIG_HOME");
82+
}
83+
84+
fn test_config_dir() {
85+
env::set_var("HOME", "/home/user");
86+
env::remove_var("XDG_CONFIG_HOME");
87+
88+
assert_eq!(config_dir(), PathBuf::from("/home/user/.config/atuin"));
89+
90+
env::remove_var("HOME");
91+
}
92+
93+
fn test_data_dir_xdg() {
94+
env::remove_var("HOME");
95+
env::set_var("XDG_DATA_HOME", "/home/user/custom_data");
96+
assert_eq!(data_dir(), PathBuf::from("/home/user/custom_data/atuin"));
97+
env::remove_var("XDG_DATA_HOME");
98+
}
99+
100+
fn test_data_dir() {
101+
env::set_var("HOME", "/home/user");
102+
env::remove_var("XDG_DATA_HOME");
103+
assert_eq!(data_dir(), PathBuf::from("/home/user/.local/share/atuin"));
104+
env::remove_var("HOME");
105+
}
106+
}

crates/atuin-common/src/utils.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ pub fn data_dir() -> PathBuf {
7777
data_dir.join("atuin")
7878
}
7979

80+
pub fn runtime_dir() -> PathBuf {
81+
std::env::var("XDG_RUNTIME_DIR").map_or_else(|_| data_dir(), PathBuf::from)
82+
}
83+
8084
pub fn dotfiles_cache_dir() -> PathBuf {
8185
// In most cases, this will be ~/.local/share/atuin/dotfiles/cache
8286
let data_dir = std::env::var("XDG_DATA_HOME")

0 commit comments

Comments
 (0)