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)]
|
||||
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) => {
|
||||
// if the user specified a file, it must exist, otherwise default to `clippy.toml` but
|
||||
// do not require the file to exist
|
||||
let (file_name, must_exist) = if let Some(ref file_name) = file_name {
|
||||
(&**file_name, true)
|
||||
let file_name = if let Some(file_name) = file_name {
|
||||
Some(file_name)
|
||||
} 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
|
||||
for error in errors {
|
||||
|
@ -2,14 +2,13 @@
|
||||
|
||||
#![deny(missing_docs_in_private_items)]
|
||||
|
||||
use std::{fmt, fs, io};
|
||||
use std::{env, fmt, fs, io, path};
|
||||
use std::io::Read;
|
||||
use syntax::{ast, codemap};
|
||||
use syntax::parse::token;
|
||||
use toml;
|
||||
|
||||
/// 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()) {
|
||||
match arg.node {
|
||||
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) => {
|
||||
if name == &"conf_file" {
|
||||
return if let ast::LitKind::Str(ref file, _) = value.node {
|
||||
Ok(Some(file.clone()))
|
||||
Ok(Some(file.to_string().into()))
|
||||
} else {
|
||||
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),
|
||||
}
|
||||
|
||||
/// Read the `toml` configuration file. The function will ignore “File not found” errors iif
|
||||
/// `!must_exist`, in which case, it will return the default configuration.
|
||||
/// Search for the configuration file.
|
||||
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.
|
||||
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 errors = Vec::new();
|
||||
|
||||
let path = if let Some(path) = path {
|
||||
path
|
||||
} else {
|
||||
return (conf, errors);
|
||||
};
|
||||
|
||||
let file = match fs::File::open(path) {
|
||||
Ok(mut file) => {
|
||||
let mut buf = String::new();
|
||||
@ -197,9 +234,6 @@ pub fn read(path: &str, must_exist: bool) -> (Conf, Vec<Error>) {
|
||||
|
||||
buf
|
||||
}
|
||||
Err(ref err) if !must_exist && err.kind() == io::ErrorKind::NotFound => {
|
||||
return (conf, errors);
|
||||
}
|
||||
Err(err) => {
|
||||
errors.push(err.into());
|
||||
return (conf, errors);
|
||||
|
Loading…
Reference in New Issue
Block a user