Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ bytecount = "0.5"
unicode-width = "0.1.5"
unicode_categories = "0.1.1"
dirs = "1.0.4"
ignore = "0.4.6"

# 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`
Expand Down
6 changes: 1 addition & 5 deletions src/config/config_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ macro_rules! create_config {
ConfigWasSet(self)
}

fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config {
fn fill_from_parsed_config(mut self, parsed: PartialConfig) -> Config {
$(
if let Some(val) = parsed.$i {
if self.$i.3 {
Expand All @@ -160,7 +160,6 @@ macro_rules! create_config {
)+
self.set_heuristics();
self.set_license_template();
self.set_ignore(dir);
self
}

Expand Down Expand Up @@ -287,9 +286,6 @@ macro_rules! create_config {
}
}

fn set_ignore(&mut self, dir: &Path) {
self.ignore.2.add_prefix(dir);
}

/// Returns `true` if the config key was explicitly set and is the default value.
pub fn is_default(&self, key: &str) -> bool {
Expand Down
10 changes: 4 additions & 6 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ impl Config {
let mut file = File::open(&file_path)?;
let mut toml = String::new();
file.read_to_string(&mut toml)?;
Config::from_toml(&toml, file_path.parent().unwrap())
.map_err(|err| Error::new(ErrorKind::InvalidData, err))
Config::from_toml(&toml).map_err(|err| Error::new(ErrorKind::InvalidData, err))
}

/// Resolves the config for input in `dir`.
Expand Down Expand Up @@ -253,7 +252,7 @@ impl Config {
}
}

pub(crate) fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
pub(crate) fn from_toml(toml: &str) -> Result<Config, String> {
let parsed: ::toml::Value = toml
.parse()
.map_err(|e| format!("Could not parse TOML: {}", e))?;
Expand All @@ -272,7 +271,7 @@ impl Config {
if !err.is_empty() {
eprint!("{}", err);
}
Ok(Config::default().fill_from_parsed_config(parsed_config, dir))
Ok(Config::default().fill_from_parsed_config(parsed_config))
}
Err(e) => {
err.push_str("Error: Decoding config file failed:\n");
Expand Down Expand Up @@ -426,8 +425,7 @@ mod test {

#[test]
fn test_was_set() {
use std::path::Path;
let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap();
let config = Config::from_toml("hard_tabs = true").unwrap();

assert_eq!(config.was_set().hard_tabs(), true);
assert_eq!(config.was_set().verbose(), false);
Expand Down
25 changes: 11 additions & 14 deletions src/config/options.rs
Original file line number Diff line number Diff line change
@@ -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]
Expand Down Expand Up @@ -399,6 +399,15 @@ impl Default for EmitMode {
#[derive(Default, Deserialize, Serialize, Clone, Debug, PartialEq)]
pub struct IgnoreList(HashSet<PathBuf>);

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
Expand All @@ -415,18 +424,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 {
Expand Down
13 changes: 11 additions & 2 deletions src/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use syntax::source_map::{FilePathMapping, SourceMap, Span, DUMMY_SP};

use crate::comment::{CharClasses, FullCodeCharKind};
use crate::config::{Config, FileName, Verbosity};
use crate::ignore_path::IgnorePathSet;
use crate::issues::BadIssueSeeker;
use crate::utils::{count_newlines, get_skip_macro_names};
use crate::visitor::{FmtVisitor, SnippetProvider};
Expand Down Expand Up @@ -90,6 +91,10 @@ fn format_project<T: FormatHandler>(
parse_session.span_diagnostic = Handler::with_emitter(true, None, 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::ModResolver::new(
context.parse_session.source_map(),
Expand All @@ -99,7 +104,8 @@ fn format_project<T: FormatHandler>(
.visit_crate(&krate)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
for (path, (module, _)) in files {
if (config.skip_children() && path != main_file) || config.ignore().skip_file(&path) {
let should_ignore = !input_is_stdin && ignore_path_set.is_match(&path);
if (config.skip_children() && path != main_file) || should_ignore {
continue;
}
should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path));
Expand Down Expand Up @@ -276,7 +282,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:",
}
}
Expand Down
55 changes: 55 additions & 0 deletions src/ignore_path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use ignore::{self, gitignore};
use std::path::PathBuf;

use crate::config::{FileName, IgnoreList};

pub struct IgnorePathSet {
ignore_set: gitignore::Gitignore,
}

impl IgnorePathSet {
pub fn from_ignore_list(ignore_list: &IgnoreList) -> Result<Self, ignore::Error> {
let mut ignore_builder = gitignore::GitignoreBuilder::new(PathBuf::from(""));

for ignore_path in ignore_list {
ignore_builder.add_line(None, ignore_path.to_str().unwrap())?;
}

Ok(IgnorePathSet {
ignore_set: ignore_builder.build()?,
})
}

pub fn is_match(&self, file_name: &FileName) -> bool {
match file_name {
FileName::Stdin => false,
FileName::Real(p) => self
.ignore_set
.matched_path_or_any_parents(p, false)
.is_ignore(),
}
}
}

#[cfg(test)]
mod test {
use crate::config::{Config, FileName};
use crate::ignore_path::IgnorePathSet;
use std::path::PathBuf;

#[test]
fn test_ignore_path_set() {
let config = Config::from_toml(
"ignore = [
\"foo.rs\",
\"bar_dir/*\",
]",
)
.unwrap();
let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap();

assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs"))));
assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("bar_dir/baz.rs"))));
assert!(!ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/bar.rs"))));
}
}
Loading