kkharji/xbase

[watchignore] support ! patterns

github-actions opened this issue · 1 comments

None // TODO(watchignore): support ! patterns

        .ok_or_else(|| anyhow::anyhow!("Fail to generate build_cache directory for {root_path:?}"))
}

pub fn get_build_cache_dir<P: AsRef<Path> + Debug>(root_path: P) -> Result<String> {
    _get_build_cache_dir(root_path, None)
}

pub fn get_build_cache_dir_with_config<P: AsRef<Path> + Debug>(
    root_path: P,
    config: &BuildSettings,
) -> Result<String> {
    _get_build_cache_dir(root_path, Some(config))
}

/// Read .gitignore from root and return vec of glob patterns if the .gitignore eixists.
pub async fn gitignore_to_glob_patterns<P: AsRef<Path>>(path: P) -> Result<Vec<String>> {
    let gitignore_path = path.as_ref().join(".gitignore");
    if !gitignore_path.exists() {
        return Ok(Default::default());
    }
    let content = tokio::fs::read_to_string(gitignore_path).await?;
    Ok(gitignore_content_to_glob_patterns(content))
}

pub fn gitignore_content_to_glob_patterns(content: String) -> Vec<String> {
    content
        .split("\n")
        .filter(|s| !s.is_empty() && !s.starts_with("#"))
        .flat_map(|s| {
            if s.starts_with("!") {
                None // TODO(watchignore): support ! patterns
            } else {
                Some(("", s))
            }
        })
        .filter(|&(_, s)| s.chars().next() != Some('/'))
        .map(|(pat, s)| {
            if s != "/" {
                (pat, format!("**/{s}"))
            } else {
                (pat, format!("{s}"))
            }
        })
        .flat_map(|(pat, s)| {
            let pattern = format!("{pat}{s}");
            vec![pattern.clone(), format!("{pattern}/**")]
        })
        .collect::<Vec<String>>()
}

#[test]
fn test_gitignore_patterns() {
    let gitignore_patterns =
        gitignore_content_to_glob_patterns(String::from(".build.log\n.compile"));
    assert_eq!(
        gitignore_patterns,
        vec![
            "**/.build.log".to_string(),
            "**/.build.log/**".to_string(),
            "**/.compile".to_string(),
            "**/.compile/**".to_string()
        ]
    );

    println!("{gitignore_patterns:#?}");
}

This issue should instead be changed to only watching sources files. The challenge now is how the state is setup and limitation of watcher reconfiguration after initial run.

Maybe as quick hack, each event filename should be checked against build file names, like done in checking for tuist configuration files