Finding out hex package version numbers

Given a hex package name (for instance gen_stage) and a version requirement string (for instance "~> 1.1"), how can I programmatically find out the latest version of the package available on hex that satisfies the requirement string? (In this case it would be 1.1.2 at the moment.) Is there a Hex function available in mix tasks that does this?

Check the source code of the mix deps.update command:

Check out mix hex.outdated – I think it’s what you’re looking for.

1 Like

Just for the record, I came up with this elixir script:

[package_name, version_requirement] = System.argv()
{:ok, requirement} = Version.parse_requirement(version_requirement)

defmodule Version.Comparison do
  def unquote(:>=)(a, b) do
    Version.compare(a, b) in [:gt, :eq]
  end
end

case Hex.API.Package.get(:hexpm, package_name) do
  {:ok, {200, response, _headers}} ->
    response
    |> Map.get("releases")
    |> Enum.map(& &1["version"])
    |> Enum.filter(&Version.match?(&1, requirement))
    |> Enum.sort(&Version.Comparison.>=/2)
    |> IO.inspect(label: "Version(s) found")

  {:ok, {404, _, _}} ->
    IO.puts("Package not found.")

  {:error, reason} ->
    IO.inspect(reason, label: "Something went wrong")
end

$ mix run hex_versions.exs gen_stage "~> 1.1"
Version(s) found: ["1.1.2", "1.1.1", "1.1.0"]
3 Likes

You can use mix hex.info PACKAGE_NAME to get the basic details such as versions etc.

$ mix hex.info ecto
A toolkit for data mapping and language integrated query for Elixir

Config: {:ecto, "~> 3.9"}
Locked version: 3.8.3
Releases: 3.9.1, 3.9.0, 3.8.4, 3.8.3, 3.8.2, 3.8.1, 3.8.0, 3.7.2, ...

Licenses: Apache-2.0
Links:
  GitHub: https://github.com/elixir-ecto/ecto

That’s a private module, which may change at any point in time. You can probably use :hex_core’s :hex_api_package.get instead.

1 Like