zf

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

mix_env.ex (2577B)


      1 defmodule Credo.Check.Warning.MixEnv do
      2   use Credo.Check,
      3     base_priority: :high,
      4     param_defaults: [excluded_paths: []],
      5     explanations: [
      6       check: """
      7       Mix is a build tool and, as such, it is not expected to be available in production.
      8       Therefore, it is recommended to access Mix.env only in configuration files and inside
      9       mix.exs, never in your application code (lib).
     10 
     11       (from the Elixir docs)
     12       """,
     13       params: [
     14         excluded_paths: "List of paths or regex to exclude from this check"
     15       ]
     16     ]
     17 
     18   alias Credo.SourceFile
     19 
     20   @call_string "Mix.env"
     21   @def_ops [:def, :defp, :defmacro]
     22 
     23   @doc false
     24   def run(%SourceFile{filename: filename} = source_file, params \\ []) do
     25     excluded_paths = Params.get(params, :excluded_paths, __MODULE__)
     26 
     27     case ignore_path?(source_file.filename, excluded_paths) do
     28       true ->
     29         []
     30 
     31       false ->
     32         issue_meta = IssueMeta.for(source_file, params)
     33 
     34         filename
     35         |> Path.extname()
     36         |> case do
     37           ".exs" -> []
     38           _ -> Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta))
     39         end
     40     end
     41   end
     42 
     43   # Check if analyzed module path is within ignored paths
     44   defp ignore_path?(filename, excluded_paths) do
     45     directory = Path.dirname(filename)
     46 
     47     Enum.any?(excluded_paths, &matches?(directory, &1))
     48   end
     49 
     50   defp matches?(directory, %Regex{} = regex), do: Regex.match?(regex, directory)
     51   defp matches?(directory, path) when is_binary(path), do: String.starts_with?(directory, path)
     52 
     53   for op <- @def_ops do
     54     # catch variables named e.g. `defp`
     55     defp traverse({unquote(op), _, nil} = ast, issues, _issue_meta, _parens?) do
     56       {ast, issues}
     57     end
     58 
     59     defp traverse({unquote(op), _, _body} = ast, issues, issue_meta) do
     60       {ast, issues ++ Credo.Code.prewalk(ast, &traverse_defs(&1, &2, issue_meta))}
     61     end
     62   end
     63 
     64   defp traverse(ast, issues, _issue_meta) do
     65     {ast, issues}
     66   end
     67 
     68   defp traverse_defs(
     69          {{:., _, [{:__aliases__, _, [:Mix]}, :env]}, meta, _arguments} = ast,
     70          issues,
     71          issue_meta
     72        ) do
     73     {ast, issues_for_call(meta, issues, issue_meta)}
     74   end
     75 
     76   defp traverse_defs(ast, issues, _issue_meta) do
     77     {ast, issues}
     78   end
     79 
     80   defp issues_for_call(meta, issues, issue_meta) do
     81     [issue_for(issue_meta, meta[:line], @call_string) | issues]
     82   end
     83 
     84   defp issue_for(issue_meta, line_no, trigger) do
     85     format_issue(
     86       issue_meta,
     87       message: "There should be no calls to Mix.env in application code.",
     88       trigger: trigger,
     89       line_no: line_no
     90     )
     91   end
     92 end