From d47419e385fb3d1a86ff32952e04d596a40ddf4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Mon, 28 Oct 2019 00:06:09 +1300 Subject: [PATCH] Forbid a whole lot more clippy stuff --- src/cli.rs | 4 ++-- src/error.rs | 24 +++++++++++----------- src/gitignore.rs | 42 ++++++++++++++++++-------------------- src/ignore.rs | 41 +++++++++++++++++-------------------- src/lib.rs | 12 +++++++++++ src/notification_filter.rs | 4 ++-- src/pathop.rs | 4 ++-- src/process.rs | 29 ++++++++++++++------------ src/signal.rs | 31 ++++++++++++++++------------ src/watcher.rs | 4 ++-- 10 files changed, 105 insertions(+), 90 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 22e8136..3807dbe 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -218,8 +218,8 @@ where for exts in extensions { filters.extend( exts.split(',') - .filter(|ext| !ext.is_empty()) - .map(|ext| format!("*.{}", ext.replace(".", ""))), + .filter_map(|ext| if ext.is_empty() { None } else { + Some(format!("*.{}", ext.replace(".", ""))) }), ); } } diff --git a/src/error.rs b/src/error.rs index 6c9fa71..36c7ade 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,48 +21,48 @@ impl StdError for Error { impl From for Error { fn from(err: clap::Error) -> Self { - Error::Clap(err) + Self::Clap(err) } } impl From for Error { fn from(err: globset::Error) -> Self { - Error::Glob(err) + Self::Glob(err) } } impl From for Error { fn from(err: io::Error) -> Self { - Error::Io(err) + Self::Io(err) } } impl From for Error { fn from(err: notify::Error) -> Self { match err { - notify::Error::Io(err) => Error::Io(err), - other => Error::Notify(other), + notify::Error::Io(err) => Self::Io(err), + other => Self::Notify(other), } } } impl<'a, T> From> for Error { fn from(_err: PoisonError) -> Self { - Error::PoisonedLock + Self::PoisonedLock } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (error_type, error) = match self { - Error::Canonicalization(path, err) => { + Self::Canonicalization(path, err) => { ("Path", format!("couldn't canonicalize '{}':\n{}", path, err)) } - Error::Clap(err) => ("Argument", err.to_string()), - Error::Glob(err) => ("Globset", err.to_string()), - Error::Io(err) => ("I/O", err.to_string()), - Error::Notify(err) => ("Notify", err.to_string()), - Error::PoisonedLock => ("Internal", "poisoned lock".to_string()), + Self::Clap(err) => ("Argument", err.to_string()), + Self::Glob(err) => ("Globset", err.to_string()), + Self::Io(err) => ("I/O", err.to_string()), + Self::Notify(err) => ("Notify", err.to_string()), + Self::PoisonedLock => ("Internal", "poisoned lock".to_string()), }; write!(f, "{} error: {}", error_type, error) diff --git a/src/gitignore.rs b/src/gitignore.rs index 4afbafb..6288d01 100644 --- a/src/gitignore.rs +++ b/src/gitignore.rs @@ -54,12 +54,11 @@ pub fn load(paths: &[PathBuf]) -> Gitignore { let gitignore_path = p.join(".gitignore"); if gitignore_path.exists() { - match GitignoreFile::new(&gitignore_path) { - Ok(f) => { + if let Ok(f) = GitignoreFile::new(&gitignore_path) { debug!("Loaded {:?}", gitignore_path); files.push(f); - } - Err(_) => debug!("Unable to load {:?}", gitignore_path), + } else { + debug!("Unable to load {:?}", gitignore_path); } } } @@ -83,8 +82,8 @@ pub fn load(paths: &[PathBuf]) -> Gitignore { } impl Gitignore { - fn new(files: Vec) -> Gitignore { - Gitignore { files } + const fn new(files: Vec) -> Self{ + Self{ files } } pub fn is_excluded(&self, path: &Path) -> bool { @@ -112,22 +111,22 @@ impl Gitignore { } impl GitignoreFile { - pub fn new(path: &Path) -> Result { + pub fn new(path: &Path) -> Result { let mut file = fs::File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; - let lines = contents.lines().collect(); + let lines: Vec<_> = contents.lines().collect(); let root = path.parent().unwrap(); - GitignoreFile::from_strings(lines, root) + Self::from_strings(&lines, root) } - pub fn from_strings(strs: Vec<&str>, root: &Path) -> Result { + pub fn from_strings(strs: &[&str], root: &Path) -> Result { let mut builder = GlobSetBuilder::new(); let mut patterns = vec![]; - let parsed_patterns = GitignoreFile::parse(strs); + let parsed_patterns = Self::parse(strs); for p in parsed_patterns { let mut pat = p.pattern.clone(); if !p.anchored && !pat.starts_with("**/") { @@ -144,7 +143,7 @@ impl GitignoreFile { patterns.push(p); } - Ok(GitignoreFile { + Ok(Self{ set: builder.build()?, patterns, root: root.to_owned(), @@ -179,18 +178,17 @@ impl GitignoreFile { self.root.as_os_str().len() } - fn parse(contents: Vec<&str>) -> Vec { + fn parse(contents: &[&str]) -> Vec { contents .iter() - .filter(|l| !l.is_empty()) - .filter(|l| !l.starts_with('#')) - .map(|l| Pattern::parse(l)) + .filter_map(|l| if !l.is_empty() && !l.starts_with('#') { + Some(Pattern::parse(l)) } else { None }) .collect() } } impl Pattern { - fn parse(pattern: &str) -> Pattern { + fn parse(pattern: &str) -> Self{ let mut normalized = String::from(pattern); let pattern_type = if normalized.starts_with('!') { @@ -215,7 +213,7 @@ impl Pattern { normalized.remove(0); } - Pattern { + Self{ pattern: normalized, pattern_type, anchored, @@ -224,14 +222,14 @@ impl Pattern { } impl From for Error { - fn from(error: globset::Error) -> Error { - Error::GlobSet(error) + fn from(error: globset::Error) -> Self{ + Self::GlobSet(error) } } impl From for Error { - fn from(error: io::Error) -> Error { - Error::Io(error) + fn from(error: io::Error) -> Self{ + Self::Io(error) } } diff --git a/src/ignore.rs b/src/ignore.rs index 8d5abfe..cd3493f 100644 --- a/src/ignore.rs +++ b/src/ignore.rs @@ -54,12 +54,11 @@ pub fn load(paths: &[PathBuf]) -> Ignore { let ignore_path = p.join(".ignore"); if ignore_path.exists() { - match IgnoreFile::new(&ignore_path) { - Ok(f) => { + if let Ok(f) = IgnoreFile::new(&ignore_path) { debug!("Loaded {:?}", ignore_path); files.push(f); - } - Err(_) => debug!("Unable to load {:?}", ignore_path), + } else { + debug!("Unable to load {:?}", ignore_path); } } } @@ -76,8 +75,8 @@ pub fn load(paths: &[PathBuf]) -> Ignore { } impl Ignore { - fn new(files: Vec) -> Ignore { - Ignore { files } + const fn new(files: Vec) -> Self { + Self { files } } pub fn is_excluded(&self, path: &Path) -> bool { @@ -105,22 +104,22 @@ impl Ignore { } impl IgnoreFile { - pub fn new(path: &Path) -> Result { + pub fn new(path: &Path) -> Result { let mut file = fs::File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; - let lines = contents.lines().collect(); + let lines: Vec<_> = contents.lines().collect(); let root = path.parent().unwrap(); - IgnoreFile::from_strings(lines, root) + Self::from_strings(&lines, root) } - pub fn from_strings(strs: Vec<&str>, root: &Path) -> Result { + pub fn from_strings(strs: &[&str], root: &Path) -> Result { let mut builder = GlobSetBuilder::new(); let mut patterns = vec![]; - let parsed_patterns = IgnoreFile::parse(strs); + let parsed_patterns = Self::parse(strs); for p in parsed_patterns { let mut pat = p.pattern.clone(); if !p.anchored && !pat.starts_with("**/") { @@ -137,7 +136,7 @@ impl IgnoreFile { patterns.push(p); } - Ok(IgnoreFile { + Ok(Self { set: builder.build()?, patterns, root: root.to_owned(), @@ -172,18 +171,16 @@ impl IgnoreFile { self.root.as_os_str().len() } - fn parse(contents: Vec<&str>) -> Vec { + fn parse(contents: &[&str]) -> Vec { contents .iter() - .filter(|l| !l.is_empty()) - .filter(|l| !l.starts_with('#')) - .map(|l| Pattern::parse(l)) + .filter_map(|l| if !l.is_empty() && !l.starts_with('#') { Some(Pattern::parse(l)) } else { None }) .collect() } } impl Pattern { - fn parse(pattern: &str) -> Pattern { + fn parse(pattern: &str) -> Self { let mut normalized = String::from(pattern); let pattern_type = if normalized.starts_with('!') { @@ -208,7 +205,7 @@ impl Pattern { normalized.remove(0); } - Pattern { + Self { pattern: normalized, pattern_type, anchored, @@ -217,14 +214,14 @@ impl Pattern { } impl From for Error { - fn from(error: globset::Error) -> Error { - Error::GlobSet(error) + fn from(error: globset::Error) -> Self { + Self::GlobSet(error) } } impl From for Error { - fn from(error: io::Error) -> Error { - Error::Io(error) + fn from(error: io::Error) -> Self { + Self::Io(error) } } diff --git a/src/lib.rs b/src/lib.rs index 71e40cb..5d84373 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,18 @@ //! //! [watchexec]: https://github.com/watchexec/watchexec +#![forbid( + clippy::pedantic, + clippy::nursery, + deprecated, + intra_doc_link_resolution_failure, +// missing_docs, +// clippy::option_unwrap_used, +// clippy::result_unwrap_used, +)] +#![deny(unsafe_code, clippy::missing_const_for_fn)] +#![allow(clippy::default_trait_access, clippy::cognitive_complexity)] + #[macro_use] extern crate clap; #[macro_use] diff --git a/src/notification_filter.rs b/src/notification_filter.rs index dd9d77a..39f40ad 100644 --- a/src/notification_filter.rs +++ b/src/notification_filter.rs @@ -18,7 +18,7 @@ impl NotificationFilter { ignores: &[String], gitignore_files: Gitignore, ignore_files: Ignore, - ) -> error::Result { + ) -> error::Result { let mut filter_set_builder = GlobSetBuilder::new(); for f in filters { filter_set_builder.add(Glob::new(f)?); @@ -36,7 +36,7 @@ impl NotificationFilter { debug!("Adding ignore: \"{}\"", pattern); } - Ok(NotificationFilter { + Ok(Self { filters: filter_set_builder.build()?, filter_count: filters.len(), ignores: ignore_set_builder.build()?, diff --git a/src/pathop.rs b/src/pathop.rs index 536344e..1b36a06 100644 --- a/src/pathop.rs +++ b/src/pathop.rs @@ -10,8 +10,8 @@ pub struct PathOp { } impl PathOp { - pub fn new(path: &Path, op: Option, cookie: Option) -> PathOp { - PathOp { + pub fn new(path: &Path, op: Option, cookie: Option) -> Self { + Self { path: path.to_path_buf(), op, cookie, diff --git a/src/process.rs b/src/process.rs index 24afb97..de3b04f 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_code)] + use crate::error::Result; use crate::pathop::PathOp; use std::collections::{HashMap, HashSet}; @@ -81,9 +83,10 @@ mod imp { #[allow(clippy::mutex_atomic)] impl Process { - pub fn new(cmd: &[String], updated_paths: &[PathOp], no_shell: bool) -> Result { + pub fn new(cmd: &[String], updated_paths: &[PathOp], no_shell: bool) -> Result { use nix::unistd::*; use std::os::unix::process::CommandExt; + use std::convert::TryInto; // Assemble command to run. // This is either the first argument from cmd (if no_shell was given) or "sh". @@ -113,8 +116,8 @@ mod imp { command .spawn() .and_then(|p| { - Ok(Process { - pgid: p.id() as i32, + Ok(Self { + pgid: p.id().try_into().unwrap(), lock: Mutex::new(false), cvar: Condvar::new(), }) @@ -254,9 +257,9 @@ mod imp { let mut command; if no_shell { - let (arg0, args) = cmd.split_first().unwrap(); - command = Command::new(arg0); - command.args(args); + let (first, rest) = cmd.split_first().unwrap(); + command = Command::new(first); + command.args(rest); } else { command = Command::new("cmd.exe"); command.arg("/C"); @@ -364,11 +367,11 @@ mod imp { /// Collect `PathOp` details into op-categories to pass onto the exec'd command as env-vars /// -/// WRITTEN -> `notify::ops::WRITE`, `notify::ops::CLOSE_WRITE` -/// META_CHANGED -> `notify::ops::CHMOD` -/// REMOVED -> `notify::ops::REMOVE` -/// CREATED -> `notify::ops::CREATE` -/// RENAMED -> `notify::ops::RENAME` +/// `WRITTEN` -> `notify::ops::WRITE`, `notify::ops::CLOSE_WRITE` +/// `META_CHANGED` -> `notify::ops::CHMOD` +/// `REMOVED` -> `notify::ops::REMOVE` +/// `CREATED` -> `notify::ops::CREATE` +/// `RENAMED` -> `notify::ops::RENAME` fn collect_path_env_vars(pathops: &[PathOp]) -> Vec<(String, String)> { #[cfg(target_family = "unix")] const ENV_SEP: &str = ":"; @@ -428,7 +431,7 @@ fn collect_path_env_vars(pathops: &[PathOp]) -> Vec<(String, String)> { fn get_longest_common_path(paths: &[PathBuf]) -> Option { match paths.len() { 0 => return None, - 1 => return paths[0].to_str().map(|ref_val| ref_val.to_string()), + 1 => return paths[0].to_str().map(ToString::to_string), _ => {} }; @@ -454,7 +457,7 @@ fn get_longest_common_path(paths: &[PathBuf]) -> Option { result.push(component.as_os_str()); } - result.to_str().map(|ref_val| ref_val.to_string()) + result.to_str().map(ToString::to_string) } #[cfg(test)] diff --git a/src/signal.rs b/src/signal.rs index 297e512..efa3edc 100644 --- a/src/signal.rs +++ b/src/signal.rs @@ -1,9 +1,15 @@ use std::sync::Mutex; +type CleanupFn = Box; lazy_static! { - static ref CLEANUP: Mutex>> = Mutex::new(None); + static ref CLEANUP: Mutex> = Mutex::new(None); } +// Indicate interest in SIGCHLD by setting a dummy handler +#[cfg(unix)] +#[allow(clippy::missing_const_for_fn)] +pub extern "C" fn sigchld_handler(_: c_int) {} + #[cfg(unix)] pub use nix::sys::signal::Signal; @@ -35,15 +41,15 @@ impl ConvertToLibc for Signal { fn convert_to_libc(self) -> c_int { // Convert from signal::Signal enum to libc::* c_int constants match self { - Signal::SIGKILL => SIGKILL, - Signal::SIGTERM => SIGTERM, - Signal::SIGINT => SIGINT, - Signal::SIGHUP => SIGHUP, - Signal::SIGSTOP => SIGSTOP, - Signal::SIGCONT => SIGCONT, - Signal::SIGCHLD => SIGCHLD, - Signal::SIGUSR1 => SIGUSR1, - Signal::SIGUSR2 => SIGUSR2, + Self::SIGKILL => SIGKILL, + Self::SIGTERM => SIGTERM, + Self::SIGINT => SIGINT, + Self::SIGHUP => SIGHUP, + Self::SIGSTOP => SIGSTOP, + Self::SIGCONT => SIGCONT, + Self::SIGCHLD => SIGCHLD, + Self::SIGUSR1 => SIGUSR1, + Self::SIGUSR2 => SIGUSR2, _ => panic!("unsupported signal: {:?}", self), } } @@ -94,9 +100,7 @@ where set_handler(handler); - // Indicate interest in SIGCHLD by setting a dummy handler - pub extern "C" fn sigchld_handler(_: c_int) {} - + #[allow(unsafe_code)] unsafe { let _ = sigaction( SIGCHLD, @@ -122,6 +126,7 @@ where let default_action = SigAction::new(SigHandler::SigDfl, SaFlags::empty(), SigSet::empty()); + #[allow(unsafe_code)] unsafe { let _ = sigaction(signal, &default_action); } diff --git a/src/watcher.rs b/src/watcher.rs index 761301f..9899291 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -26,7 +26,7 @@ impl Watcher { paths: &[PathBuf], poll: bool, interval_ms: u32, - ) -> Result { + ) -> Result { use notify::Watcher; let imp = if poll { @@ -47,7 +47,7 @@ impl Watcher { WatcherImpl::Recommended(watcher) }; - Ok(self::Watcher { watcher_impl: imp }) + Ok(Self { watcher_impl: imp }) } pub fn is_polling(&self) -> bool {