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

29
我有一个已定义版本的Elixir项目。怎样才能从正在运行的应用程序中访问它?
在mix.exs中。
  def project do
    [app: :my_app,
     version: "0.0.1"]
  end

我希望能够获取应用程序中的版本号,以便将其添加到返回的消息中。我正在寻找类似于 env 哈希中的以下内容。

__ENV__.version
# => 0.0.1
6个回答

40

Mix.Project 本身通过其 config/0 (API 文档) 函数,提供了对在 mix.exs 中定义的所有项目关键字的访问。为了简洁地访问它,可能会将其包装进一个函数中:

@version Mix.Project.config[:version]
def version(), do: @version

7
请确保像示例中展示的那样在编译时进行评估。否则,在生产环境中它将无法工作,因为 module Mix.Project 不可用。 - Joe Eifert

27

这里有一种类似的方法可以获取版本字符串。它也依赖于:application模块,但可能更加简单明了:

{:ok, vsn} = :application.get_key(:my_app, :vsn)
List.to_string(vsn)

这是更好的方法。个人而言,我仍然会使用 charlist |> string |> integer 解析管道,但这绝对比使用 which_applications 更干净。 - Chris Meyer
是的,说得好。Chris的解决方案显然更长,因为它多了一步将字符串转换为整数元组的操作。仅用于打印输出,普通字符串应该已经足够了。如果需要,您可以将这两个答案结合起来以获取元组。 - Patrick Oscity
如果你正在使用escript或类似的工具来构建一个命令行应用程序,这个解决方案非常适合 :) - undefined

22

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

接下来是使用方法:

iex(1)> AppHelper.app_version(:logger)
{1, 0, 5}

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


1
好的答案,谢谢。虽然如果这是获取它的最佳方式,有点遗憾。 - Peter Saxton
2
这是Jose Valim几周前给某人的指导,即使用:application.which_application。 https://groups.google.com/d/msg/elixir-lang-talk/qlX4hJKZvC8/pCZBqM1zCQAJ - Onorio Catenacci

3
您可以简单地使用以下方法:
YourApp.Mixfile.project[:version]

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Mogsdad

2

Application.spec(:my_app, :vsn)函数在应用程序启动时使用。如果您正在执行Mix任务并且不需要启动应用程序,则可以在Elixir 1.8中使用以下方法:

Application.compile_and_load(application_name)

MyApp.MixProject.project |> Keyword.fetch!(:version)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接