Is it possible to get the compiler to exit early, failing the build, if a compile time warning is raised?
Asked Answered
E

3

11

I find the compile time warnings very useful, but I can occasionally miss them, especially if it's on a pull request where the tests are running on a CI server.

Ideally I would specify something in the project mix file that would make the compiler more strict.

I want to this to be in effect for all mix tasks, and I do not want to have to pass the flag to the command, as this is easy to forget.

For example with a project with a compiler warning, this command should fail

mix clean && mix compile

As should this one

mix clean && mix test
Elliot answered 13/8, 2015 at 7:56 Comment(0)
C
7

Possible to some extent. There is a flag --warnings-as-errors in elixirc command.

☁  hello_elixir [master] ⚡ elixirc
Usage: elixirc [elixir switches] [compiler switches] [.ex files]

  -o               The directory to output compiled files
  --no-docs        Do not attach documentation to compiled modules
  --no-debug-info  Do not attach debug info to compiled modules
  --ignore-module-conflict
  --warnings-as-errors Treat warnings as errors and return non-zero exit code
  --verbose        Print informational messages.

** Options given after -- are passed down to the executed code
** Options can be passed to the erlang runtime using ELIXIR_ERL_OPTIONS
** Options can be passed to the erlang compiler using ERL_COMPILER_OPTIONS

For a module like this, with a warning:

defmodule Useless do
  defp another_userless, do: nil
end

When you compile without the flag:

☁  01_language [master] ⚡ elixirc useless.ex
useless.ex:2: warning: function another_userless/0 is unused
☁  01_language [master] ⚡ echo $?
0

You get the return code as 0.

But when you compile with the flag --warnings-as-errors, it returns an exit code of 1.

☁  01_language [master] ⚡ elixirc --warnings-as-errors useless.ex
useless.ex:1: warning: redefining module Useless
useless.ex:2: warning: function another_userless/0 is unused
☁  01_language [master] ⚡ echo $?
1

You can use this return code in your compile script for break the build process.

Casa answered 13/8, 2015 at 10:38 Comment(0)
S
13

In your mix.exs:

def project do
  [...,
   aliases: aliases]
end

defp aliases do
  ["compile": ["compile --warnings-as-errors"]]
end

Then mix compile will pass --warnings-as-errors to the compile.elixir subtask.

This also works for mix test since it runs the compile task implicitly.


If you don't add an alias, you can still run mix compile --warnings-as-errors and it will do what you expect, but mix test --warnings-as-errors will not do what you expect, since the flag does not reach the compile.elixir task.

Starnes answered 13/5, 2016 at 21:57 Comment(2)
You may also use elixirc_options: [warnings_as_errors: true].Fourierism
If you're using mix to compile Erlang code, you'll need erlc_options: [:warnings_as_errors]Skean
C
7

Possible to some extent. There is a flag --warnings-as-errors in elixirc command.

☁  hello_elixir [master] ⚡ elixirc
Usage: elixirc [elixir switches] [compiler switches] [.ex files]

  -o               The directory to output compiled files
  --no-docs        Do not attach documentation to compiled modules
  --no-debug-info  Do not attach debug info to compiled modules
  --ignore-module-conflict
  --warnings-as-errors Treat warnings as errors and return non-zero exit code
  --verbose        Print informational messages.

** Options given after -- are passed down to the executed code
** Options can be passed to the erlang runtime using ELIXIR_ERL_OPTIONS
** Options can be passed to the erlang compiler using ERL_COMPILER_OPTIONS

For a module like this, with a warning:

defmodule Useless do
  defp another_userless, do: nil
end

When you compile without the flag:

☁  01_language [master] ⚡ elixirc useless.ex
useless.ex:2: warning: function another_userless/0 is unused
☁  01_language [master] ⚡ echo $?
0

You get the return code as 0.

But when you compile with the flag --warnings-as-errors, it returns an exit code of 1.

☁  01_language [master] ⚡ elixirc --warnings-as-errors useless.ex
useless.ex:1: warning: redefining module Useless
useless.ex:2: warning: function another_userless/0 is unused
☁  01_language [master] ⚡ echo $?
1

You can use this return code in your compile script for break the build process.

Casa answered 13/8, 2015 at 10:38 Comment(0)
B
0

I like Michael Stalker's solution here.

Treating warnings as errors always can get annoying during TDD, where you might be rapidly refactoring code while running tests.

Instead, you can make the --warnings-as-errors flag conditional on your Mix env like this:

defmodule SomeProject.MixProject do
  use Mix.Project

  def project do
    [
      elixirc_options: [
        warnings_as_errors: treat_warnings_as_errors?(Mix.env())
      ]
      # ...
    ]
  end

  defp treat_warnings_as_errors?(:test), do: false
  defp treat_warnings_as_errors?(_), do: true
end

Warnings will go ignored when testing, but not for a dev or prod compilation.

Backwards answered 15/1, 2020 at 17:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.