#[plugin_registrar]
#[cfg_attr(rustfmt, rustfmt_skip)]
pub fn plugin_registrar(reg: &mut Registry) {
- let conferr = match utils::conf::conf_file(reg.args()) {
- Ok(Some(file_name)) => {
- utils::conf::read_conf(&file_name, true)
- }
- Ok(None) => {
- utils::conf::read_conf("Clippy.toml", false)
+ let conf = match utils::conf::conf_file(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 (ref file_name, must_exist) = if let Some(ref file_name) = file_name {
+ (&**file_name, true)
+ } else {
+ ("Clippy.toml", false)
+ };
+
+ let (conf, errors) = utils::conf::read_conf(&file_name, must_exist);
+
+ // all conf errors are non-fatal, we just use the default conf in case of error
+ for error in errors {
+ reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", error)).emit();
+ }
+
+ conf
}
Err((err, span)) => {
- reg.sess.struct_span_err(span, err).emit();
- return;
- }
- };
-
- let conf = match conferr {
- Ok(conf) => conf,
- Err(err) => {
- reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", err)).emit();
- return;
+ reg.sess.struct_span_err(span, err)
+ .span_note(span, "Clippy will use defaulf configuration")
+ .emit();
+ utils::conf::Conf::default()
}
};
/// 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.
-pub fn read_conf(path: &str, must_exist: bool) -> Result<Conf, ConfError> {
+/// In case of error, the function tries to continue as much as possible.
+pub fn read_conf(path: &str, must_exist: bool) -> (Conf, Vec<ConfError>) {
let mut conf = Conf::default();
+ let mut errors = Vec::new();
let file = match fs::File::open(path) {
Ok(mut file) => {
let mut buf = String::new();
- try!(file.read_to_string(&mut buf));
+
+ if let Err(err) = file.read_to_string(&mut buf) {
+ errors.push(err.into());
+ return (conf, errors);
+ }
+
buf
}
Err(ref err) if !must_exist && err.kind() == io::ErrorKind::NotFound => {
- return Ok(conf);
+ return (conf, errors);
}
Err(err) => {
- return Err(err.into());
+ errors.push(err.into());
+ return (conf, errors);
}
};
let toml = if let Some(toml) = parser.parse() {
toml
} else {
- return Err(ConfError::TomlError(parser.errors));
+ errors.push(ConfError::TomlError(parser.errors));
+ return (conf, errors);
};
for (key, value) in toml {
- try!(conf.set(key, value));
+ if let Err(err) = conf.set(key, value) {
+ errors.push(err);
+ }
}
- Ok(conf)
+ (conf, errors)
}