handle relative paths when using Ignore programmatically (#599)

This commit is contained in:
Jonathan Cammisuli 2023-06-03 04:24:39 -04:00 committed by GitHub
parent eb19f83761
commit 638cddcf83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 3 deletions

View File

@ -20,11 +20,12 @@ gix-config = "0.22.0"
ignore = "0.4.18"
miette = "5.3.0"
thiserror = "1.0.31"
tokio = { version = "1.24.2", default-features = false, features = ["fs"] }
tokio = { version = "1.24.2", default-features = false, features = ["fs", "macros", "rt"] }
tracing = "0.1.35"
radix_trie = "0.2.1"
dunce = "1.0.4"
[dependencies.project-origins]
version = "1.2.0"
path = "../project-origins"

View File

@ -37,4 +37,15 @@ pub enum Error {
#[error("multiple: {0:?}")]
#[diagnostic(code(ignore_file::set))]
Multi(#[related] Vec<Error>),
/// Error received when trying to canonicalize a path
#[error("cannot canonicalize '{path:?}'")]
Canonicalize {
/// the path that cannot be canonicalized
path: PathBuf,
/// the underlying error
#[source]
err: std::io::Error,
},
}

View File

@ -6,7 +6,7 @@ use ignore::{
Match,
};
use radix_trie::{Trie, TrieCommon};
use tokio::fs::read_to_string;
use tokio::fs::{canonicalize, read_to_string};
use tracing::{trace, trace_span};
use crate::{Error, IgnoreFile};
@ -55,7 +55,12 @@ impl IgnoreFilter {
/// Use [`empty()`](IgnoreFilter::empty()) if you want an empty filterer,
/// or to construct one outside an async environment.
pub async fn new(origin: impl AsRef<Path> + Send, files: &[IgnoreFile]) -> Result<Self, Error> {
let origin = dunce::simplified(origin.as_ref());
let origin = origin.as_ref().to_owned();
let origin = canonicalize(&origin)
.await
.map_err(move |err| Error::Canonicalize { path: origin, err })?;
let origin = dunce::simplified(&origin);
let _span = trace_span!("build_filterer", ?origin);
trace!(files=%files.len(), "loading file contents");
@ -368,3 +373,14 @@ fn prefix<T: AsRef<Path>>(path: T) -> String {
_ => "/".into(),
}
}
#[cfg(test)]
mod tests {
use super::IgnoreFilter;
#[tokio::test]
async fn handle_relative_paths() {
let ignore = IgnoreFilter::new(".", &[]).await.unwrap();
assert!(ignore.origin.is_absolute());
}
}