Packages
credo
0.4.4
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.7-rc.0
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.2-rc.4
1.7.2-rc.3
1.7.2-rc.2
1.7.2-rc.1
1.7.2-rc.0
1.7.1
1.7.0
1.7.0-rc.2
1.7.0-rc.1
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-rc.1
1.6.0-rc.0
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.5.0-rc.5
1.5.0-rc.4
1.5.0-rc.3
1.5.0-rc.2
1.5.0-rc.1
1.4.1
1.4.0
1.4.0-rc.2
1.4.0-rc.1
1.3.2
1.3.1
1.3.0
1.3.0-rc3
1.3.0-rc2
1.3.0-rc1
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc4
1.2.0-rc3
1.2.0-rc2
1.2.0-rc1
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.1.0-rc3
1.1.0-rc2
1.1.0-rc1
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.1-rc1
1.0.0
1.0.0-rc1
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.9.0-rc8
0.9.0-rc7
0.9.0-rc6
0.9.0-rc5
0.9.0-rc4
0.9.0-rc3
0.9.0-rc2
0.9.0-rc1
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.8.0-rc7
0.8.0-rc6
0.8.0-rc5
0.8.0-rc4
0.8.0-rc3
0.8.0-rc2
0.8.0-rc1
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.6.0-rc2
0.6.0-rc1
0.5.3
0.5.2
0.5.1
0.5.0
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.10-dev
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.4.0-beta5
0.4.0-beta4
0.4.0-beta3
0.4.0-beta2
0.4.0-beta1
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.3.0-dev2
0.3.0-dev
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.1-dev
A static code analysis tool with a focus on code consistency and teaching.
Current section
Files
Jump to
Current section
Files
lib/credo/check/readability/module_doc.ex
defmodule Credo.Check.Readability.ModuleDoc do
@moduledoc """
Every module should contain comprehensive documentation.
Many times a sentence or two in plain english, explaining why the module
exists, will suffice. Documenting your train of thought this way will help
both your co-workers and your future-self.
Other times you will want to elaborate even further and show some
examples of how the module's functions can and should be used.
In some cases however, you might not want to document things about a module,
e.g. it is part of a private API inside your project. Since Elixir prefers
explicitness over implicit behaviour, you should "tag" these modules with
@moduledoc false
to make it clear that there is no intention in documenting it.
"""
@explanation [check: @moduledoc]
@default_params [
ignore_names: [
~r/(\.\w+Controller|\.Endpoint|\.Repo|\.Router|\.\w+Socket|\.\w+View)$/
]
]
alias Credo.Code.Module
use Credo.Check
def run(%SourceFile{ast: ast} = source_file, params \\ []) do
issue_meta = IssueMeta.for(source_file, params)
ignore_names = params |> Params.get(:ignore_names, @default_params)
Credo.Code.traverse(ast, &traverse(&1, &2, issue_meta, ignore_names))
end
defp traverse({:defmodule, meta, _arguments} = ast, issues, issue_meta, ignore_names) do
exception? = Module.exception?(ast)
case Module.attribute(ast, :moduledoc) do
{:error, _} when not exception? ->
mod_name = Module.name(ast)
if mod_name |> matches?(ignore_names) do
{ast, issues}
else
{ast, [issue_for(issue_meta, meta[:line], mod_name)] ++ issues}
end
_ ->
{ast, issues}
end
end
defp traverse(ast, issues, _issue_meta, _ignore_names) do
{ast, issues}
end
defp matches?(name, patterns) when is_list(patterns) do
patterns |> Enum.any?(&matches?(name, &1))
end
defp matches?(name, string) when is_binary(string) do
name |> String.contains?(string)
end
defp matches?(name, regex) do
String.match?(name, regex)
end
defp issue_for(issue_meta, line_no, trigger) do
format_issue issue_meta,
message: "Modules should have a @moduledoc tag.",
trigger: trigger,
line_no: line_no
end
end