ex_ast 0.12.0, Elixir 1.18.4 / OTP 27.
Repro
$ mix ex_ast.search 'insert(...)' test/my_app/some_test.exs
0 match(es)
The file contains plenty of insert(...) calls. No error or warning is printed — just 0 match(es), which reads as "searched and found nothing".
Cause
resolve_paths/1 in lib/ex_ast.ex:
defp resolve_paths(glob) when is_binary(glob) do
cond do
String.contains?(glob, "*") -> Path.wildcard(glob)
File.dir?(glob) -> Path.wildcard(Path.join(glob, "**/*.ex"))
true -> [glob]
end
|> Enum.filter(&String.ends_with?(&1, ".ex"))
end
The final filter drops .exs files in all three branches — including a file the user named explicitly, and globs like test/**/*.exs. The docs say "PATH can be a file, directory, or glob" with no extension caveat.
Expected
Either of:
- include
.exs files (test suites and scripts are prime targets for AST audits — that's how we hit this, auditing ExUnit test files), or
- at minimum, error/warn loudly when an explicitly named file is filtered out instead of reporting
0 match(es).
Workaround we used: ExAST.Patcher.find_all(File.read!(path), pattern) — works fine on .exs content, so this looks like purely a CLI path-resolution issue.
ex_ast 0.12.0, Elixir 1.18.4 / OTP 27.
Repro
The file contains plenty of
insert(...)calls. No error or warning is printed — just0 match(es), which reads as "searched and found nothing".Cause
resolve_paths/1inlib/ex_ast.ex:The final filter drops
.exsfiles in all three branches — including a file the user named explicitly, and globs liketest/**/*.exs. The docs say "PATH can be a file, directory, or glob" with no extension caveat.Expected
Either of:
.exsfiles (test suites and scripts are prime targets for AST audits — that's how we hit this, auditing ExUnit test files), or0 match(es).Workaround we used:
ExAST.Patcher.find_all(File.read!(path), pattern)— works fine on.exscontent, so this looks like purely a CLI path-resolution issue.