Skip to content

Commit

Permalink
feat(run): match tasks to run with glob patterns (#1528)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajpantuso authored Jan 26, 2024
1 parent a4b6418 commit 7b3ae2e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ eyre = "0.6.11"
filetime = "0.2.23"
flate2 = "1.0.28"
fslock = "0.2.1"
globset = "0.4.14"
globwalk = "0.9.1"
home = "0.5.9"
humantime = "2.1.0"
Expand Down
39 changes: 35 additions & 4 deletions src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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 Down Expand Up @@ -134,11 +135,21 @@ impl Run {
}
})
.flat_map(|args| args.split_first().map(|(t, a)| (t.clone(), a.to_vec())))
.map(|(t, args)| match config.tasks_with_aliases().get(&t) {
Some(task) => Ok(task.clone().with_args(args.to_vec())),
None if t == "default" => self.prompt_for_task(config),
None => bail!("no task {} found", style::ered(t)),
.map(|(t, args)| {
let tasks = config.tasks_with_aliases().get_matching(&t)?;
if tasks.is_empty() {
ensure!(t == "default", "no task {} found", style::ered(t));

Ok(vec![self.prompt_for_task(config)?])
} else {
Ok(tasks
.iter()
.cloned()
.map(|t| t.clone().with_args(args.to_vec()))
.collect())
}
})
.flatten_ok()
.collect()
}

Expand Down Expand Up @@ -521,6 +532,26 @@ 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 {
Expand Down

0 comments on commit 7b3ae2e

Please sign in to comment.