Move common_prefix to its own mod

This commit is contained in:
Félix Saparelli 2021-10-16 13:55:20 +13:00
parent e577b040b9
commit 083c1e2f52
6 changed files with 56 additions and 63 deletions

View File

@ -6,13 +6,13 @@ use std::{
use clap::ArgMatches; use clap::ArgMatches;
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use watchexec::{ use watchexec::{
action::{Action, Outcome, Signal}, action::{Action, Outcome},
command::Shell, command::Shell,
config::{InitConfig, RuntimeConfig}, config::{InitConfig, RuntimeConfig},
filter::tagged::TaggedFilterer, filter::tagged::TaggedFilterer,
fs::Watcher, fs::Watcher,
handler::PrintDisplay, handler::PrintDisplay,
signal::source::MainSignal, signal::{process::SubSignal, source::MainSignal},
}; };
pub fn new(args: &ArgMatches<'static>) -> Result<(InitConfig, RuntimeConfig, Arc<TaggedFilterer>)> { pub fn new(args: &ArgMatches<'static>) -> Result<(InitConfig, RuntimeConfig, Arc<TaggedFilterer>)> {
@ -85,13 +85,13 @@ fn runtime(args: &ArgMatches<'static>) -> Result<(RuntimeConfig, Arc<TaggedFilte
let mut signal = args let mut signal = args
.value_of("signal") .value_of("signal")
.map(|s| Signal::from_str(s)) .map(|s| SubSignal::from_str(s))
.transpose() .transpose()
.into_diagnostic()? .into_diagnostic()?
.unwrap_or(Signal::SIGTERM); .unwrap_or(SubSignal::Terminate);
if args.is_present("kill") { if args.is_present("kill") {
signal = Signal::SIGKILL; signal = SubSignal::ForceStop;
} }
let print_events = args.is_present("print-events"); let print_events = args.is_present("print-events");
@ -136,17 +136,7 @@ fn runtime(args: &ArgMatches<'static>) -> Result<(RuntimeConfig, Arc<TaggedFilte
if !signals.is_empty() { if !signals.is_empty() {
let mut out = Outcome::DoNothing; let mut out = Outcome::DoNothing;
for sig in signals { for sig in signals {
out = Outcome::both( out = Outcome::both(out, Outcome::Signal(sig.into()));
out,
Outcome::Signal(match sig {
MainSignal::Hangup => Signal::SIGHUP,
MainSignal::Interrupt => Signal::SIGINT,
MainSignal::Quit => Signal::SIGQUIT,
MainSignal::Terminate => Signal::SIGTERM,
MainSignal::User1 => Signal::SIGUSR1,
MainSignal::User2 => Signal::SIGUSR2,
}),
);
} }
action.outcome(out); action.outcome(out);

View File

@ -11,6 +11,7 @@ use watchexec::{
event::Event, event::Event,
filter::tagged::{Filter, Matcher, Op, Pattern, Regex}, filter::tagged::{Filter, Matcher, Op, Pattern, Regex},
ignore_files::{self, IgnoreFile}, ignore_files::{self, IgnoreFile},
paths::common_prefix,
project::{self, ProjectType}, project::{self, ProjectType},
Watchexec, Watchexec,
}; };
@ -51,7 +52,7 @@ async fn main() -> Result<()> {
debug!(?origins, "resolved all project origins"); debug!(?origins, "resolved all project origins");
let project_origin = project::common_prefix(&origins).unwrap_or_else(|| PathBuf::from(".")); let project_origin = common_prefix(&origins).unwrap_or_else(|| PathBuf::from("."));
debug!(?project_origin, "resolved common/project origin"); debug!(?project_origin, "resolved common/project origin");
let vcs_types = project::types(&project_origin) let vcs_types = project::types(&project_origin)

View File

@ -11,8 +11,6 @@ use tokio::{
sync::{Mutex, OwnedMutexGuard}, sync::{Mutex, OwnedMutexGuard},
}; };
pub use command_group::Signal;
use crate::{command::Shell, event::Event, filter::Filterer, handler::Handler}; use crate::{command::Shell, event::Event, filter::Filterer, handler::Handler};
use super::Outcome; use super::Outcome;

View File

@ -93,6 +93,7 @@ pub mod event;
pub mod filter; pub mod filter;
pub mod fs; pub mod fs;
pub mod ignore_files; pub mod ignore_files;
pub mod paths;
pub mod project; pub mod project;
pub mod signal; pub mod signal;

47
lib/src/paths.rs Normal file
View File

@ -0,0 +1,47 @@
//! Utilities for paths and sets of paths.
use std::path::{Path, PathBuf};
/// Returns the longest common prefix of all given paths.
///
/// This is a utility function which is useful for finding the common root of a set of origins.
///
/// Returns `None` if zero paths are given or paths share no common prefix.
pub fn common_prefix<I, P>(paths: I) -> Option<PathBuf>
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
let mut paths = paths.into_iter();
let first_path = paths.next().map(|p| p.as_ref().to_owned());
let mut longest_path = if let Some(ref p) = first_path {
p.components().collect::<Vec<_>>()
} else {
return None;
};
for path in paths {
let mut greatest_distance = 0;
for component_pair in path.as_ref().components().zip(longest_path.iter()) {
if component_pair.0 != *component_pair.1 {
break;
}
greatest_distance += 1;
}
if greatest_distance != longest_path.len() {
longest_path.truncate(greatest_distance);
}
}
if longest_path.is_empty() {
None
} else {
let mut result = PathBuf::new();
for component in longest_path {
result.push(component.as_os_str());
}
Some(result)
}
}

View File

@ -190,50 +190,6 @@ pub async fn types(path: impl AsRef<Path>) -> HashSet<ProjectType> {
.collect() .collect()
} }
/// Returns the longest common prefix of all given paths.
///
/// This is a utility function which is useful for finding the common root of a set of origins.
///
/// Returns `None` if zero paths are given or paths share no common prefix.
pub fn common_prefix<I, P>(paths: I) -> Option<PathBuf>
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
let mut paths = paths.into_iter();
let first_path = paths.next().map(|p| p.as_ref().to_owned());
let mut longest_path = if let Some(ref p) = first_path {
p.components().collect::<Vec<_>>()
} else {
return None;
};
for path in paths {
let mut greatest_distance = 0;
for component_pair in path.as_ref().components().zip(longest_path.iter()) {
if component_pair.0 != *component_pair.1 {
break;
}
greatest_distance += 1;
}
if greatest_distance != longest_path.len() {
longest_path.truncate(greatest_distance);
}
}
if longest_path.is_empty() {
None
} else {
let mut result = PathBuf::new();
for component in longest_path {
result.push(component.as_os_str());
}
Some(result)
}
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct DirList(HashMap<PathBuf, FileType>); struct DirList(HashMap<PathBuf, FileType>);
impl DirList { impl DirList {