diff --git a/lib/mix/lib/mix/tasks/format.ex b/lib/mix/lib/mix/tasks/format.ex index cbcddaea8f8..8d7e13a52b9 100644 --- a/lib/mix/lib/mix/tasks/format.ex +++ b/lib/mix/lib/mix/tasks/format.ex @@ -33,6 +33,10 @@ defmodule Mix.Tasks.Format do to be used by this task. For example, `["mix.exs", "{config,lib,test}/**/*.{ex,exs}"]`. Patterns are expanded with `Path.wildcard/2`. + * `:excludes` (a list of paths and patterns) - specifies the files to exclude from the + list of inputs to this task. For example, `["config/runtime.exs", "test/**/*.{ex,exs}"]`. + Patterns are expanded with `Path.wildcard/2`. + * `:plugins` (a list of modules) (since v1.13.0) - specifies a list of modules to customize how the formatter works. See the "Plugins" section below for more information. @@ -634,9 +638,16 @@ defmodule Mix.Tasks.Format do Mix.raise("Expected :inputs or :subdirectories key in #{dot_formatter}") end + excluded_files = + formatter_opts[:excludes] + |> List.wrap() + |> Enum.flat_map(&Path.wildcard(Path.expand(&1, cwd), match_dot: true)) + |> MapSet.new() + map = for input <- List.wrap(formatter_opts[:inputs]), file <- Path.wildcard(Path.expand(input, cwd), match_dot: true), + file not in excluded_files, do: {file, {dot_formatter, formatter_opts}}, into: %{} diff --git a/lib/mix/test/mix/tasks/format_test.exs b/lib/mix/test/mix/tasks/format_test.exs index dc7d8eecead..d5d17bbace4 100644 --- a/lib/mix/test/mix/tasks/format_test.exs +++ b/lib/mix/test/mix/tasks/format_test.exs @@ -279,6 +279,35 @@ defmodule Mix.Tasks.FormatTest do end) end + test "ignores expanded patterns in excludes from .formatter.exs", context do + in_tmp(context.test, fn -> + File.write!(".formatter.exs", """ + [ + inputs: ["{a,.b}.ex"], + excludes: [".*.{ex,exs}"] + ] + """) + + File.write!("a.ex", """ + foo bar + """) + + File.write!(".b.ex", """ + foo bar + """) + + Mix.Tasks.Format.run([]) + + assert File.read!("a.ex") == """ + foo(bar) + """ + + assert File.read!(".b.ex") == """ + foo bar + """ + end) + end + defmodule Elixir.SigilWPlugin do @behaviour Mix.Tasks.Format