//! Global database path discovery for Tools //! //! Provides utilities to find and manage global database files for tools, //! allowing multiple projects to share a single database instance. //! //! # Search Order //! 1. From global config file (if database_path field exists) //! 2. `$XDG_DATA_HOME/tools/{tool_name}/{tool_name}.db` //! 3. `~/.local/share/tools/{tool_name}/{tool_name}.db` //! //! # Examples //! ```no_run //! use tools_shared::find_global_db_path; //! //! let db_path = find_global_db_path("project-lifecycle"); //! println!("Database path: {}", db_path.display()); //! ``` use crate::xdg::tool_data_dir; use std::path::PathBuf; /// Find global database path for a tool /// /// Uses tool's data directory and standard database filename /// /// # Arguments /// * `tool_name` - Name of the tool (e.g., "project-lifecycle") /// /// # Returns /// PathBuf to the global database file (may not exist yet) /// /// # Examples /// ```no_run /// use tools_shared::find_global_db_path; /// /// let db_path = find_global_db_path("tracking-manager"); /// assert!(db_path.ends_with("tracking-manager.db")); /// ``` pub fn find_global_db_path(tool_name: &str) -> PathBuf { let db_filename = format!("{}.db", tool_name); find_global_db_path_custom(tool_name, &db_filename) } /// Find global database path with custom filename /// /// Allows tools to use custom database filenames while maintaining standard directory structure /// /// # Arguments /// * `tool_name` - Name of the tool (e.g., "project-lifecycle") /// * `db_filename` - Custom database filename (e.g., "data.db") /// /// # Returns /// PathBuf to the global database file /// /// # Examples /// ```no_run /// use tools_shared::find_global_db_path_custom; /// /// let db_path = find_global_db_path_custom("my-tool", "custom.db"); /// assert!(db_path.ends_with("custom.db")); /// ``` pub fn find_global_db_path_custom(tool_name: &str, db_filename: &str) -> PathBuf { tool_data_dir(tool_name).join(db_filename) } /// Check if global database exists /// /// # Arguments /// * `tool_name` - Name of the tool /// /// # Returns /// true if global database exists, false otherwise /// /// # Examples /// ```no_run /// use tools_shared::global_db_exists; /// /// if global_db_exists("project-lifecycle") { /// println!("Database already exists"); /// } /// ``` pub fn global_db_exists(tool_name: &str) -> bool { find_global_db_path(tool_name).exists() } #[cfg(test)] mod tests { use super::*; #[test] fn test_find_global_db_path() { let db_path = find_global_db_path("test-tool"); assert!(db_path.to_string_lossy().contains("test-tool")); assert!(db_path.to_string_lossy().ends_with("test-tool.db")); } #[test] fn test_find_global_db_path_custom() { let db_path = find_global_db_path_custom("test-tool", "custom.db"); assert!(db_path.to_string_lossy().contains("test-tool")); assert!(db_path.to_string_lossy().ends_with("custom.db")); } #[test] fn test_global_db_exists_nonexistent() { // Highly unlikely this tool exists assert!(!global_db_exists("nonexistent-tool-xyz-abc-123")); } #[test] fn test_global_db_exists_check() { use tempfile::TempDir; let temp = TempDir::new().expect("Failed to create temp dir"); let db_path = temp.path().join("test.db"); // Create the file std::fs::File::create(&db_path).expect("Failed to create file"); assert!(db_path.exists()); } }