如果引发编译时警告,是否有可能让编译器提前退出,导致构建失败?
Is it possible to get the compiler to exit early, failing the build, if a compile time warning is raised?
我发现编译时警告非常有用,但我偶尔会错过它们,尤其是在拉取请求中,其中测试 运行 在 CI 服务器上。
理想情况下,我会在项目混合文件中指定一些内容,使编译器更加严格。
我希望这对所有混合任务都有效,我不想将标志传递给命令,因为这很容易忘记。
例如,对于带有编译器警告的项目,此命令应该失败
mix clean && mix compile
这个也一样
mix clean && mix test
某种程度上是有可能的。 elixirc
命令中有一个标记 --warnings-as-errors
。
☁ 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
对于这样的模块,有警告:
defmodule Useless do
defp another_userless, do: nil
end
当你编译时没有标志:
☁ 01_language [master] ⚡ elixirc useless.ex
useless.ex:2: warning: function another_userless/0 is unused
☁ 01_language [master] ⚡ echo $?
0
您得到的 return 代码为 0。
但是当你用标志 --warnings-as-errors
编译时,它 return 的退出代码是 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
您可以在编译脚本中使用此 return 代码来中断构建过程。
在你的mix.exs
中:
def project do
[...,
aliases: aliases]
end
defp aliases do
["compile": ["compile --warnings-as-errors"]]
end
然后mix compile
将--warnings-as-errors
传递给compile.elixir
子任务。
这也适用于 mix test
,因为它 运行 是隐式的 compile
任务。
如果您不添加别名,您仍然可以 运行 mix compile --warnings-as-errors
并且它会如您所愿,但 mix test --warnings-as-errors
不会如您所愿,因为标志未到达 compile.elixir
任务。
我喜欢 Michael Stalker 的解决方案 here。
将警告视为错误 总是 在 TDD 期间会很烦人,您可能会在 运行 测试时快速重构代码。
相反,您可以像这样在您的 Mix 环境中设置 --warnings-as-errors
标志条件:
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
测试时会忽略警告,但 dev
或 prod
编译时不会。
我发现编译时警告非常有用,但我偶尔会错过它们,尤其是在拉取请求中,其中测试 运行 在 CI 服务器上。
理想情况下,我会在项目混合文件中指定一些内容,使编译器更加严格。
我希望这对所有混合任务都有效,我不想将标志传递给命令,因为这很容易忘记。
例如,对于带有编译器警告的项目,此命令应该失败
mix clean && mix compile
这个也一样
mix clean && mix test
某种程度上是有可能的。 elixirc
命令中有一个标记 --warnings-as-errors
。
☁ 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
对于这样的模块,有警告:
defmodule Useless do
defp another_userless, do: nil
end
当你编译时没有标志:
☁ 01_language [master] ⚡ elixirc useless.ex
useless.ex:2: warning: function another_userless/0 is unused
☁ 01_language [master] ⚡ echo $?
0
您得到的 return 代码为 0。
但是当你用标志 --warnings-as-errors
编译时,它 return 的退出代码是 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
您可以在编译脚本中使用此 return 代码来中断构建过程。
在你的mix.exs
中:
def project do
[...,
aliases: aliases]
end
defp aliases do
["compile": ["compile --warnings-as-errors"]]
end
然后mix compile
将--warnings-as-errors
传递给compile.elixir
子任务。
这也适用于 mix test
,因为它 运行 是隐式的 compile
任务。
如果您不添加别名,您仍然可以 运行 mix compile --warnings-as-errors
并且它会如您所愿,但 mix test --warnings-as-errors
不会如您所愿,因为标志未到达 compile.elixir
任务。
我喜欢 Michael Stalker 的解决方案 here。
将警告视为错误 总是 在 TDD 期间会很烦人,您可能会在 运行 测试时快速重构代码。
相反,您可以像这样在您的 Mix 环境中设置 --warnings-as-errors
标志条件:
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
测试时会忽略警告,但 dev
或 prod
编译时不会。