{ pkgs, system, knownDenoHashes }: let target = let arch = builtins.head (builtins.split "-" system); os = builtins.elemAt (builtins.split "-" system) 1; vendor = if os == "darwin" then "apple" else "unknown"; sys = if os == "darwin" then "darwin" else "linux-gnu"; in "${arch}-${vendor}-${sys}"; # currently unused, needed for deno compile denort = pkgs.fetchzip { url = "https://dl.deno.land/release/v${pkgs.deno.version}/denort-${target}.zip"; hash = "sha256-ukIk8K2CE+N+3eFs++RPiGZlhhRRVk1gjhdt77/s+4o="; }; scrollsDir = ./deno; lib = pkgs.lib; packageDirs = builtins.attrNames (builtins.readDir scrollsDir); # hash only dependency-relevant files (lock files and configs) hashDependencyFiles = dir: let entries = builtins.readDir dir; # Only process directories and dependency-relevant files relevantEntry = name: type: if type == "directory" then hashDependencyFiles (dir + "/${name}") else if (lib.hasSuffix ".lock" name || lib.hasSuffix ".json" name || lib.hasSuffix ".jsonc" name) then builtins.readFile (dir + "/${name}") else null; contentMap = lib.filterAttrs (_: v: v != null) (builtins.mapAttrs relevantEntry entries); in builtins.toJSON contentMap; sourceContentHash = builtins.convertHash { hash = "sha1:${builtins.hashString "sha1" (hashDependencyFiles scrollsDir)}"; toHashFormat = "base64"; }; # we assume that same lock+config files yield same deno caches here # however, jsons need to be sorted and some sqlite files deleted # jsr gentlemen specifically require their package metadata # to have multiple timestamps, so they can fuck off outputHash = knownDenoHashes.${sourceContentHash} or lib.fakeSha256; unifiedCache = pkgs.stdenv.mkDerivation { name = "deno-scrolls-cache"; src = scrollsDir; nativeBuildInputs = [ pkgs.deno pkgs.jq ]; dontPatchShebangs = true; buildPhase = '' export DENO_DIR=$out ${lib.concatStringsSep "\n" (map (pkg: let config = import (scrollsDir + "/${pkg}/scroll.nix"); in '' echo "Caching ${pkg}..." cd ${pkg} ${config.cache-command} cd .. '' ) packageDirs)} echo 'Go fuck yourself, SQLite!' find $out -name "*-wal" -delete find $out -name "*-shm" -delete echo 'Go fuck yourself, JSON!' find $out/npm -name "*.json" -type f 2>/dev/null | while read -r file; do if ${pkgs.jq}/bin/jq empty "$file" 2>/dev/null; then ${pkgs.jq}/bin/jq -S . "$file" > "$file.tmp" && mv "$file.tmp" "$file" fi done echo 'sourceContentHash: ${sourceContentHash}' echo "" echo "add me to knownHashes if you see a fake sha256 error ^" echo "DON'T USE JSR DEPS UNLESS YOU MAKE THEM REPRODUCIBLE SOMEHOW" echo "" ''; installPhase = "true"; outputHashMode = "recursive"; outputHashAlgo = "sha256"; # this is basically FOD on steroids cause it # deliberately breaks on relevant source changes inherit outputHash; }; in unifiedCache