Skip to content

Commit

Permalink
generate checksum file for each target
Browse files Browse the repository at this point in the history
  • Loading branch information
cocoa-xu committed Mar 23, 2024
1 parent e41e23c commit 87a15f8
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 27 deletions.
24 changes: 22 additions & 2 deletions lib/elixir_make/artefact.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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 """
Expand Down
91 changes: 66 additions & 25 deletions lib/mix/tasks/elixir_make.checksum.ex
Original file line number Diff line number Diff line change
Expand Up @@ -103,38 +103,79 @@ 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)

from_checksum_file =
case artifact_checksum do
{:ok, body} ->
case String.split(body, " ", trim: true) do
[checksum, basename] ->
{:ok,
{:checksum, url,
%Artefact{
basename: basename,
checksum: checksum,
checksum_algo: checksum_algo
}}}

_ ->
:download_and_compute
end

_ ->
:download_and_compute
end

case from_checksum_file do
{:ok, packed} ->
packed

_ ->
{: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} ->

Check warning on line 147 in lib/mix/tasks/elixir_make.checksum.ex

View workflow job for this annotation

GitHub Actions / test (1.9.4, 20.3)

variable "url" is unused (if the variable is not meant to be used, prefix it with an underscore)

Check warning on line 147 in lib/mix/tasks/elixir_make.checksum.ex

View workflow job for this annotation

GitHub Actions / test (1.13.4, 24.3, lint)

variable "url" is unused (if the variable is not meant to be used, prefix it with an underscore)
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

Expand Down
2 changes: 2 additions & 0 deletions lib/mix/tasks/elixir_make.precompile.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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} ->
Expand Down

0 comments on commit 87a15f8

Please sign in to comment.