flake.nix (26479B)
1 { 2 description = "tricu"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs"; 6 browser-wasi = { url = "github:haskell-wasm/browser_wasi_shim/2f86b49dce50916e2984029c535321e34b234229"; flake = false; }; 7 ghc-wasm.url = "github:haskell-wasm/ghc-wasm-meta/8079eb96bbc63823d99ad8acaff0765532625474"; 8 flake-utils.url = "github:numtide/flake-utils"; 9 }; 10 11 outputs = { self, nixpkgs, flake-utils, ghc-wasm, browser-wasi }: 12 flake-utils.lib.eachDefaultSystem (system: 13 let 14 pkgs = nixpkgs.legacyPackages.${system}; 15 siteRelease = import ./ext/demo-site/release.nix { inherit pkgs; zigRuntime = self.packages.${system}.tricu-wasm; haskellRuntime = self.packages.${system}.haskellWasmBrowser; }; 16 packageName = "tricu"; 17 containerPackageName = "${packageName}-container"; 18 19 # Archived experiments must not enter active build/test source hashes. 20 tricuSource = pkgs.lib.cleanSourceWith { 21 name = "tricu-source"; 22 src = self; 23 filter = path: type: 24 let 25 relative = pkgs.lib.removePrefix "${toString self}/" path; 26 top = builtins.head (pkgs.lib.splitString "/" relative); 27 in pkgs.lib.cleanSourceFilter path type && builtins.elem top [ 28 "src" "lib" "test" "bench" "bootstrap" "demos" "ext" 29 "tricu.cabal" "LICENSE" "README.md" 30 ]; 31 }; 32 33 # All Haskell components now share the source-free runtime. The boundary 34 # check below rejects reintroducing retired frontend files into inputs. 35 runtimeSource = tricuSource; 36 37 haskellPackages = pkgs.haskellPackages; 38 hsLib = pkgs.haskell.lib; 39 40 staticPkgs = pkgs.pkgsStatic; 41 staticHaskellPackages = staticPkgs.haskellPackages; 42 staticHsLib = staticPkgs.haskell.lib; 43 44 tricuMuslStatic = 45 staticHsLib.justStaticExecutables ( 46 staticHsLib.dontCheck ( 47 staticHaskellPackages.callCabal2nix packageName runtimeSource {} 48 ) 49 ); 50 51 tricuStatic = pkgs.runCommand "${packageName}-static-upx" { 52 nativeBuildInputs = [ pkgs.upx ]; 53 } '' 54 mkdir -p $out/bin 55 cp ${tricuMuslStatic}/bin/tricu $out/bin/tricu 56 chmod +w $out/bin/tricu 57 58 # Good compression, slower build. 59 upx --best --lzma $out/bin/tricu 60 61 chmod 755 $out/bin/tricu 62 ''; 63 64 tricuPackageTests = 65 haskellPackages.callCabal2nix packageName tricuSource {}; 66 67 tricuPackage = 68 hsLib.dontCheck ( 69 haskellPackages.callCabal2nix packageName runtimeSource {} 70 ); 71 72 # Compile once with the packaged stable compiler. Runtime needs neither 73 # source lookup nor a writable compiler/application cache. 74 arboricxServerBundle = pkgs.runCommand "arboricx-server-bundle" { 75 nativeBuildInputs = [ tricuPackage ]; 76 } '' 77 mkdir -p $out 78 tricu arboricx compile --file ${./.}/tricu-apps/arboricxServer.tri --store build-store \ 79 --output $out/server.arboricx --compile-timeout 900 \ 80 +RTS -N1 -M8192m -RTS 81 tricu arboricx import --file $out/server.arboricx --store $out/runtime \ 82 > import.log 83 sed -n 's/^Created module alias .* -> //p' import.log > $out/manifest 84 test "$(wc -l < $out/manifest)" -eq 1 85 grep -Eq '^[0-9a-f]{64}$' $out/manifest 86 ''; 87 88 arboricxServerRunner = pkgs.writeShellScriptBin "arboricx-server" '' 89 exec ${tricuPackage}/bin/tricu arboricx run \ 90 --module "$(${pkgs.coreutils}/bin/cat ${arboricxServerBundle}/manifest)" --name main \ 91 --store ${arboricxServerBundle}/runtime \ 92 --io --no-result --allow-read ./store --allow-write ./store \ 93 +RTS -N1 -M2048m -RTS 94 ''; 95 96 tricuBench = 97 (hsLib.overrideCabal 98 (hsLib.doBenchmark (hsLib.dontCheck ( 99 haskellPackages.callCabal2nix packageName runtimeSource {} 100 ))) 101 (oldAttrs: { 102 postInstall = (oldAttrs.postInstall or "") + '' 103 mkdir -p $out/bin 104 cp dist/build/tricu-bench/tricu-bench $out/bin/ 105 ''; 106 })).overrideAttrs (_: { 107 # No implicit timing run without a caller-selected worker bundle. 108 benchmarkPhase = "true"; 109 }); 110 111 # Opt-in application build, never part of the fast gate. Retain the exact 112 # sources, compiler metadata and receipts beside the worker bundle. 113 benchmarkWorkers = pkgs.runCommand "tricu-benchmark-workers" { 114 nativeBuildInputs = [ tricuPackage ]; 115 } '' 116 mkdir -p $out/workspace 117 ${pkgs.lib.concatMapStringsSep "\n" (name: 118 "cp ${./lib}/${name}.tri $out/workspace/${name}.tri") [ 119 "base" "prelude" "bytes" "conversions" "io" "parser" "http" "socket" 120 ]} 121 cp ${./lib/math/native.tri} $out/workspace/native_math.tri 122 cp ${./lib/intensionalContracts.tri} $out/workspace/intensional.tri 123 cp ${./lib/arboricx/server.tri} $out/workspace/server.tri 124 cp ${./bench/workers.tri} $out/workspace/workers.tri 125 cp ${./bootstrap/stable-compiler.json} $out/compiler.json 126 timeout 930 tricu arboricx compile --file $out/workspace/workers.tri \ 127 --store $out/store --output $out/workers.arboricx --compile-timeout 900 \ 128 +RTS -N1 -M8192m -RTS 129 sha256sum $out/workers.arboricx | cut -d ' ' -f 1 > $out/sha256 130 ''; 131 132 # ------------------------------------------------------------------ 133 # Zig Arboricx host 134 # ------------------------------------------------------------------ 135 tricuZig = pkgs.stdenv.mkDerivation { 136 pname = "tricu-zig"; 137 version = "0.1.0"; 138 src = ./ext/zig; 139 passthru.optimizationMode = "ReleaseSafe"; 140 nativeBuildInputs = [ pkgs.zig pkgs.pkg-config ]; 141 buildInputs = [ pkgs.libuv ]; 142 buildPhase = '' 143 export ZIG_GLOBAL_CACHE_DIR=$TMPDIR/zig-cache 144 zig build -Doptimize=ReleaseSafe 145 zig build test -Doptimize=ReleaseSafe 146 zig build test -Doptimize=Debug 147 ''; 148 installPhase = '' 149 mkdir -p $out/bin $out/lib $out/include 150 cp zig-out/bin/* $out/bin/ 2>/dev/null || true 151 cp zig-out/lib/* $out/lib/ 2>/dev/null || true 152 cp include/arboricx.h $out/include/ 153 ''; 154 }; 155 156 tricuWasm = pkgs.stdenv.mkDerivation { 157 pname = "tricu-wasm"; 158 version = "0.1.0"; 159 src = ./ext/zig; 160 nativeBuildInputs = [ pkgs.zig ]; 161 buildPhase = '' 162 export ZIG_GLOBAL_CACHE_DIR=$TMPDIR/zig-cache 163 zig build wasm 164 ''; 165 installPhase = '' 166 mkdir -p $out/lib 167 cp zig-out/bin/arboricx.wasm $out/lib/ 168 ''; 169 }; 170 171 tricuWasmTests = pkgs.runCommand "tricu-wasm-tests" { 172 nativeBuildInputs = [ pkgs.nodejs pkgs.typescript ]; 173 } '' 174 cp -r ${tricuSource} source 175 chmod -R u+w source 176 cd source 177 tsc -p ext/demo-site/tsconfig.json 178 timeout 120 node ext/wasm/check.mjs ${tricuWasm}/lib/arboricx.wasm 179 timeout 120 node ext/wasm/backend-check.mjs ${tricuWasm}/lib/arboricx.wasm 180 mkdir -p $out 181 ''; 182 183 tricuWasmBrowser = pkgs.runCommand "tricu-wasm-browser" { 184 nativeBuildInputs = [ pkgs.nodejs pkgs.typescript pkgs.chromium ]; 185 } '' 186 export HOME=$TMPDIR/home 187 mkdir -p "$HOME" $out 188 cp -r ${tricuSource} source 189 chmod -R u+w source 190 cd source 191 tsc -p ext/demo-site/tsconfig.json 192 timeout 240 node ext/wasm/browser.mjs ${tricuWasm}/lib/arboricx.wasm chromium $out/report.json 193 ''; 194 195 tricuWasmComparison = pkgs.runCommand "tricu-wasm-comparison" { 196 nativeBuildInputs = [ pkgs.nodejs pkgs.typescript ]; 197 } '' 198 cp -r ${tricuSource} source 199 chmod -R u+w source 200 cd source 201 tsc -p ext/demo-site/tsconfig.json 202 mkdir -p $out 203 node ext/wasm/compare.mjs ${tricuWasm}/lib/arboricx.wasm $out/report.json 204 node ext/wasm/preview-compare.mjs ${tricuWasm}/lib/arboricx.wasm $out/preview-report.json 205 ''; 206 207 # Explicit, Linux-only smoke measurements; not a timing threshold gate. 208 tricuZigPerformanceSmoke = pkgs.stdenv.mkDerivation { 209 pname = "tricu-zig-performance-smoke"; 210 version = "0.1.0"; 211 src = ./.; 212 nativeBuildInputs = [ pkgs.gcc pkgs.python3 ]; 213 buildPhase = '' 214 gcc -O2 -Wall -Wextra -Werror ext/zig/tests/performance_smoke.c \ 215 -DARB_HOST_MODE='"${tricuZig.optimizationMode}"' \ 216 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 217 -Wl,-rpath,${tricuZig}/lib -o performance-smoke 218 ''; 219 installPhase = '' 220 mkdir -p $out/bin 221 cp performance-smoke $out/bin/ 222 python3 ext/zig/tests/performance_smoke.py \ 223 $out/bin/performance-smoke test/fixtures $out/report.json 224 ''; 225 }; 226 227 tricuZigTests = pkgs.stdenv.mkDerivation { 228 pname = "tricu-zig-tests"; 229 version = "0.1.0"; 230 src = ./.; 231 nativeBuildInputs = [ pkgs.gcc pkgs.python3 tricuZig ]; 232 buildInputs = [ pkgs.libuv ]; 233 buildPhase = "true"; 234 doCheck = true; 235 checkPhase = '' 236 export LD_LIBRARY_PATH=${tricuZig}/lib:$LD_LIBRARY_PATH 237 ulimit -s 32768 238 239 cd ext/zig 240 241 gcc -Wall -Wextra -Werror -o /tmp/handles_test tests/handles_test.c \ 242 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 243 -Wl,-rpath,${tricuZig}/lib 244 /tmp/handles_test 245 246 test "$(tricu-zig --type string ../../test/fixtures/id.arboricx hello)" = hello 247 test "$(tricu-zig --type string --kernel ../../test/fixtures/append.arboricx 'Hello, ' 'world!')" = 'Hello, world!' 248 249 # C ABI smoke test 250 gcc -o /tmp/c_abi_test tests/c_abi_test.c \ 251 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 252 -Wl,-rpath,${tricuZig}/lib 253 /tmp/c_abi_test 254 255 # IO protocol shape test 256 gcc -o /tmp/io_protocol_test tests/io_protocol_test.c \ 257 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 258 -Wl,-rpath,${tricuZig}/lib 259 /tmp/io_protocol_test 260 261 # IO run test (synchronous driver) 262 gcc -o /tmp/io_run_test tests/io_run_test.c \ 263 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 264 -Wl,-rpath,${tricuZig}/lib 265 /tmp/io_run_test 266 267 # Kernel path append test 268 gcc -o /tmp/c_abi_append_test tests/c_abi_append_test.c \ 269 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 270 -Wl,-rpath,${tricuZig}/lib 271 /tmp/c_abi_append_test 272 273 # Native bundle tests 274 gcc -o /tmp/native_bundle_append_test tests/native_bundle_append_test.c \ 275 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 276 -Wl,-rpath,${tricuZig}/lib 277 /tmp/native_bundle_append_test 278 279 gcc -o /tmp/native_bundle_id_test tests/native_bundle_id_test.c \ 280 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 281 -Wl,-rpath,${tricuZig}/lib 282 /tmp/native_bundle_id_test 283 284 gcc -o /tmp/native_bundle_bools_test tests/native_bundle_bools_test.c \ 285 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 286 -Wl,-rpath,${tricuZig}/lib 287 /tmp/native_bundle_bools_test 288 289 # Python FFI test 290 ARBORICX_LIB=${tricuZig}/lib/libarboricx.so \ 291 python3 tests/python_ffi_test.py 292 293 mkdir -p $out 294 echo "All Zig tests passed" > $out/result 295 ''; 296 }; 297 298 # ------------------------------------------------------------------ 299 # PHP FFI host 300 # ------------------------------------------------------------------ 301 tricuPhp = pkgs.stdenv.mkDerivation { 302 pname = "tricu-php"; 303 version = "0.1.0"; 304 src = ./ext/php; 305 nativeBuildInputs = [ pkgs.makeWrapper phpWithFfi tricuZig ]; 306 buildPhase = "true"; 307 installPhase = '' 308 mkdir -p $out/share/tricu-php $out/lib $out/bin 309 cp -r src public run.php $out/share/tricu-php/ 310 cp ${tricuZig}/lib/libarboricx.so $out/lib/ 311 cp ${tricuZig}/include/arboricx.h $out/share/tricu-php/ 312 313 makeWrapper ${phpWithFfi}/bin/php $out/bin/tricu-php \ 314 --add-flags "$out/share/tricu-php/run.php" \ 315 --set ARBORICX_LIB "$out/lib/libarboricx.so" \ 316 --prefix LD_LIBRARY_PATH : "$out/lib" 317 ''; 318 }; 319 320 # ------------------------------------------------------------------ 321 # JS FFI host 322 # ------------------------------------------------------------------ 323 tricuJs = pkgs.buildNpmPackage { 324 pname = "tricu-js"; 325 version = "0.1.0"; 326 src = ./ext/js; 327 npmDepsHash = "sha256-81C7tsNcbyZVhm3uqiWdDQxp5LAXXO9aueHdMDztCfM="; 328 nativeBuildInputs = [ pkgs.nodejs tricuZig ]; 329 dontNpmBuild = true; 330 installPhase = '' 331 mkdir -p $out/lib/ 332 cp -r . $out/lib/ 333 cp ${tricuZig}/lib/libarboricx.so $out/lib/src 334 ''; 335 }; 336 337 # ------------------------------------------------------------------ 338 # JS FFI host tests (separate target) 339 # ------------------------------------------------------------------ 340 tricuJsTests = pkgs.stdenv.mkDerivation { 341 pname = "tricu-js-tests"; 342 version = "0.1.0"; 343 src = ./.; 344 nativeBuildInputs = [ pkgs.nodejs tricuZig ]; 345 buildPhase = "true"; 346 doCheck = true; 347 checkPhase = '' 348 export ARBORICX_LIB=${tricuZig}/lib/libarboricx.so 349 export LD_LIBRARY_PATH=${tricuZig}/lib:$LD_LIBRARY_PATH 350 ulimit -s 32768 351 352 cd ext/js 353 # node_modules are pre-fetched by buildNpmPackage; copy them in 354 cp -r ${tricuJs}/lib/node_modules . 355 npm test 356 357 mkdir -p $out 358 echo "All JS tests passed" > $out/result 359 ''; 360 }; 361 362 # ------------------------------------------------------------------ 363 # PHP FFI tests (separate target) 364 # ------------------------------------------------------------------ 365 phpWithFfi = pkgs.php.withExtensions (exts: [ pkgs.phpExtensions.ffi ]); 366 367 tricuPhpTests = pkgs.stdenv.mkDerivation { 368 pname = "tricu-php-tests"; 369 version = "0.1.0"; 370 src = ./.; 371 nativeBuildInputs = [ phpWithFfi tricuPhp ]; 372 buildPhase = "true"; 373 doCheck = true; 374 checkPhase = '' 375 export ARBORICX_LIB=${tricuPhp}/lib/libarboricx.so 376 export LD_LIBRARY_PATH=${tricuPhp}/lib:$LD_LIBRARY_PATH 377 ulimit -s 32768 378 379 php ext/php/tests/ownership.php 380 381 # Run PHP host against fixture bundles 382 php ext/php/run.php run test/fixtures/id.arboricx hello 383 php ext/php/run.php run test/fixtures/append.arboricx "Hello, " "world!" 384 php ext/php/run.php run test/fixtures/true.arboricx 385 php ext/php/run.php run test/fixtures/false.arboricx 386 php ext/php/run.php run test/fixtures/notQ.arboricx "t t t" 387 388 mkdir -p $out 389 echo "All PHP tests passed" > $out/result 390 ''; 391 }; 392 in { 393 packages.haskellWasmBrowser = import ./ext/haskell-wasm/browser.nix { 394 inherit pkgs; 395 probe = self.packages.${system}.haskellWasmProbe; 396 toolchain = ghc-wasm.packages.${system}.all_9_14; 397 shimSource = browser-wasi; 398 }; 399 packages.haskellWasmProbe = import ./ext/haskell-wasm/build.nix { 400 inherit pkgs; 401 toolchain = ghc-wasm.packages.${system}.all_9_14; 402 }; 403 packages.${packageName} = tricuPackage; 404 packages.default = tricuPackage; 405 # Independent Haskell oracle for the opt-in published-library consumer. 406 # Opt-in Linux paired runtime measurements. Build first; timing runs 407 # explicitly outside the Nix build, never during the fast check gate. 408 packages.reducerComparison = pkgs.stdenv.mkDerivation { 409 pname = "tricu-reducer-comparison"; 410 version = "0.1.0"; 411 src = ./.; 412 nativeBuildInputs = [ pkgs.gcc pkgs.makeWrapper 413 (haskellPackages.ghcWithPackages (p: [ 414 p.cryptonite p.memory p.base16-bytestring p.vector 415 ])) ]; 416 buildPhase = '' 417 ghc -O2 -threaded -rtsopts -XOverloadedStrings -XScopedTypeVariables \ 418 -XMultiWayIf -XLambdaCase -isrc -outputdir objects \ 419 bench/ReducerSmoke.hs -o haskell-reducer-smoke 420 gcc -O2 -Wall -Wextra -Werror ext/zig/tests/performance_smoke.c \ 421 -DARB_HOST_MODE='"${tricuZig.optimizationMode}"' \ 422 -I ${tricuZig}/include -L ${tricuZig}/lib -larboricx \ 423 -Wl,-rpath,${tricuZig}/lib -o zig-reducer-smoke 424 ''; 425 doCheck = true; 426 checkPhase = '' 427 for kind in id append deep distribution; do 428 fixture=test/fixtures/id.arboricx 429 if [ "$kind" = append ]; then fixture=test/fixtures/append.arboricx; fi 430 ./haskell-reducer-smoke "$kind" 64 2 "$fixture" +RTS -N1 -M512m -K8m -RTS 431 ./zig-reducer-smoke "$kind" 64 2 "$fixture" 432 done 433 # A real but wrong worker must fail complete-result validation. 434 if ./haskell-reducer-smoke id 256 1 test/fixtures/append.arboricx \ 435 +RTS -N1 -M512m -K8m -RTS >bad-haskell.log 2>&1; then exit 1; fi 436 grep -q 'incorrect complete result' bad-haskell.log 437 if ./zig-reducer-smoke id 256 1 test/fixtures/append.arboricx \ 438 >bad-zig.log 2>&1; then exit 1; fi 439 grep -q 'failed:' bad-zig.log 440 ''; 441 installPhase = '' 442 mkdir -p $out/bin $out/libexec 443 cp haskell-reducer-smoke zig-reducer-smoke $out/bin/ 444 cp test/reducer_comparison.py test/process_rss.py $out/libexec/ 445 ghc --version > $out/compiler-version 446 makeWrapper ${pkgs.python3}/bin/python3 $out/bin/compare-reducers \ 447 --add-flags "$out/libexec/reducer_comparison.py $out/bin/haskell-reducer-smoke $out/bin/zig-reducer-smoke ${./test/fixtures}" 448 ''; 449 meta.mainProgram = "compare-reducers"; 450 }; 451 packages.inspectorOracle = pkgs.runCommand "arboricx-inspector-oracle" { 452 nativeBuildInputs = [ (haskellPackages.ghcWithPackages (p: [ 453 p.cryptonite p.memory p.base16-bytestring p.vector 454 ])) ]; 455 } '' 456 mkdir -p $out/bin 457 ghc -O1 -XOverloadedStrings -XScopedTypeVariables -XMultiWayIf -XLambdaCase \ 458 -i${./src} -outputdir "$TMPDIR/objects" ${./test/InspectorOracle.hs} \ 459 -o $out/bin/inspector-oracle 460 ''; 461 packages.arboricxArtwork = import ./ext/demo-site/artwork.nix { inherit pkgs; }; 462 packages.arboricxWebkitCheck = import ./ext/demo-site/webkit.nix { inherit pkgs; }; 463 packages.arboricxSite = siteRelease.arboricxSite; 464 packages.arboricxSiteDeps = siteRelease.arboricxSiteDeps; 465 packages.tricu-static = tricuMuslStatic; 466 packages.tricu-static-upx = tricuStatic; 467 packages.tricu-bench = tricuBench; 468 packages.benchmarkWorkers = benchmarkWorkers; 469 packages.benchmarkSmoke = pkgs.runCommand "tricu-benchmark-smoke" {} '' 470 ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 471 "$(cat ${benchmarkWorkers}/sha256)" --verify-only +RTS -N1 -M8192m -RTS 472 if ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 473 "$(printf '%064d' 0)" --verify-only >bad-hash.log 2>&1; then 474 echo "benchmark accepted a wrong digest" >&2; exit 1 475 fi 476 grep -q 'SHA256 mismatch' bad-hash.log 477 if ${tricuBench}/bin/tricu-bench ${./test/fixtures/id.arboricx} \ 478 "$(sha256sum ${./test/fixtures/id.arboricx} | cut -d ' ' -f 1)" \ 479 --verify-only >bad-interface.log 2>&1; then 480 echo "benchmark accepted the wrong interface" >&2; exit 1 481 fi 482 grep -q 'exactly the benchmark export interface' bad-interface.log 483 printf 'not a bundle' > malformed.arboricx 484 if ${tricuBench}/bin/tricu-bench malformed.arboricx \ 485 "$(sha256sum malformed.arboricx | cut -d ' ' -f 1)" \ 486 --verify-only >malformed.log 2>&1; then 487 echo "benchmark accepted authenticated malformed bytes" >&2; exit 1 488 fi 489 ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 490 "$(cat ${benchmarkWorkers}/sha256)" --list >names 491 test "$(grep -c '^contracts/' names)" -eq 12 492 test "$(grep -c '^registry-hash/' names)" -eq 15 493 ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 494 "$(cat ${benchmarkWorkers}/sha256)" --iters 1 +RTS -N1 -M8192m -RTS 495 mkdir -p $out 496 ''; 497 498 packages.tricu-zig = tricuZig; 499 packages.tricu-wasm = tricuWasm; 500 packages.tricu-wasm-tests = tricuWasmTests; 501 packages.tricu-wasm-browser = tricuWasmBrowser; 502 packages.tricu-wasm-comparison = tricuWasmComparison; 503 packages.tricu-zig-tests = tricuZigTests; 504 packages.tricu-zig-performance-smoke = tricuZigPerformanceSmoke; 505 packages.tricu-php = tricuPhp; 506 packages.tricu-php-tests = tricuPhpTests; 507 packages.tricu-js = tricuJs; 508 packages.tricu-js-tests = tricuJsTests; 509 510 checks.runtimeBoundary = pkgs.runCommand "tricu-runtime-source-boundary" {} '' 511 test -f ${runtimeSource}/src/Runtime/Tree.hs 512 for path in Research.hs Eval.hs FileEval.hs Lexer.hs Parser.hs \ 513 Frontend Module/Resolver.hs Module/Workspace.hs; do 514 test ! -e "${runtimeSource}/src/$path" 515 done 516 mkdir -p $out 517 ''; 518 519 checks.${packageName} = tricuPackageTests; 520 checks.default = tricuPackageTests; 521 # Fast packaging/filesystem checks only, no compiler or application runs. 522 checks.arboricxSite = pkgs.runCommand "arboricx-site-release-check" { 523 nativeBuildInputs = [ pkgs.python3 ]; 524 } '' 525 python3 ${./ext/demo-site/test/asset-release.py} ${./ext/demo-site/asset-release.py} 526 python3 ${./ext/demo-site/test/release.py} \ 527 --site ${siteRelease.arboricxSite} --deps ${siteRelease.arboricxSiteDeps} \ 528 --seeder ${./ext/demo-site/seed.py} 529 mkdir -p $out 530 ''; 531 checks.bootstrapRetention = pkgs.runCommand "tricu-bootstrap-retention-tests" { 532 nativeBuildInputs = [ pkgs.python3 ]; 533 } '' 534 export PYTHONDONTWRITEBYTECODE=1 535 cd ${tricuSource} 536 python3 test/bootstrap_retention_test.py 537 mkdir -p $out 538 ''; 539 checks.hostPolicy = pkgs.stdenv.mkDerivation { 540 pname = "tricu-host-policy-tests"; 541 version = "0.1.0"; 542 src = tricuSource; 543 nativeBuildInputs = [ pkgs.python3 tricuPackage ]; 544 buildPhase = "true"; 545 doCheck = true; 546 checkPhase = '' 547 test ! -e archive 548 export PYTHONDONTWRITEBYTECODE=1 549 python3 test/unit.py 550 python3 test/shipped_compiler.py 551 python3 test/executable_arguments.py ${tricuPackage}/bin/tricu 552 python3 test/package_registry.py ${tricuPackage}/bin/tricu 553 python3 test/project_dependencies.py ${tricuPackage}/bin/tricu 554 python3 test/project_inspection.py ${tricuPackage}/bin/tricu 555 python3 test/interaction_inspection.py ${tricuPackage}/bin/tricu 556 python3 test/provenance.py ${tricuPackage}/bin/tricu 557 ''; 558 installPhase = "mkdir -p $out"; 559 }; 560 # Source compilation and bootstrap generations remain explicit opt-in 561 # jobs. Haskell package tests above gate the supported host. 562 563 devShells.default = pkgs.mkShell { 564 buildInputs = with pkgs; [ 565 haskellPackages.cabal-install 566 haskellPackages.ghc-events 567 haskellPackages.ghcid 568 haskellPackages.ghc 569 upx 570 gcc 571 python3 572 ]; 573 574 inputsFrom = [ 575 tricuPackage 576 tricuZig 577 tricuPhp 578 ]; 579 }; 580 581 packages.${containerPackageName} = pkgs.dockerTools.buildImage { 582 name = "tricu"; 583 tag = "latest"; 584 585 copyToRoot = pkgs.buildEnv { 586 name = "image-root"; 587 paths = [ tricuStatic ]; 588 pathsToLink = [ "/bin" ]; 589 }; 590 591 config = { 592 Cmd = [ "/bin/tricu" ]; 593 WorkingDir = "/app"; 594 }; 595 }; 596 597 # Opt-in: compiles and exercises the actual deployment entrypoint. 598 packages.arboricxServerTest = pkgs.runCommand "arboricx-server-test" { 599 nativeBuildInputs = [ pkgs.python3 ]; 600 } '' 601 python3 ${./test/arboricx_deployment.py} ${arboricxServerRunner}/bin/arboricx-server 602 mkdir -p $out 603 ''; 604 packages.arboricxServerBundle = arboricxServerBundle; 605 packages.arboricxServerRunner = arboricxServerRunner; 606 packages.arboricxServer = pkgs.dockerTools.buildImage { 607 name = "arboricx-server"; 608 tag = "latest"; 609 610 copyToRoot = pkgs.runCommand "arboricx-server-root" {} '' 611 mkdir -p $out/app/store 612 ''; 613 614 config = { 615 Entrypoint = [ "${arboricxServerRunner}/bin/arboricx-server" ]; 616 WorkingDir = "/app"; 617 ExposedPorts = { "8080/tcp" = {}; }; 618 }; 619 }; 620 }); 621 }