anchor_coverage/util/
mod.rs

1use anyhow::{bail, Result};
2use std::{
3    env::current_dir,
4    ffi::OsStr,
5    fs::read_dir,
6    path::{Path, PathBuf},
7};
8
9pub mod var_guard;
10
11pub fn files_with_extension(dir: impl AsRef<Path>, extension: &str) -> Result<Vec<PathBuf>> {
12    let mut pcs_paths = Vec::new();
13    for result in read_dir(dir)? {
14        let entry = result?;
15        let path = entry.path();
16        if path.is_file() && path.extension() == Some(OsStr::new(extension)) {
17            pcs_paths.push(path);
18        }
19    }
20    Ok(pcs_paths)
21}
22
23pub fn patched_agave_tools(path: impl AsRef<Path>) -> Result<Option<PathBuf>> {
24    let mut path_bufs = Vec::new();
25    for result in read_dir(path)? {
26        let entry = result?;
27        let path = entry.path();
28        let Some(file_name) = path.file_name().and_then(OsStr::to_str) else {
29            continue;
30        };
31        if !file_name.starts_with("patched-agave-tools-") {
32            continue;
33        }
34        if !path.is_dir() {
35            // smoelius: Don't warn if there is an adjacent directory with the same basename.
36            if let Some(file_stem) = file_name.strip_suffix(".tar.gz")
37                && let Some(parent) = path.parent()
38                && parent.join(file_stem).is_dir()
39            {
40                continue;
41            }
42            eprintln!(
43                "Warning: Found `{}` but it is not a directory. If it contains patched Agave \
44                 tools that you want to use, please unzip and untar it.",
45                path.display()
46            );
47            continue;
48        }
49        path_bufs.push(path);
50    }
51    let mut iter = path_bufs.into_iter();
52    let Some(path_buf) = iter.next() else {
53        return Ok(None);
54    };
55    if iter.next().is_some() {
56        bail!("Found multiple patched Agave tools directories");
57    }
58    Ok(Some(path_buf))
59}
60
61pub trait StripCurrentDir {
62    fn strip_current_dir(&self) -> &Self;
63}
64
65impl StripCurrentDir for Path {
66    fn strip_current_dir(&self) -> &Self {
67        let Ok(current_dir) = current_dir() else {
68            return self;
69        };
70        self.strip_prefix(current_dir).unwrap_or(self)
71    }
72}