defmodule Mix.Tasks.Arch.Collect.CredoIssues do
@moduledoc """
Mix Task to run Credo and save the issues it found.
Usage:
mix arch.collect.credo_issues [options]
The following options are accepted:
* `--include-deps` - Wildcard glob style to filter dependencies
This option is accepted but currently ignored.
For more information see:
[Basic usage guide](guides/introduction/basic_usage.md#include-dependencies-in-the-analysis)
"""
use Mix.Task
alias Archeometer.Util.DumpStats
alias Archeometer.Collect.{CredoIssues, Project}
@impl Mix.Task
def run(argv) do
case get_args(argv) do
{:error, error} ->
Mix.shell().error("Error: #{error}")
print_help()
{:error, error}
# XXX: properly implement support for external apps
[include_deps: _deps_filter] ->
if Archeometer.Repo.db_ready?(:basic) do
CredoIssues.collect()
|> Map.get(:credo_issues)
|> DumpStats.save_credo_issues()
:ok
else
Mix.shell().error("Please run static analysis first")
print_help()
{:error, :no_static_analysis_found}
end
end
end
defp get_args(argv) do
{opts, _args, invalid} =
OptionParser.parse(
argv,
strict: [include_deps: :keep]
)
case invalid do
[] ->
deps_filter = Keyword.get_values(opts, :include_deps)
validate_options(deps_filter)
_ ->
{:error, :wrong_arguments}
end
end
defp validate_options(deps_filter) do
case Project.filter_deps(deps_filter) do
[] ->
{:validate_error, "Filter doesn't match any dependency"}
_ ->
[include_deps: deps_filter]
end
end
defp print_help() do
Mix.shell().info("""
Usage: mix arch.collect.credo_issues [opts]
opts: --include-deps 'deps_filter'
Where `deps_filter` is a glob Unix-like pattern, matches dependencies name
--include-deps can be used more than once.
- `*` matches none or many tokens
- `?` matches exactly one token
- `[abc]` matches a set of tokens
- `[a-z]` matches a range of tokens
- `[!...]` matches anything but a set of tokens
""")
end
end