Skip to content

Commit de32209

Browse files
committed
Fix files_included not being honored by Runner
when reading from stdin. Refs #1115
1 parent 6d867b2 commit de32209

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

lib/credo.ex

+2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ defmodule Credo do
3131
|> WriteDebugReport.call([])
3232
end
3333

34+
@doc false
3435
def run(argv_or_exec, files_that_changed) do
3536
argv_or_exec
3637
|> Execution.build(files_that_changed)
3738
|> Execution.run()
3839
|> WriteDebugReport.call([])
3940
end
4041

42+
@doc false
4143
def version, do: @version
4244
end

lib/credo/check/runner.ex

+15-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,21 @@ defmodule Credo.Check.Runner do
5151
# but it is necessary to avoid hitting the filesystem when reading from STDIN
5252
[%Credo.SourceFile{filename: filename}] = Execution.get_source_files(exec)
5353

54-
if filename in files_excluded do
54+
file_included? =
55+
if files_included != [] do
56+
Credo.Sources.filename_matches?(filename, files_included)
57+
else
58+
true
59+
end
60+
61+
file_excluded? =
62+
if files_excluded != [] do
63+
Credo.Sources.filename_matches?(filename, files_excluded)
64+
else
65+
false
66+
end
67+
68+
if !file_included? || file_excluded? do
5569
:skip_run
5670
else
5771
[]

lib/credo/sources.ex

+35
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,41 @@ defmodule Credo.Sources do
99
@default_sources_glob ~w(** *.{ex,exs})
1010
@stdin_filename "stdin"
1111

12+
@doc false
13+
def filename_matches?(filename, patterns) do
14+
patterns
15+
|> List.wrap()
16+
|> Enum.any?(&match_filename_pattern(filename, &1))
17+
end
18+
19+
defp match_filename_pattern(filename, pattern) when is_binary(pattern) do
20+
if String.contains?(pattern, "*") do
21+
matches_glob_naively?(filename, pattern)
22+
else
23+
String.starts_with?(filename, pattern)
24+
end
25+
end
26+
27+
defp match_filename_pattern(filename, %Regex{} = pattern), do: String.match?(filename, pattern)
28+
29+
defp match_filename_pattern(_, pattern),
30+
do: raise("Expected String or Regex, got: #{inspect(pattern)}")
31+
32+
# naively converts glob pattern to regex
33+
# does not account for brace or tilde expansion or command substitution
34+
# or anything other than * and **
35+
defp matches_glob_naively?(filename, pattern) do
36+
pattern
37+
|> String.replace("/", "\\/")
38+
|> String.replace("**", ".+")
39+
|> String.replace("*", "[^\/]+")
40+
|> Regex.compile()
41+
|> case do
42+
{:ok, regex} -> String.match?(filename, regex)
43+
_ -> raise "Compiling glob pattern to regex failed: #{inspect(pattern)}"
44+
end
45+
end
46+
1247
@doc """
1348
Finds sources for a given `Credo.Execution`.
1449

test/credo/sources_test.exs

+17
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,21 @@ defmodule Credo.SourcesTest do
293293

294294
assert expected == Credo.Sources.find_in_dir(dir, ["*.ex"], [~r/.ex$/])
295295
end
296+
297+
test "it matches filenames given patterns" do
298+
assert Credo.Sources.filename_matches?("lib/credo/check/runner.ex", [
299+
"lib/credo/check/runner.ex"
300+
])
301+
302+
assert Credo.Sources.filename_matches?("lib/credo/check.ex", ["lib/*/check.ex"])
303+
assert Credo.Sources.filename_matches?("lib/credo/check/runner.ex", ["lib/**/runner.ex"])
304+
assert Credo.Sources.filename_matches?("lib/credo/check/runner.ex", ["lib/**/*.ex"])
305+
306+
assert Credo.Sources.filename_matches?("lib/credo/check/foo.ex", ["lib/**/*.ex"])
307+
assert Credo.Sources.filename_matches?("lib/credo/check/foo.ex", [~r/.ex$/])
308+
309+
refute Credo.Sources.filename_matches?("lib/credo/check/runner.ex", ["lib/*/runner.ex"])
310+
refute Credo.Sources.filename_matches?("lib/credo/check/runner.ex", ["*.exs"])
311+
refute Credo.Sources.filename_matches?("lib/credo/check/runner.ex", [~r/.exs$/])
312+
end
296313
end

0 commit comments

Comments
 (0)