Skip to content

Commit

Permalink
Add --migrate flag to mix format (#13846)
Browse files Browse the repository at this point in the history
  • Loading branch information
sabiwara authored Sep 21, 2024
1 parent 5902c29 commit 4126cdd
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
7 changes: 5 additions & 2 deletions lib/elixir/src/elixir_bitstring.erl
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,13 @@ format_error({undefined_bittype, Expr}) ->
io_lib:format("unknown bitstring specifier: ~ts", ['Elixir.Macro':to_string(Expr)]);
format_error({unknown_bittype, Name}) ->
io_lib:format("bitstring specifier \"~ts\" does not exist and is being expanded to \"~ts()\","
" please use parentheses to remove the ambiguity", [Name, Name]);
" please use parentheses to remove the ambiguity.\n"
"You may run \"mix format --migrate\" to fix this warning automatically.", [Name, Name]);
format_error({parens_bittype, Name}) ->
io_lib:format("extra parentheses on a bitstring specifier \"~ts()\" have been deprecated. "
"Please remove the parentheses: \"~ts\"",
"Please remove the parentheses: \"~ts\".\n"
"You may run \"mix format --migrate\" to fix this warning automatically."
,
[Name, Name]);
format_error({bittype_mismatch, Val1, Val2, Where}) ->
io_lib:format("conflicting ~ts specification for bit field: \"~p\" and \"~p\"", [Where, Val1, Val2]);
Expand Down
5 changes: 4 additions & 1 deletion lib/elixir/src/elixir_tokenizer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,10 @@ tokenize([$" | T], Line, Column, Scope, Tokens) ->

%% TODO: Remove me in Elixir v2.0
tokenize([$' | T], Line, Column, Scope, Tokens) ->
NewScope = prepend_warning(Line, Column, "single-quoted strings represent charlists. Use ~c\"\" if you indeed want a charlist or use \"\" instead", Scope),
Message = "single-quoted strings represent charlists. "
"Use ~c\"\" if you indeed want a charlist or use \"\" instead.\n"
"You may run \"mix format --migrate\" to fix this warning automatically.",
NewScope = prepend_warning(Line, Column, Message, Scope),
handle_strings(T, Line, Column + 1, $', NewScope, Tokens);

% Operator atoms
Expand Down
33 changes: 23 additions & 10 deletions lib/mix/lib/mix/tasks/format.ex
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ defmodule Mix.Tasks.Format do
as `.heex`. Without passing this flag, it is assumed that the code being
passed via stdin is valid Elixir code. Defaults to "stdin.exs".
* `--migrate` - enables the `:migrate` option, which should be able to
automatically fix some deprecation warnings but is changing the AST.
This should be safe in typical projects, but there is a non-zero risk
of breaking code for meta-programming heavy projects that relied on a
specific AST, or projects that are re-defining functions from the `Kernel`.
See the "Migration formatting" section in `Code.format_string!/2` for
more information.
## When to format code
We recommend developers to format code directly in their editors, either
Expand Down Expand Up @@ -184,7 +192,8 @@ defmodule Mix.Tasks.Format do
dot_formatter: :string,
dry_run: :boolean,
stdin_filename: :string,
force: :boolean
force: :boolean,
migrate: :boolean
]

@manifest_timestamp "format_timestamp"
Expand Down Expand Up @@ -362,17 +371,21 @@ defmodule Mix.Tasks.Format do
end

defp eval_dot_formatter(cwd, opts) do
cond do
dot_formatter = opts[:dot_formatter] ->
{dot_formatter, eval_file_with_keyword_list(dot_formatter)}
{dot_formatter, format_opts} =
cond do
dot_formatter = opts[:dot_formatter] ->
{dot_formatter, eval_file_with_keyword_list(dot_formatter)}

File.regular?(Path.join(cwd, ".formatter.exs")) ->
dot_formatter = Path.join(cwd, ".formatter.exs")
{".formatter.exs", eval_file_with_keyword_list(dot_formatter)}
File.regular?(Path.join(cwd, ".formatter.exs")) ->
dot_formatter = Path.join(cwd, ".formatter.exs")
{".formatter.exs", eval_file_with_keyword_list(dot_formatter)}

true ->
{".formatter.exs", []}
end
true ->
{".formatter.exs", []}
end

# the --migrate flag overrides settings from the dot formatter
{dot_formatter, Keyword.take(opts, [:migrate]) ++ format_opts}
end

# This function reads exported configuration from the imported
Expand Down
12 changes: 12 additions & 0 deletions lib/mix/test/mix/tasks/format_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,18 @@ defmodule Mix.Tasks.FormatTest do
end)
end

test "respects the --migrate flag", context do
in_tmp(context.test, fn ->
File.write!("a.ex", "unless foo, do: 'bar'\n")

Mix.Tasks.Format.run(["a.ex"])
assert File.read!("a.ex") == "unless foo, do: 'bar'\n"

Mix.Tasks.Format.run(["a.ex", "--migrate"])
assert File.read!("a.ex") == "if !foo, do: ~c\"bar\"\n"
end)
end

test "uses inputs and configuration from --dot-formatter", context do
in_tmp(context.test, fn ->
File.write!("custom_formatter.exs", """
Expand Down

0 comments on commit 4126cdd

Please sign in to comment.