From a4bc8c023063a27b59acc15c81d144ad095393dd Mon Sep 17 00:00:00 2001 From: EatThePooh Date: Sat, 2 Aug 2025 08:21:03 +0700 Subject: [PATCH] improve deno cache FOD --- flake.nix | 5 ++++ shelf/deno-workspace.nix | 46 ++++++++++++++++++++++++++++++++--- shelf/deno/uses-hjq/deno.json | 2 +- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index aa6f0ec..54ab156 100644 --- a/flake.nix +++ b/flake.nix @@ -12,6 +12,11 @@ pkgs = nixpkgs.legacyPackages.${system}; denoWorkspace = import ./shelf/deno-workspace.nix { inherit pkgs system; + # collective hash of all deno sources - resulting shared deno cache hash + knownDenoHashes = { + "UnKGEQo7oF1X5JeWyx7w0oCwqPQ=" = + "sha256-7csbrTbGd6J4a0Gkj9ndKhNxv90KeOHjr7DDNal3L4Q="; + }; }; in { diff --git a/shelf/deno-workspace.nix b/shelf/deno-workspace.nix index 98109d5..fc03777 100644 --- a/shelf/deno-workspace.nix +++ b/shelf/deno-workspace.nix @@ -1,4 +1,4 @@ -{ pkgs, system }: +{ pkgs, system, knownDenoHashes }: let target = @@ -18,8 +18,38 @@ let scrollsDir = ./deno; lib = pkgs.lib; packageDirs = builtins.attrNames (builtins.readDir scrollsDir); - - # Separate FOD for cache only + + # 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; @@ -50,13 +80,21 @@ let ${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"; - outputHash = "sha256-maP/JMY6n95A9FQx72YFwRtnprGXc97v1ZdPgt2GB8s="; + # this is basically FOD on steroids cause it + # deliberately breaks on relevant source changes + inherit outputHash; }; in diff --git a/shelf/deno/uses-hjq/deno.json b/shelf/deno/uses-hjq/deno.json index b7d93f4..881c23c 100644 --- a/shelf/deno/uses-hjq/deno.json +++ b/shelf/deno/uses-hjq/deno.json @@ -2,7 +2,7 @@ "tasks": { "start": "deno run --cached-only main.ts" }, - "patch": [ + "links": [ "../hjq" ] }