Hex files have old format?


I triesd to make a local hex repo based on the docs here: Self-hosting | Hex and i run into a problem. Certain tar files downloaded from the official hex repo are not working with my local repo.

Here’s a bash script that reproduces the error:

#!/bin/bash -x
rm -rf $DIR
mkdir -p $DIR/tarballs
mix hex.package fetch hackney 1.4.2
cp hackney-1.4.2.tar $DIR/tarballs/
openssl genrsa -out /tmp/private_key.pem
mix hex.registry build $DIR --name=test --private-key=/tmp/private_key.pem 
mix --version

Here’s it’s output:

+ DIR=try
+ rm -rf try
+ mkdir -p try/tarballs
+ mix hex.package fetch hackney 1.4.2
hackney v1.4.2 downloaded to /home/otp00300830/hackney-1.4.2.tar
+ cp hackney-1.4.2.tar try/tarballs/
+ openssl genrsa -out /tmp/private_key.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
e is 65537 (0x010001)
+ mix hex.registry build try --name=test --private-key=/tmp/private_key.pem
* creating try/public_key
** (BadMapError) expected a map, got: "0.1.1"
    (stdlib 3.9.2) :maps.get("app", "0.1.1")
    (hex 2.0.6) lib/mix/tasks/hex.registry.ex:167: anonymous fn/3 in Mix.Tasks.Hex.Registry.build_release/2
    (stdlib 3.9.2) maps.erl:232: :maps.fold_1/3
    (hex 2.0.6) lib/mix/tasks/hex.registry.ex:166: Mix.Tasks.Hex.Registry.build_release/2
    (elixir 1.13.3) lib/enum.ex:1593: Enum."-map/2-lists^map/1-0-"/2
    (hex 2.0.6) lib/mix/tasks/hex.registry.ex:108: anonymous fn/4 in Mix.Tasks.Hex.Registry.build/3
    (elixir 1.13.3) lib/enum.ex:1597: anonymous fn/3 in Enum.map/2
    (stdlib 3.9.2) maps.erl:232: :maps.fold_1/3
+ mix --version
Erlang/OTP 22 [erts-10.4.4] [source] [64-bit] [smp:128:128] [ds:128:128:10] [async-threads:1] [hipe]

Mix 1.13.3 (compiled with Erlang/OTP 22)

What goes wrong here?

I tried it with OTP 23 and 25, and Elixir 1.13.3 and 1.14.x, and the same thing happened. Seems like :erlang.map_get("app", "0.1.1") tries to handle a binary as a map.

The tarball format is on version 3 based on the spec: specifications/package_tarball.md at main · hexpm/specifications · GitHub

Comparing the metadata of hackney 1.4.2 with a recent one it seems like the "requirements" metadata format has changed and the mix task you’re using seems to expect the latest format.

The mix task I’m using is hex.registry and it comes from hex. Even the latest hex.registry (from hex version 2.0.7-dev) fails. Shouldn’t hex tasks handle the old format?

The mix hex.registry tasks was built to work with packages generated from mix hex.build, it wasn’t really meant to be used for mirroring packages from repo.hex.pm. If you want to mirror packages I think there are better tools for that. But we would accept PRs that make mix hex.registry work with older packages.