     |> List.last
   end
 
-  def pre_version?(version) do
-    {:ok, version} = Hex.Version.parse(version)
+  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

defmodule Credo.CheckForUpdates do
  def run() do
    all_versions = all_hex_versions("credo")
    current = Credo.version

    if should_update?(all_versions, current) do

        :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
