From 4cfb125cbb098f0823322ce743c1aa724d8acbd5 Mon Sep 17 00:00:00 2001 From: Ky Bishop Date: Thu, 20 Feb 2025 11:27:08 -0500 Subject: [PATCH] Feature: Explicitly pick style fixups with :only & :exclude --- README.md | 25 ++++++++- lib/quokka/config.ex | 125 ++++++++++++++++++++++--------------------- test/config_test.exs | 30 +++++++---- 3 files changed, 106 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index 042ac64..ea944b0 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,27 @@ in `.formatter.exs` to fine tune your setup: excluded: ["lib/example.ex", ...] }, newline_fixes_only: true | false + only: [ + :blocks + | :comment_directives + | :configs + | :defs + | :deprecations + | :line_length + | :module_directives + | :pipes + | :single_node + ], + exclude: [ + :blocks + | :comment_directives + | :configs + | :defs + | :deprecations + | :module_directives + | :pipes + | :single_node + ] ] ] ``` @@ -71,9 +92,9 @@ in `.formatter.exs` to fine tune your setup: | Option | Description | Default | | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | | `:files` | Quokka gets files from `.formatter.exs[:inputs]`. However, in some cases you may need to selectively exclude/include files you wish to still run in `mix format`, but have different behavior with Quokka. | `%{included: [], excluded: []}` (all files included, none excluded) | +| `:only` | Only include the given modules. The special `:line_length` option excludes all changes except line length fixups. | `[]` (all modules included) | +| `:exclude` | Exclude the given modules. This is just a convenience function that filters from the `:only` list. | `[]` (all modules included) | | `:inefficient_function_rewrites` | Rewrite inefficient functions to more efficient form | `true` | -| `:reorder_configs` | Alphabetize `config` by key in `config/*.exs` files | `true` | -| `:rewrite_deprecations` | Rewrite deprecated functions to their new form | `true` | ## Credo inspired rewrites diff --git a/lib/quokka/config.ex b/lib/quokka/config.ex index e0f3ddc..eeee56c 100644 --- a/lib/quokka/config.ex +++ b/lib/quokka/config.ex @@ -33,16 +33,16 @@ defmodule Quokka.Config do @key __MODULE__ - @styles [ - ModuleDirectives, - Pipes, - SingleNode, - Defs, - Blocks, - Deprecations, - Configs, - CommentDirectives - ] + @styles_by_atom %{ + blocks: Blocks, + comment_directives: CommentDirectives, + configs: Configs, + defs: Defs, + deprecations: Deprecations, + module_directives: ModuleDirectives, + pipes: Pipes, + single_node: SingleNode + } @stdlib ~w( Access Agent Application Atom Base Behaviour Bitwise Code Date DateTime Dict Ecto Enum Exception @@ -62,52 +62,42 @@ defmodule Quokka.Config do credo_opts = extract_configs_from_credo() lift_alias_excluded_namespaces = - (credo_opts[:lift_alias_excluded_namespaces] || []) |> Enum.map(&Atom.to_string/1) + Enum.map(credo_opts[:lift_alias_excluded_namespaces] || [], &Atom.to_string/1) lift_alias_excluded_lastnames = - (credo_opts[:lift_alias_excluded_lastnames] || []) |> Enum.map(&Atom.to_string/1) - - inefficient_function_rewrites = - if is_nil(config[:inefficient_function_rewrites]), - do: true, - else: config[:inefficient_function_rewrites] - - newline_fixes_only = if is_nil(config[:newline_fixes_only]), do: false, else: config[:newline_fixes_only] - - reorder_configs = - if is_nil(config[:reorder_configs]), do: true, else: config[:reorder_configs] - - rewrite_deprecations = - if is_nil(config[:rewrite_deprecations]), do: true, else: config[:rewrite_deprecations] + Enum.map(credo_opts[:lift_alias_excluded_lastnames] || [], &Atom.to_string/1) default_order = [:shortdoc, :moduledoc, :behaviour, :use, :import, :alias, :require] strict_module_layout_order = credo_opts[:strict_module_layout_order] || default_order - :persistent_term.put(@key, %{ - block_pipe_exclude: credo_opts[:block_pipe_exclude] || [], - block_pipe_flag: credo_opts[:block_pipe_flag] || false, - directories_excluded: Map.get(config[:files] || %{}, :excluded, []), - directories_included: Map.get(config[:files] || %{}, :included, []), - inefficient_function_rewrites: inefficient_function_rewrites, - large_numbers_gt: credo_opts[:large_numbers_gt] || :infinity, - lift_alias: credo_opts[:lift_alias] || false, - lift_alias_depth: credo_opts[:lift_alias_depth] || 0, - lift_alias_excluded_lastnames: MapSet.new(lift_alias_excluded_lastnames ++ @stdlib), - lift_alias_excluded_namespaces: MapSet.new(lift_alias_excluded_namespaces ++ @stdlib), - lift_alias_frequency: credo_opts[:lift_alias_frequency] || 0, - line_length: credo_opts[:line_length] || 98, - newline_fixes_only: newline_fixes_only, - pipe_chain_start_excluded_argument_types: credo_opts[:pipe_chain_start_excluded_argument_types] || [], - pipe_chain_start_excluded_functions: credo_opts[:pipe_chain_start_excluded_functions] || [], - pipe_chain_start_flag: credo_opts[:pipe_chain_start_flag] || false, - reorder_configs: reorder_configs, - rewrite_deprecations: rewrite_deprecations, - rewrite_multi_alias: credo_opts[:rewrite_multi_alias] || false, - single_pipe_flag: credo_opts[:single_pipe_flag] || false, - sort_order: credo_opts[:sort_order] || :alpha, - strict_module_layout_order: strict_module_layout_order ++ (default_order -- strict_module_layout_order), - zero_arity_parens: credo_opts[:zero_arity_parens] || false - }) + :persistent_term.put( + @key, + # quokka:sort + %{ + block_pipe_exclude: credo_opts[:block_pipe_exclude] || [], + block_pipe_flag: credo_opts[:block_pipe_flag] || false, + directories_excluded: Map.get(config[:files] || %{}, :excluded, []), + directories_included: Map.get(config[:files] || %{}, :included, []), + exclude_styles: config[:exclude] || [], + inefficient_function_rewrites: Keyword.get(config, :inefficient_function_rewrites, true), + large_numbers_gt: credo_opts[:large_numbers_gt] || :infinity, + lift_alias: credo_opts[:lift_alias] || false, + lift_alias_depth: credo_opts[:lift_alias_depth] || 0, + lift_alias_excluded_lastnames: MapSet.new(lift_alias_excluded_lastnames ++ @stdlib), + lift_alias_excluded_namespaces: MapSet.new(lift_alias_excluded_namespaces ++ @stdlib), + lift_alias_frequency: credo_opts[:lift_alias_frequency] || 0, + line_length: credo_opts[:line_length] || 98, + only_styles: config[:only] || [], + pipe_chain_start_excluded_argument_types: credo_opts[:pipe_chain_start_excluded_argument_types] || [], + pipe_chain_start_excluded_functions: credo_opts[:pipe_chain_start_excluded_functions] || [], + pipe_chain_start_flag: credo_opts[:pipe_chain_start_flag] || false, + rewrite_multi_alias: credo_opts[:rewrite_multi_alias] || false, + single_pipe_flag: credo_opts[:single_pipe_flag] || false, + sort_order: credo_opts[:sort_order] || :alpha, + strict_module_layout_order: strict_module_layout_order ++ (default_order -- strict_module_layout_order), + zero_arity_parens: credo_opts[:zero_arity_parens] || false + } + ) end def set_for_test!(key, value) do @@ -122,18 +112,29 @@ defmodule Quokka.Config do end def get_styles() do - if get(:newline_fixes_only) do - [Defs] - else - styles_to_remove = - for {module, flag_name} <- [ - {Configs, :reorder_configs}, - {Deprecations, :rewrite_deprecations} - ], - do: if(get(flag_name), do: nil, else: module) - - @styles -- styles_to_remove - end + styles_to_apply = + cond do + :line_length in only_styles() -> + [] + + only_styles() == [] -> + Map.values(@styles_by_atom) + + true -> + Enum.map(only_styles(), &@styles_by_atom[&1]) + |> Enum.filter(&(&1 != nil)) + end + + styles_to_exclude = Enum.map(exclude_styles(), &@styles_by_atom[&1]) + Enum.filter(styles_to_apply, fn style -> !Enum.member?(styles_to_exclude, style) end) + end + + def only_styles() do + get(:only_styles) + end + + def exclude_styles() do + get(:exclude_styles) end def sort_order() do diff --git a/test/config_test.exs b/test/config_test.exs index f822833..0ad4b41 100644 --- a/test/config_test.exs +++ b/test/config_test.exs @@ -10,19 +10,29 @@ defmodule Quokka.ConfigTest do assert :ok = set!([]) end - test "rewrite deprecations flag is respected" do - assert :ok = set!(rewrite_deprecations: false) - assert Deprecations not in Quokka.Config.get_styles() - - assert :ok = set!(rewrite_deprecations: true) - assert Deprecations in Quokka.Config.get_styles() + test "respects the `:only` configuration" do + assert :ok = set!(only: [:deprecations]) + assert [Deprecations] == Quokka.Config.get_styles() end - test "reorder configs flag is respected" do - assert :ok = set!(reorder_configs: false) - assert Configs not in Quokka.Config.get_styles() + test "respects the `:exclude` configuration" do + assert :ok = set!(exclude: [:deprecations]) - assert :ok = set!(reorder_configs: true) + # Check for one of the default configs assert Configs in Quokka.Config.get_styles() + + # Check that the excluded config is not present + assert Deprecations not in Quokka.Config.get_styles() + end + + test "respects the `:only` and `:exclude` configuration" do + assert :ok = set!(only: [:configs, :deprecations], exclude: [:deprecations]) + + assert [Configs] == Quokka.Config.get_styles() + end + + test "only applies line-length changes if :line_length is present in the `:only` configuration" do + assert :ok = set!(only: [:line_length]) + assert [] == Quokka.Config.get_styles() end end