# `MixAffected.Glob`
[🔗](https://github.com/mnox/mix_affected/blob/v0.1.0/lib/mix_affected/glob.ex#L1)

Matches root-relative paths against shell-style globs without touching the
filesystem, so deleted files match too.

  * `**` matches any run of characters, `/` included; `**/` also matches
    no directory at all (`**/*.md` matches `README.md`)
  * `*` matches any run of characters except `/`
  * `?` matches one character except `/`
  * `{a,b}` matches either alternative (alternatives may hold globs)

A glob matches the whole path. A leading `./` is ignored on both sides.
Every other character is literal, so a glob with no metacharacter matches
exactly one path: `"lib/workers"` never matches `lib/workers/a.ex`
(`literal?/1`; write `"lib/workers/**"`). Unbalanced braces are an error
(`compile/1`), never a guess.

# `compile`

```elixir
@spec compile(String.t()) :: {:ok, Regex.t()} | {:error, String.t()}
```

Compiles `glob` to an anchored regex, or explains why it is malformed (a
`{` never closed, a `}` never opened, bytes that are not valid UTF-8).
Never raises.

# `find`

```elixir
@spec find([String.t()], String.t()) :: String.t() | nil
```

Whether `path` matches any of `globs`; returns the first matching glob or `nil`.

# `literal?`

```elixir
@spec literal?(String.t()) :: boolean()
```

Whether `glob` has no metacharacter (`*`, `?`, `{`), so it matches one path only.

# `match?`

```elixir
@spec match?(String.t(), String.t()) :: boolean()
```

Whether `path` matches `glob`; raises `ArgumentError` on a glob `compile/1` rejects.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
