Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Commit b380f71

Browse files
authored
revert: restore original Nix wrapper script (#4)
* Revert "refactor: improve nix packaging with deterministic dependency vendoring" This reverts commit 316068f. - Revert Nix packaging changes that caused reproducibility issues over time - Deno's lock file mechanism proved insufficient for long-term dependency pinning in Nix builds - Restore original wrapper script approach until a robust solution is found The deterministic dependency vendoring approach introduced in the previous refactor relied on Deno's lock file for reproducibility. However, Deno's ecosystem does not guarantee that dependencies remain fetchable indefinitely, causing Nix builds to fail when upstream packages become unavailable or change. * Revert "chore: automate Nix hash update when lock file changes" This reverts commit 73fd886. - Revert Nix packaging changes that caused reproducibility issues over time - Deno's lock file mechanism proved insufficient for long-term dependency pinning in Nix builds - Restore original wrapper script approach until a robust solution is found The deterministic dependency vendoring approach introduced in the previous refactor relied on Deno's lock file for reproducibility. However, Deno's ecosystem does not guarantee that dependencies remain fetchable indefinitely, causing Nix builds to fail when upstream packages become unavailable or change.
1 parent b058225 commit b380f71

File tree

3 files changed

+25
-155
lines changed

3 files changed

+25
-155
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ jobs:
1818
- uses: denoland/setup-deno@v2
1919
with:
2020
deno-version: ${{ env.DENO_VERSION }}
21-
- uses: nixbuild/nix-quick-install-action@v34
2221
- run: deno fmt --check
2322
- run: deno lint
2423
- run: deno task check

deno.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
"coverage": "deno coverage .coverage --include='src/'",
2828
"verify": "deno fmt && deno lint && deno task check && deno task test",
2929
"probitas": "deno run -A --unstable-kv --lock ./deno.lock ./mod.ts",
30-
"update-nix-hash": "nix run .#probitas.updateDepsHash",
31-
"update-lock": "rm deno.lock && deno cache -r mod.ts jsr:@probitas/probitas jsr:@probitas/probitas@^0 && deno install && deno task update-nix-hash",
30+
"update-lock": "rm deno.lock && deno cache -r mod.ts jsr:@probitas/probitas jsr:@probitas/probitas@^0",
3231
"update-version": "deno run -A .scripts/update_version.ts"
3332
},
3433
"imports": {

flake.nix

Lines changed: 24 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -7,171 +7,43 @@
77
};
88

99
outputs = { self, nixpkgs, flake-utils }:
10+
let
11+
# Overlay that adds probitas to pkgs
12+
overlay = final: prev: {
13+
probitas = prev.writeShellApplication {
14+
name = "probitas";
15+
runtimeInputs = [ prev.deno ];
16+
text = ''
17+
export DENO_NO_UPDATE_CHECK=1
18+
exec deno run -A \
19+
--unstable-kv \
20+
--config=${self}/deno.json \
21+
--frozen --lock=${self}/deno.lock \
22+
${self}/mod.ts "$@"
23+
'';
24+
};
25+
};
26+
in
1027
{
1128
# Overlay for easy integration
12-
overlays.default = final: prev: {
13-
inherit (self.packages.${final.stdenv.hostPlatform.system}) probitas;
14-
};
29+
overlays.default = overlay;
1530
}
1631
//
1732
flake-utils.lib.eachDefaultSystem (system:
1833
let
19-
pkgs = import nixpkgs { inherit system; };
20-
21-
# Map Nix platform to npm's os/cpu values (Node.js process.platform/process.arch)
22-
npmPlatform = {
23-
os =
24-
if pkgs.stdenv.hostPlatform.isDarwin then "darwin"
25-
else if pkgs.stdenv.hostPlatform.isLinux then "linux"
26-
else null;
27-
cpu =
28-
if pkgs.stdenv.hostPlatform.isAarch64 then "arm64"
29-
else if pkgs.stdenv.hostPlatform.isx86_64 then "x64"
30-
else null;
31-
};
32-
33-
# Use `deno cache --vendor` for deterministic output instead of $DENO_DIR cache.
34-
# The cache approach (`deno install` alone) is non-deterministic due to:
35-
# - JSR cache metadata with timestamps (normalizing breaks cache lookup)
36-
# - SQLite databases with non-deterministic page ordering (deleting causes re-downloads)
37-
deps = pkgs.stdenvNoCC.mkDerivation {
38-
name = "probitas-deps";
39-
src = pkgs.lib.cleanSource ./.;
40-
nativeBuildInputs = with pkgs; [
41-
deno
42-
jq
43-
writableTmpDirAsHomeHook
44-
];
45-
# Remove os/cpu fields from deno.lock for cross-platform deterministic hash
46-
postPatch = ''
47-
jq '
48-
if .npm then
49-
.npm |= map_values(del(.os, .cpu))
50-
else .
51-
end
52-
' deno.lock > deno.lock.tmp
53-
mv deno.lock.tmp deno.lock
54-
'';
55-
installPhase = ''
56-
runHook preInstall
57-
58-
mkdir -p $out
59-
# vendor dependencies for deterministic output
60-
deno cache --vendor --frozen mod.ts jsr:@probitas/probitas@^0
61-
62-
cp -r vendor node_modules $out/
63-
64-
runHook postInstall
65-
'';
66-
outputHashAlgo = "sha256";
67-
outputHashMode = "recursive";
68-
outputHash = "sha256-7/6p+Gcglet123zKj8ixFaeQHbMdI53b3kXNBnuafuQ=";
34+
pkgs = import nixpkgs {
35+
inherit system;
36+
overlays = [ overlay ];
6937
};
7038
in
7139
{
7240
packages = {
73-
default = self.packages.${system}.probitas;
74-
probitas = pkgs.stdenvNoCC.mkDerivation (finalAttrs: {
75-
pname = "probitas";
76-
version = self.shortRev or self.dirtyShortRev or "dev";
77-
src = pkgs.lib.cleanSource ./.;
78-
79-
postPatch = ''
80-
substituteInPlace deno.json \
81-
--replace-fail '"version": "0.0.0"' '"version": "${finalAttrs.version}"'
82-
'';
83-
84-
nativeBuildInputs = with pkgs; [
85-
deno
86-
jq
87-
makeBinaryWrapper
88-
] ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [
89-
autoPatchelfHook
90-
];
91-
92-
installPhase = ''
93-
runHook preInstall
94-
95-
mkdir -p $out/share/probitas
96-
cp -r src assets $out/share/probitas/
97-
cp mod.ts deno.json deno.lock $out/share/probitas/
98-
99-
cp -r ${deps}/{vendor,node_modules} $out/share/probitas/
100-
# Make node_modules writable to allow removal of platform-specific packages
101-
chmod -R +w $out/share/probitas/node_modules
102-
103-
# Remove npm packages with os/cpu constraints that don't match current platform
104-
# Uses deno.lock as the source of truth for platform-specific packages
105-
incompatiblePackages=$(jq -r --arg os "${npmPlatform.os}" --arg cpu "${npmPlatform.cpu}" '
106-
.npm // {} | to_entries[] |
107-
select(
108-
(.value.os != null and (.value.os | index($os) | not)) or
109-
(.value.cpu != null and (.value.cpu | index($cpu) | not))
110-
) |
111-
.key | gsub("/"; "+")
112-
' "deno.lock")
113-
114-
for pkg in $incompatiblePackages; do
115-
rm -rf "$out/share/probitas/node_modules/.deno/$pkg"
116-
done
117-
118-
# Clean up broken symlinks left after removing platform-specific packages
119-
find "$out/share/probitas/node_modules" -xtype l -delete
120-
121-
makeWrapper ${pkgs.lib.getExe pkgs.deno} $out/bin/probitas \
122-
--set DENO_NO_UPDATE_CHECK 1 \
123-
--add-flags "run -A" \
124-
--add-flags "--unstable-kv" \
125-
--add-flags "--vendor" \
126-
--add-flags "--frozen" \
127-
--add-flags "--config=$out/share/probitas/deno.json" \
128-
--add-flags "--lock=$out/share/probitas/deno.lock" \
129-
--add-flags "$out/share/probitas/mod.ts"
130-
131-
runHook postInstall
132-
'';
133-
134-
doInstallCheck = true;
135-
nativeInstallCheckInputs = [ pkgs.versionCheckHook ];
136-
137-
passthru = {
138-
inherit deps;
139-
updateDepsHash = pkgs.writeShellScriptBin "update-probitas-deps" ''
140-
set -euo pipefail
141-
cd "$(${pkgs.lib.getExe pkgs.git} rev-parse --show-toplevel)"
142-
143-
fakehash="${pkgs.lib.fakeHash}"
144-
curhash=$(nix eval .#probitas.deps.outputHash --raw)
145-
146-
# Replace current hash with fakeHash
147-
${pkgs.gnused}/bin/sed -i "s|\"$curhash\"|\"$fakehash\"|" flake.nix
148-
149-
# Build with fakeHash to get the correct hash from error output
150-
set +e
151-
newhash=$(
152-
nix build .#probitas.deps --no-link --log-format internal-json 2>&1 >/dev/null \
153-
| ${pkgs.gnugrep}/bin/grep "$fakehash" \
154-
| ${pkgs.gnugrep}/bin/grep -oP 'sha256-[A-Za-z0-9+/=]+' \
155-
| tail -1
156-
)
157-
set -e
158-
159-
if [[ -n "$newhash" ]]; then
160-
${pkgs.gnused}/bin/sed -i "s|\"$fakehash\"|\"$newhash\"|" flake.nix
161-
echo "Updated deps hash to: $newhash"
162-
else
163-
${pkgs.gnused}/bin/sed -i "s|\"$fakehash\"|\"$curhash\"|" flake.nix
164-
echo "Failed to get hash, restored original"
165-
fi
166-
'';
167-
};
168-
169-
meta.mainProgram = "probitas";
170-
});
41+
inherit (pkgs) probitas;
42+
default = pkgs.probitas;
17143
};
17244

17345
apps.default = flake-utils.lib.mkApp {
174-
drv = self.packages.${system}.default;
46+
drv = pkgs.probitas;
17547
};
17648

17749
devShells.default = pkgs.mkShell {

0 commit comments

Comments
 (0)