Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 34bf137

Browse files
rchaser53topecongiro
authored andcommitted
Allow specifying glob pattern to ignore config option (rust-lang#3488)
1 parent 7862051 commit 34bf137

File tree

9 files changed

+167
-28
lines changed

9 files changed

+167
-28
lines changed

Cargo.lock

Lines changed: 78 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ bytecount = "0.5"
5757
unicode-width = "0.1.5"
5858
unicode_categories = "0.1.1"
5959
dirs = "1.0.4"
60+
ignore = "0.4.6"
6061

6162
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
6263
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

src/config/config_type.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ macro_rules! create_config {
141141
ConfigWasSet(self)
142142
}
143143

144-
fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config {
144+
fn fill_from_parsed_config(mut self, parsed: PartialConfig) -> Config {
145145
$(
146146
if let Some(val) = parsed.$i {
147147
if self.$i.3 {
@@ -160,7 +160,6 @@ macro_rules! create_config {
160160
)+
161161
self.set_heuristics();
162162
self.set_license_template();
163-
self.set_ignore(dir);
164163
self
165164
}
166165

@@ -287,9 +286,6 @@ macro_rules! create_config {
287286
}
288287
}
289288

290-
fn set_ignore(&mut self, dir: &Path) {
291-
self.ignore.2.add_prefix(dir);
292-
}
293289

294290
/// Returns `true` if the config key was explicitly set and is the default value.
295291
pub fn is_default(&self, key: &str) -> bool {

src/config/mod.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,7 @@ impl Config {
190190
let mut file = File::open(&file_path)?;
191191
let mut toml = String::new();
192192
file.read_to_string(&mut toml)?;
193-
Config::from_toml(&toml, file_path.parent().unwrap())
194-
.map_err(|err| Error::new(ErrorKind::InvalidData, err))
193+
Config::from_toml(&toml).map_err(|err| Error::new(ErrorKind::InvalidData, err))
195194
}
196195

197196
/// Resolves the config for input in `dir`.
@@ -253,7 +252,7 @@ impl Config {
253252
}
254253
}
255254

256-
pub(crate) fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
255+
pub(crate) fn from_toml(toml: &str) -> Result<Config, String> {
257256
let parsed: ::toml::Value = toml
258257
.parse()
259258
.map_err(|e| format!("Could not parse TOML: {}", e))?;
@@ -272,7 +271,7 @@ impl Config {
272271
if !err.is_empty() {
273272
eprint!("{}", err);
274273
}
275-
Ok(Config::default().fill_from_parsed_config(parsed_config, dir))
274+
Ok(Config::default().fill_from_parsed_config(parsed_config))
276275
}
277276
Err(e) => {
278277
err.push_str("Error: Decoding config file failed:\n");
@@ -426,8 +425,7 @@ mod test {
426425

427426
#[test]
428427
fn test_was_set() {
429-
use std::path::Path;
430-
let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap();
428+
let config = Config::from_toml("hard_tabs = true").unwrap();
431429

432430
assert_eq!(config.was_set().hard_tabs(), true);
433431
assert_eq!(config.was_set().verbose(), false);

src/config/options.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use std::collections::HashSet;
1+
use std::collections::{hash_set, HashSet};
22
use std::path::{Path, PathBuf};
33

44
use atty;
55

66
use crate::config::config_type::ConfigType;
77
use crate::config::lists::*;
8-
use crate::config::{Config, FileName};
8+
use crate::config::Config;
99

1010
/// Macro that will stringify the enum variants or a provided textual repr
1111
#[macro_export]
@@ -399,6 +399,15 @@ impl Default for EmitMode {
399399
#[derive(Default, Deserialize, Serialize, Clone, Debug, PartialEq)]
400400
pub struct IgnoreList(HashSet<PathBuf>);
401401

402+
impl<'a> IntoIterator for &'a IgnoreList {
403+
type Item = &'a PathBuf;
404+
type IntoIter = hash_set::Iter<'a, PathBuf>;
405+
406+
fn into_iter(self) -> Self::IntoIter {
407+
self.0.iter()
408+
}
409+
}
410+
402411
impl IgnoreList {
403412
pub fn add_prefix(&mut self, dir: &Path) {
404413
self.0 = self
@@ -415,18 +424,6 @@ impl IgnoreList {
415424
})
416425
.collect();
417426
}
418-
419-
fn skip_file_inner(&self, file: &Path) -> bool {
420-
self.0.iter().any(|path| file.starts_with(path))
421-
}
422-
423-
pub fn skip_file(&self, file: &FileName) -> bool {
424-
if let FileName::Real(ref path) = file {
425-
self.skip_file_inner(path)
426-
} else {
427-
false
428-
}
429-
}
430427
}
431428

432429
impl ::std::str::FromStr for IgnoreList {

src/formatting.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use syntax::source_map::{FilePathMapping, SourceMap, Span, DUMMY_SP};
1414

1515
use crate::comment::{CharClasses, FullCodeCharKind};
1616
use crate::config::{Config, FileName, Verbosity};
17+
use crate::ignore_path::IgnorePathSet;
1718
use crate::issues::BadIssueSeeker;
1819
use crate::utils::{count_newlines, get_skip_macro_names};
1920
use crate::visitor::{FmtVisitor, SnippetProvider};
@@ -90,6 +91,10 @@ fn format_project<T: FormatHandler>(
9091
parse_session.span_diagnostic = Handler::with_emitter(true, None, silent_emitter);
9192

9293
let mut context = FormatContext::new(&krate, report, parse_session, config, handler);
94+
let ignore_path_set = match IgnorePathSet::from_ignore_list(&config.ignore()) {
95+
Ok(set) => set,
96+
Err(e) => return Err(ErrorKind::InvalidGlobPattern(e)),
97+
};
9398

9499
let files = modules::ModResolver::new(
95100
context.parse_session.source_map(),
@@ -99,7 +104,8 @@ fn format_project<T: FormatHandler>(
99104
.visit_crate(&krate)
100105
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
101106
for (path, (module, _)) in files {
102-
if (config.skip_children() && path != main_file) || config.ignore().skip_file(&path) {
107+
let should_ignore = !input_is_stdin && ignore_path_set.is_match(&path);
108+
if (config.skip_children() && path != main_file) || should_ignore {
103109
continue;
104110
}
105111
should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path));
@@ -276,7 +282,10 @@ impl FormattingError {
276282
| ErrorKind::IoError(_)
277283
| ErrorKind::ParseError
278284
| ErrorKind::LostComment => "internal error:",
279-
ErrorKind::LicenseCheck | ErrorKind::BadAttr | ErrorKind::VersionMismatch => "error:",
285+
ErrorKind::LicenseCheck
286+
| ErrorKind::BadAttr
287+
| ErrorKind::InvalidGlobPattern(..)
288+
| ErrorKind::VersionMismatch => "error:",
280289
ErrorKind::BadIssue(_) | ErrorKind::DeprecatedAttr => "warning:",
281290
}
282291
}

src/ignore_path.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use ignore::{self, gitignore};
2+
use std::path::PathBuf;
3+
4+
use crate::config::{FileName, IgnoreList};
5+
6+
pub struct IgnorePathSet {
7+
ignore_set: gitignore::Gitignore,
8+
}
9+
10+
impl IgnorePathSet {
11+
pub fn from_ignore_list(ignore_list: &IgnoreList) -> Result<Self, ignore::Error> {
12+
let mut ignore_builder = gitignore::GitignoreBuilder::new(PathBuf::from(""));
13+
14+
for ignore_path in ignore_list {
15+
ignore_builder.add_line(None, ignore_path.to_str().unwrap())?;
16+
}
17+
18+
Ok(IgnorePathSet {
19+
ignore_set: ignore_builder.build()?,
20+
})
21+
}
22+
23+
pub fn is_match(&self, file_name: &FileName) -> bool {
24+
match file_name {
25+
FileName::Stdin => false,
26+
FileName::Real(p) => self
27+
.ignore_set
28+
.matched_path_or_any_parents(p, false)
29+
.is_ignore(),
30+
}
31+
}
32+
}
33+
34+
#[cfg(test)]
35+
mod test {
36+
use crate::config::{Config, FileName};
37+
use crate::ignore_path::IgnorePathSet;
38+
use std::path::PathBuf;
39+
40+
#[test]
41+
fn test_ignore_path_set() {
42+
let config = Config::from_toml(
43+
"ignore = [
44+
\"foo.rs\",
45+
\"bar_dir/*\",
46+
]",
47+
)
48+
.unwrap();
49+
let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap();
50+
51+
assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs"))));
52+
assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("bar_dir/baz.rs"))));
53+
assert!(!ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/bar.rs"))));
54+
}
55+
}

0 commit comments

Comments
 (0)