diff --git a/Cargo.lock b/Cargo.lock index 5168cc7..ade7635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,6 +486,15 @@ dependencies = [ "rand", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "html-escape" version = "0.2.13" @@ -1341,8 +1350,8 @@ dependencies = [ "anyhow", "clap", "clap_complete", - "dirs", "hex_color", + "home", "serde", "serde_yaml", "shell-words", @@ -1352,6 +1361,7 @@ dependencies = [ "tinted-scheme-extractor", "toml", "url", + "xdg", ] [[package]] @@ -1705,6 +1715,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index 744b1a7..eb7545b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ categories = ["command-line-utilities"] anyhow = "1.0.89" clap = { version = "4.5.4", features = ["derive"] } clap_complete = { version = "4.5.29" } -dirs = "5.0.1" hex_color = "3.0.0" serde = { version = "1.0.210", features = ["derive"] } serde_yaml = "0.9.31" @@ -26,3 +25,5 @@ tinted-builder= "0.7.0" tinted-scheme-extractor = "0.4.0" toml = "0.8.19" url = "2.5.2" +xdg = "2.5.2" +home = "0.5.9" diff --git a/src/config.rs b/src/config.rs index 7d1d0a5..d4d85aa 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use crate::constants::REPO_NAME; use anyhow::{anyhow, Context, Result}; +use home::home_dir; use serde::de::{self, Deserializer, Unexpected, Visitor}; use serde::Deserialize; use std::collections::HashSet; @@ -10,6 +11,7 @@ use url::Url; pub const DEFAULT_CONFIG_SHELL: &str = "sh -c '{}'"; pub const CONFIG_FILE_NAME: &str = "config.toml"; +pub const ORG_NAME: &str = "tinted-theming"; pub const BASE16_SHELL_REPO_URL: &str = "https://github.com/tinted-theming/tinted-shell"; pub const BASE16_SHELL_REPO_NAME: &str = "tinted-shell"; pub const BASE16_SHELL_THEMES_DIR: &str = "scripts"; @@ -196,7 +198,7 @@ impl Config { // Replace `~/` with absolute home path let trimmed_path = item.path.trim(); if trimmed_path.starts_with("~/") { - match dirs::home_dir() { + match home_dir() { Some(home_dir) => { item.path = trimmed_path.replacen( "~/", diff --git a/src/main.rs b/src/main.rs index 51c18db..8902e6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,38 +20,38 @@ use crate::cli::{build_cli, get_matches}; use anyhow::{anyhow, Context, Result}; use clap::Command; use clap_complete::{generate, Generator, Shell}; -use config::CONFIG_FILE_NAME; +use config::{CONFIG_FILE_NAME, ORG_NAME}; use constants::{CUSTOM_SCHEMES_DIR_NAME, REPO_DIR, REPO_NAME, SCHEMES_REPO_NAME}; use operations::generate_scheme; use std::path::PathBuf; use tinted_builder::{SchemeSystem, SchemeVariant}; use utils::{ensure_directory_exists, replace_tilde_slash_with_home}; +use xdg::BaseDirectories; /// Entry point of the application. fn main() -> Result<()> { // Parse the command line arguments let matches = get_matches(); + let xdg_dirs = BaseDirectories::with_prefix(format!("{}/{}", ORG_NAME, REPO_NAME)).unwrap(); // Other configuration paths let config_path_result: Result = if let Some(config_file_path) = matches.get_one::("config") { replace_tilde_slash_with_home(config_file_path) } else { - Ok(dirs::config_dir() - .ok_or_else(|| anyhow!("Error getting config directory"))? - .join(format!("tinted-theming/{}/{}", REPO_NAME, CONFIG_FILE_NAME))) + xdg_dirs + .place_config_file(CONFIG_FILE_NAME) + .context(format!( + "Unable to create XDG_HOME/{}/{}/{}", + ORG_NAME, REPO_NAME, CONFIG_FILE_NAME + )) }; let config_path = config_path_result?; - // Determine the data-dir path - let data_path_result: Result = - if let Some(data_file_path) = matches.get_one::("data-dir") { - replace_tilde_slash_with_home(data_file_path) - } else { - Ok(dirs::data_dir() - .ok_or_else(|| anyhow!("Error getting data directory"))? - .join(format!("tinted-theming/{}", REPO_NAME))) - }; - let data_path = data_path_result?; + let data_path: PathBuf = if let Some(data_file_path) = matches.get_one::("data-dir") { + replace_tilde_slash_with_home(data_file_path)? + } else { + xdg_dirs.get_data_home() + }; let data_repo_path = data_path.join(REPO_DIR); // Ensure config dirs exist diff --git a/src/utils.rs b/src/utils.rs index 2b02bc0..9cac66e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,7 @@ use crate::config::{Config, ConfigItem, SupportedSchemeSystems, DEFAULT_CONFIG_SHELL}; use crate::constants::{REPO_NAME, SCHEME_EXTENSION}; use anyhow::{anyhow, Context, Result}; +use home::home_dir; use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; @@ -171,14 +172,14 @@ pub fn get_all_scheme_names( pub fn replace_tilde_slash_with_home(path_str: &str) -> Result { let trimmed_path_str = path_str.trim(); if trimmed_path_str.starts_with("~/") { - match dirs::home_dir() { - Some(home_dir) => Ok(PathBuf::from(trimmed_path_str.replacen( - "~/", - format!("{}/", home_dir.display()).as_str(), - 1, - ))), - None => Err(anyhow!("Unable to determine a home directory for \"{}\", please use an absolute path instead", trimmed_path_str)) - } + match home_dir() { + Some(home_dir) => Ok(PathBuf::from(trimmed_path_str.replacen( + "~/", + format!("{}/", home_dir.display()).as_str(), + 1, + ))), + None => Err(anyhow!("Unable to determine a home directory for \"{}\", please use an absolute path instead", trimmed_path_str)) + } } else { Ok(PathBuf::from(trimmed_path_str)) } diff --git a/tests/cli_general_tests.rs b/tests/cli_general_tests.rs index d773c3b..03d9fc7 100644 --- a/tests/cli_general_tests.rs +++ b/tests/cli_general_tests.rs @@ -2,9 +2,9 @@ mod utils; use crate::utils::{ cleanup, read_file_to_string, setup, write_to_file, COMMAND_NAME, CURRENT_SCHEME_FILE_NAME, - REPO_NAME, + ORG_NAME, REPO_NAME, }; -use anyhow::{anyhow, Result}; +use anyhow::Result; use std::{fs, path::PathBuf}; #[test] @@ -36,7 +36,7 @@ fn test_cli_config_path_tilde_as_home() -> Result<()> { // ------- let name = "test_cli_config_path_tilde_as_home"; let config_path_name = format!("config_path_{}", name); - let home_path = dirs::home_dir().unwrap(); + let home_path = home::home_dir().unwrap(); let config_path = home_path.join(&config_path_name); let provided_config_path = format!("~/{}", config_path_name); let data_path = PathBuf::from(format!("data_path_{}", name)); @@ -87,9 +87,9 @@ fn test_cli_default_data_path() -> Result<()> { let config_path = PathBuf::from(format!("{}.toml", "test_cli_default_data_path")); let scheme_name = "base16-uwunicorn"; let init_scheme_name = "base16-mocha"; - let data_path = dirs::data_dir() - .ok_or_else(|| anyhow!("Error getting data directory"))? - .join(format!("tinted-theming/{}", REPO_NAME)); + let xdg_dirs = + xdg::BaseDirectories::with_prefix(format!("{}/{}", ORG_NAME, REPO_NAME)).unwrap(); + let data_path = xdg_dirs.get_data_home(); let init_command = format!( "{} --config=\"{}\" init", COMMAND_NAME, @@ -159,7 +159,7 @@ fn test_cli_data_path_tilde_as_home() -> Result<()> { // Arrange // ------- let data_path_name = "test_cli_data_path_tilde_as_home"; - let home_path = dirs::home_dir().unwrap(); + let home_path = home::home_dir().unwrap(); let config_path = PathBuf::from(format!("{}.toml", data_path_name)); let data_path = home_path.join(data_path_name); let provided_data_path = format!("~/{}", data_path_name); diff --git a/tests/utils.rs b/tests/utils.rs index e28ef3a..0608897 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -8,6 +8,8 @@ use std::str; #[allow(dead_code)] pub const REPO_NAME: &str = env!("CARGO_PKG_NAME"); +#[allow(dead_code)] +pub const ORG_NAME: &str = "tinted-theming"; pub const COMMAND_NAME: &str = "./target/release/tinty"; #[allow(dead_code)] pub const CURRENT_SCHEME_FILE_NAME: &str = "current_scheme";