{ description = "A naersk based rust flake"; inputs = { utils.url = "github:numtide/flake-utils"; naersk = { url = "github:nix-community/naersk"; inputs.nixpkgs.follows = "nixpkgs"; }; index = { flake = false; url = "github:rust-lang/crates.io-index"; }; }; outputs = { self, nixpkgs, utils, naersk, index, }: let crate = self.lib.crate "bat"; pname = crate.latest.name; filterAttrs = pred: set: builtins.removeAttrs set (builtins.filter (name: !pred name set.${name}) (builtins.attrNames set)); forPkgs = pkgs: rec { packages = pkgs.lib.mapAttrs ( _name: versions: pkgs.lib.mapAttrs (_v: attrs: attrs.build { inherit pkgs; }) versions ) self.lib.crates_io; # # `nix build` # packages.${pname} = crate.latest.package { inherit pkgs; }; # # `nix run` # apps.${pname} = utils.lib.mkApp { # drv = packages.${pname}; # }; # defaultApp = apps.${pname}; }; forSystem = system: forPkgs nixpkgs.legacyPackages."${system}"; in (utils.lib.eachDefaultSystem forSystem) // rec { overlays.default = final: prev: { crates_io = final.lib.mapAttrs ( _: value: final.lib.mapAttrs ( _version: attrs: attrs // { src = lib.crateTarball attrs; build = attrs.build { pkgs = final; }; } ) value ) lib.crates_io; }; lib = rec { config = builtins.fromJSON (builtins.readFile "${index}/config.json"); buildCrate = meta: extra@{ pkgs, ... }: let naersk-lib = naersk.lib."${pkgs.system}"; in naersk-lib.buildPackage ( (removeAttrs extra [ "pkgs" ]) // { root = pkgs.runCommandLocal "unpack-${meta.name}" { } '' mkdir -p $out tar xzvf ${crateTarball meta} -C $out --strip-components=1 ''; } ); crateTarball = { name, vers, cksum, ... }: let url = "${config.dl}/${name}/${vers}/download"; in builtins.fetchurl { inherit url; sha256 = cksum; }; crate = name: let dbg = val: builtins.trace val val; strlen = builtins.stringLength; substr = builtins.substring; path = if strlen name < 4 then "${toString (strlen name)}/${substr 0 1 name}/${name}" else "${substr 0 2 name}/${substr 2 2 name}/${name}"; versions = builtins.foldl' ( p: i: let meta = i // rec { url = "${config.dl}/${name}/${i.vers}/download"; package = buildCrate meta; tarball = crateTarball meta; }; in p // { latest = meta; "${i.vers}" = meta; } ) { } ( map builtins.fromJSON ( builtins.filter (s: builtins.isString s && strlen s > 0) ( builtins.split "\n" (builtins.readFile "${index}/${path}") ) ) ); in versions; crates_io = let traverse = path: levels: let entries = (builtins.readDir path); filterTy = t: builtins.attrNames (filterAttrs (_: ty: ty == t) entries); dirs = filterTy "directory"; crateDirs = builtins.filter (dir: (builtins.substring 0 1 dir) != ".") dirs; files = filterTy "regular"; in if levels == 0 then map (name: "${path}/${name}") files else builtins.concatLists (map (dir: traverse "${path}/${dir}" (levels - 1)) crateDirs); cratePaths = traverse "${index}" 2; crateVersions = path: let meta = builtins.readFile path; metaLines = builtins.split "\n" meta; versionsLines = builtins.filter (l: builtins.isString l && builtins.stringLength l > 10) metaLines; versionsMeta = map builtins.fromJSON versionsLines; versions = map ( meta: let inherit (meta) vers; in { name = vers; value = meta // { build = lib.buildCrate meta; }; } ) versionsMeta; in ( (builtins.listToAttrs versions) // { "latest" = (builtins.elemAt versions (builtins.length versions - 1)).value; } ); crateNames = map baseNameOf cratePaths; in builtins.listToAttrs ( map (path: { name = baseNameOf (builtins.unsafeDiscardStringContext path); value = crateVersions path; }) cratePaths ); }; }; }