From bd8f625c156ce04dcc859229962d71b02b49633e Mon Sep 17 00:00:00 2001 From: Philip Sampaio Date: Wed, 11 Sep 2024 16:55:51 -0300 Subject: [PATCH] Fix rustler_precompiled.download mix task - use correct function There was a missing piece in the refactor to add support for headers in v0.8. This is a fix for https://github.com/philss/rustler_precompiled/issues/82 --- CHANGELOG.md | 11 ++++ lib/mix/tasks/rustler_precompiled.download.ex | 10 +-- lib/rustler_precompiled.ex | 10 +-- test/rustler_precompiled_test.exs | 65 +++++++++++++++++++ 4 files changed, 86 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b5297d..d769090 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Fix return of `available_nifs/1`. It was returning only URLs. + +- Fix the "rustler_precompiled.download" mix task to use the correct + function for the download of artifacts. + +### Changed + +- Print SHA256 of artifacts when downloading them from the mix task. + ## [0.8.0] - 2024-08-28 ### Added diff --git a/lib/mix/tasks/rustler_precompiled.download.ex b/lib/mix/tasks/rustler_precompiled.download.ex index 51942a1..371fda7 100644 --- a/lib/mix/tasks/rustler_precompiled.download.ex +++ b/lib/mix/tasks/rustler_precompiled.download.ex @@ -53,21 +53,21 @@ defmodule Mix.Tasks.RustlerPrecompiled.Download do ) end - urls = + nifs_with_urls = cond do options[:all] -> - RustlerPrecompiled.available_nif_urls(module) + RustlerPrecompiled.available_nifs(module) options[:only_local] -> - RustlerPrecompiled.current_target_nif_urls(module) + RustlerPrecompiled.current_target_nifs(module) true -> raise "you need to specify either \"--all\" or \"--only-local\" flags" end - result = RustlerPrecompiled.download_nif_artifacts_with_checksums!(urls, options) + result = RustlerPrecompiled.download_nif_artifacts_with_checksums!(nifs_with_urls, options) - if options[:print] do + if Keyword.get(options, :print, true) do result |> Enum.map(fn map -> {Path.basename(Map.fetch!(map, :path)), Map.fetch!(map, :checksum)} diff --git a/lib/rustler_precompiled.ex b/lib/rustler_precompiled.ex index c781e04..11ea6de 100644 --- a/lib/rustler_precompiled.ex +++ b/lib/rustler_precompiled.ex @@ -291,10 +291,10 @@ defmodule RustlerPrecompiled do nif_module |> metadata_file() |> read_map_from_file() - |> nif_urls_from_metadata() + |> nifs_from_metadata() |> case do - {:ok, urls} -> - urls + {:ok, nifs_with_urls} -> + nifs_with_urls {:error, wrong_meta} -> raise "metadata about current target for the module #{inspect(nif_module)} is not available. " <> @@ -956,12 +956,12 @@ defmodule RustlerPrecompiled do # Download a list of files from URLs and calculate its checksum. # Returns a list with details of the download and the checksum of each file. @doc false - def download_nif_artifacts_with_checksums!(urls, options \\ []) do + def download_nif_artifacts_with_checksums!(nifs_with_urls, options \\ []) do ignore_unavailable? = Keyword.get(options, :ignore_unavailable, false) attempts = max_retries(options) download_results = - for {lib_name, url} <- urls, + for {lib_name, url} <- nifs_with_urls, do: {lib_name, with_retry(fn -> download_nif_artifact(url) end, attempts)} cache_dir = cache_dir("precompiled_nifs") diff --git a/test/rustler_precompiled_test.exs b/test/rustler_precompiled_test.exs index e627443..b5d33aa 100644 --- a/test/rustler_precompiled_test.exs +++ b/test/rustler_precompiled_test.exs @@ -968,6 +968,71 @@ defmodule RustlerPrecompiledTest do end end + describe "available NIFs and download them" do + setup do + root_path = File.cwd!() + nif_fixtures_dir = Path.join(root_path, "test/fixtures") + checksum_sample_file = Path.join(nif_fixtures_dir, "checksum-sample-file.exs") + checksum_sample = File.read!(checksum_sample_file) + + {:ok, nif_fixtures_dir: nif_fixtures_dir, checksum_sample: checksum_sample} + end + + @tag :tmp_dir + test "a project downloading precompiled NIFs", %{ + tmp_dir: tmp_dir, + checksum_sample: checksum_sample, + nif_fixtures_dir: nif_fixtures_dir + } do + bypass = Bypass.open() + + in_tmp(tmp_dir, fn -> + File.write!("checksum-Elixir.RustlerPrecompilationExample.Native.exs", checksum_sample) + + Bypass.expect_once(bypass, fn conn -> + file_name = List.last(conn.path_info) + file = File.read!(Path.join([nif_fixtures_dir, "precompiled_nifs", file_name])) + + Plug.Conn.resp(conn, 200, file) + end) + + result = + capture_log(fn -> + config = + RustlerPrecompiled.Config.new( + otp_app: :rustler_precompiled, + module: RustlerPrecompilationExample.Native, + base_cache_dir: tmp_dir, + base_url: "http://localhost:#{bypass.port}/download", + version: "0.2.0", + crate: "example", + targets: @available_targets, + nif_versions: @default_nif_versions, + force_build: false + ) + + {:ok, metadata} = RustlerPrecompiled.build_metadata(config) + + assert {:ok, nifs_with_urls} = RustlerPrecompiled.nifs_from_metadata(metadata) + + assert [{lib_name, {url, []}} = first | _] = nifs_with_urls + + assert "libexample" <> _ = lib_name + assert "http://localhost" <> _ = url + + results = + RustlerPrecompiled.download_nif_artifacts_with_checksums!([first], all: true) + + assert [%{path: _, lib_name: _, checksum: _, checksum_algo: _}] = results + end) + + assert result =~ "Downloading" + assert result =~ "http://localhost:#{bypass.port}/download" + assert result =~ "NIF cached at" + end) + end + end + describe "nif_urls_from_metadata/1" do test "builds a list of tar gz urls and its variants" do base_url =