Forbid a whole lot more clippy stuff

This commit is contained in:
Félix Saparelli 2019-10-28 00:06:09 +13:00
parent b842c149b6
commit d47419e385
No known key found for this signature in database
GPG Key ID: 25940898BB90EA51
10 changed files with 105 additions and 90 deletions

View File

@ -218,8 +218,8 @@ where
for exts in extensions { for exts in extensions {
filters.extend( filters.extend(
exts.split(',') exts.split(',')
.filter(|ext| !ext.is_empty()) .filter_map(|ext| if ext.is_empty() { None } else {
.map(|ext| format!("*.{}", ext.replace(".", ""))), Some(format!("*.{}", ext.replace(".", ""))) }),
); );
} }
} }

View File

@ -21,48 +21,48 @@ impl StdError for Error {
impl From<clap::Error> for Error { impl From<clap::Error> for Error {
fn from(err: clap::Error) -> Self { fn from(err: clap::Error) -> Self {
Error::Clap(err) Self::Clap(err)
} }
} }
impl From<globset::Error> for Error { impl From<globset::Error> for Error {
fn from(err: globset::Error) -> Self { fn from(err: globset::Error) -> Self {
Error::Glob(err) Self::Glob(err)
} }
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(err: io::Error) -> Self { fn from(err: io::Error) -> Self {
Error::Io(err) Self::Io(err)
} }
} }
impl From<notify::Error> for Error { impl From<notify::Error> for Error {
fn from(err: notify::Error) -> Self { fn from(err: notify::Error) -> Self {
match err { match err {
notify::Error::Io(err) => Error::Io(err), notify::Error::Io(err) => Self::Io(err),
other => Error::Notify(other), other => Self::Notify(other),
} }
} }
} }
impl<'a, T> From<PoisonError<T>> for Error { impl<'a, T> From<PoisonError<T>> for Error {
fn from(_err: PoisonError<T>) -> Self { fn from(_err: PoisonError<T>) -> Self {
Error::PoisonedLock Self::PoisonedLock
} }
} }
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (error_type, error) = match self { let (error_type, error) = match self {
Error::Canonicalization(path, err) => { Self::Canonicalization(path, err) => {
("Path", format!("couldn't canonicalize '{}':\n{}", path, err)) ("Path", format!("couldn't canonicalize '{}':\n{}", path, err))
} }
Error::Clap(err) => ("Argument", err.to_string()), Self::Clap(err) => ("Argument", err.to_string()),
Error::Glob(err) => ("Globset", err.to_string()), Self::Glob(err) => ("Globset", err.to_string()),
Error::Io(err) => ("I/O", err.to_string()), Self::Io(err) => ("I/O", err.to_string()),
Error::Notify(err) => ("Notify", err.to_string()), Self::Notify(err) => ("Notify", err.to_string()),
Error::PoisonedLock => ("Internal", "poisoned lock".to_string()), Self::PoisonedLock => ("Internal", "poisoned lock".to_string()),
}; };
write!(f, "{} error: {}", error_type, error) write!(f, "{} error: {}", error_type, error)

View File

@ -54,12 +54,11 @@ pub fn load(paths: &[PathBuf]) -> Gitignore {
let gitignore_path = p.join(".gitignore"); let gitignore_path = p.join(".gitignore");
if gitignore_path.exists() { if gitignore_path.exists() {
match GitignoreFile::new(&gitignore_path) { if let Ok(f) = GitignoreFile::new(&gitignore_path) {
Ok(f) => {
debug!("Loaded {:?}", gitignore_path); debug!("Loaded {:?}", gitignore_path);
files.push(f); files.push(f);
} } else {
Err(_) => debug!("Unable to load {:?}", gitignore_path), debug!("Unable to load {:?}", gitignore_path);
} }
} }
} }
@ -83,8 +82,8 @@ pub fn load(paths: &[PathBuf]) -> Gitignore {
} }
impl Gitignore { impl Gitignore {
fn new(files: Vec<GitignoreFile>) -> Gitignore { const fn new(files: Vec<GitignoreFile>) -> Self{
Gitignore { files } Self{ files }
} }
pub fn is_excluded(&self, path: &Path) -> bool { pub fn is_excluded(&self, path: &Path) -> bool {
@ -112,22 +111,22 @@ impl Gitignore {
} }
impl GitignoreFile { impl GitignoreFile {
pub fn new(path: &Path) -> Result<GitignoreFile, Error> { pub fn new(path: &Path) -> Result<Self, Error> {
let mut file = fs::File::open(path)?; let mut file = fs::File::open(path)?;
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents)?; file.read_to_string(&mut contents)?;
let lines = contents.lines().collect(); let lines: Vec<_> = contents.lines().collect();
let root = path.parent().unwrap(); 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<GitignoreFile, Error> { pub fn from_strings(strs: &[&str], root: &Path) -> Result<Self, Error> {
let mut builder = GlobSetBuilder::new(); let mut builder = GlobSetBuilder::new();
let mut patterns = vec![]; let mut patterns = vec![];
let parsed_patterns = GitignoreFile::parse(strs); let parsed_patterns = Self::parse(strs);
for p in parsed_patterns { for p in parsed_patterns {
let mut pat = p.pattern.clone(); let mut pat = p.pattern.clone();
if !p.anchored && !pat.starts_with("**/") { if !p.anchored && !pat.starts_with("**/") {
@ -144,7 +143,7 @@ impl GitignoreFile {
patterns.push(p); patterns.push(p);
} }
Ok(GitignoreFile { Ok(Self{
set: builder.build()?, set: builder.build()?,
patterns, patterns,
root: root.to_owned(), root: root.to_owned(),
@ -179,18 +178,17 @@ impl GitignoreFile {
self.root.as_os_str().len() self.root.as_os_str().len()
} }
fn parse(contents: Vec<&str>) -> Vec<Pattern> { fn parse(contents: &[&str]) -> Vec<Pattern> {
contents contents
.iter() .iter()
.filter(|l| !l.is_empty()) .filter_map(|l| if !l.is_empty() && !l.starts_with('#') {
.filter(|l| !l.starts_with('#')) Some(Pattern::parse(l)) } else { None })
.map(|l| Pattern::parse(l))
.collect() .collect()
} }
} }
impl Pattern { impl Pattern {
fn parse(pattern: &str) -> Pattern { fn parse(pattern: &str) -> Self{
let mut normalized = String::from(pattern); let mut normalized = String::from(pattern);
let pattern_type = if normalized.starts_with('!') { let pattern_type = if normalized.starts_with('!') {
@ -215,7 +213,7 @@ impl Pattern {
normalized.remove(0); normalized.remove(0);
} }
Pattern { Self{
pattern: normalized, pattern: normalized,
pattern_type, pattern_type,
anchored, anchored,
@ -224,14 +222,14 @@ impl Pattern {
} }
impl From<globset::Error> for Error { impl From<globset::Error> for Error {
fn from(error: globset::Error) -> Error { fn from(error: globset::Error) -> Self{
Error::GlobSet(error) Self::GlobSet(error)
} }
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(error: io::Error) -> Error { fn from(error: io::Error) -> Self{
Error::Io(error) Self::Io(error)
} }
} }

View File

@ -54,12 +54,11 @@ pub fn load(paths: &[PathBuf]) -> Ignore {
let ignore_path = p.join(".ignore"); let ignore_path = p.join(".ignore");
if ignore_path.exists() { if ignore_path.exists() {
match IgnoreFile::new(&ignore_path) { if let Ok(f) = IgnoreFile::new(&ignore_path) {
Ok(f) => {
debug!("Loaded {:?}", ignore_path); debug!("Loaded {:?}", ignore_path);
files.push(f); files.push(f);
} } else {
Err(_) => debug!("Unable to load {:?}", ignore_path), debug!("Unable to load {:?}", ignore_path);
} }
} }
} }
@ -76,8 +75,8 @@ pub fn load(paths: &[PathBuf]) -> Ignore {
} }
impl Ignore { impl Ignore {
fn new(files: Vec<IgnoreFile>) -> Ignore { const fn new(files: Vec<IgnoreFile>) -> Self {
Ignore { files } Self { files }
} }
pub fn is_excluded(&self, path: &Path) -> bool { pub fn is_excluded(&self, path: &Path) -> bool {
@ -105,22 +104,22 @@ impl Ignore {
} }
impl IgnoreFile { impl IgnoreFile {
pub fn new(path: &Path) -> Result<IgnoreFile, Error> { pub fn new(path: &Path) -> Result<Self, Error> {
let mut file = fs::File::open(path)?; let mut file = fs::File::open(path)?;
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents)?; file.read_to_string(&mut contents)?;
let lines = contents.lines().collect(); let lines: Vec<_> = contents.lines().collect();
let root = path.parent().unwrap(); 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<IgnoreFile, Error> { pub fn from_strings(strs: &[&str], root: &Path) -> Result<Self, Error> {
let mut builder = GlobSetBuilder::new(); let mut builder = GlobSetBuilder::new();
let mut patterns = vec![]; let mut patterns = vec![];
let parsed_patterns = IgnoreFile::parse(strs); let parsed_patterns = Self::parse(strs);
for p in parsed_patterns { for p in parsed_patterns {
let mut pat = p.pattern.clone(); let mut pat = p.pattern.clone();
if !p.anchored && !pat.starts_with("**/") { if !p.anchored && !pat.starts_with("**/") {
@ -137,7 +136,7 @@ impl IgnoreFile {
patterns.push(p); patterns.push(p);
} }
Ok(IgnoreFile { Ok(Self {
set: builder.build()?, set: builder.build()?,
patterns, patterns,
root: root.to_owned(), root: root.to_owned(),
@ -172,18 +171,16 @@ impl IgnoreFile {
self.root.as_os_str().len() self.root.as_os_str().len()
} }
fn parse(contents: Vec<&str>) -> Vec<Pattern> { fn parse(contents: &[&str]) -> Vec<Pattern> {
contents contents
.iter() .iter()
.filter(|l| !l.is_empty()) .filter_map(|l| if !l.is_empty() && !l.starts_with('#') { Some(Pattern::parse(l)) } else { None })
.filter(|l| !l.starts_with('#'))
.map(|l| Pattern::parse(l))
.collect() .collect()
} }
} }
impl Pattern { impl Pattern {
fn parse(pattern: &str) -> Pattern { fn parse(pattern: &str) -> Self {
let mut normalized = String::from(pattern); let mut normalized = String::from(pattern);
let pattern_type = if normalized.starts_with('!') { let pattern_type = if normalized.starts_with('!') {
@ -208,7 +205,7 @@ impl Pattern {
normalized.remove(0); normalized.remove(0);
} }
Pattern { Self {
pattern: normalized, pattern: normalized,
pattern_type, pattern_type,
anchored, anchored,
@ -217,14 +214,14 @@ impl Pattern {
} }
impl From<globset::Error> for Error { impl From<globset::Error> for Error {
fn from(error: globset::Error) -> Error { fn from(error: globset::Error) -> Self {
Error::GlobSet(error) Self::GlobSet(error)
} }
} }
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(error: io::Error) -> Error { fn from(error: io::Error) -> Self {
Error::Io(error) Self::Io(error)
} }
} }

View File

@ -9,6 +9,18 @@
//! //!
//! [watchexec]: https://github.com/watchexec/watchexec //! [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] #[macro_use]
extern crate clap; extern crate clap;
#[macro_use] #[macro_use]

View File

@ -18,7 +18,7 @@ impl NotificationFilter {
ignores: &[String], ignores: &[String],
gitignore_files: Gitignore, gitignore_files: Gitignore,
ignore_files: Ignore, ignore_files: Ignore,
) -> error::Result<NotificationFilter> { ) -> error::Result<Self> {
let mut filter_set_builder = GlobSetBuilder::new(); let mut filter_set_builder = GlobSetBuilder::new();
for f in filters { for f in filters {
filter_set_builder.add(Glob::new(f)?); filter_set_builder.add(Glob::new(f)?);
@ -36,7 +36,7 @@ impl NotificationFilter {
debug!("Adding ignore: \"{}\"", pattern); debug!("Adding ignore: \"{}\"", pattern);
} }
Ok(NotificationFilter { Ok(Self {
filters: filter_set_builder.build()?, filters: filter_set_builder.build()?,
filter_count: filters.len(), filter_count: filters.len(),
ignores: ignore_set_builder.build()?, ignores: ignore_set_builder.build()?,

View File

@ -10,8 +10,8 @@ pub struct PathOp {
} }
impl PathOp { impl PathOp {
pub fn new(path: &Path, op: Option<op::Op>, cookie: Option<u32>) -> PathOp { pub fn new(path: &Path, op: Option<op::Op>, cookie: Option<u32>) -> Self {
PathOp { Self {
path: path.to_path_buf(), path: path.to_path_buf(),
op, op,
cookie, cookie,

View File

@ -1,3 +1,5 @@
#![allow(unsafe_code)]
use crate::error::Result; use crate::error::Result;
use crate::pathop::PathOp; use crate::pathop::PathOp;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -81,9 +83,10 @@ mod imp {
#[allow(clippy::mutex_atomic)] #[allow(clippy::mutex_atomic)]
impl Process { impl Process {
pub fn new(cmd: &[String], updated_paths: &[PathOp], no_shell: bool) -> Result<Process> { pub fn new(cmd: &[String], updated_paths: &[PathOp], no_shell: bool) -> Result<Self> {
use nix::unistd::*; use nix::unistd::*;
use std::os::unix::process::CommandExt; use std::os::unix::process::CommandExt;
use std::convert::TryInto;
// Assemble command to run. // Assemble command to run.
// This is either the first argument from cmd (if no_shell was given) or "sh". // This is either the first argument from cmd (if no_shell was given) or "sh".
@ -113,8 +116,8 @@ mod imp {
command command
.spawn() .spawn()
.and_then(|p| { .and_then(|p| {
Ok(Process { Ok(Self {
pgid: p.id() as i32, pgid: p.id().try_into().unwrap(),
lock: Mutex::new(false), lock: Mutex::new(false),
cvar: Condvar::new(), cvar: Condvar::new(),
}) })
@ -254,9 +257,9 @@ mod imp {
let mut command; let mut command;
if no_shell { if no_shell {
let (arg0, args) = cmd.split_first().unwrap(); let (first, rest) = cmd.split_first().unwrap();
command = Command::new(arg0); command = Command::new(first);
command.args(args); command.args(rest);
} else { } else {
command = Command::new("cmd.exe"); command = Command::new("cmd.exe");
command.arg("/C"); 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 /// Collect `PathOp` details into op-categories to pass onto the exec'd command as env-vars
/// ///
/// WRITTEN -> `notify::ops::WRITE`, `notify::ops::CLOSE_WRITE` /// `WRITTEN` -> `notify::ops::WRITE`, `notify::ops::CLOSE_WRITE`
/// META_CHANGED -> `notify::ops::CHMOD` /// `META_CHANGED` -> `notify::ops::CHMOD`
/// REMOVED -> `notify::ops::REMOVE` /// `REMOVED` -> `notify::ops::REMOVE`
/// CREATED -> `notify::ops::CREATE` /// `CREATED` -> `notify::ops::CREATE`
/// RENAMED -> `notify::ops::RENAME` /// `RENAMED` -> `notify::ops::RENAME`
fn collect_path_env_vars(pathops: &[PathOp]) -> Vec<(String, String)> { fn collect_path_env_vars(pathops: &[PathOp]) -> Vec<(String, String)> {
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
const ENV_SEP: &str = ":"; 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<String> { fn get_longest_common_path(paths: &[PathBuf]) -> Option<String> {
match paths.len() { match paths.len() {
0 => return None, 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<String> {
result.push(component.as_os_str()); 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)] #[cfg(test)]

View File

@ -1,9 +1,15 @@
use std::sync::Mutex; use std::sync::Mutex;
type CleanupFn = Box<dyn Fn(self::Signal) + Send>;
lazy_static! { lazy_static! {
static ref CLEANUP: Mutex<Option<Box<dyn Fn(self::Signal) + Send>>> = Mutex::new(None); static ref CLEANUP: Mutex<Option<CleanupFn>> = 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)] #[cfg(unix)]
pub use nix::sys::signal::Signal; pub use nix::sys::signal::Signal;
@ -35,15 +41,15 @@ impl ConvertToLibc for Signal {
fn convert_to_libc(self) -> c_int { fn convert_to_libc(self) -> c_int {
// Convert from signal::Signal enum to libc::* c_int constants // Convert from signal::Signal enum to libc::* c_int constants
match self { match self {
Signal::SIGKILL => SIGKILL, Self::SIGKILL => SIGKILL,
Signal::SIGTERM => SIGTERM, Self::SIGTERM => SIGTERM,
Signal::SIGINT => SIGINT, Self::SIGINT => SIGINT,
Signal::SIGHUP => SIGHUP, Self::SIGHUP => SIGHUP,
Signal::SIGSTOP => SIGSTOP, Self::SIGSTOP => SIGSTOP,
Signal::SIGCONT => SIGCONT, Self::SIGCONT => SIGCONT,
Signal::SIGCHLD => SIGCHLD, Self::SIGCHLD => SIGCHLD,
Signal::SIGUSR1 => SIGUSR1, Self::SIGUSR1 => SIGUSR1,
Signal::SIGUSR2 => SIGUSR2, Self::SIGUSR2 => SIGUSR2,
_ => panic!("unsupported signal: {:?}", self), _ => panic!("unsupported signal: {:?}", self),
} }
} }
@ -94,9 +100,7 @@ where
set_handler(handler); set_handler(handler);
// Indicate interest in SIGCHLD by setting a dummy handler #[allow(unsafe_code)]
pub extern "C" fn sigchld_handler(_: c_int) {}
unsafe { unsafe {
let _ = sigaction( let _ = sigaction(
SIGCHLD, SIGCHLD,
@ -122,6 +126,7 @@ where
let default_action = let default_action =
SigAction::new(SigHandler::SigDfl, SaFlags::empty(), SigSet::empty()); SigAction::new(SigHandler::SigDfl, SaFlags::empty(), SigSet::empty());
#[allow(unsafe_code)]
unsafe { unsafe {
let _ = sigaction(signal, &default_action); let _ = sigaction(signal, &default_action);
} }

View File

@ -26,7 +26,7 @@ impl Watcher {
paths: &[PathBuf], paths: &[PathBuf],
poll: bool, poll: bool,
interval_ms: u32, interval_ms: u32,
) -> Result<Watcher, Error> { ) -> Result<Self, Error> {
use notify::Watcher; use notify::Watcher;
let imp = if poll { let imp = if poll {
@ -47,7 +47,7 @@ impl Watcher {
WatcherImpl::Recommended(watcher) WatcherImpl::Recommended(watcher)
}; };
Ok(self::Watcher { watcher_impl: imp }) Ok(Self { watcher_impl: imp })
} }
pub fn is_polling(&self) -> bool { pub fn is_polling(&self) -> bool {