Skip to content

Commit

Permalink
Feature: Explicitly pick style fixups with :only & :exclude
Browse files Browse the repository at this point in the history
  • Loading branch information
kybishop committed Feb 20, 2025
1 parent 3bae4cc commit 4cfb125
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 74 deletions.
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,37 @@ 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
]
]
]
```

| 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

Expand Down
125 changes: 63 additions & 62 deletions lib/quokka/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
30 changes: 20 additions & 10 deletions test/config_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 4cfb125

Please sign in to comment.