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 help deps, чтобы узнать больше о зависимостях в Mix.
Среды
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_INSTALL_DIR— (с версии v1.12.0) указывает каталог, гдеMix.install/2хранит кеш установок -
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.- install(deps, opts \\ [])
Устанавливает и запускает зависимости.
- path_for(atom)
Путь к локальным архивам или escripts.
- raise(message)
Вызывает ошибку Mix, которая оформлена в удобном формате, по умолчанию с кодом выхода
1.- raise(message, opts)
Вызывает ошибку Mix, которая оформлена в удобном формате.
- shell()
Возвращает текущую оболочку.
- shell(shell)
Устанавливает текущую оболочку.
- target()
Возвращает цель Mix.
- target(target)
Изменяет текущую цель Mix на
target.
Функции
compilers()Source
Specs
compilers() :: [atom()]
Возвращает стандартные компиляторы, используемые Mix.
Можно использовать в вашем mix.exs для добавления новых компиляторов в Mix:
def project do [compilers: Mix.compilers() ++ [:foo, :bar]] end
debug(debug)Source
Specs
debug(boolean()) :: :ok
Устанавливает режим отладки Mix.
debug?()Source
Specs
debug?() :: boolean()
Возвращает true, если Mix в режиме отладки, false в противном случае.
env()Source
Specs
env() :: atom()
Возвращает текущую среду Mix.
Эта функция не должна использоваться во время выполнения в прикладном коде (в отличие от инфраструктурного и билд-кода, такого как задачи Mix). Mix — это инструмент для сборки, и он может быть недоступен после компиляции кода (например, в релизе).
Для различения поведения программы в зависимости от среды рекомендуется использовать среду приложения через Application.get_env/3. Правильная конфигурация может быть задана в файлах конфигурации, часто по каждой среде (см. модуль Config для получения дополнительной информации).
env(env)Source
Specs
env(atom()) :: :ok
Изменяет текущую среду Mix на env.
Будьте внимательны при вызове этой функции, так как любая конфигурация проекта не будет перезагружена.
Эта функция не должна использоваться во время выполнения в прикладном коде (см. env/0 для получения дополнительной информации).
install(deps, opts \\ [])Source
Устанавливает и запускает зависимости.
Указанные deps должны быть в том же формате, что и в обычном проекте Mix. См. mix help deps для получения дополнительной информации. В качестве сокращения в качестве зависимости может быть указан атом, означающий последнюю версию. Другими словами, указание :decimal эквивалентно {:decimal, ">= 0.0.0"}.
После каждой успешной установки заданный набор зависимостей кэшируется, поэтому при запуске другой виртуальной машины и вызове Mix.install/2 с теми же зависимостями будут избегаться ненужные загрузки и компиляции. Местоположение каталога кэша может контролироваться с помощью переменной окружения MIX_INSTALL_DIR.
Эта функция может вызываться только вне проекта Mix и только с теми же зависимостями в данной виртуальной машине.
Примечание: эта функция в настоящее время находится на стадии экспериментальной разработки и может быть изменена в будущих версиях.
Параметры
:force- еслиtrue, удаляет кэш установки. Это полезно, когда вы хотите обновить свои зависимости или ваша установка попала в несогласованное состояние (по умолчанию:false):verbose- еслиtrue, выводит дополнительную информацию для отладки (по умолчанию:false):consolidate_protocols- еслиtrue, выполняет консолидацию протоколов через задачуmix compile.protocols(по умолчанию:true)
Примеры
Mix.install([
:decimal,
{:jason, "~> 1.0"}
]) path_for(atom)Source
Specs
path_for(:archives | :escripts) :: String.t()
Путь для локальных архивов или escripts.
raise(message)Source
Specs
raise(binary()) :: no_return()
Вызывает ошибку Mix, которая имеет приятный формат, по умолчанию с кодом завершения 1.
raise(message, opts)Source
Specs
raise(binary(), [{:exit_code, non_neg_integer()}]) :: no_return() Вызывает ошибку Mix, которая имеет приятный формат.
Параметры
-
:exit_code- определяет значение кода завершения, по умолчанию1
shell()Source
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)Source
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()Source
Specs
target() :: atom()
Возвращает цель Mix.
target(target)Source
Specs
target(atom()) :: :ok
Изменяет текущую цель Mix на target.
Будьте внимательны при вызове этой функции, так как любая конфигурация проекта не будет перезагружена.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/mix/1.12.0/Mix.html