One of the bittersweet things about Go is its relentlessness with warnings.
You cannot compile your Go code which has warnings in it. This is great for the long term health of the project.
However, it is not so pleasant while writing the code. Elixir takes an opposite approach to this where even
errors which should break your build are treated as warnings. One such instance are Behaviours.
If you have a module which implements a behaviour and does not implement a non optional callback, all elixir does is emit a warning!
It should really throw an error and stop the compilation. However, all hope is not lost! You can use an elixir compiler flag to treat
warnings as errors. All you need to do is add the following to your
def project do
# treat warnings as errors in non dev environments
elixirc_options: [warnings_as_errors: Mix.env != :dev],
You can even hard code it to
true and it will always treat warnings as errors. However, non dev is the sweet spot for me, as I may be testing incomplete code with warnings in dev.
You can also pass these options to via the cli like so:
# using elixirc
elixirc --warnings-as-errors awesome_possum.ex
# using mix
mix compile --warnings-as-errors
A few days ago I created a mix task for one of my hex packages. This package
was just a wrapper around the awesome shipit package.
Now, this task is specific to my hex package and isn’t going to be used by apps
which depend on my hex package. However, today I found my mix task happily listed
in the host apps’ list of tasks. This is not a good thing :)
I initially tried changing the extension of the mix task to
.exs but that didn’t help.
The mix task was not even listed in my hex package now.
After a lot of digging I found two useful pieces of info which helped me get around this.
Mix deps have an
:env key which defaults to
:prod. This means, when mix compiles a dependency, the value of Mix.env inside that dependency is set to
Mix compiler has an
:elixirc_paths flag which tells the compiler where to look for elixir source code.
Knowing this, all I had to do was:
- Move the mix tasks from
./mix/tasks so that it is not picked up by default.
mix.exs by adding the following to the project, so that in the
:dev env of the hex package our mix task is loaded/compiled.
def project do
defp elixirc_paths(:dev), do: ["lib", "mix"]
defp elixirc_paths(_), do: ["lib"]
Now my hex specific mix tasks are loaded only when I am working on my hex package. And the users of my hex package don’t see my mix utility tasks.