From 35078c81f261c0f47bb426ede91891c4a6269ee6 Mon Sep 17 00:00:00 2001 From: Pablo Brudnick Date: Sat, 30 Jul 2022 15:53:35 -0300 Subject: [PATCH 1/3] #74: first solution for config/3 --- config/test.exs | 4 ++++ .../rules/unused_configuration_options.ex | 24 ++++++++++++++++++- .../examples/module.exs | 8 ++++--- .../examples/none.exs | 6 +++++ .../unused_configuration_options_test.exs | 22 ++++++++++------- 5 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 test/rules/unused_configuration_options/examples/none.exs diff --git a/config/test.exs b/config/test.exs index afe2b54..71773df 100644 --- a/config/test.exs +++ b/config/test.exs @@ -6,3 +6,7 @@ config :meandro, other_unused_option: "value3", input_key_option: :ok, nice_option: :nice + +config :meandro, MeandroTest.UnusedConfigurationOptions.Module, + used_keyed_option: "value1", + unused_keyed_option: "value2" diff --git a/lib/meandro/rules/unused_configuration_options.ex b/lib/meandro/rules/unused_configuration_options.ex index 9f40bb9..8f92776 100644 --- a/lib/meandro/rules/unused_configuration_options.ex +++ b/lib/meandro/rules/unused_configuration_options.ex @@ -47,7 +47,13 @@ defmodule Meandro.Rule.UnusedConfigurationOptions do end defp analyze_asts(asts, app_name, mix_env) do - options_set = app_name |> Application.get_all_env() |> Keyword.keys() |> Enum.sort() + options_set = + app_name + |> Application.get_all_env() + |> Keyword.keys() + |> Enum.sort() + |> maybe_aggregate_options(app_name) + |> IO.inspect() usage_map = Enum.reduce(asts, %{get_all_env: false, used_options: MapSet.new()}, fn ast, acc -> @@ -67,6 +73,22 @@ defmodule Meandro.Rule.UnusedConfigurationOptions do end end + # This covers cases where using the macro config/3 + # config(root_key, key, opts) so, `options` here is a root_key + defp maybe_aggregate_options(options, app_name) do + Enum.reduce(options, [], fn option, acc -> + key = Application.get_env(app_name, option) + + case Keyword.keyword?(key) do + true -> + [Keyword.keys(key) | acc] |> List.flatten() + + false -> + [option | acc] + end + end) + end + defp analyze_ast(ast, acc0, app_name) do {_, usage_map} = Macro.prewalk(ast, acc0, fn node, acc -> diff --git a/test/rules/unused_configuration_options/examples/module.exs b/test/rules/unused_configuration_options/examples/module.exs index 7513a96..b18b5a2 100644 --- a/test/rules/unused_configuration_options/examples/module.exs +++ b/test/rules/unused_configuration_options/examples/module.exs @@ -1,18 +1,20 @@ defmodule MeandroTest.UnusedConfigurationOptions.Module do # a function that returns a config option def some_fun() do - Application.get_env(:meandro, used_option) + Application.get_env(:meandro, :used_option) other_fun(Application.fetch_env!(:meandro, :input_key_option)) end def other_fun(key) do [ key, - Application.fetch_env(:meandro, nice_option), + Application.fetch_env(:meandro, :nice_option), # calls get_all_env from other app -> ignore it! Application.get_all_env(:other_app), # calls to an unused option but from other app -> ignore it! - Application.fetch_env(:other_app, unused_option) + Application.fetch_env(:other_app, :unused_option), + # uses a keyed option also + Application.get_env(:meandro, :used_keyed_option) ] end end diff --git a/test/rules/unused_configuration_options/examples/none.exs b/test/rules/unused_configuration_options/examples/none.exs new file mode 100644 index 0000000..5dfee2a --- /dev/null +++ b/test/rules/unused_configuration_options/examples/none.exs @@ -0,0 +1,6 @@ +defmodule MeandroTest.UnusedConfigurationOptions.None do + # it doesn't use any config option + def some_fun() do + :ok + end +end diff --git a/test/rules/unused_configuration_options/unused_configuration_options_test.exs b/test/rules/unused_configuration_options/unused_configuration_options_test.exs index c0f76d0..4f80b55 100644 --- a/test/rules/unused_configuration_options/unused_configuration_options_test.exs +++ b/test/rules/unused_configuration_options/unused_configuration_options_test.exs @@ -10,26 +10,30 @@ defmodule MeandroTest.Rule.UnusedConfigurationOptions do file = @test_directory_path <> "module.exs" files_and_asts = TestHelpers.parse_files([file]) - expected_text1 = - "Configuration option :other_unused_option (MIX_ENV=test) is not used anywhere in the code" - - expected_text2 = - "Configuration option :unused_option (MIX_ENV=test) is not used anywhere in the code" - assert [ + %Rule{ + file: nil, + line: 0, + pattern: :unused_option, + rule: UnusedConfigurationOptions, + text: + "Configuration option :unused_option (MIX_ENV=test) is not used anywhere in the code" + }, %Rule{ file: nil, line: 0, pattern: :other_unused_option, rule: UnusedConfigurationOptions, - text: ^expected_text1 + text: + "Configuration option :other_unused_option (MIX_ENV=test) is not used anywhere in the code" }, %Rule{ file: nil, line: 0, - pattern: :unused_option, + pattern: :unused_keyed_option, rule: UnusedConfigurationOptions, - text: ^expected_text2 + text: + "Configuration option :unused_keyed_option (MIX_ENV=test) is not used anywhere in the code" } ] = Rule.analyze(UnusedConfigurationOptions, files_and_asts, From 03cabd2d3afbb412cc77ee3048adf1cf1f48125f Mon Sep 17 00:00:00 2001 From: Pablo Brudnick Date: Sat, 30 Jul 2022 15:58:10 -0300 Subject: [PATCH 2/3] Removes unused file and IO.inspect --- lib/meandro/rules/unused_configuration_options.ex | 1 - test/rules/unused_configuration_options/examples/none.exs | 6 ------ 2 files changed, 7 deletions(-) delete mode 100644 test/rules/unused_configuration_options/examples/none.exs diff --git a/lib/meandro/rules/unused_configuration_options.ex b/lib/meandro/rules/unused_configuration_options.ex index 45221c8..e6ef092 100644 --- a/lib/meandro/rules/unused_configuration_options.ex +++ b/lib/meandro/rules/unused_configuration_options.ex @@ -53,7 +53,6 @@ defmodule Meandro.Rule.UnusedConfigurationOptions do |> Keyword.keys() |> Enum.sort() |> maybe_aggregate_options(app_name) - |> IO.inspect() usage_map = Enum.reduce(asts, %{get_all_env: false, used_options: MapSet.new()}, fn ast, acc -> diff --git a/test/rules/unused_configuration_options/examples/none.exs b/test/rules/unused_configuration_options/examples/none.exs deleted file mode 100644 index 5dfee2a..0000000 --- a/test/rules/unused_configuration_options/examples/none.exs +++ /dev/null @@ -1,6 +0,0 @@ -defmodule MeandroTest.UnusedConfigurationOptions.None do - # it doesn't use any config option - def some_fun() do - :ok - end -end From 96653696e5b5ae19a04b7d9ffc2310a629d6be2b Mon Sep 17 00:00:00 2001 From: Pablo Brudnick Date: Sat, 30 Jul 2022 16:01:43 -0300 Subject: [PATCH 3/3] Sort --- lib/meandro/rules/unused_configuration_options.ex | 2 +- .../unused_configuration_options_test.exs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/meandro/rules/unused_configuration_options.ex b/lib/meandro/rules/unused_configuration_options.ex index e6ef092..fd0d827 100644 --- a/lib/meandro/rules/unused_configuration_options.ex +++ b/lib/meandro/rules/unused_configuration_options.ex @@ -51,8 +51,8 @@ defmodule Meandro.Rule.UnusedConfigurationOptions do app_name |> Application.get_all_env() |> Keyword.keys() - |> Enum.sort() |> maybe_aggregate_options(app_name) + |> Enum.sort() usage_map = Enum.reduce(asts, %{get_all_env: false, used_options: MapSet.new()}, fn ast, acc -> diff --git a/test/rules/unused_configuration_options/unused_configuration_options_test.exs b/test/rules/unused_configuration_options/unused_configuration_options_test.exs index 4f80b55..64d9153 100644 --- a/test/rules/unused_configuration_options/unused_configuration_options_test.exs +++ b/test/rules/unused_configuration_options/unused_configuration_options_test.exs @@ -14,26 +14,26 @@ defmodule MeandroTest.Rule.UnusedConfigurationOptions do %Rule{ file: nil, line: 0, - pattern: :unused_option, + pattern: :other_unused_option, rule: UnusedConfigurationOptions, text: - "Configuration option :unused_option (MIX_ENV=test) is not used anywhere in the code" + "Configuration option :other_unused_option (MIX_ENV=test) is not used anywhere in the code" }, %Rule{ file: nil, line: 0, - pattern: :other_unused_option, + pattern: :unused_keyed_option, rule: UnusedConfigurationOptions, text: - "Configuration option :other_unused_option (MIX_ENV=test) is not used anywhere in the code" + "Configuration option :unused_keyed_option (MIX_ENV=test) is not used anywhere in the code" }, %Rule{ file: nil, line: 0, - pattern: :unused_keyed_option, + pattern: :unused_option, rule: UnusedConfigurationOptions, text: - "Configuration option :unused_keyed_option (MIX_ENV=test) is not used anywhere in the code" + "Configuration option :unused_option (MIX_ENV=test) is not used anywhere in the code" } ] = Rule.analyze(UnusedConfigurationOptions, files_and_asts,