Search for clippy.toml
recursively
This commit is contained in:
parent
49c2c2c628
commit
d52af53e04
@ -136,17 +136,23 @@ mod reexport {
|
|||||||
|
|
||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
||||||
let conf = match utils::conf::file(reg.args()) {
|
let conf = match utils::conf::file_from_args(reg.args()) {
|
||||||
Ok(file_name) => {
|
Ok(file_name) => {
|
||||||
// if the user specified a file, it must exist, otherwise default to `clippy.toml` but
|
// if the user specified a file, it must exist, otherwise default to `clippy.toml` but
|
||||||
// do not require the file to exist
|
// do not require the file to exist
|
||||||
let (file_name, must_exist) = if let Some(ref file_name) = file_name {
|
let file_name = if let Some(file_name) = file_name {
|
||||||
(&**file_name, true)
|
Some(file_name)
|
||||||
} else {
|
} else {
|
||||||
("clippy.toml", false)
|
match utils::conf::lookup_conf_file() {
|
||||||
|
Ok(path) => path,
|
||||||
|
Err(error) => {
|
||||||
|
reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", error)).emit();
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (conf, errors) = utils::conf::read(file_name, must_exist);
|
let (conf, errors) = utils::conf::read(file_name.as_ref().map(|p| p.as_ref()));
|
||||||
|
|
||||||
// all conf errors are non-fatal, we just use the default conf in case of error
|
// all conf errors are non-fatal, we just use the default conf in case of error
|
||||||
for error in errors {
|
for error in errors {
|
||||||
|
@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
#![deny(missing_docs_in_private_items)]
|
#![deny(missing_docs_in_private_items)]
|
||||||
|
|
||||||
use std::{fmt, fs, io};
|
use std::{env, fmt, fs, io, path};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use syntax::{ast, codemap};
|
use syntax::{ast, codemap};
|
||||||
use syntax::parse::token;
|
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
/// Get the configuration file from arguments.
|
/// Get the configuration file from arguments.
|
||||||
pub fn file(args: &[codemap::Spanned<ast::NestedMetaItemKind>]) -> Result<Option<token::InternedString>, (&'static str, codemap::Span)> {
|
pub fn file_from_args(args: &[codemap::Spanned<ast::NestedMetaItemKind>]) -> Result<Option<path::PathBuf>, (&'static str, codemap::Span)> {
|
||||||
for arg in args.iter().filter_map(|a| a.meta_item()) {
|
for arg in args.iter().filter_map(|a| a.meta_item()) {
|
||||||
match arg.node {
|
match arg.node {
|
||||||
ast::MetaItemKind::Word(ref name) |
|
ast::MetaItemKind::Word(ref name) |
|
||||||
@ -21,7 +20,7 @@ pub fn file(args: &[codemap::Spanned<ast::NestedMetaItemKind>]) -> Result<Option
|
|||||||
ast::MetaItemKind::NameValue(ref name, ref value) => {
|
ast::MetaItemKind::NameValue(ref name, ref value) => {
|
||||||
if name == &"conf_file" {
|
if name == &"conf_file" {
|
||||||
return if let ast::LitKind::Str(ref file, _) = value.node {
|
return if let ast::LitKind::Str(ref file, _) = value.node {
|
||||||
Ok(Some(file.clone()))
|
Ok(Some(file.to_string().into()))
|
||||||
} else {
|
} else {
|
||||||
Err(("`conf_file` value must be a string", value.span))
|
Err(("`conf_file` value must be a string", value.span))
|
||||||
};
|
};
|
||||||
@ -179,13 +178,51 @@ define_Conf! {
|
|||||||
("enum-variant-name-threshold", enum_variant_name_threshold, 3 => u64),
|
("enum-variant-name-threshold", enum_variant_name_threshold, 3 => u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the `toml` configuration file. The function will ignore “File not found” errors iif
|
/// Search for the configuration file.
|
||||||
/// `!must_exist`, in which case, it will return the default configuration.
|
pub fn lookup_conf_file() -> io::Result<Option<path::PathBuf>> {
|
||||||
|
/// Possible filename to search for.
|
||||||
|
const CONFIG_FILE_NAMES: [&'static str; 2] = [".clippy.toml", "clippy.toml"];
|
||||||
|
|
||||||
|
let mut current = try!(env::current_dir());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
for config_file_name in &CONFIG_FILE_NAMES {
|
||||||
|
let config_file = current.join(config_file_name);
|
||||||
|
match fs::metadata(&config_file) {
|
||||||
|
// Only return if it's a file to handle the unlikely situation of a directory named
|
||||||
|
// `clippy.toml`.
|
||||||
|
Ok(ref md) if md.is_file() => return Ok(Some(config_file)),
|
||||||
|
// Return the error if it's something other than `NotFound`; otherwise we didn't
|
||||||
|
// find the project file yet, and continue searching.
|
||||||
|
Err(e) => {
|
||||||
|
if e.kind() != io::ErrorKind::NotFound {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current directory has no parent, we're done searching.
|
||||||
|
if !current.pop() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the `toml` configuration file.
|
||||||
|
///
|
||||||
/// In case of error, the function tries to continue as much as possible.
|
/// In case of error, the function tries to continue as much as possible.
|
||||||
pub fn read(path: &str, must_exist: bool) -> (Conf, Vec<Error>) {
|
pub fn read(path: Option<&path::Path>) -> (Conf, Vec<Error>) {
|
||||||
let mut conf = Conf::default();
|
let mut conf = Conf::default();
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
|
let path = if let Some(path) = path {
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
return (conf, errors);
|
||||||
|
};
|
||||||
|
|
||||||
let file = match fs::File::open(path) {
|
let file = match fs::File::open(path) {
|
||||||
Ok(mut file) => {
|
Ok(mut file) => {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
@ -197,9 +234,6 @@ pub fn read(path: &str, must_exist: bool) -> (Conf, Vec<Error>) {
|
|||||||
|
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
Err(ref err) if !must_exist && err.kind() == io::ErrorKind::NotFound => {
|
|
||||||
return (conf, errors);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
errors.push(err.into());
|
errors.push(err.into());
|
||||||
return (conf, errors);
|
return (conf, errors);
|
||||||
|
Loading…
Reference in New Issue
Block a user