From 78fe565bba599f3dada5f3d7ba947ed514e4d730 Mon Sep 17 00:00:00 2001 From: Thomas Depierre Date: Sun, 7 May 2023 20:44:51 +0200 Subject: Add :root option for formatter_for_file (#12541) --- lib/mix/lib/mix/tasks/format.ex | 16 ++++++++++++++-- lib/mix/test/mix/tasks/format_test.exs | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/mix/lib/mix/tasks/format.ex b/lib/mix/lib/mix/tasks/format.ex index 6d4afc874..a164f3aac 100644 --- a/lib/mix/lib/mix/tasks/format.ex +++ b/lib/mix/lib/mix/tasks/format.ex @@ -251,10 +251,12 @@ defmodule Mix.Tasks.Format do def formatter_for_file(file, opts \\ []) do {dot_formatter, formatter_opts} = eval_dot_formatter(opts) + prefix = Keyword.get(opts, :root, []) + {formatter_opts_and_subs, _sources} = - eval_deps_and_subdirectories(dot_formatter, [], formatter_opts, [dot_formatter]) + eval_deps_and_subdirectories(dot_formatter, prefix, formatter_opts, [dot_formatter]) - find_formatter_and_opts_for_file(file, formatter_opts_and_subs) + find_formatter_and_opts_for_file(file, prefix, formatter_opts_and_subs) end @doc """ @@ -275,6 +277,10 @@ defmodule Mix.Tasks.Format do File.regular?(".formatter.exs") -> {".formatter.exs", eval_file_with_keyword_list(".formatter.exs")} + opts[:root] && File.regular?(Path.join(opts[:root], ".formatter.exs")) -> + dot_formatter = Path.join(opts[:root], ".formatter.exs") + {dot_formatter, eval_file_with_keyword_list(dot_formatter)} + true -> {".formatter.exs", []} end @@ -582,6 +588,12 @@ defmodule Mix.Tasks.Format do {find_formatter_for_file(file, formatter_opts), formatter_opts} end + defp find_formatter_and_opts_for_file(file, prefix, formatter_opts_and_subs) do + split = file |> Path.relative_to(prefix) |> Path.split() + formatter_opts = recur_formatter_opts_for_file(split, formatter_opts_and_subs) + {find_formatter_for_file(file, formatter_opts), formatter_opts} + end + defp recur_formatter_opts_for_file(split, {formatter_opts, subs}) do Enum.find_value(subs, formatter_opts, fn {sub, formatter_opts_and_subs} -> if List.starts_with?(split, Path.split(sub)) do diff --git a/lib/mix/test/mix/tasks/format_test.exs b/lib/mix/test/mix/tasks/format_test.exs index cf6f6b544..05be1212e 100644 --- a/lib/mix/test/mix/tasks/format_test.exs +++ b/lib/mix/test/mix/tasks/format_test.exs @@ -523,6 +523,35 @@ defmodule Mix.Tasks.FormatTest do end) end + test "uses inputs and configuration from :root path", context do + in_tmp(context.test, fn -> + File.write!(".formatter.exs", """ + [ + locals_without_parens: [foo: 1] + ] + """) + + File.mkdir_p!("lib") + + File.write!("lib/a.ex", """ + foo bar baz + """) + + root = File.cwd!() + + {formatter_function, _options} = + File.cd!("lib", fn -> + Mix.Tasks.Format.formatter_for_file("lib/a.ex", root: root) + end) + + assert formatter_function.(""" + foo bar baz + """) == """ + foo bar(baz) + """ + end) + end + test "reads exported configuration from subdirectories", context do in_tmp(context.test, fn -> File.write!(".formatter.exs", """ -- cgit v1.2.1