@@ -290,15 +290,14 @@ impl Source {
290290 fn lock_local(ctx: &Context, dir: PathBuf) -> Result<LockedSource> {
291291let dir = ctx.expand_tilde(dir);
292292293-if let Ok(glob) = glob::glob(&dir.to_string_lossy()) {
294-let mut directories: Vec<_> = glob
295-.filter_map(|result| {
296-if let Ok(dir) = result {
297-if dir.is_dir() {
298-return Some(dir);
299-}
300-}
301-None
293+if dir.exists() && dir.is_dir() {
294+status!(ctx, "Checked", dir.as_path());
295+Ok(LockedSource { dir, file: None })
296+} else if let Ok(walker) = globwalk::glob(dir.to_string_lossy()) {
297+let mut directories: Vec<_> = walker
298+.filter_map(|result| match result {
299+Ok(entry) if entry.path().is_dir() => Some(entry.into_path()),
300+ _ => None,
302301})
303302.collect();
304303@@ -313,12 +312,6 @@ impl Source {
313312 directories.len()
314313))
315314}
316-} else if fs::metadata(&dir)
317-.with_context(s!("failed to find dir `{}`", dir.display()))?
318-.is_dir()
319-{
320-status!(ctx, "Checked", dir.as_path());
321-Ok(LockedSource { dir, file: None })
322315} else {
323316Err(anyhow!("`{}` is not a dir", dir.display()))
324317}
@@ -360,19 +353,20 @@ impl Source {
360353}
361354362355impl ExternalPlugin {
363-fn match_globs(pattern: PathBuf, files: &mut Vec<PathBuf>) -> Result<bool> {
356+fn match_globs(dir: &Path, pattern: &str, files: &mut Vec<PathBuf>) -> Result<bool> {
364357let mut matched = false;
365-let pattern = pattern.to_string_lossy();
366-let paths: glob::Paths =
367-glob::glob(&pattern).with_context(s!("failed to parse glob pattern `{}`", &pattern))?;
368-369-for path in paths {
358+for entry in globwalk::GlobWalkerBuilder::new(dir, &pattern)
359+ .sort_by(|a, b| a.file_name().cmp(b.file_name()))
360+.build()
361+ .with_context(s!("failed to parse glob pattern `{}`", pattern))?
362+{
370363 files.push(
371- path.with_context(s!("failed to read path matched by pattern `{}`", &pattern))?,
364+ entry
365+.with_context(s!("failed to read path matched by pattern `{}`", &pattern))?
366+.into_path(),
372367);
373368 matched = true;
374369}
375-376370Ok(matched)
377371}
378372@@ -428,22 +422,20 @@ impl ExternalPlugin {
428422// If the plugin defined what files to use, we do all of them.
429423if let Some(uses) = &self.uses {
430424for u in uses {
431-let rendered = templates
425+let pattern = templates
432426.render_template(u, &data)
433427.with_context(s!("failed to render template `{}`", u))?;
434-let pattern = dir.join(&rendered);
435-if !Self::match_globs(pattern, &mut files)? {
436-bail!("failed to find any files matching `{}`", &rendered);
428+if !Self::match_globs(dir, &pattern, &mut files)? {
429+bail!("failed to find any files matching `{}`", &pattern);
437430};
438431}
439432// Otherwise we try to figure out which files to use...
440433} else {
441434for g in matches {
442-let rendered = templates
435+let pattern = templates
443436.render_template(g, &data)
444437.with_context(s!("failed to render template `{}`", g))?;
445-let pattern = dir.join(rendered);
446-if Self::match_globs(pattern, &mut files)? {
438+if Self::match_globs(dir, &pattern, &mut files)? {
447439break;
448440}
449441}