Elixir - Mix
21 May 2017Mix assumes that we are in the development environment unless we tell it otherwise with MIX_ENV=
mix some_task.
common tasks
-
mix compile
compiles the whole project including dependencies.
-
mix deps.compile [<package>]
compiles project dependencies only (say, when you need to recompile dependencies after editing their source code manually).
-
mix deps.get
=bundle install
gets all missing and out of date dependencies (updates existing ones up to the version specified in mix.lock).
-
mix deps.clean --unused --unlock
=bundle install
removes dependencies which are no longer listed in mix.exs (
--unused
) and updates mix.lock (--unlock
). -
mix deps.update --all
=bundle update
updates all dependencies and writes updated versions to mix.lock.
-
mix deps.update <package>
=bundle update <gem>
updates dependency and writes updated version to mix.lock.
Phoenix tasks
mix phx.server
=rails server
mix phx.routes
=rake routes
mix phx.gen.secret
=rake secret
mix.exs
-
application name
def project do [ app: :neko, ... ] end
- stored in neko.app (created when project is compiled)
- used to start/stop application manually in IEx
-
application inference
deps should be no longer listed in applications list explicitly:
def application do [ # this line is longer necessary - all dependencies # are added to `applications` by default in Elixir 1.4 #applications: [:httpoison], # specify only extra applications from Erlang/Elixir extra_applications: [:logger], mod: {Neko.Application, []} ] end defp deps do [ {:httpoison, "~> 0.11.1"} ] end
tips
(how to) run multiple tasks at once
$ mix do deps.get, compile
which is equivalent to:
$ mix deps.get && mix compile
(how to) set default environment for any task
- https://hexdocs.pm/mix/Mix.Task.html#preferred_cli_env/1
- https://elixirforum.com/t/how-do-i-set-the-env-at-alias/16304
https://hexdocs.pm/mix/Mix.Task.html#module-attributes
@preferred_cli_env - recommends environment to run task. It is used in absence of a Mix project recommendation, or explicit MIX_ENV, and it only works for tasks in the current project.
# mix.exs
def project do
[
# ...
preferred_cli_env: [
deploy: :prod
]
]
end
troubleshooting
Mix doesn’t allow to run the same task twice in alias
Rake has the same behaviour - task must be reenabled explicitly before it can be run again.
thus it’s impossible to create alias in mix.exs for the list of tasks in which the same task is run multiple times with different arguments:
defp aliases do
[
# works
"ecto.reset": ["ecto.drop", "ecto.setup"],
# doesn't work (the 2nd task is not run)
"deploy.prod": [
"edeliver build release",
"edeliver deploy release production"
]
]
end
alternating between 2 tasks doesn’t reenable the 1st task:
defp aliases do
[
"edeliver.all": [
"edeliver build release",
"deps.get",
# edeliver task is not reenabled
"edeliver deploy release production"
]
]
end
solution
- https://stackoverflow.com/questions/36846041
- https://hexdocs.pm/mix/Mix.Task.html#rerun/2
- https://hexdocs.pm/mix/Mix.html#module-aliases
- https://github.com/elixir-lang/elixir/blob/master/lib/mix/test/mix/task_test.exs#L138
it’s possible to pass function instead of a string with task name and
task arguments - that function would need to use Mix.Task.rerun/2
to
run the same task multiple times (it reenables the task before running it):
defp aliases do
[
"deploy.stage": [
&deploy_stage/1,
"cmd ssh devops@billing sudo systemctl restart billing_stage"
]
]
end
defp deploy_stage(_) do
Mix.shell().info("[billing staging]")
Mix.Task.run(:edeliver, ["update", "staging", "--mix-env=stage"])
Mix.Task.rerun(:edeliver, ["migrate", "staging"])
end
for some reason it’s required to define function with arity of 1 - otherwise Mix complains:
(FunctionClauseError) no function clause matching in Mix.Task.run_alias/3