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