tarball: generate packages.json in nix

Instead of using nix-env, let's generate directly in Nix.
This fixes the issue that version and pname contain the wrong information,
as nix-env generates those by splitting name into version and pname
instead of directly using those to attrs.

This would work towards fixing the following issues:
https://github.com/NixOS/nixos-search/issues/770
https://github.com/repology/repology-updater/issues/854
This commit is contained in:
jopejoe1 2025-10-12 20:26:21 +02:00
parent b590506a44
commit e6fd126284
2 changed files with 53 additions and 5 deletions

View file

@ -44,11 +44,7 @@ pkgs.releaseTools.sourceTarball {
checkPhase = ''
echo "generating packages.json"
(
echo -n '{"version":2,"packages":'
NIX_STATE_DIR=$TMPDIR NIX_PATH= nix-env -f $src -qa --meta --json --show-trace --arg config 'import ${./packages-config.nix}'
echo -n '}'
) | sed "s|$src/||g" | jq -c > packages.json
NIX_STATE_DIR=$TMPDIR NIX_PATH= nix-instantiate --eval --raw --expr "import $src/pkgs/top-level/packages-info.nix {}" | sed "s|$src/||g" | jq -c > packages.json
# Arbitrary number. The index has ~115k packages as of April 2024.
if [ $(jq -r '.packages | length' < packages.json) -lt 100000 ]; then

View file

@ -0,0 +1,52 @@
{
trace ? false,
}:
let
pkgs = import ../.. { config = import ./packages-config.nix; };
inherit (pkgs) lib;
generateInfo =
path: value:
let
result =
if path == [ "AAAAAASomeThingsFailToEvaluate" ] || !(lib.isAttrs value) then
[ ]
else if lib.isDerivation value then
[
{
name = lib.showAttrPath path;
value = {
${if value ? "meta" then "meta" else null} = value.meta;
${if value ? "name" then "name" else null} = value.name;
${if value ? "outputName" then "outputName" else null} = value.outputName;
${if value ? "outputs" then "outputs" else null} = lib.listToAttrs (
lib.map (x: {
name = x;
value = null;
}) value.outputs
);
${if value ? "pname" then "pname" else null} = value.pname;
${if value ? "system" then "system" else null} = value.system;
${if value ? "version" then "version" else null} = value.version;
};
}
]
else if value.recurseForDerivations or false then
lib.pipe value [
(lib.mapAttrsToList (
name: value:
lib.addErrorContext "while evaluating package set attribute path '${
lib.showAttrPath (path ++ [ name ])
}'" (generateInfo (path ++ [ name ]) value)
))
lib.concatLists
]
else
[ ];
in
lib.traceIf trace "** ${lib.showAttrPath path}" (lib.deepSeq result result);
in
lib.strings.toJSON {
version = "2";
packages = lib.listToAttrs (generateInfo [ ] (lib.recurseIntoAttrs pkgs));
}