Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions lib/credo/check/readability/max_line_length.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule Credo.Check.Readability.MaxLineLength do
param_defaults: [
max_length: 120,
ignore_definitions: true,
ignore_definition_args: false,
ignore_heredocs: true,
ignore_specs: false,
ignore_sigils: true,
Expand All @@ -25,6 +26,8 @@ defmodule Credo.Check.Readability.MaxLineLength do
params: [
max_length: "The maximum number of characters a line may consist of.",
ignore_definitions: "Set to `true` to ignore lines including function definitions.",
ignore_definition_args:
"Set to `true` to ignore pattern matching clauses and arguments in function definitions.",
ignore_specs: "Set to `true` to ignore lines including `@spec`s.",
ignore_sigils: "Set to `true` to ignore lines that are sigils, e.g. regular expressions.",
ignore_strings: "Set to `true` to ignore lines that are strings or in heredocs.",
Expand All @@ -45,14 +48,17 @@ defmodule Credo.Check.Readability.MaxLineLength do
max_length = Params.get(params, :max_length, __MODULE__)

ignore_definitions = Params.get(params, :ignore_definitions, __MODULE__)
ignore_definition_args = Params.get(params, :ignore_definition_args, __MODULE__)

ignore_specs = Params.get(params, :ignore_specs, __MODULE__)
ignore_sigils = Params.get(params, :ignore_sigils, __MODULE__)
ignore_strings = Params.get(params, :ignore_strings, __MODULE__)
ignore_heredocs = Params.get(params, :ignore_heredocs, __MODULE__)
ignore_urls = Params.get(params, :ignore_urls, __MODULE__)

definitions = Credo.Code.prewalk(source_file, &find_definitions/2)
definitions =
Credo.Code.prewalk(source_file, &find_definitions(&1, &2, ignore_definition_args))

specs = Credo.Code.prewalk(source_file, &find_specs/2)

source =
Expand Down Expand Up @@ -105,16 +111,39 @@ defmodule Credo.Check.Readability.MaxLineLength do
end

for op <- @def_ops do
defp find_definitions({unquote(op), meta, arguments} = ast, definitions)
defp find_definitions({unquote(op), meta, arguments} = ast, definitions, ignore_args)
when is_list(arguments) do
{ast, [meta[:line] | definitions]}
lines =
if ignore_args do
last_line = find_last_line_of_definition(arguments, meta[:line])
Enum.to_list(meta[:line]..last_line)
else
[meta[:line]]
end

{ast, lines ++ definitions}
end
end

defp find_definitions(ast, definitions) do
defp find_definitions(ast, definitions, _ignore_args) do
{ast, definitions}
end

defp find_last_line_of_definition(ast, initial) do
{_, max} =
Macro.prewalk(ast, initial, fn
{_, meta, _} = node, acc ->
line = meta[:line]
acc = if line && line > acc, do: line, else: acc
{node, acc}

node, acc ->
{node, acc}
end)

max
end

defp find_specs({:spec, meta, arguments} = ast, specs) when is_list(arguments) do
{ast, [meta[:line] | specs]}
end
Expand Down
21 changes: 21 additions & 0 deletions test/credo/check/readability/max_line_length_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@
|> refute_issues()
end

test "it should NOT report expected code if function definition arguments are excluded" do

Check failure on line 72 in test/credo/check/readability/max_line_length_test.exs

View workflow job for this annotation

GitHub Actions / Test for lib/ changes

test it should NOT report expected code if function definition arguments are excluded (Credo.Check.Readability.MaxLineLengthTest)
~S'''
defmodule CredoSampleModule do
use ExUnit.Case

def some_fun(
%{"name" => name, "value" => value, "timestamp" => timestamp} = map_variable,
%MyStruct{some_id: MyConst.some_id(:some_long_atom_name), other_id: MyConst.other_id(:another_long_name)} =
struct_variable,
other_arguments
)
when name in @some_attributes do
assert 1 + 1 == 2
end
end
'''
|> to_source_file
|> run_check(@described_check, max_length: 80, ignore_definition_args: true)
|> refute_issues()
end

test "it should NOT report expected code if @spec's are excluded" do
~S'''
defmodule CredoSampleModule do
Expand Down
Loading