Merge pull request #2522 from topecongiro/ignore-config-option
Add ignore config option
This commit is contained in:
commit
a0e063a6e1
@ -2135,3 +2135,30 @@ Copyright 2018 The Rust Project Developers.`, etc.:
|
||||
```
|
||||
|
||||
`\{`, `\}` and `\\` match literal braces / backslashes.
|
||||
|
||||
## `ignore`
|
||||
|
||||
Skip formatting the specified files and directories.
|
||||
|
||||
- **Default value**: format every files
|
||||
- **Possible values**: See an example below
|
||||
- **Stable**: No
|
||||
|
||||
### Example
|
||||
|
||||
If you want to ignore specific files, put the following to your config file:
|
||||
|
||||
```toml
|
||||
ignore = [
|
||||
"src/types.rs",
|
||||
"src/foo/bar.rs",
|
||||
]
|
||||
```
|
||||
|
||||
If you want to ignore every file under `examples/`, put the following to your config file:
|
||||
|
||||
```toml
|
||||
ignore [
|
||||
"examples",
|
||||
]
|
||||
```
|
||||
|
@ -18,6 +18,7 @@
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use getopts::{Matches, Options};
|
||||
|
||||
@ -25,8 +26,6 @@
|
||||
use rustfmt::config::file_lines::FileLines;
|
||||
use rustfmt::{run, FileName, Input, Summary};
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
type FmtError = Box<error::Error + Send + Sync>;
|
||||
type FmtResult<T> = std::result::Result<T, FmtError>;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use config::file_lines::FileLines;
|
||||
use config::options::WidthHeuristics;
|
||||
use config::options::{IgnoreList, WidthHeuristics};
|
||||
|
||||
/// Trait for types that can be used in `Config`.
|
||||
pub trait ConfigType: Sized {
|
||||
@ -54,6 +54,12 @@ fn doc_hint() -> String {
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigType for IgnoreList {
|
||||
fn doc_hint() -> String {
|
||||
String::from("[<string>,..]")
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if we're in a nightly build.
|
||||
///
|
||||
/// The environment variable `CFG_RELEASE_CHANNEL` is set during the rustc bootstrap
|
||||
@ -176,7 +182,7 @@ pub fn was_set<'a>(&'a self) -> ConfigWasSet<'a> {
|
||||
ConfigWasSet(self)
|
||||
}
|
||||
|
||||
fn fill_from_parsed_config(mut self, parsed: PartialConfig) -> Config {
|
||||
fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config {
|
||||
$(
|
||||
if let Some(val) = parsed.$i {
|
||||
if self.$i.3 {
|
||||
@ -195,6 +201,7 @@ fn fill_from_parsed_config(mut self, parsed: PartialConfig) -> Config {
|
||||
)+
|
||||
self.set_heuristics();
|
||||
self.set_license_template();
|
||||
self.set_ignore(dir);
|
||||
self
|
||||
}
|
||||
|
||||
@ -216,7 +223,7 @@ pub fn is_valid_name(name: &str) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_toml(toml: &str) -> Result<Config, String> {
|
||||
pub fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
|
||||
let parsed: ::toml::Value =
|
||||
toml.parse().map_err(|e| format!("Could not parse TOML: {}", e))?;
|
||||
let mut err: String = String::new();
|
||||
@ -236,7 +243,7 @@ pub fn from_toml(toml: &str) -> Result<Config, String> {
|
||||
if !err.is_empty() {
|
||||
eprint!("{}", err);
|
||||
}
|
||||
Ok(Config::default().fill_from_parsed_config(parsed_config))
|
||||
Ok(Config::default().fill_from_parsed_config(parsed_config, dir: &Path))
|
||||
}
|
||||
Err(e) => {
|
||||
err.push_str("Error: Decoding config file failed:\n");
|
||||
@ -300,7 +307,8 @@ pub fn from_toml_path(file_path: &Path) -> Result<Config, Error> {
|
||||
let mut file = File::open(&file_path)?;
|
||||
let mut toml = String::new();
|
||||
file.read_to_string(&mut toml)?;
|
||||
Config::from_toml(&toml).map_err(|err| Error::new(ErrorKind::InvalidData, err))
|
||||
Config::from_toml(&toml, file_path.parent().unwrap())
|
||||
.map_err(|err| Error::new(ErrorKind::InvalidData, err))
|
||||
}
|
||||
|
||||
/// Resolve the config for input in `dir`.
|
||||
@ -401,6 +409,10 @@ fn set_license_template(&mut self) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_ignore(&mut self, dir: &Path) {
|
||||
self.ignore.2.add_prefix(dir);
|
||||
}
|
||||
}
|
||||
|
||||
// Template for the default configuration
|
||||
|
@ -141,6 +141,8 @@
|
||||
"Report all, none or unnumbered occurrences of TODO in source file comments";
|
||||
report_fixme: ReportTactic, ReportTactic::Never, false,
|
||||
"Report all, none or unnumbered occurrences of FIXME in source file comments";
|
||||
ignore: IgnoreList, IgnoreList::default(), false,
|
||||
"Skip formatting the specified files and directories.";
|
||||
|
||||
// Not user-facing.
|
||||
verbose: bool, false, false, "Use verbose output";
|
||||
@ -208,7 +210,8 @@ fn test_config_used_to_toml() {
|
||||
|
||||
#[test]
|
||||
fn test_was_set() {
|
||||
let config = Config::from_toml("hard_tabs = true").unwrap();
|
||||
use std::path::Path;
|
||||
let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap();
|
||||
|
||||
assert_eq!(config.was_set().hard_tabs(), true);
|
||||
assert_eq!(config.was_set().verbose(), false);
|
||||
|
@ -8,9 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use syntax::codemap::FileName;
|
||||
|
||||
use config::config_type::ConfigType;
|
||||
use config::lists::*;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Macro for deriving implementations of Serialize/Deserialize for enums
|
||||
#[macro_export]
|
||||
macro_rules! impl_enum_serialize_and_deserialize {
|
||||
@ -244,3 +249,50 @@ fn from_str(_: &str) -> Result<Self, Self::Err> {
|
||||
Err("WidthHeuristics is not parsable")
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of directories, files and modules that rustfmt should ignore.
|
||||
#[derive(Default, Deserialize, Serialize, Clone, Debug)]
|
||||
pub struct IgnoreList(HashSet<PathBuf>);
|
||||
|
||||
impl IgnoreList {
|
||||
pub fn add_prefix(&mut self, dir: &Path) {
|
||||
self.0 = self.0
|
||||
.iter()
|
||||
.map(|s| {
|
||||
if s.has_root() {
|
||||
s.clone()
|
||||
} else {
|
||||
let mut path = PathBuf::from(dir);
|
||||
path.push(s);
|
||||
path
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
fn skip_file_inner(&self, file: &Path) -> bool {
|
||||
for path in &self.0 {
|
||||
if file.starts_with(path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
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 {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(_: &str) -> Result<Self, Self::Err> {
|
||||
Err("IgnoreList is not parsable")
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ fn format_ast<F>(
|
||||
// nothing to distinguish the nested module contents.
|
||||
let skip_children = config.skip_children() || config.write_mode() == config::WriteMode::Plain;
|
||||
for (path, module) in modules::list_files(krate, parse_session.codemap())? {
|
||||
if skip_children && path != *main_file {
|
||||
if (skip_children && path != *main_file) || config.ignore().skip_file(&path) {
|
||||
continue;
|
||||
}
|
||||
should_emit_verbose(&path, config, || println!("Formatting {}", path));
|
||||
|
@ -293,7 +293,7 @@ fn format_lines_errors_are_reported() {
|
||||
fn format_lines_errors_are_reported_with_tabs() {
|
||||
let long_identifier = String::from_utf8(vec![b'a'; 97]).unwrap();
|
||||
let input = Input::Text(format!("fn a() {{\n\t{}\n}}", long_identifier));
|
||||
let config = Config::from_toml("hard_tabs = true").unwrap();
|
||||
let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap();
|
||||
let (error_summary, _file_map, _report) =
|
||||
format_input::<io::Stdout>(input, &config, None).unwrap();
|
||||
assert!(error_summary.has_formatting_errors());
|
||||
@ -435,7 +435,7 @@ fn get_config(config_file: Option<&Path>) -> Config {
|
||||
.read_to_string(&mut def_config)
|
||||
.expect("Couldn't read config");
|
||||
|
||||
Config::from_toml(&def_config).expect("Invalid toml")
|
||||
Config::from_toml(&def_config, Path::new("tests/config/")).expect("Invalid toml")
|
||||
}
|
||||
|
||||
// Reads significant comments of the form: // rustfmt-key: value
|
||||
|
Loading…
Reference in New Issue
Block a user