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 miette::{IntoDiagnostic, Result};
use watchexec::{
action::{Action, Outcome, Signal},
action::{Action, Outcome},
command::Shell,
config::{InitConfig, RuntimeConfig},
filter::tagged::TaggedFilterer,
fs::Watcher,
handler::PrintDisplay,
signal::source::MainSignal,
signal::{process::SubSignal, source::MainSignal},
};
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
.value_of("signal")
.map(|s| Signal::from_str(s))
.map(|s| SubSignal::from_str(s))
.transpose()
.into_diagnostic()?
.unwrap_or(Signal::SIGTERM);
.unwrap_or(SubSignal::Terminate);
if args.is_present("kill") {
signal = Signal::SIGKILL;
signal = SubSignal::ForceStop;
}
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() {
let mut out = Outcome::DoNothing;
for sig in signals {
out = Outcome::both(
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,
}),
);
out = Outcome::both(out, Outcome::Signal(sig.into()));
}
action.outcome(out);

View File

@ -11,6 +11,7 @@ use watchexec::{
event::Event,
filter::tagged::{Filter, Matcher, Op, Pattern, Regex},
ignore_files::{self, IgnoreFile},
paths::common_prefix,
project::{self, ProjectType},
Watchexec,
};
@ -51,7 +52,7 @@ async fn main() -> Result<()> {
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");
let vcs_types = project::types(&project_origin)

View File

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

View File

@ -93,6 +93,7 @@ pub mod event;
pub mod filter;
pub mod fs;
pub mod ignore_files;
pub mod paths;
pub mod project;
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()
}
/// 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)]
struct DirList(HashMap<PathBuf, FileType>);
impl DirList {