Skip to content

Commit

Permalink
Switch to globwalk package over glob
Browse files Browse the repository at this point in the history
This means that gitignores extended glob syntax is now available in all
locations where globs are allowed. For example the following plugin
would not have been allowed previously.

```toml
[plugins.ohmyzsh]
github = "ohmyzsh/ohmyzsh"
dir = "lib"
use = ["{!git,!nvm,*}.zsh]
```
  • Loading branch information
rossmacarthur committed Aug 12, 2020
1 parent 02484e8 commit a972c35
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 35 deletions.
53 changes: 49 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -20,7 +20,7 @@ anyhow = "1.0.32"
casual = "0.1.2"
fs2 = "0.4.3"
git2 = "0.13.8"
glob = "0.3.0"
globwalk = "0.8.0"
handlebars = "3.3.0"
home = "0.5.3"
indexmap = { version = "1.5.0", features = ["serde-1", "rayon"] }
Expand Down
52 changes: 22 additions & 30 deletions src/lock.rs
Expand Up @@ -290,15 +290,14 @@ impl Source {
fn lock_local(ctx: &Context, dir: PathBuf) -> Result<LockedSource> {
let dir = ctx.expand_tilde(dir);

if let Ok(glob) = glob::glob(&dir.to_string_lossy()) {
let mut directories: Vec<_> = glob
.filter_map(|result| {
if let Ok(dir) = result {
if dir.is_dir() {
return Some(dir);
}
}
None
if dir.exists() && dir.is_dir() {
status!(ctx, "Checked", dir.as_path());
Ok(LockedSource { dir, file: None })
} else if let Ok(walker) = globwalk::glob(dir.to_string_lossy()) {
let mut directories: Vec<_> = walker
.filter_map(|result| match result {
Ok(entry) if entry.path().is_dir() => Some(entry.into_path()),
_ => None,
})
.collect();

Expand All @@ -313,12 +312,6 @@ impl Source {
directories.len()
))
}
} else if fs::metadata(&dir)
.with_context(s!("failed to find dir `{}`", dir.display()))?
.is_dir()
{
status!(ctx, "Checked", dir.as_path());
Ok(LockedSource { dir, file: None })
} else {
Err(anyhow!("`{}` is not a dir", dir.display()))
}
Expand Down Expand Up @@ -360,19 +353,20 @@ impl Source {
}

impl ExternalPlugin {
fn match_globs(pattern: PathBuf, files: &mut Vec<PathBuf>) -> Result<bool> {
fn match_globs(dir: &Path, pattern: &str, files: &mut Vec<PathBuf>) -> Result<bool> {
let mut matched = false;
let pattern = pattern.to_string_lossy();
let paths: glob::Paths =
glob::glob(&pattern).with_context(s!("failed to parse glob pattern `{}`", &pattern))?;

for path in paths {
for entry in globwalk::GlobWalkerBuilder::new(dir, &pattern)
.sort_by(|a, b| a.file_name().cmp(b.file_name()))
.build()
.with_context(s!("failed to parse glob pattern `{}`", pattern))?
{
files.push(
path.with_context(s!("failed to read path matched by pattern `{}`", &pattern))?,
entry
.with_context(s!("failed to read path matched by pattern `{}`", &pattern))?
.into_path(),
);
matched = true;
}

Ok(matched)
}

Expand Down Expand Up @@ -428,22 +422,20 @@ impl ExternalPlugin {
// If the plugin defined what files to use, we do all of them.
if let Some(uses) = &self.uses {
for u in uses {
let rendered = templates
let pattern = templates
.render_template(u, &data)
.with_context(s!("failed to render template `{}`", u))?;
let pattern = dir.join(&rendered);
if !Self::match_globs(pattern, &mut files)? {
bail!("failed to find any files matching `{}`", &rendered);
if !Self::match_globs(dir, &pattern, &mut files)? {
bail!("failed to find any files matching `{}`", &pattern);
};
}
// Otherwise we try to figure out which files to use...
} else {
for g in matches {
let rendered = templates
let pattern = templates
.render_template(g, &data)
.with_context(s!("failed to render template `{}`", g))?;
let pattern = dir.join(rendered);
if Self::match_globs(pattern, &mut files)? {
if Self::match_globs(dir, &pattern, &mut files)? {
break;
}
}
Expand Down

0 comments on commit a972c35

Please sign in to comment.