Hook up --ignore, --filter, --exts properly

This commit is contained in:
Félix Saparelli 2021-12-24 18:51:35 +13:00
parent 6cd2252b6c
commit 6f8049dd93
No known key found for this signature in database
GPG key ID: B948C4BAE44FC474

View file

@ -1,30 +1,105 @@
use std::{ffi::OsString, sync::Arc};
use std::{
ffi::{OsStr, OsString},
sync::Arc,
};
use clap::ArgMatches;
use miette::{IntoDiagnostic, Result};
use watchexec::filter::globset::GlobsetFilterer;
pub async fn globset(args: &ArgMatches<'static>) -> Result<Arc<GlobsetFilterer>> {
let (project_origin, _workdir) = super::common::dirs(args).await?;
let _ignores = super::common::ignores(args, &project_origin).await?;
// TODO: load ignorefiles
let (project_origin, workdir) = super::common::dirs(args).await?;
let ignorefiles = super::common::ignores(args, &project_origin).await?;
let mut ignores = Vec::new();
for ignore in ignorefiles {
ignores.extend(GlobsetFilterer::list_from_ignore_file(&ignore).await?);
}
let filters = args
.values_of("filter")
.unwrap_or_default()
.map(|f| (f.to_owned(), None));
// TODO: scope to workdir?
.map(|f| (f.to_owned(), Some(workdir.clone())));
// TODO: load ignores from args
ignores.extend(
args.values_of("ignore")
.unwrap_or_default()
.map(|f| (f.to_owned(), Some(workdir.clone()))),
);
let exts = args
.values_of("extensions")
.values_of_os("extensions")
.unwrap_or_default()
.map(|s| s.split(',').map(|s| OsString::from(s.trim())))
.map(|s| s.split(b','))
.flatten();
// TODO: get osstrings directly
Ok(Arc::new(
GlobsetFilterer::new(project_origin, filters, vec![], exts).into_diagnostic()?,
GlobsetFilterer::new(project_origin, filters, ignores, exts).into_diagnostic()?,
))
}
trait OsStringSplit {
fn split(&self, sep: u8) -> OsSplit;
}
impl OsStringSplit for OsStr {
fn split(&self, sep: u8) -> OsSplit {
OsSplit {
os: self.to_os_string(),
pos: 0,
sep,
}
}
}
struct OsSplit {
os: OsString,
pos: usize,
sep: u8,
}
#[cfg(unix)]
impl Iterator for OsSplit {
type Item = OsString;
fn next(&mut self) -> Option<Self::Item> {
use std::os::unix::ffi::{OsStrExt, OsStringExt};
let bytes = self.os.as_bytes();
if self.pos >= bytes.len() {
None
} else {
let mut pos = self.pos;
while pos < bytes.len() && bytes[pos] != self.sep {
pos += 1;
}
let res = OsString::from_vec(bytes[self.pos..=pos].to_vec());
self.pos = pos + 1;
Some(res)
}
}
}
#[cfg(windows)]
impl Iterator for OsSplit {
type Item = OsString;
fn next(&mut self) -> Option<Self::Item> {
use std::os::windows::ffi::{OsStrExt, OsStringExt};
let mut wides = self.os.encode_wide();
wides.skip(self.pos);
let mut cur = Vec::new();
for wide in wides {
if wide == u16::from(self.sep) {
break;
}
cur.push(wide);
}
let res = OsString::from_wide(&cur);
self.pos = cur.len() + 1;
Some(res)
}
}