Skip to content

Commit

Permalink
feat(tasks): unify glob strategy for tasks and dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajpantuso committed Jan 26, 2024
1 parent 7b3ae2e commit 8a84b5b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 34 deletions.
24 changes: 1 addition & 23 deletions src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use console::Color;
use demand::{DemandOption, Select};
use duct::IntoExecutablePath;
use eyre::Result;
use globset::Glob;
use globwalk::GlobWalkerBuilder;
use itertools::Itertools;
use once_cell::sync::Lazy;
Expand All @@ -23,7 +22,7 @@ use crate::config::{Config, Settings};
use crate::errors::Error;
use crate::errors::Error::ScriptFailed;
use crate::file::display_path;
use crate::task::{Deps, Task};
use crate::task::{Deps, GetMatchingExt, Task};
use crate::toolset::{InstallOptions, ToolsetBuilder};
use crate::ui::ctrlc;
use crate::ui::style;
Expand Down Expand Up @@ -532,27 +531,6 @@ fn get_color() -> Color {
static COLOR_IDX: AtomicUsize = AtomicUsize::new(0);
COLORS[COLOR_IDX.fetch_add(1, Ordering::Relaxed) % COLORS.len()]
}
trait GetMatchingExt<T> {
fn get_matching(&self, pat: &str) -> Result<Vec<&T>>;
}

impl<T> GetMatchingExt<T> for std::collections::HashMap<String, T> {
fn get_matching(&self, pat: &str) -> Result<Vec<&T>> {
let normalized = pat.split(':').collect::<PathBuf>();
let matcher = Glob::new(&normalized.to_string_lossy())?.compile_matcher();

Ok(self
.keys()
.filter(|k| {
let p: PathBuf = k.split(':').collect();

matcher.is_match(p)
})
.flat_map(|k| self.get(k))
.collect())
}
}

#[cfg(test)]
mod tests {
use crate::file;
Expand Down
47 changes: 36 additions & 11 deletions src/task.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use globset::Glob;
use petgraph::graph::DiGraph;
use petgraph::prelude::*;
use petgraph::{Direction, Graph};
Expand Down Expand Up @@ -134,17 +135,7 @@ impl Task {
let depends = self
.depends
.iter()
.map(|name| match name.strip_suffix('*') {
Some(prefix) => Ok(tasks
.values()
.unique()
.filter(|t| *t != self && t.name.starts_with(prefix))
.collect::<Vec<_>>()),
None => tasks
.get(name)
.map(|task| vec![task])
.ok_or_else(|| eyre!("task not found: {name}")),
})
.map(|pat| match_tasks(tasks, pat))
.collect::<Result<Vec<_>>>()?
.into_iter()
.flatten()
Expand All @@ -169,6 +160,15 @@ fn name_from_path(root: impl AsRef<Path>, path: impl AsRef<Path>) -> Result<Stri
.join(":"))
}

fn match_tasks<'a>(tasks: &'a HashMap<String, Task>, pat: &str) -> Result<Vec<&'a Task>> {
let matches = tasks.get_matching(pat)?;
if matches.is_empty() {
return Err(eyre!("task not found: {pat}"));
};

Ok(matches)
}

impl Display for Task {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if let Some(cmd) = self.command_string() {
Expand Down Expand Up @@ -368,3 +368,28 @@ mod tests {
}
}
}

pub trait GetMatchingExt<T> {
fn get_matching(&self, pat: &str) -> Result<Vec<&T>>;
}

impl<T> GetMatchingExt<T> for std::collections::HashMap<String, T>
where
T: std::cmp::Eq + std::hash::Hash,
{
fn get_matching(&self, pat: &str) -> Result<Vec<&T>> {
let normalized = pat.split(':').collect::<PathBuf>();
let matcher = Glob::new(&normalized.to_string_lossy())?.compile_matcher();

Ok(self
.iter()
.filter(|(k, _)| {
let p: PathBuf = k.split(':').collect();

matcher.is_match(p)
})
.map(|(_, t)| t)
.unique()
.collect())
}
}

0 comments on commit 8a84b5b

Please sign in to comment.