1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use anyhow::{Error, Result};
use async_std::fs;
use async_std::path::{self, Path, PathBuf};
use std::io::ErrorKind;

/// Name of the directory in which Žinoma stores its own files.
const WORK_DIR_NAME: &str = ".zinoma";

pub fn is_in_work_dir(path: &Path) -> bool {
    path.components().any(|component| match component {
        path::Component::Normal(name) => name == WORK_DIR_NAME,
        _ => false,
    })
}

#[cfg(test)]
mod tests {
    use super::is_in_work_dir;
    use async_std::path::Path;

    #[test]
    fn test_is_in_work_dir() {
        assert!(is_in_work_dir(Path::new(".zinoma/my/file.json")));
        assert!(is_in_work_dir(Path::new(
            "/my/project/.zinoma/my/file.json"
        )));
        assert!(!is_in_work_dir(Path::new("/my/file.json")));
    }
}

pub fn get_work_dir_path(project_dir: &Path) -> PathBuf {
    project_dir.join(WORK_DIR_NAME)
}

pub async fn remove_work_dir(project_dir: &Path) -> Result<()> {
    let checksums_dir = get_work_dir_path(project_dir);
    match fs::remove_dir_all(&checksums_dir).await {
        Ok(_) => {}
        Err(e) if e.kind() == ErrorKind::NotFound => {}
        Err(e) => {
            return Err(Error::new(e).context(format!(
                "Failed to remove checksums directory {}",
                checksums_dir.display()
            )));
        }
    }

    Ok(())
}

pub fn is_work_dir(entry: &walkdir::DirEntry) -> bool {
    entry
        .file_name()
        .to_str()
        .map(|file_name| file_name == WORK_DIR_NAME)
        .unwrap_or(false)
}