Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions lib/mix/lib/mix/tasks/format.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
45 changes: 45 additions & 0 deletions lib/mix/test/mix/tasks/format_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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", """
Expand Down
Loading