在elixir应用程序中访问项目版本

Pet*_*ton 19 elixir erlang-otp

我有一个定义版本的elixir项目.如何从正在运行的应用程序中访问它.

在mix.exs中

  def project do
    [app: :my_app,
     version: "0.0.1"]
  end
Run Code Online (Sandbox Code Playgroud)

我想在应用程序中访问此版本号,以便我可以将其添加到返回的消息中.我在env哈希中寻找一些东西,如下所示

__ENV__.version
# => 0.0.1
Run Code Online (Sandbox Code Playgroud)

0x0*_*0me 28

Mix.Project本身提供对mix.exs使用其config/0(api doc)函数定义的所有项目关键字的访问.为了简洁访问,它可能被包装到一个函数中:

@version Mix.Project.config[:version]
def version(), do: @version
Run Code Online (Sandbox Code Playgroud)

  • 确保在编译时评估它,如示例中所示.否则它将无法在生产中工作,因为`模块Mix.Project不可用. (4认同)

Pat*_*ity 16

这是检索版本字符串的类似方法.它也依赖于:application模块,但可能更直接:

{:ok, vsn} = :application.get_key(:my_app, :vsn)
List.to_string(vsn)
Run Code Online (Sandbox Code Playgroud)


Dr.*_*nie 11

在最新版本的Elixir中,“应用程序”模块现在为您包装了以下内容:

https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/application.ex

Application.spec(:my_app, :vsn)


Chr*_*yer 6

我发现里面的版本:application.which_applications,但它需要一些解析:

defmodule AppHelper do
  @spec app_version(atom) :: {integer, integer, integer}
  def app_version(target_app) do
    :application.which_applications
    |> Enum.filter(fn({app, _, _}) ->
                    app == target_app
                   end)
    |> get_app_vsn
  end

  # I use a sensible fallback when we can't find the app,
  # you could omit the first signature and just crash when the app DNE.
  defp get_app_vsn([]), do: {0,0,0} 
  defp get_app_vsn([{_app, _desc, vsn}]) do
    [maj, min, rev] = vsn
                      |> List.to_string
                      |> String.split(".")
                      |> Enum.map(&String.to_integer/1)
    {maj, min, rev}
  end
end
Run Code Online (Sandbox Code Playgroud)

然后用于:

iex(1)> AppHelper.app_version(:logger)
{1, 0, 5}
Run Code Online (Sandbox Code Playgroud)

一如既往,可能有更好的方法.

  • 这是何塞·瓦利姆几周前给某人的指导。也就是说,使用 :application.which_application。https://groups.google.com/d/msg/elixir-lang-talk/qlX4hJKZvC8/pCZBqM1zCQAJ (2认同)