Access project version within elixir application

后端 未结 6 1103
挽巷
挽巷 2021-02-12 07:42

I have an elixir project with a defined version. How can I access this from within the running application.

in mix.exs

  def project do
    [app: :my_app         


        
相关标签:
6条回答
  • 2021-02-12 08:25

    Mix.Project itself provides access to all project keywords defined in mix.exs using its config/0 (api doc) function. For concise access it might be wrapped into a function:

    @version Mix.Project.config[:version]
    def version(), do: @version
    
    0 讨论(0)
  • 2021-02-12 08:30

    Here's a similar approach to retrieve the version string. It also relies on the :application module, but is maybe a bit more straightforward:

    {:ok, vsn} = :application.get_key(:my_app, :vsn)
    List.to_string(vsn)
    
    0 讨论(0)
  • 2021-02-12 08:41

    What about :

    YourApp.Mixfile.project[:version]
    
    0 讨论(0)
  • 2021-02-12 08:44

    Application.spec(:my_app, :vsn) works when the application is started. If you're in a Mix task and you don't need to start the application, in Elixir 1.8 you can use:

    MyApp.MixProject.project |> Keyword.fetch!(:version)
    
    0 讨论(0)
  • 2021-02-12 08:46

    In recent versions of Elixir, the Application module now wraps this for you:

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

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

    The Kernel.to_string() method is necessary as Application.spec/2 for the keys :vsn and :description return charlists. to_string() from the Kernel module converts them to a binary.

    0 讨论(0)
  • 2021-02-12 08:48

    I found the version inside of :application.which_applications, but it requires some parsing:

    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
    

    And then for usage:

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

    As always, there's probably a better way.

    0 讨论(0)
提交回复
热议问题