From 766f655c3aacb7b13e91a0da73d69a4303cc8bf0 Mon Sep 17 00:00:00 2001 From: Brian Underwood Date: Mon, 20 Sep 2021 21:28:52 +0200 Subject: [PATCH] Fixes * Timezone lookup issue * Custom tag name in params --- lib/check.ex | 43 +++++++++++++++--------------- lib/credo_todo_or_die.ex | 13 --------- lib/todo_or_die/alert/date_time.ex | 3 ++- lib/todo_or_die/lines.ex | 8 +++--- test/alert_test.exs | 2 +- test/check_test.exs | 35 +++++++++++++++++++----- test/lines_test.exs | 26 ++++++++++-------- 7 files changed, 72 insertions(+), 58 deletions(-) delete mode 100644 lib/credo_todo_or_die.ex diff --git a/lib/check.ex b/lib/check.ex index 1f4fd62..c2138ab 100644 --- a/lib/check.ex +++ b/lib/check.ex @@ -1,25 +1,30 @@ defmodule CredoTodoOrDie.Check do @moduledoc "DO THIS!" use Credo.Check, - param_defaults: [timezone: "Etc/UTC"], + param_defaults: [timezone: "Etc/UTC", tag_name: "TODO"], category: :design, explanations: [ - params: [timezone: """ - When specifing date/time you can specify the timezone of your development / CI machine - so that it reports as accurately as possible + params: [ + tag_name: "The tag to look for (TODO/FIXME/NOTE/etc...)", + timezone: """ + When specifing date/time you can specify the timezone of your development / CI machine + so that it reports as accurately as possible - Timezone can be anything specified in Timex.is_valid_timezone? - https://hexdocs.pm/timex/Timex.html#is_valid_timezone?/1 - """] + Timezone can be anything specified in Timex.is_valid_timezone? + https://hexdocs.pm/timex/Timex.html#is_valid_timezone?/1 + """ + ] ] - @tag_name "TODO" - def run(%Credo.SourceFile{} = source_file, params) do + Application.ensure_all_started(:timex) + issue_meta = IssueMeta.for(source_file, params) + tag_name = Keyword.get(params, :tag_name, "TODO") + source_file - |> items_with_index(@tag_name, params) + |> items_with_index(tag_name, params) |> Enum.map(&issue_for(issue_meta, &1, params)) end @@ -43,17 +48,13 @@ defmodule CredoTodoOrDie.Check do alert_options = alert_options(params) - if source =~ regex do - source - |> Credo.Code.clean_charlists_strings_and_sigils() - |> String.split("\n") - |> TodoOrDie.Lines.items_for() - |> Enum.filter(fn {item, line_no} -> - TodoOrDie.Alert.alert?(item, context(params), alert_options) - end) - else - [] - end + source + |> Credo.Code.clean_charlists_strings_and_sigils() + |> String.split("\n") + |> TodoOrDie.Lines.items_for(tag_name) + |> Enum.filter(fn {item, line_no} -> + TodoOrDie.Alert.alert?(item, context(params), alert_options) + end) end def alert_options(params) do diff --git a/lib/credo_todo_or_die.ex b/lib/credo_todo_or_die.ex deleted file mode 100644 index 8bbf446..0000000 --- a/lib/credo_todo_or_die.ex +++ /dev/null @@ -1,13 +0,0 @@ -defmodule CredoTodoOrDie do - @moduledoc false - - alias Credo.Plugin - - @config_file :code.priv_dir(:credo_todo_or_die) - |> Path.join(".credo.exs") - |> File.read!() - - def init(exec) do - Plugin.register_default_config(exec, @config_file) - end -end diff --git a/lib/todo_or_die/alert/date_time.ex b/lib/todo_or_die/alert/date_time.ex index 633625a..2ccef40 100644 --- a/lib/todo_or_die/alert/date_time.ex +++ b/lib/todo_or_die/alert/date_time.ex @@ -23,7 +23,8 @@ defmodule TodoOrDie.Alert.DateTime do duration_string = context.current_datetime |> Timex.diff(datetime) - |> Timex.Duration.from_microseconds() + |> div(1_000_000 * 60) + |> Timex.Duration.from_minutes() |> Timex.format_duration(:humanized) {:ok, "#{duration_string} past"} diff --git a/lib/todo_or_die/lines.ex b/lib/todo_or_die/lines.ex index 4833dd7..152ce7c 100644 --- a/lib/todo_or_die/lines.ex +++ b/lib/todo_or_die/lines.ex @@ -1,13 +1,11 @@ defmodule TodoOrDie.Lines do - @tags ~w[TODO FIXME] - alias TodoOrDie.Item - def items_for(lines) do - tags_string = "(#{Enum.join(@tags, "|")})" - regex = Regex.compile!("(\\A|[^\\?])#\\s*#{tags_string}\\(([^\)]+)\\):?\\s*(.+)", "i") + def items_for(lines, tag_name) do + regex = Regex.compile!("(\\A|[^\\?])#\\s*(#{tag_name})\\(([^\)]+)\\):?\\s*(.+)", "i") lines_with_index = Enum.with_index(lines) + for {line, index} <- lines_with_index, result = line_match(line, regex), do: {result, index} end diff --git a/test/alert_test.exs b/test/alert_test.exs index 554423a..3ead537 100644 --- a/test/alert_test.exs +++ b/test/alert_test.exs @@ -26,7 +26,7 @@ defmodule TodoOrDie.AlertTest do assert Alert.alert?(item, %{current_datetime: parse_datetime("2021-02-15 12:34")}, options) == true assert Alert.alert?(item, %{current_datetime: parse_datetime("2021-02-16 12:35")}, options) == true - assert Alert.message(item, %{current_datetime: parse_datetime("2021-02-15 12:34:08")}, options) == "Found a TOTEST tag: Test String (8 seconds past)" + assert Alert.message(item, %{current_datetime: parse_datetime("2021-02-15 12:36:08")}, options) == "Found a TOTEST tag: Test String (2 minutes past)" assert Alert.message(item, %{current_datetime: parse_datetime("2021-02-16 12:35")}, options) == "Found a TOTEST tag: Test String (1 day, 1 minute past)" end diff --git a/test/check_test.exs b/test/check_test.exs index 73cb585..e4e357c 100644 --- a/test/check_test.exs +++ b/test/check_test.exs @@ -3,21 +3,26 @@ defmodule CredoTodoOrDie.CheckTest do def assert_check_issue(code, message) do code - |> to_source_file() - |> run_check(CredoTodoOrDie.Check) |> assert_issue(fn issue -> assert issue.message == message + assert issue.category == :design end) end test "Invalid expressions" do "# TODO(2021-09-2) Do something!!" + |> to_source_file() + |> run_check(CredoTodoOrDie.Check, []) |> assert_check_issue("Invalid expression: 2021-09-2") "# TODO(Some text) Do something!!" + |> to_source_file() + |> run_check(CredoTodoOrDie.Check, []) |> assert_check_issue("Invalid expression: Some text") "# TODO(2020-15-01) Do something!!" + |> to_source_file() + |> run_check(CredoTodoOrDie.Check, []) |> assert_check_issue("Invalid expression: Expected `2 digit month` at line 1, column 6.") end @@ -39,10 +44,7 @@ defmodule CredoTodoOrDie.CheckTest do code |> to_source_file() |> run_check(CredoTodoOrDie.Check, current_datetime: ~U[2021-09-20 00:00:00.000000Z]) - |> assert_issue(fn issue -> - assert issue.message == "Found a TODO tag: Do something!! (today is the day!)" - assert issue.category == :design - end) + |> assert_check_issue("Found a TODO tag: Do something!! (today is the day!)") code = """ @@ -67,6 +69,27 @@ defmodule CredoTodoOrDie.CheckTest do end) end + test "Custom tag" do + code = + """ + defmodule CredoSampleModule do + @somedoc "This is somedoc" + + # TEST_TAG(2021-09-20) Do something!! + end + """ + + code + |> to_source_file() + |> run_check(CredoTodoOrDie.Check, tag_name: "TEST_TAG", current_datetime: ~U[2021-09-19 23:59:59.999999Z]) + |> refute_issues() + + code + |> to_source_file() + |> run_check(CredoTodoOrDie.Check, tag_name: "TEST_TAG", current_datetime: ~U[2021-09-20 00:00:00.000000Z]) + |> assert_check_issue("Found a TEST_TAG tag: Do something!! (today is the day!)") + end + test "Uses the timezone param" do code = """ diff --git a/test/lines_test.exs b/test/lines_test.exs index 171fa5f..76b58bf 100644 --- a/test/lines_test.exs +++ b/test/lines_test.exs @@ -4,27 +4,31 @@ defmodule TodoOrDie.LinesTest do alias TodoOrDie.{Lines, Item} test "Non-matching lines" do - assert Lines.items_for([]) == [] - assert Lines.items_for([""]) == [] - assert Lines.items_for(["def foobar do"]) == [] - assert Lines.items_for(["1 + 5"]) == [] - assert Lines.items_for([" # Just a comment!"]) == [] - assert Lines.items_for([" # TODO: Plain TODO"]) == [] - assert Lines.items_for([" # TODO Plain TODO"]) == [] + assert Lines.items_for([], "TODO") == [] + assert Lines.items_for([""], "TODO") == [] + assert Lines.items_for(["def foobar do"], "TODO") == [] + assert Lines.items_for(["1 + 5"], "TODO") == [] + assert Lines.items_for([" # Just a comment!"], "TODO") == [] + assert Lines.items_for([" # TODO: Plain TODO"], "TODO") == [] + assert Lines.items_for([" # TODO Plain TODO"], "TODO") == [] + assert Lines.items_for([" # RANDOM Plain RANDOM"], "RANDOM") == [] end test "Matching lines" do - assert Lines.items_for([" # TODO(2021-09-14) Clean this up"]) == + assert Lines.items_for([" # TODO(2021-09-14) Clean this up"], "TODO") == [{%Item{tag: :TODO, expression: "2021-09-14", string: "Clean this up"}, 0}] - assert Lines.items_for([" # TODO(2021-09-14 15:43) Clean this up"]) == + assert Lines.items_for([" # TODO(2021-09-14 15:43) Clean this up"], "TODO") == [{%Item{tag: :TODO, expression: "2021-09-14 15:43", string: "Clean this up"}, 0}] - assert Lines.items_for([" def fun_name do", " # TODO(#1234) Clean this up"]) == + assert Lines.items_for([" def fun_name do", " # TODO(#1234) Clean this up"], "TODO") == [{%Item{tag: :TODO, expression: "#1234", string: "Clean this up"}, 1}] - assert Lines.items_for([" # TODO(something else!) Clean this up"]) == + assert Lines.items_for([" # TODO(something else!) Clean this up"], "TODO") == [{%Item{tag: :TODO, expression: "something else!", string: "Clean this up"}, 0}] + + assert Lines.items_for([" # RANDOM(2021-09-14) Clean this up"], "RANDOM") == + [{%Item{tag: :RANDOM, expression: "2021-09-14", string: "Clean this up"}, 0}] end end