2025-08-02 08:21:03 +07:00
|
|
|
{ pkgs, system, knownDenoHashes }:
|
2025-08-02 05:10:30 +07:00
|
|
|
|
|
|
|
|
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);
|
2025-08-02 08:21:03 +07:00
|
|
|
|
|
|
|
|
# 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;
|
|
|
|
|
|
2025-08-02 05:10:30 +07:00
|
|
|
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
|
2025-08-02 08:21:03 +07:00
|
|
|
|
|
|
|
|
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 ""
|
2025-08-02 05:10:30 +07:00
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
installPhase = "true";
|
|
|
|
|
|
|
|
|
|
outputHashMode = "recursive";
|
|
|
|
|
outputHashAlgo = "sha256";
|
2025-08-02 08:21:03 +07:00
|
|
|
# this is basically FOD on steroids cause it
|
|
|
|
|
# deliberately breaks on relevant source changes
|
|
|
|
|
inherit outputHash;
|
2025-08-02 05:10:30 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
in
|
|
|
|
|
unifiedCache
|