Search for clippy.toml recursively
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user