Files
cargoxx-pkgs/flake.nix

86 lines
3.2 KiB
Nix

{
description = "cargoxx package registry";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
# Gitea-hosted cargoxx. flake.lock pins the exact rev — bump it
# explicitly via `nix flake update cargoxx` when the registry should
# adopt a newer cargoxx codegen.
cargoxx.url = "git+https://git.amadey.xyz/mozart/cargoxx";
};
outputs = { self, nixpkgs, flake-utils, cargoxx }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
# version_safe: 1.2.3 → "1_2_3". The attr name `<pkg>_<safe>` is
# the canonical handle for a (name, version) pair; bare `<pkg>`
# aliases the highest-versioned entry.
sanitizeVersion = v:
builtins.replaceStrings ["." "-" "+"] ["_" "_" "_"] v;
# Read recipes/<name>/versions/<v>.toml → buildCppPackage'd drv.
mkPackage = recipeFile:
let r = builtins.fromTOML (builtins.readFile recipeFile);
in cargoxx.lib.${system}.buildCppPackage {
src = pkgs.fetchgit {
inherit (r.source) url;
rev = r.source.commit;
hash = r.source.sha256;
};
name = "${r.name}-${r.version}";
};
# builtins.readDir → attrset of name → type ("regular"/"directory").
# Yields [{ name, type }] entries, filtering on a predicate.
dirEntries = path: predicate:
if builtins.pathExists path
then pkgs.lib.filterAttrs (n: t: predicate n t) (builtins.readDir path)
else {};
# All package directories under recipes/.
packageNames = builtins.attrNames
(dirEntries ./recipes (_: t: t == "directory"));
# For one package: enumerate its versions, returning an attrset
# { "<pkg>_<safe>" = <drv>; "<pkg>" = <highest-version drv>; }.
versionsFor = pkgName:
let
versionsDir = ./recipes + "/${pkgName}/versions";
files = builtins.attrNames
(dirEntries versionsDir (n: t:
t == "regular" && pkgs.lib.hasSuffix ".toml" n));
versions = map (f:
let
version = pkgs.lib.removeSuffix ".toml" f;
attr = "${pkgName}_${sanitizeVersion version}";
drv = mkPackage (versionsDir + "/${f}");
in { inherit version attr drv; }
) files;
byVersion = pkgs.lib.listToAttrs
(map (v: { name = v.attr; value = v.drv; }) versions);
highest = pkgs.lib.last
(pkgs.lib.sort (a: b:
builtins.compareVersions a.version b.version < 0) versions);
latestAlias =
if versions == [] then {}
else { ${pkgName} = highest.drv; };
in byVersion // latestAlias;
packagesAttrs = pkgs.lib.foldl' (acc: n:
acc // (versionsFor n)) {} packageNames;
in {
packages = packagesAttrs;
# Bare `nix flake check` should pass with zero recipes.
checks = {
schema-ok = pkgs.runCommand "registry-schema-ok" {} ''
touch $out
'';
};
});
}