Mix
Mix — это инструмент сборки, предоставляющий задачи для создания, компиляции и тестирования проектов Elixir, управления его зависимостями и многое другое.
Mix.Project
Основой Mix является проект. Проект можно определить, используя Mix.Project в модуле, обычно размещаемом в файле с именем mix.exs:
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :my_app,
version: "1.0.0"
]
end
end
Для получения подробной документации по проектам Mix см. Mix.Project модуль.
После определения проекта ряд задач Mix по умолчанию можно выполнить непосредственно из командной строки:
-
mix compile— компилирует текущий проект -
mix test— выполняет тесты для данного проекта -
mix run— выполняет определённую команду внутри проекта
Каждая задача имеет свои параметры и иногда специфическую конфигурацию, которая должна быть определена в функции project/0. Вы можете использовать mix help для перечисления всех доступных задач и mix help NAME для отображения справки по конкретной задаче.
Лучший способ начать работу с первым проектом — вызвать mix new my_project из командной строки.
Mix.Task
Задачи делают Mix расширяемым.
Проекты могут расширить поведение Mix, добавив свои собственные задачи. Например, добавление задачи ниже в ваш проект сделает её доступной всем, кто использует ваш проект:
defmodule Mix.Tasks.Hello do
use Mix.Task
def run(_) do
Mix.shell().info("Hello world")
end
end
Теперь задачу можно вызвать с помощью mix hello.
Для получения подробной документации по задачам Mix см. Mix.Task поведение.
Зависимости
Mix также управляет вашими зависимостями и хорошо интегрируется с менеджером пакетов Hex.
Для использования зависимостей необходимо добавить ключ :deps в вашу конфигурацию проекта. Часто список зависимостей выделяют в отдельную функцию:
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :my_app,
version: "1.0.0",
deps: deps()
]
end
defp deps do
[
{:ecto, "~> 2.0"},
{:plug, github: "elixir-lang/plug"}
]
end
end
Чтобы узнать больше о зависимостях в Mix, выполните mix help deps.
Среды
Mix поддерживает разные среды. Среды позволяют разработчикам подготовить и организовать проект для различных сценариев. По умолчанию Mix предоставляет три среды:
-
:dev— среда по умолчанию -
:test— среда, в которой выполняетсяmix test -
:prod— среда, в которой работают ваши зависимости
Среду можно изменить через командную строку, установив переменную среды MIX_ENV, например:
$ MIX_ENV=prod mix run server.exs
Также можно указать, что определённые зависимости доступны только для определённых сред:
{:some_test_dependency, "~> 1.0", only: :test}
Среду можно прочитать с помощью Mix.env/0.
Цели
Помимо сред, Mix поддерживает цели. Цели полезны, когда проект необходимо скомпилировать для разных архитектур, а некоторые зависимости доступны только для некоторых из них. По умолчанию цель — :host , но её можно установить с помощью переменной среды MIX_TARGET . Цель можно прочитать с помощью Mix.target/0.
Псевдонимы
Псевдонимы — это сокращения или задачи, специфичные для текущего проекта.
В разделе "Mix.Task" мы определили задачу, которая была бы доступна всем, кто использует наш проект в качестве зависимости. А что, если мы хотим, чтобы задача была доступна только для нашего проекта? Просто определите псевдоним:
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :my_app,
version: "1.0.0",
aliases: aliases()
]
end
defp aliases do
[
c: "compile",
hello: &hello/1
]
end
defp hello(_) do
Mix.shell().info("Hello world")
end
end
В примере выше мы определили два псевдонима. Один — mix c , который является сокращением для mix compile. Другой — mix hello, который эквивалентен Mix.Tasks.Hello , определённому в разделе "Mix.Task".
Псевдонимы также могут быть списками, задавая несколько задач, которые будут выполняться последовательно:
[all: [&hello/1, "deps.get --only #{Mix.env()}", "compile"]]
В примере выше мы определили псевдоним mix all, который выводит "Hello world", затем получает зависимости, специфичные для текущей среды, и компилирует проект.
Псевдонимы также могут быть использованы для дополнения существующих задач. Предположим, вы хотите дополнить mix clean, чтобы очистить другую директорию, о которой Mix не знает:
[clean: ["clean", &clean_extra/1]]
Где &clean_extra/1 будет функцией в вашем mix.exs с дополнительной логикой очистки.
Аргументы, заданные псевдониму, будут добавлены к аргументам последней задачи в списке. За исключением переопределения существующей задачи. В этом случае аргументы будут переданы исходной задаче, чтобы сохранить семантику. Например, в псевдониме :clean выше, аргументы, заданные псевдониму, будут переданы в "clean", а не в clean_extra/1.
Псевдонимы, определённые в текущем проекте, не влияют на его зависимости, и псевдонимы, определённые в зависимостях, недоступны из текущего проекта.
Псевдонимы могут быть очень мощными для запуска скриптов Elixir и команд оболочки, например:
# priv/hello1.exs
IO.puts("Hello One")
# priv/hello2.exs
IO.puts("Hello Two")
# priv/world.sh
#!/bin/sh
echo "world!"
# mix.exs
defp aliases do
[
some_alias: ["hex.info", "run priv/hello1.exs", "cmd priv/world.sh"]
]
end
В примере выше мы создали псевдоним some_alias , который выполнит задачу mix hex.info, затем mix run для запуска скрипта Elixir, затем mix cmd для выполнения скрипта командной строки. Это демонстрирует, насколько мощными могут быть псевдонимы в сочетании с задачами Mix.
Задачи Mix предназначены для выполнения только один раз. Это предотвращает повторное выполнение одной и той же задачи. Например, если есть несколько задач, зависящих от mix compile, код будет скомпилирован один раз. Задачи можно выполнить снова, если они явным образом повторно активированы с помощью Mix.Task.reenable/1:
another_alias: [
"format --check-formatted priv/hello1.exs",
"cmd priv/world.sh",
fn _ -> Mix.Task.reenable("format") end,
"format --check-formatted priv/hello2.exs"
]
Однако некоторые задачи автоматически повторно активируются, поскольку ожидается, что они будут вызываться несколько раз. Это: mix cmd, mix do, mix loadconfig, mix profile.cprof, mix profile.eprof, mix profile.fprof, mix run и mix xref.
Стоит отметить, что некоторые задачи, как в случае с командой mix format в примере выше, могут принимать несколько файлов, поэтому её можно переписать как:
another_alias: ["format --check-formatted priv/hello1.exs priv/hello2.exs"]
Переменные окружения
Несколько переменных окружения могут быть использованы для изменения поведения Mix.
Mix реагирует на следующие переменные:
-
MIX_ARCHIVES— задаёт директорию, в которую должны быть установлены архивы (по умолчанию:~/.mix/archives) -
MIX_BUILD_ROOT— задаёт корневую директорию, в которую должны быть записаны артефакты сборки. Например, "_build". ЕслиMIX_BUILD_PATHустановлено, этот параметр игнорируется. -
MIX_BUILD_PATH— задаёт конфигурацию проектаMix.Project.build_path/0. Этот параметр всегда должен указывать на поддиректорию внутри временной директории. Например, никогда не "/tmp" или "_build", а "_build/PROD" или "/tmp/PROD", как требуется Mix -
MIX_DEPS_PATH— задаёт конфигурацию проектаMix.Project.deps_path/0(по умолчанию:deps) -
MIX_DEBUG— выводит отладочную информацию о каждой задаче перед её запуском -
MIX_ENV— задаёт среду, которая должна быть использована. См. Среды -
MIX_TARGET— задаёт цель, которая должна быть использована. См. Цели -
MIX_EXS— изменяет полный путь к файлуmix.exs -
MIX_HOME— путь к домашнему каталогу Mix, хранит конфигурационные файлы и скрипты, используемые Mix (по умолчанию:~/.mix) -
MIX_PATH— добавляет дополнительные пути к коду -
MIX_QUIET— не выводит информационные сообщения в терминал -
MIX_REBAR— путь к команде rebar, которая переопределяет установленную Mix (по умолчанию:~/.mix/rebar) -
MIX_REBAR3— путь к команде rebar3, которая переопределяет установленную Mix (по умолчанию:~/.mix/rebar3) -
MIX_XDG— просит Mix следовать Спецификации XDG для директорий для своего домашнего каталога и конфигурационных файлов. Это поведение нужно включать по необходимости из-за обратной совместимости.MIX_HOMEимеет более высокий приоритет, чемMIX_XDG. Если ни одна из переменных не установлена, будет использоваться каталога по умолчанию~/.mix
Переменные окружения, которые не предназначены для хранения значения (и действуют в основном как флаги), должны быть установлены в 1 или true, например:
$ MIX_DEBUG=1 mix compile
Обзор
Функции
- compilers()
Возвращает по умолчанию используемые Mix компиляторы.
- debug(debug)
Устанавливает режим отладки Mix.
- debug?()
Возвращает
trueесли Mix в режиме отладки,falseв противном случае.- env()
Возвращает текущую среду Mix.
- env(env)
Изменяет текущую среду Mix на
env.- path_for(atom)
Путь к локальным архивам или escripts.
- raise(message)
Вызывает ошибку Mix с красивым форматированием.
- shell()
Возвращает текущую оболочку.
- shell(shell)
Устанавливает текущую оболочку.
- target()
Возвращает цель Mix.
- target(target)
Изменяет текущую цель Mix на
target.
Функции
compilers()
Specs
compilers() :: [atom()]
Возвращает по умолчанию используемые Mix компиляторы.
Его можно использовать в вашем mix.exs для добавления новых компиляторов в Mix:
def project do [compilers: Mix.compilers() ++ [:foo, :bar]] end
debug(debug)
Specs
debug(boolean()) :: :ok
Устанавливает режим отладки Mix.
debug?()
Specs
debug?() :: boolean()
Возвращает true если Mix в режиме отладки, false в противном случае.
env()
Specs
env() :: atom()
Возвращает текущую среду Mix.
Эта функция не должна использоваться во время выполнения в коде приложения (в отличие от инфраструктурного и билда кода, например, задач Mix). Mix — это инструмент сборки и может быть недоступен после компиляции кода (например, в релизе).
Для различения поведения программы в зависимости от среды рекомендуется использовать среду приложения через Application.get_env/3. Правильную конфигурацию можно задать в файлах конфигурации, часто по каждой среде (см. модуль Config для получения дополнительной информации).
env(env)
Specs
env(atom()) :: :ok
Изменяет текущую среду Mix на env.
Будьте осторожны при вызове этой функции, так как любая конфигурация проекта не будет перезагружена.
Эта функция не должна использоваться во время выполнения в коде приложения (см. env/0 для получения дополнительной информации).
path_for(atom)
Specs
path_for(:archives | :escripts) :: String.t()
Путь к локальным архивам или escripts.
raise(message)
Specs
raise(binary()) :: no_return()
Вызывает ошибку Mix с красивым форматированием.
shell()
Specs
shell() :: module()
Возвращает текущую оболочку.
shell/0 может использоваться в качестве оболочки для текущей оболочки. Она содержит удобства для запроса информации у пользователя, вывода в оболочку и так далее. Оболочка Mix взаимозаменяема (см. shell/1), позволяя разработчикам использовать тестовую оболочку, которая просто отправляет сообщения в текущий процесс вместо выполнения ввода-вывода (см. Mix.Shell.Process).
По умолчанию это возвращает Mix.Shell.IO.
Примеры
Mix.shell().info("Preparing to do something dangerous...")
if Mix.shell().yes?("Are you sure?") do
# do something dangerous
end shell(shell)
Specs
shell(module()) :: :ok
Устанавливает текущую оболочку.
В качестве аргумента можно передать Mix.Shell.IO, Mix.Shell.Process, Mix.Shell.Quiet или любой модуль, который реализует поведение Mix.Shell.
После вызова этой функции shell становится оболочкой, возвращаемой shell/0.
Примеры
iex> Mix.shell(Mix.Shell.IO) :ok
Можно использовать shell/0 и shell/1 для временного переключения оболочек, например, если вы хотите запустить задачу Mix, которая обычно генерирует много вывода:
shell = Mix.shell()
Mix.shell(Mix.Shell.Quiet)
try do
Mix.Task.run("noisy.task")
after
Mix.shell(shell)
end target()
Specs
target() :: atom()
Возвращает цель Mix.
target(target)
Specs
target(atom()) :: :ok
Изменяет текущую цель Mix на target.
Будьте осторожны при вызове этой функции, так как любая конфигурация проекта не будет перезагружена.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/mix/1.11.2/Mix.html