Current section
Files
Jump to
Current section
Files
lib/config.ex
defmodule Doctor.Config do
@moduledoc """
This module defines a struct which houses all the
configuration data for Doctor.
"""
@config_file ".doctor.exs"
require Logger
alias __MODULE__
@typedoc """
* `:min_module_doc_coverage` - Minimum ratio of @doc vs public functions
per module.
* `:min_overall_doc_coverage` - Minimum ratio of @doc vs public functions
across the codebase.
* `:min_overall_moduledoc_coverage` - Minimum ratio of @moduledoc to modules
across the codebase.
* `:moduledoc_required` - If true, `:min_overall_moduledoc_coverage` is
automatically set to 100%. Deprecated.
"""
@type t :: %Config{
ignore_modules: [Regex.t() | String.t()],
ignore_paths: [Regex.t() | module()],
min_module_doc_coverage: integer() | float(),
min_module_spec_coverage: integer() | float(),
min_overall_doc_coverage: integer() | float(),
min_overall_moduledoc_coverage: integer() | float(),
min_overall_spec_coverage: integer() | float(),
moduledoc_required: boolean(),
exception_moduledoc_required: boolean() | nil,
raise: boolean(),
reporter: module(),
struct_type_spec_required: boolean(),
umbrella: boolean(),
failed: false
}
defstruct ignore_modules: [],
ignore_paths: [],
min_module_doc_coverage: 40,
min_module_spec_coverage: 0,
min_overall_doc_coverage: 50,
min_overall_moduledoc_coverage: 100,
min_overall_spec_coverage: 0,
moduledoc_required: nil,
exception_moduledoc_required: true,
raise: false,
reporter: Doctor.Reporters.Full,
struct_type_spec_required: true,
umbrella: false,
failed: false
@doc """
Create a new Config struct from a map, keyword list or preexisting Config.
"""
@spec new(keyword | map) :: Config.t()
def new(attrs \\ %{}) do
config =
case attrs do
%Config{} = c -> c
map_or_keyword -> struct(Config, map_or_keyword)
end
interpret_moduledoc_required(config)
end
@doc """
Returns true if a specific module should fail validation if it lacks a
moduledoc."
"""
@spec moduledoc_required?(t) :: boolean
def moduledoc_required?(%{min_overall_moduledoc_coverage: 100}), do: true
def moduledoc_required?(_), do: false
@doc """
Get the configuration defaults as a string
"""
def config_defaults_as_string do
config = quote do: unquote(%Config{})
config
|> Macro.to_string()
|> Code.format_string!()
|> to_string()
|> String.replace(~r/\s+moduledoc_required:.*/, "")
end
@doc """
Get the configuration file name
"""
def config_file, do: @config_file
# If `:moduledoc_required` is defined in the config, warn the user about the
# deprecation. In a future version, the struct key and associated
# backwards-compatibility code could be removed.
@spec interpret_moduledoc_required(Config.t()) :: Config.t()
defp interpret_moduledoc_required(%{moduledoc_required: nil} = config) do
config
end
defp interpret_moduledoc_required(%{moduledoc_required: true} = config) do
warn_deprecation(true, 100)
%{config | min_overall_moduledoc_coverage: 100}
end
defp interpret_moduledoc_required(%{moduledoc_required: false} = config) do
warn_deprecation(false, 0)
%{config | min_overall_moduledoc_coverage: 0}
end
defp warn_deprecation(_bool, val) do
Logger.warning("""
:moduledoc_required in #{Config.config_file()} is a deprecated option. \
Now running with the equivalent :min_overall_moduledoc_coverage #{val} \
but you should replace the deprecated option with the new one to avoid \
this warning.\
""")
end
end