diff --git a/lib/elixir_make/artefact.ex b/lib/elixir_make/artefact.ex index 9e910c6..787a82a 100644 --- a/lib/elixir_make/artefact.ex +++ b/lib/elixir_make/artefact.ex @@ -23,13 +23,33 @@ defmodule ElixirMake.Artefact do cache_dir end + @doc """ + Returns the checksum algorithm + """ + def checksum_algo do + @checksum_algo + end + @doc """ Computes the checksum and artefact for the given contents. """ def checksum(basename, contents) do - hash = :crypto.hash(@checksum_algo, contents) + hash = :crypto.hash(checksum_algo(), contents) checksum = Base.encode16(hash, case: :lower) - %Artefact{basename: basename, checksum: checksum, checksum_algo: @checksum_algo} + %Artefact{basename: basename, checksum: checksum, checksum_algo: checksum_algo()} + end + + @doc """ + Writes checksum for the target to disk. + """ + def write_checksum_for_target!(%Artefact{ + basename: basename, + checksum: checksum, + checksum_algo: checksum_algo + }) do + cache_dir = Artefact.cache_dir() + file = Path.join(cache_dir, "#{basename}.#{Atom.to_string(checksum_algo)}") + File.write!(file, [checksum, " ", basename, "\n"]) end @doc """ diff --git a/lib/mix/tasks/elixir_make.checksum.ex b/lib/mix/tasks/elixir_make.checksum.ex index 58fd32b..31a0648 100644 --- a/lib/mix/tasks/elixir_make.checksum.ex +++ b/lib/mix/tasks/elixir_make.checksum.ex @@ -103,38 +103,62 @@ defmodule Mix.Tasks.ElixirMake.Checksum do tasks = Task.async_stream( urls, - fn {{_target, _nif_version}, url} -> {url, Artefact.download(url)} end, + fn {{_target, _nif_version}, url} -> + checksum_algo = Artefact.checksum_algo() + checksum_file_url = "#{url}.#{Atom.to_string(checksum_algo)}" + artifact_checksum = Artefact.download(checksum_file_url) + + with {:ok, body} <- artifact_checksum, + [checksum, basename] <- String.split(body, " ", trim: true) do + {:checksum, url, + %Artefact{ + basename: String.trim(basename), + checksum: checksum, + checksum_algo: checksum_algo + }} + else + _ -> {:download, url, Artefact.download(url)} + end + end, timeout: :infinity, ordered: false ) cache_dir = Artefact.cache_dir() - Enum.flat_map(tasks, fn {:ok, {url, download}} -> - case download do - {:ok, body} -> - basename = basename_from_url(url) - path = Path.join(cache_dir, basename) - File.write!(path, body) - artefact = Artefact.checksum(basename, body) - - Mix.shell().info( - "NIF cached at #{path} with checksum #{artefact.checksum} (#{artefact.checksum_algo})" - ) - - [artefact] - - result -> - if ignore_unavailable? do - msg = "Skipped unavailable NIF artifact. Reason: #{inspect(result)}" - Mix.shell().info(msg) - else - msg = "Could not finish the download of NIF artifacts. Reason: #{inspect(result)}" - Mix.shell().error(msg) - end + Enum.flat_map(tasks, fn + {:ok, {:checksum, _url, artefact}} -> + Mix.shell().info( + "NIF checksum file with checksum #{artefact.checksum} (#{artefact.checksum_algo})" + ) - [] - end + [artefact] + + {:ok, {:download, url, download}} -> + case download do + {:ok, body} -> + basename = basename_from_url(url) + path = Path.join(cache_dir, basename) + File.write!(path, body) + artefact = Artefact.checksum(basename, body) + + Mix.shell().info( + "NIF cached at #{path} with checksum #{artefact.checksum} (#{artefact.checksum_algo})" + ) + + [artefact] + + result -> + if ignore_unavailable? do + msg = "Skipped unavailable NIF artifact. Reason: #{inspect(result)}" + Mix.shell().info(msg) + else + msg = "Could not finish the download of NIF artifacts. Reason: #{inspect(result)}" + Mix.shell().error(msg) + end + + [] + end end) end diff --git a/lib/mix/tasks/elixir_make.precompile.ex b/lib/mix/tasks/elixir_make.precompile.ex index 67d751d..79bb2f3 100644 --- a/lib/mix/tasks/elixir_make.precompile.ex +++ b/lib/mix/tasks/elixir_make.precompile.ex @@ -48,6 +48,8 @@ defmodule Mix.Tasks.ElixirMake.Precompile do precompiler.post_precompile_target(target) end + Artefact.write_checksum_for_target!(precompiled_artefacts) + precompiled_artefacts {:error, msg} ->