From 6f8049dd93cde4ab3b7107ac47edaf6c1de34d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Fri, 24 Dec 2021 18:51:35 +1300 Subject: [PATCH] Hook up --ignore, --filter, --exts properly --- cli/src/filterer/globset.rs | 97 ++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/cli/src/filterer/globset.rs b/cli/src/filterer/globset.rs index 633b29b..0cc0066 100644 --- a/cli/src/filterer/globset.rs +++ b/cli/src/filterer/globset.rs @@ -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> { - 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 { + 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 { + 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) + } +}