LoginSignup
1
1

More than 5 years have passed since last update.

mix.exs の中の version の値を外部ファイルに外出し

Posted at

諸般の事情により mix.exs の中で設定しているバージョン番号をコントローラから取得するニーズがあってちょっと調べてみたんですが、残念ながら直接そういう機能が無かったため、簡単なマクロで実現してみました。

ロジックは非常に単純で、mix.exs と同じ場所に VERSION というファイルを置き、その中にバージョン番号を記入するだけです。

コンパイル時にこの値を読み込んで、モジュールの中に version() という関数を動的に生成してくれるので、あとは mix.exs あるいはコントローラの好きな場所で呼び出すだけです。

VERSIONファイルの例
1.2.3
mix.exs
defmodule Foo.Mixfile do
  use Mix.Project

  ########## ここから追加
  version = File.stream!("VERSION", [], :line)
  |> Enum.at(0)
  |> String.strip()

  def version(), do: unquote(version)
  ########## ここまで追加

  def project do
    [app: :foo,
     version: version(),   ##### ← version()に変更
     elixir: "~> 1.3",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix, :gettext] ++ Mix.compilers,
     build_embedded: (Mix.env == :stg) or (Mix.env == :prod),
     start_permanent: (Mix.env == :stg) or (Mix.env == :prod),
     aliases: aliases,
     deps: deps]
  end

・コントローラからバージョンを取得する時用の関数

controller/foo.ex
defmodule Foo.util do

  version = File.stream!("VERSION", [], :line)
  |> Enum.at(0)
  |> String.strip()

  def version(), do: unquote(version)
end

本当は DRY にしたかったんですが、mix.exs から他のモジュール(上記の例だと Foo.util.version)の関数を呼び出しても、おそらく優先度の関係でモジュールを見つけることができずエラーになってしまいました。

その逆に Foo.Mixfile モジュール の中の関数を Foo.util.version() から呼ぼうとしても、まぁ当たり前ですがリリースビルド版では * (UndefinedFunctionError) function Foo.Mixfile.version/0 is undefined (module Foo.Mixfile is not available) になってしまいました。

まぁロジックも短いので気にしないことにします(いい解決方法をご存知の方、ぜひコメントを!)

1
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1