More config work

This commit is contained in:
Javier Feliz 2025-09-07 16:09:41 -04:00
parent 85326e435c
commit 1ed1f6065a
6 changed files with 61 additions and 7 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
.direnv/ .direnv/
waycast_cache waycast_cache
waycast.toml waycast.toml
# Using locally to test .config, .cache, and data dir
xdg

1
Cargo.lock generated
View File

@ -1460,6 +1460,7 @@ dependencies = [
"redb", "redb",
"serde", "serde",
"tempfile", "tempfile",
"waycast-config",
] ]
[[package]] [[package]]

View File

@ -1,20 +1,33 @@
use config::Config; use config::{Config, Environment};
use directories::ProjectDirs; use directories::ProjectDirs;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::Path; use std::path::Path;
use std::sync::OnceLock; use std::sync::OnceLock;
use std::{fs::File, path::PathBuf}; use std::{env, fs::File, path::PathBuf};
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct WaycastConfig {} pub struct WaycastConfig {}
static CONFIG_SINGLETON: OnceLock<Config> = OnceLock::new(); static CONFIG_SINGLETON: OnceLock<Config> = OnceLock::new();
fn is_development_mode() -> bool {
// Check if we're in development by looking for Cargo.toml in current directory
env::current_dir()
.map(|dir| dir.join("Cargo.toml").exists())
.unwrap_or(false)
}
pub fn project_dirs() -> Option<ProjectDirs> { pub fn project_dirs() -> Option<ProjectDirs> {
ProjectDirs::from("dev.thegrind", "The Grind", "waycast") ProjectDirs::from("dev.thegrind", "The Grind", "waycast")
} }
pub fn config_dir() -> Option<PathBuf> { pub fn config_dir() -> Option<PathBuf> {
if is_development_mode() {
return env::current_dir()
.map(|d| d.join("xdg").join(".config").join("waycast"))
.ok();
}
if let Some(dirs) = project_dirs() { if let Some(dirs) = project_dirs() {
return Some(dirs.config_dir().to_path_buf()); return Some(dirs.config_dir().to_path_buf());
} }
@ -23,6 +36,12 @@ pub fn config_dir() -> Option<PathBuf> {
} }
pub fn cache_dir() -> Option<PathBuf> { pub fn cache_dir() -> Option<PathBuf> {
if is_development_mode() {
return env::current_dir()
.ok()
.map(|d| d.join("xdg").join(".cache"));
}
if let Some(dirs) = project_dirs() { if let Some(dirs) = project_dirs() {
return Some(dirs.cache_dir().to_path_buf()); return Some(dirs.cache_dir().to_path_buf());
} }
@ -31,6 +50,12 @@ pub fn cache_dir() -> Option<PathBuf> {
} }
pub fn data_dir() -> Option<PathBuf> { pub fn data_dir() -> Option<PathBuf> {
if is_development_mode() {
return env::current_dir()
.ok()
.map(|d| d.join("xdg").join(".local/share"));
}
if let Some(dirs) = project_dirs() { if let Some(dirs) = project_dirs() {
return Some(dirs.data_dir().to_path_buf()); return Some(dirs.data_dir().to_path_buf());
} }
@ -46,6 +71,14 @@ pub fn config_path<P: AsRef<Path>>(file: P) -> Option<PathBuf> {
None None
} }
pub fn cache_path<P: AsRef<Path>>(file: P) -> Option<PathBuf> {
if let Some(p) = cache_dir() {
return Some(p.join(file));
}
None
}
pub fn config_file() -> &'static Config { pub fn config_file() -> &'static Config {
CONFIG_SINGLETON.get_or_init(|| init()) CONFIG_SINGLETON.get_or_init(|| init())
} }
@ -57,14 +90,18 @@ pub fn get<T: DeserializeOwned>(key: &str) -> Result<T, config::ConfigError> {
fn init() -> Config { fn init() -> Config {
let mut cfg = Config::builder(); let mut cfg = Config::builder();
cfg = cfg.add_source(config::File::with_name("waycast.toml").required(false)); // Local file for dev println!("Config: {}", config_path("waycast.toml").unwrap().display());
// Production version in ~/.config
if let Some(path) = config_path("waycast.toml") { if let Some(path) = config_path("waycast.toml") {
cfg = cfg.add_source(config::File::with_name(&path.to_string_lossy()).required(false)); cfg = cfg.add_source(config::File::with_name(&path.to_string_lossy()).required(false));
} }
cfg = cfg.add_source(config::Environment::with_prefix("WAYCAST")); cfg = cfg.add_source(Environment::with_prefix("WAYCAST"));
println!("Using directories");
println!("---");
println!("{}", config_dir().unwrap().display());
println!("{}", cache_dir().unwrap().display());
println!("{}", data_dir().unwrap().display());
cfg.build().unwrap() cfg.build().unwrap()
} }

View File

@ -7,6 +7,7 @@ edition = "2021"
bincode = "1.3" bincode = "1.3"
redb = "3.0.1" redb = "3.0.1"
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
waycast-config = { path = "../waycast-config" }
[dev-dependencies] [dev-dependencies]
tempfile = "3.21.0" tempfile = "3.21.0"

View File

@ -33,7 +33,19 @@ pub struct Cache {
} }
pub fn get() -> &'static Cache { pub fn get() -> &'static Cache {
CACHE_SINGLETON.get_or_init(|| new("waycast_cache").expect("Failed to initialize cache :(")) CACHE_SINGLETON.get_or_init(|| {
let cache_path = waycast_config::cache_path("waycast_cache.db")
.unwrap_or_else(|| std::env::current_dir().unwrap().join("waycast_cache.db"));
// Ensure cache directory exists
if let Some(parent) = cache_path.parent() {
if let Err(e) = std::fs::create_dir_all(parent) {
eprintln!("Warning: Failed to create cache directory {}: {}", parent.display(), e);
}
}
new(cache_path).expect("Failed to initialize cache :(")
})
} }
// Get an existing cache at the given path or // Get an existing cache at the given path or

View File

@ -178,6 +178,7 @@ impl FileSearchPlugin {
let mut local_files = Vec::new(); let mut local_files = Vec::new();
for path in &self.search_paths { for path in &self.search_paths {
println!("Scanning: {}", path.display());
let walker = WalkDir::new(path).into_iter(); let walker = WalkDir::new(path).into_iter();
for entry in walker for entry in walker
.filter_entry(|e| { .filter_entry(|e| {