ExMinimatch

ExMinimatch

Globbing paths without walking the tree! Elixir and Erlang provide wildcard functions in the stdlib. But these will walk the directory tree. If you simply want to test whether a file path matches a glob, ExMinimatch is for you.

Quick examples:

iex> import ExMinimatch
nil

iex> match("**/*{1..2}{a,b}.{png,jpg}", "asdf/pic2a.jpg")
true

iex> match("*.+(bar|foo)", "bar.foo")
true

iex> ["me.jpg", "images/me.png", "images/you.svg"] |> filter("**/*.{png,jpg}")
["me.jpg", "images/me.png"]

Compiled forms below allows us to cache the %ExMinimatcher{} struct when used against large number of files repeated.

iex> compile("**/*{1..2}{a,b}.{png,jpg}") |> match("asdf/pic2a.jpg")
true

iex> ["me.jpg", "images/me.png", "images/you.svg"] |> filter(compile("**/*.{png,jpg}"))
["me.jpg", "images/me.png"]

ExMinimatch is a port of the minimatch javascript project. It is a close port but not exactly the same. See "Comparison to minimatch.js" section below.

Glob Patterns

Supports these glob features:

See:

Options

compile, match, and filter all have forms that take an options argument (as a map %{}). The following are the explanations. By default, all fo these are false.

log

Possible values are :info, and :debug. If set, will dump information into repl. :debug dumps more.

nobrace

Do not expand {a,b} and {1..3} brace sets.

noglobstar

Disable ** matching against multiple folder names.

dot

Allow patterns to match filenames starting with a period, even if the pattern does not explicitly have a period in that spot.

Note that by default, a/**/b will not match a/.d/b, unless dot is set, e.g. match("a/**/b", "a/.d/b", %{dot: true})

noext

Disable "extglob" style patterns like +(a|b).

nocase

Perform a case-insensitive match.

match_base

If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, a?b would match the path /xyz/123/acb, but not /xyz/acb/123.

nocomment

Suppress the behavior of treating # at the start of a pattern as a comment.

nonegate

Suppress the behavior of treating leading ! character as negation.

Comparison to minimatch.js

minimatch.js converts a glob into a list of regular expressions. However, when it comes to matching, one can choose to use minimatch.match or use the complete regular expression generated by minimatch.makeRe to test it against a file pattern. Unfortunately, the 2 approaches are inconsistent. Notably the full regular expression based approach has a few important pieces missing. Therefore, here we implement the first approach. For detail, take a look at ExMinimatcher.Matcher.

Summary

compile(glob)

Return a compiled %ExMinimatcher{} struct, which can be used in conjunction with match/2, 'match/3', or filter/2 to match files

compile(glob, options)
filter(files, matcher)

return a list of files that match the given pattern. This is a convenience function

filter(files, pattern, options)
match(exminimatcher, file)

Return true if the file matches the glob. This is a convenience function that is literally glob |> compile(options) |> match(file)

match(glob, file, options)

Functions

compile(glob)

Return a compiled %ExMinimatcher{} struct, which can be used in conjunction with match/2, 'match/3', or filter/2 to match files.

This purpose of this function is to save time by precompiling the glob pattern.

For possible glob patterns and available options, please refer to moduledoc.

compile(glob, options)
filter(files, matcher)

return a list of files that match the given pattern. This is a convenience function

For possible glob patterns and available options, please refer to moduledoc.

Examples

iex> filter(["qwer.png", "asdf/qwer.png"], "**/*.png")
["qwer.png", "asdf/qwer.png"]

iex> filter(["qwer/pic1a.png", "qwer/asdf/pic2a.png", "asdf/pic2c.jpg"], "**/*{1..2}{a,b}.{png,jpg}")
["qwer/pic1a.png", "qwer/asdf/pic2a.png"]
filter(files, pattern, options)
match(exminimatcher, file)

Return true if the file matches the glob. This is a convenience function that is literally glob |> compile(options) |> match(file)

Use this for one off matching, as the glob is recompiled every time this is called.

For possible glob patterns and available options, please refer to moduledoc.

Examples

iex> match("**/*.png", "qwer.png")
true

iex> match("**/*.png", "qwer/qwer.png")
true
match(glob, file, options)