suggest_command.ex (3805B)
1 defmodule Credo.CLI.Command.Suggest.SuggestCommand do 2 @moduledoc false 3 4 alias Credo.Check.Params 5 alias Credo.CLI.Command.Suggest.SuggestOutput 6 alias Credo.CLI.Switch 7 alias Credo.CLI.Task 8 alias Credo.Execution 9 10 use Credo.CLI.Command, 11 short_description: "Suggest code objects to look at next (default)", 12 cli_switches: [ 13 Switch.boolean("all_priorities", alias: :A), 14 Switch.boolean("all", alias: :a), 15 Switch.boolean("crash_on_error"), 16 Switch.keep("files_included"), 17 Switch.keep("files_excluded"), 18 Switch.keep("checks_with_tag"), 19 Switch.keep("checks_without_tag"), 20 Switch.string("checks", alias: :c), 21 Switch.string("enable_disabled_checks"), 22 Switch.string("min_priority"), 23 Switch.boolean("mute_exit_status"), 24 Switch.boolean("first_run"), 25 Switch.string("format"), 26 Switch.boolean("help", alias: :h), 27 Switch.string("ignore_checks"), 28 Switch.string("ignore", alias: :i), 29 Switch.string("only"), 30 Switch.boolean("read_from_stdin"), 31 Switch.boolean("strict"), 32 Switch.boolean("verbose"), 33 Switch.boolean("watch") 34 ] 35 36 def init(exec) do 37 Execution.put_pipeline(exec, "suggest", 38 load_and_validate_source_files: [Task.LoadAndValidateSourceFiles], 39 prepare_analysis: [Task.PrepareChecksToRun], 40 __manipulate_config_if_rerun__: [__MODULE__.ManipulateConfigIfRerun], 41 print_before_analysis: [__MODULE__.PrintBeforeInfo], 42 run_analysis: [Task.RunChecks], 43 filter_issues: [Task.SetRelevantIssues], 44 print_after_analysis: [__MODULE__.PrintResultsAndSummary] 45 ) 46 end 47 48 def call(%Execution{help: true} = exec, _opts), do: SuggestOutput.print_help(exec) 49 def call(exec, _opts), do: Execution.run_pipeline(exec, __MODULE__) 50 51 defmodule PrintBeforeInfo do 52 @moduledoc false 53 54 use Credo.Execution.Task 55 56 def call(exec) do 57 source_files = Execution.get_source_files(exec) 58 59 SuggestOutput.print_before_info(source_files, exec) 60 61 exec 62 end 63 end 64 65 defmodule PrintResultsAndSummary do 66 @moduledoc false 67 68 use Credo.Execution.Task 69 70 def call(exec) do 71 source_files = Execution.get_source_files(exec) 72 73 time_load = Execution.get_assign(exec, "credo.time.source_files") 74 time_run = Execution.get_assign(exec, "credo.time.run_checks") 75 76 SuggestOutput.print_after_info(source_files, exec, time_load, time_run) 77 78 exec 79 end 80 end 81 82 defmodule ManipulateConfigIfRerun do 83 @moduledoc false 84 85 use Credo.Execution.Task 86 87 def call(exec, _opts) do 88 case Execution.get_rerun(exec) do 89 :notfound -> 90 exec 91 92 {previous_exec, files_that_changed} -> 93 exec 94 |> selectively_transfer_issues_from_previous_exec(previous_exec, files_that_changed) 95 |> modify_config_to_only_include_needed_checks(files_that_changed) 96 end 97 end 98 99 def selectively_transfer_issues_from_previous_exec(exec, previous_exec, files_that_changed) do 100 issues_to_keep = 101 previous_exec 102 |> Execution.get_issues() 103 |> Enum.reject(fn issue -> 104 issue.category == :consistency || 105 Enum.member?(files_that_changed, issue.filename) 106 end) 107 108 # all checks on `files_that_changed` 109 # consistency checks on all files 110 111 Execution.put_issues(exec, issues_to_keep) 112 end 113 114 def modify_config_to_only_include_needed_checks(%Credo.Execution{} = exec, files_that_changed) do 115 checks = 116 Enum.map(exec.checks, fn {check, params} -> 117 if check.category == :consistency do 118 {check, params} 119 else 120 {check, Params.put_rerun_files_that_changed(params, files_that_changed)} 121 end 122 end) 123 124 %Execution{exec | checks: checks} 125 end 126 end 127 end