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:
- Brace Expansion
- Extended glob matching
- "Globstar" ** matching
See:
- man sh
- man bash
- man 3 match
- man 5 gitignore
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 |
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 |
match(glob, file, options) |
Functions
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.
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"]
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