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

Posted

技术标签:

【中文标题】在 elixir 应用程序中访问项目版本【英文标题】:Access project version within elixir application 【发布时间】:2016-01-03 06:28:18 【问题描述】:

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

在 mix.exs 中

  def project do
    [app: :my_app,
     version: "0.0.1"]
  end

我想在应用程序中访问此版本号,以便将其添加到返回的消息中。我在 env 哈希中寻找如下内容

__ENV__.version
# => 0.0.1

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

确保在编译时对其进行评估,如示例中所示。否则它将无法在生产中工作,因为module Mix.Project is not available.【参考方案2】:

这是检索版本字符串的类似方法。它还依赖于:application 模块,但可能更简单一些:

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

【讨论】:

这是一个更好的方法。就个人而言,我仍然会使用charlist |> string |> integer 解析管道,但这绝对比使用which_applications 更干净。 是的,好点。 Chris 的解决方案显然更长,因为它做了一个额外的步骤来将字符串转换为整数元组。只是为了打印,纯字符串应该足够了。如果需要,您可以结合这两个答案来获取元组。【参考方案3】:

在最新版本的 Elixir 中,Application 模块现在为您包装了这个:

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

Application.spec(:my_app, :vsn) |> to_string()

Kernel.to_string() 方法是必需的,因为 Application.spec/2 用于键 :vsn:description 返回字符列表。 Kernel 模块中的 to_string() 将它们转换为二进制文件。

【讨论】:

【参考方案4】:

我在: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

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

【讨论】:

好答案欢呼。虽然如果这是实现它的最佳方式有点遗憾。 这是 Jose Valim 几周前给某人的指导。也就是说,使用 :application.which_application。 groups.google.com/d/msg/elixir-lang-talk/qlX4hJKZvC8/…【参考方案5】:

怎么样:

YourApp.Mixfile.project[:version]

【讨论】:

仅供参考,这是在审查期间自动插入的罐头评论 - 它确实没有反映这种情况,这是不幸的。我自己的看法:答案是一个陈述,最好有权威的参考资料、例子和/或经验作为后盾。虽然这里没有问号,但“What about...”是一个问题。如果这确实是一个答案,我建议您将其编辑为听起来像一个答案,并提供一个简短的解释,通过将所提供的解决方案与问题联系起来来教育读者。【参考方案6】:

Application.spec(:my_app, :vsn) 在应用程序启动时工作。如果您在 Mix 任务中并且不需要启动应用程序,则在 Elixir 1.8 中您可以使用:

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

【讨论】:

以上是关于在 elixir 应用程序中访问项目版本的主要内容,如果未能解决你的问题,请参考以下文章

Elixir 依赖不生成应用文件

为啥元组在 Elixir 中不可枚举?

Elixir/Erlang 并发状态访问

如何在服务器上正确安装 Erlang、Elixir 和 mix?

如何运行 Elixir 应用程序?

E1.获取Elixir/Erlang版本信息