<Enjoy-Elixir>Mix
Enjoy-Elixirと称する、プログラミング言語Elixirを勉強する記事群の1つです。
Mixとは?
mix
コマンドはElixirをインストールした時に付随してインストールされているはずです。とりあえず help
を見てみましょう。
$ mix --help
Mix is a build tool for Elixir
Usage: mix [task]
Examples:
mix - Invokes the default task (mix run) in a project
mix new PATH - Creates a new Elixir project at the given path
mix help - Lists all available tasks
mix help TASK - Prints documentation for a given task
The --help and --version options can be given instead of a task for usage and versioning information.
Mix is a build tool for Elixir
mix
はElixirのためのビルドツールです。ビルドツールって何でしょうね?
hexdocs
を見るともう少し詳しいことが書いてあります。
Mix is a build tool that provides tasks for creating, compiling, and testing Elixir projects, managing its dependencies, and more.
まず Elixirプロジェクト(Mixプロジェクト)
という概念・モノがあります。 mix
は、この Elixirプロジェクト(Mixプロジェクト)
を作成したり、コンパイルしたりテスト実行できるものです。さらにプロジェクトに必要な依存関係も管理してくれます。もっといろんなことも。
というわけで、単に「ビルドツール」と呼ぶより、 Elixirプロジェクトを管理するツール と考えたほうがわかりやすいでしょう。
Elixirプロジェクトを見てみよう
ここでは既存の Elixirプロジェクト
を持ってきて、 mix
コマンドを使い、どんなことができるかやってみます。
Elixirプロジェクトとして、JSONライブラリである michalmuskala/jason
を使います。
# 準備
$ git clone https://github.com/michalmuskala/jason.git
$ cd jason
$ ls -1
CHANGELOG.md
LICENSE
README.md
bench
dialyzer.ignore
formatter_test_suite
json_test_suite
lib
mix.exs
mix.lock
test
mix help
コマンドを実行すると、このプロジェクトで利用できる task
がわかります。
# current dir is /path/to/jason
$ mix help
mix # Runs the default task (current: "mix run")
mix app.config # Configures all registered apps
mix app.start # Starts all registered apps
mix app.tree # Prints the application tree
mix archive # Lists installed archives
mix archive.build # Archives this project into a .ez file
mix archive.install # Installs an archive locally
mix archive.uninstall # Uninstalls archives
mix clean # Deletes generated application files
mix cmd # Executes the given command
mix compile # Compiles source files
mix deps # Lists dependencies and their status
mix deps.clean # Deletes the given dependencies' files
mix deps.compile # Compiles dependencies
mix deps.get # Gets all out of date dependencies
mix deps.tree # Prints the dependency tree
mix deps.unlock # Unlocks the given dependencies
mix deps.update # Updates the given dependencies
mix do # Executes the tasks separated by comma
mix escript # Lists installed escripts
mix escript.build # Builds an escript for the project
mix escript.install # Installs an escript locally
mix escript.uninstall # Uninstalls escripts
mix format # Formats the given files/patterns
mix help # Prints help information for tasks
mix hex # Prints Hex help information
mix hex.audit # Shows retired Hex deps for the current project
mix hex.build # Builds a new package version locally
mix hex.config # Reads, updates or deletes local Hex config
mix hex.docs # Fetches or opens documentation of a package
mix hex.info # Prints Hex information
mix hex.organization # Manages Hex.pm organizations
mix hex.outdated # Shows outdated Hex deps for the current project
mix hex.owner # Manages Hex package ownership
mix hex.package # Fetches or diffs packages
mix hex.publish # Publishes a new package version
mix hex.repo # Manages Hex repositories
mix hex.retire # Retires a package version
mix hex.search # Searches for package names
mix hex.user # Manages your Hex user account
mix loadconfig # Loads and persists the given configuration
mix local # Lists local tasks
mix local.hex # Installs Hex locally
mix local.public_keys # Manages public keys
mix local.rebar # Installs Rebar locally
mix new # Creates a new Elixir project
mix profile.cprof # Profiles the given file or expression with cprof
mix profile.eprof # Profiles the given file or expression with eprof
mix profile.fprof # Profiles the given file or expression with fprof
mix release # Assembles a self-contained release
mix release.init # Generates sample files for releases
mix run # Starts and runs the current application
mix test # Runs a project's tests
mix test.coverage # Build report from exported test coverage
mix xref # Prints cross reference information
iex -S mix # Starts IEx and runs the default task
けっこう色んな task
がありますね。
とりあえずは mix run
を実行してみます。
$ mix run
Unchecked dependencies for environment dev:
* ex_doc (Hex package)
the dependency is not available, run "mix deps.get"
* decimal (Hex package)
the dependency is not available, run "mix deps.get"
* dialyxir (Hex package)
the dependency is not available, run "mix deps.get"
** (Mix) Can't continue due to errors on dependencies
プロジェクトに必要な依存関係が解決されていないようです。
プロジェクトに必要なものを揃えるために、 mix deps.get
を実行します。
$ mix deps.get
07:12:39.800 [error] Task #PID<0.160.0> started from :hex_fetcher terminating
** (UndefinedFunctionError) function :ssl.cipher_suites/1 is undefined or private
(ssl 10.4.1) :ssl.cipher_suites(:openssl)
(hex 0.20.5) lib/hex/http/ssl.ex:124: Hex.HTTP.SSL.filter_ciphers/1
(hex 0.20.5) lib/hex/http/ssl.ex:66: Hex.HTTP.SSL.ssl_opts/1
(hex 0.20.5) lib/hex/http.ex:41: Hex.HTTP.build_http_opts/2
(hex 0.20.5) lib/hex/http.ex:16: Hex.HTTP.request/5
(hex 0.20.5) lib/hex/registry/server.ex:306: anonymous fn/3 in Hex.Registry.Server.prefetch_online
/2
(elixir 1.12.1) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
(elixir 1.12.1) lib/task/supervised.ex:35: Task.Supervised.reply/5
Function: #Function<17.86168715/0 in Hex.Registry.Server.prefetch_online/2>
Args: []
なんかエラーが出ました。。。
調べると、 mix local.hex
をする必要があるみたいです。
Hex
について少し調べてみましょう。
Hex
はパッケージマネージャーです。Hex
のサイトにElixrやErlangのアプリケーション、ライブラリが登録されていて、そこからいい感じにバージョンや依存関係を解決して、取得できるものです。
Mix
はプロジェクト管理ツールでしたね。 Mix
の仕事の1つに依存関係の解決がありますが、そこで Hex
を使っているわけです。
Mix
で依存関係の解決を行うためには Hex
が必要になります。
というわけで、 Hex
を導入しましょう。
$ mix local.hex
この後、再び mix deps.get
を実行します。
$ mix deps.get
Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
decimal 2.0.0
dialyxir 1.0.0
earmark_parser 1.4.10
erlex 0.2.6
ex_doc 0.23.0
makeup 1.0.5
makeup_elixir 0.15.0
nimble_parsec 1.1.0
stream_data 0.5.0
* Getting decimal (Hex package)
* Getting dialyxir (Hex package)
* Getting ex_doc (Hex package)
* Getting stream_data (Hex package)
* Getting earmark_parser (Hex package)
* Getting makeup_elixir (Hex package)
* Getting makeup (Hex package)
* Getting nimble_parsec (Hex package)
* Getting erlex (Hex package)
jason
プロジェクトに必要なライブラリを取得して、依存関係を解決することができましたね。
mix run
を実行してみましょう。
$ mix run
==> earmark_parser
Compiling 1 file (.yrl)
Compiling 2 files (.xrl)
Compiling 3 files (.erl)
Compiling 32 files (.ex)
Generated earmark_parser app
==> erlex
Compiling 1 file (.yrl)
src/parser.yrl: Warning: conflicts: 27 shift/reduce, 0 reduce/reduce
Compiling 1 file (.xrl)
Compiling 2 files (.erl)
Compiling 1 file (.ex)
Generated erlex app
==> nimble_parsec
Compiling 4 files (.ex)
Generated nimble_parsec app
==> makeup
Compiling 44 files (.ex)
Generated makeup app
==> decimal
Compiling 4 files (.ex)
Generated decimal app
==> dialyxir
Compiling 59 files (.ex)
warning: Mix.Project.compile/1 is deprecated. Use Mix.Task.run("compile", args) instead
lib/dialyxir/project.ex:47: Dialyxir.Project.cons_apps/0
warning: Mix.Project.compile/1 is deprecated. Use Mix.Task.run("compile", args) instead
lib/mix/tasks/dialyzer.ex:164: Mix.Tasks.Dialyzer.run/1
Generated dialyxir app
==> makeup_elixir
Compiling 6 files (.ex)
Generated makeup_elixir app
==> ex_doc
Compiling 22 files (.ex)
Generated ex_doc app
==> jason
Compiling 9 files (.ex)
Generated jason app
mix run
を実行すると、 Generated jason app
と最後に出力されているので、アプリケーションのビルドが実行されましたね。アプリケーションのビルドは、プロジェクト管理ツールの仕事の1つですね。
テストも実行してみましょう。テストの実行は mix test
です。
$ mix test
==> makeup_elixir
Compiling 6 files (.ex)
Generated makeup_elixir app
bash-3.2$ mix test
==> erlex
Compiling 2 files (.erl)
Compiling 1 file (.ex)
Generated erlex app
==> stream_data
Compiling 3 files (.ex)
Generated stream_data app
==> decimal
Compiling 4 files (.ex)
Generated decimal app
==> dialyxir
Compiling 59 files (.ex)
warning: Mix.Project.compile/1 is deprecated. Use Mix.Task.run("compile", args) instead
lib/dialyxir/project.ex:47: Dialyxir.Project.cons_apps/0
warning: Mix.Project.compile/1 is deprecated. Use Mix.Task.run("compile", args) instead
lib/mix/tasks/dialyzer.ex:164: Mix.Tasks.Dialyzer.run/1
Generated dialyxir app
==> jason
Compiling 9 files (.ex)
Generated jason app
......................................................................................................
......................................................................................................
......................................................................................................
......................................................................................................
.............................
Finished in 0.5 seconds (0.5s async, 0.00s sync)
25 doctests, 9 properties, 403 tests, 0 failures
アプリケーションを再コンパイルして、テストを実行、そしてテスト結果が出力されました。テスト実行もプロジェクト管理ツールの1つです。
まとめ
今回の記事は Mix
の紹介でした。
以下に内容をまとめます。
Elixirプロジェクト(Mixプロジェクト)
という概念・モノがあるmix
はElixirプロジェクト
を管理するツールhex
はパッケージマネージャー。mix
の依存関係解決の仕事で使われるので必要になるmix
に定義されているtask
を実行することで、プロジェクトに関することが色々できる- たとえば
mix deps.get
で依存関係の解決ができる - たとえば
mix test
でテストを実行できる
Mix
はElixirプロジェジエクトの管理ツールだ、というところを押さえておきましょう。
次は michalmuskala/jason
ライブラリ(Elixirプロジェクト) をコードリーティングしながら、学習を進めていく予定です。