use crate::error::NoloError;
use ignore::Walk;
use std::{
io,
path::{Path, PathBuf},
process::Command,
};
use tracing::debug;
pub fn discover(paths: &Path) -> Result<Vec<PathBuf>, NoloError> {
debug!("Discovering files in: {:?}", paths);
if paths.is_file() {
debug!("Input is a file, returning single file: {:?}", paths);
Ok(vec![paths.to_path_buf()])
} else if paths.is_dir() {
debug!("Input is a directory, scanning recursively: {:?}", paths);
collect_files(paths).map_err(|e| NoloError::FileDiscovery {
path: paths.display().to_string(),
source: e,
})
} else {
Err(NoloError::FileDiscovery {
path: paths.display().to_string(),
source: io::Error::new(io::ErrorKind::NotFound, "Path does not exist"),
})
}
}
pub fn git_root() -> Option<String> {
let output = Command::new("git")
.arg("rev-parse")
.arg("--show-toplevel")
.output();
match output {
Ok(root) => Some(
String::from_utf8(root.stdout)
.unwrap()
.trim_end()
.to_owned(),
),
Err(_) => None,
}
}
fn collect_files<P: AsRef<Path>>(dir: P) -> io::Result<Vec<PathBuf>> {
let mut files = Vec::new();
for result in Walk::new(dir) {
match result {
Ok(entry) => {
let path = entry.path();
if path.is_file() {
files.push(path.to_path_buf());
}
}
Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)),
}
}
Ok(files)
}