Packages
styler
0.6.1
1.11.0
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.0
1.6.0
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
1.0.0-alpha.0
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.5
0.10.4
retired
0.10.3
0.10.2
0.10.1
0.10.0
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
retired
0.9.1
retired
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.1
0.1.0
A code-style enforcer that will just FIFY instead of complaining
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/style.ex
# Copyright 2023 Adobe. All rights reserved.
# This file is licensed to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy
# of the License at http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
defmodule Mix.Tasks.Style do
@shortdoc "Rewrites (styles!) and formats your code as a drop in replacement for `mix format`"
@moduledoc """
Formats and rewrites the given files and patterns.
mix style mix.exs "lib/**/*.{ex,exs}" "test/**/*.{ex,exs}"
If `-` is one of the files, input is read from stdin and written to stdout.
`mix style` uses the same options as `mix format` specified in `.formatter.exs` to
format the code, and to determine which files to style if you don't pass any as arguments
## Task-specific options
* `--check-formatted` - an alias for `--check-styled`, included for compatibility with `mix format`
* `--check-styled` - checks that the file is already styled rather than styling it.
useful for CI.
"""
use Mix.Task
@impl Mix.Task
def run(args) do
# we take `check_formatted` so we can easily replace `mix format`
{opts, files} = OptionParser.parse!(args, strict: [check_styled: :boolean, check_formatted: :boolean])
check_styled? = opts[:check_styled] || opts[:check_formatted] || false
{_, formatter_opts} = Mix.Tasks.Format.formatter_for_file("mix.exs")
files =
if Enum.empty?(files) do
case Keyword.fetch(formatter_opts, :inputs) do
:error -> Mix.raise("you must pass file arguments or run `mix style` from the project's root directory")
{:ok, inputs} -> inputs
end
else
files
end
files
|> Stream.flat_map(fn
"-" ->
[:stdin]
path ->
path |> Path.expand() |> Path.wildcard(match_dot: true) |> Enum.filter(&String.ends_with?(&1, [".ex", "exs"]))
end)
|> Task.async_stream(&style_file(&1, formatter_opts, check_styled?),
ordered: false,
timeout: :timer.seconds(30)
)
|> Enum.reduce({[], []}, fn
{:ok, :ok}, acc -> acc
{:ok, {:exit, exit}}, {exits, not_styled} -> {[exit | exits], not_styled}
{:ok, {:not_styled, file}}, {exits, not_styled} -> {exits, [file | not_styled]}
end)
|> check!()
end
defp check!({[], []}) do
:ok
end
defp check!({[{:stdin, exception, stacktrace} | _], _not_styled}) do
Mix.shell().error("mix style failed for stdin:")
reraise exception, stacktrace
end
defp check!({[{file, exception, stacktrace} | _], _not_styled}) do
Mix.shell().error("mix style failed for file: #{Path.relative_to_cwd(file)}")
reraise exception, stacktrace
end
defp check!({_exits, [_ | _] = not_styled}) do
Mix.raise("""
mix style failed due to --check-styled.
The following files are not styled:
#{Enum.join(not_styled, "\n")}
""")
end
defp style_file(file, formatter_opts, check_styled?) do
input =
if file == :stdin,
do: IO.stream() |> Enum.to_list() |> IO.iodata_to_binary(),
else: file |> File.read!() |> String.trim()
styled = Styler.format(input, formatter_opts, on_error: :raise)
changed? = input != styled
cond do
check_styled? and changed? -> {:not_styled, file}
file == :stdin -> IO.write(styled)
changed? -> File.write!(file, styled)
true -> :ok
end
rescue
exception -> {:exit, {file, exception, __STACKTRACE__}}
end
end