tempo_cli/utils/
paths.rs

1use anyhow::Result;
2use std::path::{Path, PathBuf};
3
4pub fn get_data_dir() -> Result<PathBuf> {
5    let data_dir = dirs::data_dir()
6        .or_else(|| dirs::home_dir())
7        .ok_or_else(|| anyhow::anyhow!("Could not determine data directory"))?;
8    
9    let vibe_dir = data_dir.join(".vibe");
10    std::fs::create_dir_all(&vibe_dir)?;
11    
12    Ok(vibe_dir)
13}
14
15pub fn get_log_dir() -> Result<PathBuf> {
16    let log_dir = get_data_dir()?.join("logs");
17    std::fs::create_dir_all(&log_dir)?;
18    Ok(log_dir)
19}
20
21pub fn get_backup_dir() -> Result<PathBuf> {
22    let backup_dir = get_data_dir()?.join("backups");
23    std::fs::create_dir_all(&backup_dir)?;
24    Ok(backup_dir)
25}
26
27pub fn canonicalize_path(path: &Path) -> Result<PathBuf> {
28    Ok(path.canonicalize()?)
29}
30
31pub fn is_git_repository(path: &Path) -> bool {
32    path.join(".git").exists()
33}
34
35pub fn has_vibe_marker(path: &Path) -> bool {
36    path.join(".vibe").exists()
37}
38
39pub fn detect_project_name(path: &Path) -> String {
40    path.file_name()
41        .and_then(|name| name.to_str())
42        .unwrap_or("unknown")
43        .to_string()
44}
45
46pub fn get_git_hash(path: &Path) -> Option<String> {
47    if !is_git_repository(path) {
48        return None;
49    }
50    
51    // Try to read .git/HEAD and .git/config to create a unique hash
52    let git_dir = path.join(".git");
53    
54    let head_content = std::fs::read_to_string(git_dir.join("HEAD")).ok()?;
55    let config_content = std::fs::read_to_string(git_dir.join("config")).ok()?;
56    
57    // Create a simple hash from the combination
58    use std::collections::hash_map::DefaultHasher;
59    use std::hash::{Hash, Hasher};
60    
61    let mut hasher = DefaultHasher::new();
62    head_content.hash(&mut hasher);
63    config_content.hash(&mut hasher);
64    
65    Some(format!("{:x}", hasher.finish()))
66}