From fe9c0bd68dedcab14022f732c0910c30559e0b82 Mon Sep 17 00:00:00 2001 From: Aaron Tinio Date: Sun, 7 Jun 2026 18:30:01 +0800 Subject: [PATCH] Honor --no-compile in mix format --- lib/mix/lib/mix/tasks/format.ex | 14 +++++--- lib/mix/test/mix/tasks/format_test.exs | 45 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/lib/mix/lib/mix/tasks/format.ex b/lib/mix/lib/mix/tasks/format.ex index 1dbc398563c..5cfad60e8d3 100644 --- a/lib/mix/lib/mix/tasks/format.ex +++ b/lib/mix/lib/mix/tasks/format.ex @@ -78,6 +78,10 @@ defmodule Mix.Tasks.Format do * `--dry-run` - does not save files after formatting. + * `--no-compile` - does not compile, even if compilation is required + to load formatter plugins. If a plugin cannot be loaded, an error + is raised. + * `--verbose` - prints the names of files that were formatted. * `--dot-formatter` - path to the file with formatter configuration. @@ -152,7 +156,7 @@ defmodule Mix.Tasks.Format do ] Notice that, when running the formatter with plugins, your code will be - compiled first. + compiled first, unless the `--no-compile` flag is given. In addition, the order by which you input your plugins is the format order. So, in the above `.formatter.exs`, the `MixMarkdownFormatter` will format @@ -316,7 +320,7 @@ defmodule Mix.Tasks.Format do plugins = if plugins != [] do - Keyword.get(opts, :plugin_loader, &plugin_loader/1).(plugins) + Keyword.get(opts, :plugin_loader, &plugin_loader(&1, opts)).(plugins) else [] end @@ -357,12 +361,12 @@ defmodule Mix.Tasks.Format do end)} end - defp plugin_loader(plugins) do + defp plugin_loader(plugins, opts) do if plugins != [] do - Mix.Task.run("loadpaths", []) + Mix.Task.run("loadpaths", if(opts[:no_compile], do: ["--no-compile"], else: [])) end - if not Enum.all?(plugins, &Code.ensure_loaded?/1) do + if !opts[:no_compile] and not Enum.all?(plugins, &Code.ensure_loaded?/1) do Mix.Task.run("compile", []) end diff --git a/lib/mix/test/mix/tasks/format_test.exs b/lib/mix/test/mix/tasks/format_test.exs index eaf1aa1aade..1498d2a162f 100644 --- a/lib/mix/test/mix/tasks/format_test.exs +++ b/lib/mix/test/mix/tasks/format_test.exs @@ -597,6 +597,51 @@ defmodule Mix.Tasks.FormatTest do end) end + defmodule FormatWithPluginApp do + def project do + [app: :format_with_plugin, version: "0.1.0"] + end + end + + test "doesn't compile plugins with --no-compile", context do + in_tmp(context.test, fn -> + Mix.Project.push(__MODULE__.FormatWithPluginApp) + on_exit(fn -> purge([UncompiledPlugin]) end) + + File.write!(".formatter.exs", """ + [ + inputs: ["a.ex"], + plugins: [UncompiledPlugin] + ] + """) + + File.mkdir_p!("lib") + + File.write!("lib/uncompiled_plugin.ex", """ + defmodule UncompiledPlugin do + @behaviour Mix.Tasks.Format + + def features(_opts), do: [extensions: [".ex"]] + def format(contents, _opts), do: "# formatted\\n" <> contents + end + """) + + File.write!("a.ex", """ + foo bar + """) + + assert_raise Mix.Error, "Formatter plugin UncompiledPlugin cannot be found", fn -> + Mix.Tasks.Format.run(["--no-compile"]) + end + + refute_received {:mix_shell, :info, ["Compiling" <> _]} + + assert File.read!("a.ex") == """ + foo bar + """ + end) + end + test "uses extension plugins with --stdin-filename", context do in_tmp(context.test, fn -> File.write!(".formatter.exs", """