Current section

Files

Jump to
credo lib credo check_for_updates.ex
Raw

lib/credo/check_for_updates.ex

defmodule Credo.CheckForUpdates do
def run() do
"credo"
|> fetch_all_hex_versions()
|> do_run()
end
defp do_run(nil), do: nil
defp do_run(all_versions) do
current = Credo.version
if should_update?(all_versions, current) do
latest = latest_version(all_versions, current)
[
:orange,
:bright,
"A new Credo version is available (#{latest})",
:reset,
:orange,
", please update with `mix deps.update credo`"
]
|> warn()
end
end
def should_update?(all_versions, current) do
latest = latest_version(all_versions, current)
Version.compare(current, latest) == :lt
end
defp latest_version(all_versions, default) do
including_pre_versions? = pre_version?(default)
latest =
all_versions
|> highest_version(including_pre_versions?)
latest || default
end
defp highest_version(versions, including_pre_versions?) do
if including_pre_versions? do
versions
else
versions |> Enum.reject(&pre_version?/1)
end
|> List.last
end
defp pre_version?(version) do
{:ok, version} = Version.parse(version)
version.pre != []
end
defp warn(value) do
IO.puts(:stderr, Bunt.format(value))
end
defp fetch_all_hex_versions(package_name) do
case fetch("https://hex.pm/api/packages/#{package_name}") do
nil -> nil
package_info -> package_info |> hex_versions()
end
end
defp fetch(url) do
:httpc.request(:get, {String.to_charlist(url),
[{'User-Agent', user_agent()},
{'Accept', 'application/vnd.hex+erlang'}]}, [], [])
|> convert_response_body()
end
defp user_agent do
'Credo/#{Credo.version} (Elixir/#{System.version}) (OTP/#{System.otp_release})'
end
defp convert_response_body({:ok, {_status, _headers, body}}) do
body |> IO.iodata_to_binary() |> :erlang.binary_to_term()
end
defp convert_response_body(_), do: nil
defp hex_versions(nil), do: nil
defp hex_versions(%{"releases" => releases}) do
releases |> Enum.map(&(&1["version"]))
end
end