From 472d20ca72104b0cc47d53b6a2302dc631550e0f Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 23 Feb 2019 17:55:28 +0900 Subject: [PATCH] Allow specifying glob pattern to ignore config option --- Cargo.lock | 20 ++++++++++++++++++++ Cargo.toml | 1 + src/config/options.rs | 25 +++++++++++-------------- src/formatting.rs | 12 ++++++++++-- src/ignore.rs | 26 ++++++++++++++++++++++++++ src/lib.rs | 4 ++++ 6 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 src/ignore.rs diff --git a/Cargo.lock b/Cargo.lock index 4eed10e320d..c00e3230357 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,6 +233,11 @@ dependencies = [ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fnv" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -246,6 +251,18 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "globset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "humantime" version = "1.2.0" @@ -630,6 +647,7 @@ dependencies = [ "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -892,8 +910,10 @@ dependencies = [ "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" +"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" diff --git a/Cargo.toml b/Cargo.toml index 2274ae86bd2..8e2f94f52f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ bytecount = "0.5" unicode-width = "0.1.5" unicode_categories = "0.1.1" dirs = "1.0.4" +globset = "0.4" # A noop dependency that changes in the Rust repository, it's a bit of a hack. # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` diff --git a/src/config/options.rs b/src/config/options.rs index be32c142916..27956e4b7ee 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -1,11 +1,11 @@ -use std::collections::HashSet; +use std::collections::{hash_set, HashSet}; use std::path::{Path, PathBuf}; use atty; use crate::config::config_type::ConfigType; use crate::config::lists::*; -use crate::config::{Config, FileName}; +use crate::config::Config; /// Macro that will stringify the enum variants or a provided textual repr #[macro_export] @@ -398,6 +398,15 @@ impl Default for EmitMode { #[derive(Default, Deserialize, Serialize, Clone, Debug, PartialEq)] pub struct IgnoreList(HashSet); +impl<'a> IntoIterator for &'a IgnoreList { + type Item = &'a PathBuf; + type IntoIter = hash_set::Iter<'a, PathBuf>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + impl IgnoreList { pub fn add_prefix(&mut self, dir: &Path) { self.0 = self @@ -414,18 +423,6 @@ impl IgnoreList { }) .collect(); } - - fn skip_file_inner(&self, file: &Path) -> bool { - self.0.iter().any(|path| file.starts_with(path)) - } - - pub fn skip_file(&self, file: &FileName) -> bool { - if let FileName::Real(ref path) = file { - self.skip_file_inner(path) - } else { - false - } - } } impl ::std::str::FromStr for IgnoreList { diff --git a/src/formatting.rs b/src/formatting.rs index 38440802ef2..ba2ca2c280a 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -14,6 +14,7 @@ use syntax::source_map::{FilePathMapping, SourceMap, Span}; use crate::comment::{CharClasses, FullCodeCharKind}; use crate::config::{Config, FileName, Verbosity}; +use crate::ignore::IgnorePathSet; use crate::issues::BadIssueSeeker; use crate::visitor::{FmtVisitor, SnippetProvider}; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; @@ -86,10 +87,14 @@ fn format_project( parse_session.span_diagnostic = Handler::with_emitter(true, false, silent_emitter); let mut context = FormatContext::new(&krate, report, parse_session, config, handler); + let ignore_path_set = match IgnorePathSet::from_ignore_list(&config.ignore()) { + Ok(set) => set, + Err(e) => return Err(ErrorKind::InvalidGlobPattern(e)), + }; let files = modules::list_files(&krate, context.parse_session.source_map())?; for (path, module) in files { - if (config.skip_children() && path != main_file) || config.ignore().skip_file(&path) { + if (config.skip_children() && path != main_file) || ignore_path_set.is_match(&path) { continue; } should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path)); @@ -259,7 +264,10 @@ impl FormattingError { | ErrorKind::IoError(_) | ErrorKind::ParseError | ErrorKind::LostComment => "internal error:", - ErrorKind::LicenseCheck | ErrorKind::BadAttr | ErrorKind::VersionMismatch => "error:", + ErrorKind::LicenseCheck + | ErrorKind::BadAttr + | ErrorKind::InvalidGlobPattern(..) + | ErrorKind::VersionMismatch => "error:", ErrorKind::BadIssue(_) | ErrorKind::DeprecatedAttr => "warning:", } } diff --git a/src/ignore.rs b/src/ignore.rs new file mode 100644 index 00000000000..9dadde3b1c8 --- /dev/null +++ b/src/ignore.rs @@ -0,0 +1,26 @@ +use globset::{self, Glob, GlobSet, GlobSetBuilder}; + +use crate::config::{FileName, IgnoreList}; + +pub struct IgnorePathSet { + ignore_glob_set: GlobSet, +} + +impl IgnorePathSet { + pub fn from_ignore_list(ignore_list: &IgnoreList) -> Result { + let mut globset_builder = GlobSetBuilder::new(); + for ignore_path in ignore_list { + globset_builder.add(Glob::new(&ignore_path.to_string_lossy())?); + } + Ok(IgnorePathSet { + ignore_glob_set: globset_builder.build()?, + }) + } + + pub fn is_match(&self, file_name: &FileName) -> bool { + match file_name { + FileName::Stdin => false, + FileName::Real(p) => self.ignore_glob_set.is_match(p), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 520a6e66fcd..281f23b9299 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,6 +44,7 @@ mod comment; pub(crate) mod config; mod expr; pub(crate) mod formatting; +mod ignore; mod imports; mod issues; mod items; @@ -108,6 +109,9 @@ pub enum ErrorKind { /// If we had formatted the given node, then we would have lost a comment. #[fail(display = "not formatted because a comment would be lost")] LostComment, + /// Invalid glob pattern in `ignore` configuration option. + #[fail(display = "Invalid glob pattern found in ignore list: {}", _0)] + InvalidGlobPattern(globset::Error), } impl ErrorKind {