zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

validate_config.ex (3811B)


      1 defmodule Credo.Execution.Task.ValidateConfig do
      2   @moduledoc false
      3 
      4   use Credo.Execution.Task
      5 
      6   alias Credo.Check
      7   alias Credo.Check.Params
      8   alias Credo.CLI.Output.UI
      9 
     10   def call(exec, _opts) do
     11     exec
     12     |> validate_checks()
     13     |> validate_only_checks()
     14     |> validate_ignore_checks()
     15     |> remove_missing_checks()
     16     |> inspect_config_if_debug()
     17   end
     18 
     19   defp validate_only_checks(%Execution{only_checks: only_checks} = exec)
     20        when is_list(only_checks) do
     21     if Enum.any?(only_checks, &(&1 == "")) do
     22       UI.warn([
     23         :red,
     24         "** (config) Including all checks, since an empty string was given as a pattern: #{inspect(only_checks)}"
     25       ])
     26     end
     27 
     28     exec
     29   end
     30 
     31   defp validate_only_checks(exec) do
     32     exec
     33   end
     34 
     35   defp validate_ignore_checks(%Execution{ignore_checks: ignore_checks} = exec)
     36        when is_list(ignore_checks) do
     37     if Enum.any?(ignore_checks, &(&1 == "")) do
     38       UI.warn([
     39         :red,
     40         "** (config) Ignoring all checks, since an empty string was given as a pattern: #{inspect(ignore_checks)}"
     41       ])
     42     end
     43 
     44     exec
     45   end
     46 
     47   defp validate_ignore_checks(exec) do
     48     exec
     49   end
     50 
     51   defp validate_checks(%Execution{checks: %{enabled: checks}} = exec) do
     52     Enum.each(checks, fn check_tuple ->
     53       warn_if_check_missing(check_tuple)
     54       warn_if_check_params_invalid(check_tuple)
     55     end)
     56 
     57     exec
     58   end
     59 
     60   defp warn_if_check_params_invalid({_check, false}), do: nil
     61   defp warn_if_check_params_invalid({_check, []}), do: nil
     62 
     63   defp warn_if_check_params_invalid({check, params}) do
     64     if Check.defined?(check) do
     65       do_warn_if_check_params_invalid({check, params})
     66     end
     67   end
     68 
     69   defp do_warn_if_check_params_invalid({check, params}) do
     70     valid_param_names = check.param_names ++ Params.builtin_param_names()
     71     check = check |> to_string |> String.to_existing_atom()
     72 
     73     Enum.each(params, fn {param_name, _param_value} ->
     74       unless Enum.member?(valid_param_names, param_name) do
     75         candidate = find_best_match(valid_param_names, param_name)
     76         warning = warning_message_for(check, param_name, candidate)
     77 
     78         UI.warn([:red, warning])
     79       end
     80     end)
     81   end
     82 
     83   defp warning_message_for(check, param_name, candidate) do
     84     if candidate do
     85       "** (config) #{check_name(check)}: unknown param `#{param_name}`. Did you mean `#{candidate}`?"
     86     else
     87       "** (config) #{check_name(check)}: unknown param `#{param_name}`."
     88     end
     89   end
     90 
     91   defp find_best_match(candidates, given, threshold \\ 0.8) do
     92     given_string = to_string(given)
     93 
     94     {jaro_distance, candidate} =
     95       candidates
     96       |> Enum.map(fn candidate_name ->
     97         distance = String.jaro_distance(given_string, to_string(candidate_name))
     98         {distance, candidate_name}
     99       end)
    100       |> Enum.sort()
    101       |> List.last()
    102 
    103     if jaro_distance > threshold do
    104       candidate
    105     end
    106   end
    107 
    108   defp warn_if_check_missing({check, _params}) do
    109     unless Check.defined?(check) do
    110       UI.warn([:red, "** (config) Ignoring an undefined check: #{check_name(check)}"])
    111     end
    112   end
    113 
    114   defp check_name(atom) do
    115     atom
    116     |> to_string()
    117     |> String.replace(~r/^Elixir\./, "")
    118   end
    119 
    120   defp inspect_config_if_debug(%Execution{debug: true} = exec) do
    121     require Logger
    122 
    123     Logger.debug(fn ->
    124       """
    125       Execution struct after #{__MODULE__}:
    126 
    127       #{inspect(exec, pretty: true)}
    128       """
    129     end)
    130 
    131     exec
    132   end
    133 
    134   defp inspect_config_if_debug(exec), do: exec
    135 
    136   defp remove_missing_checks(
    137          %Execution{checks: %{enabled: enabled_checks, disabled: disabled_checks}} = exec
    138        ) do
    139     enabled_checks = Enum.filter(enabled_checks, &Check.defined?/1)
    140     disabled_checks = Enum.filter(disabled_checks, &Check.defined?/1)
    141 
    142     %Execution{exec | checks: %{enabled: enabled_checks, disabled: disabled_checks}}
    143   end
    144 end