From 9f977be589879cc564a6dd06cc1902e4480d021e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 23 Aug 2023 12:24:10 +0200 Subject: [PATCH] Load and compile plugins from cache, closes #12880 --- lib/mix/lib/mix/tasks/format.ex | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/mix/lib/mix/tasks/format.ex b/lib/mix/lib/mix/tasks/format.ex index 097aba5e0fb..af8dfae6b0f 100644 --- a/lib/mix/lib/mix/tasks/format.ex +++ b/lib/mix/lib/mix/tasks/format.ex @@ -303,13 +303,7 @@ defmodule Mix.Tasks.Format do Mix.raise("Expected :plugins to return a list of modules, got: #{inspect(plugins)}") end - if plugins != [] do - Mix.Task.run("loadpaths", []) - end - - if not Enum.all?(plugins, &Code.ensure_loaded?/1) do - Mix.Task.run("compile", []) - end + maybe_load_and_compile_plugins(plugins) for plugin <- plugins do cond do @@ -351,12 +345,19 @@ defmodule Mix.Tasks.Format do else manifest = Path.join(Mix.Project.manifest_path(), @manifest) - {{locals_without_parens, subdirectories}, sources} = + {cached?, {{locals_without_parens, subdirectories}, sources}} = maybe_cache_in_manifest(dot_formatter, manifest, fn -> {subdirectories, sources} = eval_subs_opts(subs, cwd, sources) {{eval_deps_opts(deps), subdirectories}, sources} end) + # If we read from cache, we may still need to load and compile plugins. + if cached? do + Enum.each(subdirectories, fn {_path, {opts, _deps}} -> + maybe_load_and_compile_plugins(Keyword.get(opts, :plugins, [])) + end) + end + formatter_opts = Keyword.update( formatter_opts, @@ -369,11 +370,21 @@ defmodule Mix.Tasks.Format do end end + defp maybe_load_and_compile_plugins(plugins) do + if plugins != [] do + Mix.Task.run("loadpaths", []) + end + + if not Enum.all?(plugins, &Code.ensure_loaded?/1) do + Mix.Task.run("compile", []) + end + end + defp maybe_cache_in_manifest(dot_formatter, manifest, fun) do cond do - is_nil(Mix.Project.get()) or dot_formatter != ".formatter.exs" -> fun.() - entry = read_manifest(manifest) -> entry - true -> write_manifest!(manifest, fun.()) + is_nil(Mix.Project.get()) or dot_formatter != ".formatter.exs" -> {false, fun.()} + entry = read_manifest(manifest) -> {true, entry} + true -> {false, write_manifest!(manifest, fun.())} end end