diff --git a/Cargo.lock b/Cargo.lock index 49b79bda..b3b54d3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,6 +479,11 @@ dependencies = [ "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "h2" version = "0.1.26" @@ -1896,6 +1901,7 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2192,6 +2198,7 @@ dependencies = [ "checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8e190892c840661957ba9f32dacfb3eb405e657f9f9f60485605f0bb37d6f8" +"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" diff --git a/Cargo.toml b/Cargo.toml index bad3c77f..4fabaea3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ tokio-process = "0.2.3" futures = "0.1.27" openssl-probe = { version = "0.1.2", optional = true } pretty_env_logger = "0.3.0" +glob = "0.3.0" [target.'cfg(unix)'.dependencies] nix = "0.14.0" diff --git a/README.md b/README.md index 780b821d..a1928af4 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,8 @@ Here's an example for a configuration file: ``` toml git_repos = [ - "~/dev/topgrade", + "~/src/*/", + "~/.config/something" ] # Same options as the command line flag diff --git a/src/main.rs b/src/main.rs index 7c52646a..8392acb9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -242,7 +242,7 @@ fn run() -> Result<(), Error> { if config.should_run(Step::GitRepos) { if let Some(custom_git_repos) = config.git_repos() { for git_repo in custom_git_repos { - git_repos.insert(git_repo); + git_repos.glob_insert(git_repo); } } execute( diff --git a/src/steps/git.rs b/src/steps/git.rs index 624288b9..e411d683 100644 --- a/src/steps/git.rs +++ b/src/steps/git.rs @@ -1,9 +1,10 @@ -use crate::error::{Error, ErrorKind}; +puse crate::error::{Error, ErrorKind}; use crate::executor::{CommandExt, RunType}; use crate::terminal::print_separator; use crate::utils::{which, HumanizedPath}; use console::style; use futures::future::{join_all, Future}; +use glob::{glob_with, MatchOptions}; use log::{debug, error}; use std::collections::HashSet; use std::io; @@ -17,10 +18,10 @@ pub struct Git { git: Option, } -#[derive(Debug)] pub struct Repositories<'a> { git: &'a Git, repositories: HashSet, + glob_match_options: MatchOptions, } fn get_head_revision(git: &Path, repo: &str) -> Option { @@ -162,9 +163,16 @@ impl Git { impl<'a> Repositories<'a> { pub fn new(git: &'a Git) -> Self { + let mut glob_match_options = MatchOptions::new(); + + if cfg!(windows) { + glob_match_options.case_sensitive = false; + } + Self { git, repositories: HashSet::new(), + glob_match_options, } } @@ -173,4 +181,19 @@ impl<'a> Repositories<'a> { self.repositories.insert(repo); } } + + pub fn glob_insert(&mut self, pattern: &str) { + if let Ok(glob) = glob_with(pattern, self.glob_match_options) { + for entry in glob { + match entry { + Ok(path) => self.insert(path), + Err(e) => { + error!("Error in path {}", e); + } + } + } + } else { + error!("Bad glob pattern: {}", pattern); + } + } }