flake.nix (46358B)
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; haskellRuntime = self.packages.${system}.haskellWasmBrowser; }; 16 packageName = "tricu"; 17 containerPackageName = "${packageName}-container"; 18 19 # Keep active build/test source hashes scoped to current sources. 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 # Narrow GHC 9.14 compatibility changes; upstream test suites stay enabled. 38 nativeHaskellOverrides = final: previous: { 39 # The upstream completion-order fix preserves the diagnostic-message test. 40 sandwich = hsLib.overrideCabal previous.sandwich (old: { 41 patches = (old.patches or []) ++ [ ./ext/haskell/patches/sandwich-introduce-with-completion.patch ]; 42 }); 43 string-interpolate = hsLib.overrideCabal previous.string-interpolate (old: { 44 postPatch = (old.postPatch or "") + '' 45 substituteInPlace string-interpolate.cabal \ 46 --replace-fail 'template-haskell <2.24' 'template-haskell <2.25' 47 ''; 48 }); 49 brick = hsLib.overrideCabal previous.brick (old: { 50 postPatch = (old.postPatch or "") + '' 51 substituteInPlace brick.cabal \ 52 --replace-fail 'base >= 4.9.0.0 && < 4.22.0.0' 'base >= 4.9.0.0 && < 4.23.0.0' 53 ''; 54 }); 55 config-ini = hsLib.overrideCabal previous.config-ini (old: { 56 postPatch = (old.postPatch or "") + '' 57 substituteInPlace config-ini.cabal \ 58 --replace-fail 'containers >=0.5 && <0.8' 'containers >=0.5 && <0.9' 59 ''; 60 }); 61 }; 62 haskellPackages = pkgs.haskell.packages.ghc914.override { 63 overrides = nativeHaskellOverrides; 64 }; 65 picHaskellPackages = haskellPackages.override { 66 # Build tools and dependencies must use the same boot-library IDs. 67 buildHaskellPackages = picHaskellPackages; 68 overrides = pkgs.lib.composeExtensions nativeHaskellOverrides (final: previous: { 69 mkDerivation = args: previous.mkDerivation (args // { 70 configureFlags = (args.configureFlags or []) ++ [ 71 "--ghc-option=-fPIC" "--ghc-option=-optc-fPIC" 72 ]; 73 }); 74 }); 75 ghc = haskellPackages.ghc.override { 76 enableRelocatedStaticLibs = true; 77 # These build-only variants are unused by the embedding experiment. 78 enableProfiledLibs = false; 79 enableDocs = false; 80 }; 81 }; 82 hsLib = pkgs.haskell.lib; 83 84 staticPkgs = pkgs.pkgsStatic; 85 staticHaskellPackages = staticPkgs.haskellPackages; 86 staticHsLib = staticPkgs.haskell.lib; 87 88 tricuMuslStatic = 89 staticHsLib.justStaticExecutables ( 90 staticHsLib.dontCheck ( 91 staticHaskellPackages.callCabal2nix packageName runtimeSource {} 92 ) 93 ); 94 95 tricuStatic = pkgs.runCommand "${packageName}-static-upx" { 96 nativeBuildInputs = [ pkgs.upx ]; 97 } '' 98 mkdir -p $out/bin 99 cp ${tricuMuslStatic}/bin/tricu $out/bin/tricu 100 chmod +w $out/bin/tricu 101 102 # Good compression, slower build. 103 upx --best --lzma $out/bin/tricu 104 105 chmod 755 $out/bin/tricu 106 ''; 107 108 tricuPackageTests = 109 haskellPackages.callCabal2nix packageName tricuSource {}; 110 111 tricuPackage = 112 hsLib.dontCheck ( 113 haskellPackages.callCabal2nix packageName runtimeSource {} 114 ); 115 116 # Compile once with the packaged stable compiler. Runtime needs neither 117 # source lookup nor a writable compiler/application cache. 118 mkRegistryBundle = name: source: pkgs.runCommand "${name}-bundle" { 119 nativeBuildInputs = [ tricuPackage ]; 120 } '' 121 mkdir -p $out 122 tricu arboricx compile --file ${source} --store build-store \ 123 --output $out/server.arboricx --compile-timeout 900 \ 124 +RTS -N1 -M8192m -RTS 125 tricu arboricx import --file $out/server.arboricx --store $out/runtime \ 126 > import.log 127 sed -n 's/^Created module alias .* -> //p' import.log > $out/manifest 128 test "$(wc -l < $out/manifest)" -eq 1 129 grep -Eq '^[0-9a-f]{64}$' $out/manifest 130 ''; 131 132 arboricxServerBundle = mkRegistryBundle "arboricx-server" "${./.}/tricu-apps/arboricxServer.tri"; 133 arboricxServerRunner = mkRegistryRunner "arboricx-server" arboricxServerBundle; 134 arboricxStreamingBundle = mkRegistryBundle "arboricx-streaming" "${./.}/tricu-apps/arboricxStreaming.tri"; 135 mkRegistryRunner = name: bundle: pkgs.writeShellScriptBin name '' 136 exec ${tricuPackage}/bin/tricu arboricx run \ 137 --module "$(${pkgs.coreutils}/bin/cat ${bundle}/manifest)" --name main \ 138 --store ${bundle}/runtime --io --no-result \ 139 +RTS -N1 -M2048m -RTS 140 ''; 141 arboricxStreamingRunner = mkRegistryRunner "arboricx-streaming" arboricxStreamingBundle; 142 arboricxStreamingFaultBundle = mkRegistryBundle "arboricx-streaming-fault" "${./.}/test/io/registry-log-failure.tri"; 143 arboricxStreamingFaultRunner = mkRegistryRunner "arboricx-streaming-fault" arboricxStreamingFaultBundle; 144 mkRegistryTest = name: runner: pkgs.runCommand "${name}-test" { 145 nativeBuildInputs = [ pkgs.python3 ]; 146 } '' 147 mkdir -p $out 148 python3 ${./test/arboricx_deployment.py} ${runner}/bin/${name} \ 149 --io-version 2 --handler-policy \ 150 --fault-runner ${arboricxStreamingFaultRunner}/bin/arboricx-streaming-fault \ 151 --report $out/report.json 152 python3 ${./test/streaming_protocol.py} ${runner}/bin/${name} \ 153 --io-version 2 > $out/protocol.txt 154 PYTHONDONTWRITEBYTECODE=1 python3 ${./.}/test/registry_download.py \ 155 ${runner}/bin/${name} ${./test/fixtures/compiler-library.arboricx} \ 156 --report $out/compiler-download.json > $out/compiler-download-summary.json 157 PYTHONDONTWRITEBYTECODE=1 python3 ${./.}/test/body_retention.py \ 158 --runner ${runner}/bin/${name} \ 159 --phases streaming-publish streaming-download --bounded-streaming \ 160 --sizes 65536 1048576 --repeats 3 \ 161 --directory $out/retention > $out/retention-summary.json 162 ''; 163 164 tricuBench = 165 (hsLib.overrideCabal 166 (hsLib.doBenchmark (hsLib.dontCheck ( 167 haskellPackages.callCabal2nix packageName runtimeSource {} 168 ))) 169 (oldAttrs: { 170 postInstall = (oldAttrs.postInstall or "") + '' 171 mkdir -p $out/bin 172 cp dist/build/tricu-bench/tricu-bench $out/bin/ 173 ''; 174 })).overrideAttrs (_: { 175 # Require a caller-selected worker bundle for the timing run. 176 benchmarkPhase = "true"; 177 }); 178 179 # Opt-in application build with its own acceptance gate. Retain the exact 180 # sources, compiler metadata and receipts beside the worker bundle. 181 benchmarkWorkers = pkgs.runCommand "tricu-benchmark-workers" { 182 nativeBuildInputs = [ tricuPackage ]; 183 } '' 184 mkdir -p $out/workspace 185 ${pkgs.lib.concatMapStringsSep "\n" (name: 186 "cp ${./lib}/${name}.tri $out/workspace/${name}.tri") [ 187 "base" "prelude" "bytes" "conversions" "io" "parser" "http" "socket" 188 ]} 189 cp ${./lib/math/native.tri} $out/workspace/native_math.tri 190 cp ${./lib/intensionalContracts.tri} $out/workspace/intensional.tri 191 cp ${./lib/arboricx/server.tri} $out/workspace/server.tri 192 cp ${./bench/workers.tri} $out/workspace/workers.tri 193 cp ${./bootstrap/stable-compiler.json} $out/compiler.json 194 timeout 930 tricu arboricx compile --file $out/workspace/workers.tri \ 195 --store $out/store --output $out/workers.arboricx --compile-timeout 900 \ 196 +RTS -N1 -M8192m -RTS 197 sha256sum $out/workers.arboricx | cut -d ' ' -f 1 > $out/sha256 198 ''; 199 200 siteJavaScript = import ./ext/demo-site/javascript.nix { inherit pkgs; }; 201 202 tricuHaskell = import ./ext/haskell/build.nix { 203 inherit pkgs haskellPackages; 204 source = tricuSource; 205 }; 206 tricuHaskellArchive = import ./ext/haskell/build.nix { 207 inherit pkgs; 208 source = tricuSource; 209 haskellPackages = picHaskellPackages; 210 archiveHaskell = true; 211 }; 212 embeddingIntegration = libraryPackage: pkgs.runCommand "tricu-haskell-ffi-integration" { 213 nativeBuildInputs = [ pkgs.python3 tricuPackage ]; 214 } '' 215 export PYTHONDONTWRITEBYTECODE=1 216 export PYTHONPATH=${tricuSource}/ext/haskell/python 217 mkdir -p $out workspace 218 cp ${tricuSource}/lib/base.tri workspace/base.tri 219 cp ${tricuSource}/lib/math/native.tri workspace/native_math.tri 220 cp ${tricuSource}/lib/io.tri workspace/io.tri 221 cp ${tricuSource}/lib/handlers.tri workspace/handlers.tri 222 cp ${tricuSource}/demos/io/copy.tri workspace/copy.tri 223 tricu arboricx compile --file workspace/copy.tri --store copy-store \ 224 --output $out/copy.arboricx --compile-timeout 120 +RTS -N1 -M1024m -RTS 225 library=${libraryPackage}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} 226 python3 ${tricuSource}/ext/haskell/test_embedding.py "$library" \ 227 ${tricuSource}/test/fixtures --copy-bundle $out/copy.arboricx > $out/integration.json 228 python3 ${tricuSource}/ext/haskell/compiler_probe.py "$library" \ 229 ${tricuSource}/bootstrap/build-stable.arboricx --tricu ${tricuPackage}/bin/tricu \ 230 --directory compiler-probe > $out/compiler.log 231 cp compiler-probe/report.json $out/compiler.json 232 ''; 233 tricuPython = pkgs.python3Packages.buildPythonPackage { 234 pname = "tricu-runtime"; 235 version = "2026.10.24"; 236 src = ./ext/haskell/python; 237 pyproject = true; 238 build-system = [ pkgs.python3Packages.setuptools ]; 239 postInstall = '' 240 ln -s ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} \ 241 $out/${pkgs.python3.sitePackages}/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} 242 ''; 243 pythonImportsCheck = [ "tricu" ]; 244 }; 245 pythonWithTricu = pkgs.python3.withPackages (_: [ tricuPython ]); 246 247 tricuFilecheckBundle = pkgs.runCommand "tricu-filecheck-worker" { 248 nativeBuildInputs = [ tricuPackage ]; 249 } '' 250 mkdir -p $out workspace 251 cp ${tricuSource}/lib/base.tri workspace/base.tri 252 cp ${tricuSource}/lib/math/native.tri workspace/native_math.tri 253 cp ${tricuSource}/lib/io.tri workspace/io.tri 254 cp ${tricuSource}/demos/python-filecheck/worker.tri workspace/worker.tri 255 tricu arboricx compile --file workspace/worker.tri --store build-store \ 256 --output $out/worker.arboricx --compile-timeout 120 +RTS -N1 -M1024m -RTS 257 sha256sum $out/worker.arboricx | cut -d' ' -f1 > $out/worker.sha256 258 ''; 259 tricuFilecheck = pkgs.python3Packages.buildPythonPackage { 260 pname = "tricu-filecheck"; 261 version = "2026.10.24"; 262 src = ./demos/python-filecheck; 263 pyproject = true; 264 build-system = [ pkgs.python3Packages.setuptools ]; 265 dependencies = [ tricuPython ]; 266 postPatch = '' 267 cp ${tricuFilecheckBundle}/worker.arboricx tricu_filecheck/worker.arboricx 268 printf 'BUNDLE_SHA256 = "%s"\n' "$(cat ${tricuFilecheckBundle}/worker.sha256)" \ 269 > tricu_filecheck/_bundle_pin.py 270 ''; 271 pythonImportsCheck = [ "tricu_filecheck" ]; 272 }; 273 pythonWithFilecheck = pkgs.python3.withPackages (_: [ tricuFilecheck ]); 274 275 tricuWorkflowBundle = pkgs.runCommand "tricu-workflow-demo-bundle" { 276 nativeBuildInputs = [ tricuPackage ]; 277 } '' 278 mkdir -p $out workspace 279 cp ${tricuSource}/lib/base.tri workspace/base.tri 280 cp ${tricuSource}/lib/math/native.tri workspace/native_math.tri 281 cp ${tricuSource}/demos/workflow-planning/workflow.tri workspace/workflow.tri 282 cp ${tricuSource}/demos/workflow-planning/pipeline.tri workspace/pipeline.tri 283 tricu arboricx compile --file workspace/pipeline.tri --store build-store \ 284 --output $out/pipeline.arboricx --compile-timeout 120 +RTS -N1 -M1024m -RTS 285 sha256sum $out/pipeline.arboricx | cut -d' ' -f1 > $out/pipeline.sha256 286 ''; 287 tricuWorkflow = pkgs.python3Packages.buildPythonPackage { 288 pname = "tricu-workflow-demo"; 289 version = "2026.10.24"; 290 src = ./demos/workflow-planning; 291 pyproject = true; 292 build-system = [ pkgs.python3Packages.setuptools ]; 293 dependencies = [ tricuPython ]; 294 postPatch = '' 295 cp ${tricuWorkflowBundle}/pipeline.arboricx tricu_workflow_demo/pipeline.arboricx 296 printf 'BUNDLE_SHA256 = "%s"\n' "$(cat ${tricuWorkflowBundle}/pipeline.sha256)" \ 297 > tricu_workflow_demo/_bundle_pin.py 298 ''; 299 pythonImportsCheck = [ "tricu_workflow_demo" ]; 300 }; 301 pythonWithWorkflow = pkgs.python3.withPackages (_: [ tricuWorkflow ]); 302 303 # ------------------------------------------------------------------ 304 # PHP FFI host 305 # ------------------------------------------------------------------ 306 tricuPhp = pkgs.stdenv.mkDerivation { 307 pname = "tricu-php"; 308 version = "2026.10.24"; 309 src = ./ext/php; 310 nativeBuildInputs = [ pkgs.makeWrapper ]; 311 dontBuild = true; 312 installPhase = '' 313 mkdir -p $out/share/tricu-php $out/bin 314 cp -r src public run.php $out/share/tricu-php/ 315 cp ${tricuHaskell}/include/tricu*.h $out/share/tricu-php/ 316 ln -s ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} $out/share/tricu-php/ 317 makeWrapper ${phpWithFfi}/bin/php $out/bin/tricu-php \ 318 --add-flags "$out/share/tricu-php/run.php" \ 319 --set TRICU_LIB "${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary}" 320 ''; 321 }; 322 323 tricuJs = pkgs.buildNpmPackage { 324 pname = "tricu-js"; 325 version = "2026.10.24"; 326 src = ./ext/js; 327 npmDepsHash = "sha256-81C7tsNcbyZVhm3uqiWdDQxp5LAXXO9aueHdMDztCfM="; 328 dontNpmBuild = true; 329 installPhase = '' 330 mkdir -p $out/lib/ $out/bin 331 cp -r . $out/lib/ 332 ln -s ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/src/ 333 makeWrapper ${pkgs.nodejs}/bin/node $out/bin/arboricx-run \ 334 --add-flags "$out/lib/src/cli.js" 335 ''; 336 nativeBuildInputs = [ pkgs.makeWrapper ]; 337 }; 338 339 tricuJsTests = pkgs.runCommand "tricu-js-tests" { 340 nativeBuildInputs = [ pkgs.nodejs ]; 341 } '' 342 export TRICU_LIB=${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} 343 cp -r ${tricuSource} source 344 chmod -R u+w source 345 cd source/ext/js 346 ln -s ${tricuJs}/lib/node_modules node_modules 347 timeout 90s npm test 348 test "$(${tricuJs}/bin/arboricx-run run ../../test/fixtures/id.arboricx id hello)" = hello 349 test "$(${tricuJs}/bin/arboricx-run run ../../test/fixtures/true.arboricx true --format bool)" = true 350 if ${tricuJs}/bin/arboricx-run run ../../test/fixtures/id.arboricx missing; then exit 1; fi 351 mkdir -p $out 352 ''; 353 354 phpWithFfi = pkgs.php.withExtensions (exts: [ pkgs.phpExtensions.ffi ]); 355 tricuPhpTests = pkgs.runCommand "tricu-php-tests" { 356 nativeBuildInputs = [ phpWithFfi pkgs.python3 ]; 357 } '' 358 export TRICU_LIB=${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} 359 mkdir -p $out 360 timeout 90s php ${tricuSource}/ext/php/tests/conformance.php "$TRICU_LIB" \ 361 ${tricuSource}/test/fixtures ${tricuSource}/ext/haskell/bindings/fixtures.json > $out/report.json 362 test "$(${tricuPhp}/bin/tricu-php run ${tricuSource}/test/fixtures/id.arboricx id hello)" = hello 363 test "$(${tricuPhp}/bin/tricu-php run ${tricuSource}/test/fixtures/false.arboricx false --format bool)" = false 364 if ${tricuPhp}/bin/tricu-php run ${tricuSource}/test/fixtures/id.arboricx missing; then exit 1; fi 365 timeout 60s python3 ${tricuSource}/ext/php/tests/web.py ${phpWithFfi}/bin/php \ 366 ${tricuPhp}/share/tricu-php/public ${tricuSource}/test/fixtures/id.arboricx 367 ''; 368 tricuPythonTests = pkgs.runCommand "tricu-python-tests" { 369 nativeBuildInputs = [ pythonWithTricu ]; 370 } '' 371 export PYTHONDONTWRITEBYTECODE=1 372 mkdir -p $out 373 # Exercise installed-module discovery through its default library lookup. 374 python3 -c 'from tricu import Library; c = Library().context(); c.close()' 375 timeout 90s python3 ${tricuSource}/ext/haskell/bindings/python.py \ 376 ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} \ 377 ${tricuSource}/test/fixtures ${tricuSource}/ext/haskell/bindings/fixtures.json > $out/report.json 378 ''; 379 in { 380 packages.haskellWasmBrowser = import ./ext/haskell-wasm/browser.nix { 381 inherit pkgs; 382 probe = self.packages.${system}.haskellWasmProbe; 383 toolchain = ghc-wasm.packages.${system}.all_9_14; 384 shimSource = browser-wasi; 385 }; 386 packages.haskellWasmProbe = import ./ext/haskell-wasm/build.nix { 387 inherit pkgs; 388 toolchain = ghc-wasm.packages.${system}.all_9_14; 389 }; 390 packages.${packageName} = tricuPackage; 391 packages.default = tricuPackage; 392 packages.tricu-haskell-ffi = tricuHaskell; 393 packages.tricu-haskell-ffi-archive = tricuHaskellArchive; 394 packages.tricu-redistribution = import ./ext/haskell/redistribution.nix { 395 inherit pkgs; 396 host = tricuHaskellArchive; 397 source = self; 398 nixpkgsSource = nixpkgs; 399 flakeUtilsSource = flake-utils; 400 systemsSource = flake-utils.inputs.systems; 401 }; 402 packages.tricu-portable = pkgs.runCommand "tricu-portable-linux-x86_64" { 403 nativeBuildInputs = [ pkgs.python3 pkgs.patchelf pkgs.binutils pkgs.glibc.bin ]; 404 meta.platforms = [ "x86_64-linux" ]; 405 } '' 406 mkdir -p $out 407 python3 ${./ext/haskell/portable.py} --host ${tricuHaskellArchive} \ 408 --glibc ${pkgs.glibc} --output $out/tricu \ 409 --materials ${self.packages.${system}.tricu-redistribution} 410 cp ${./LICENSE} $out/tricu/LICENSE 411 cp ${./ext/haskell/portable-README.md} $out/tricu/README.md 412 tar --hard-dereference --sort=name --mtime=@1 --owner=0 --group=0 --numeric-owner \ 413 -C $out -czf $out/tricu-linux-x86_64.tar.gz tricu 414 tar --hard-dereference --sort=name --mtime=@1 --owner=0 --group=0 --numeric-owner \ 415 --transform='flags=r;s,^\.,tricu-source-materials,' \ 416 -C ${self.packages.${system}.tricu-redistribution} -cf - . \ 417 | gzip -n -6 > $out/tricu-source-materials.tar.gz 418 python3 ${./ext/haskell/verify_redistribution.py} \ 419 --materials ${self.packages.${system}.tricu-redistribution} \ 420 --runtime $out/tricu --archives $out 421 ''; 422 packages.tricu-portable-test-system = pkgs.runCommand "tricu-portable-test-system" { 423 nativeBuildInputs = [ pkgs.python3 pkgs.patchelf pkgs.glibc.bin ]; 424 meta.platforms = [ "x86_64-linux" ]; 425 } '' 426 mkdir tools 427 cp ${./ext/haskell/portable.py} tools/portable.py 428 cp ${./ext/haskell/portable_fixture.py} tools/fixture.py 429 python3 tools/fixture.py --python ${pkgs.python3}/bin/python3 \ 430 --stdlib ${pkgs.python3}/lib/python${pkgs.python3.pythonVersion} \ 431 --loader ${pkgs.glibc}/lib/ld-linux-x86-64.so.2 --output $out 432 ''; 433 packages.tricu-portable-test = pkgs.runCommand "tricu-portable-test" { 434 nativeBuildInputs = [ pkgs.python3 pkgs.bubblewrap ]; 435 meta.platforms = [ "x86_64-linux" ]; 436 } '' 437 python3 ${./ext/haskell/test_portable.py} \ 438 --release ${self.packages.${system}.tricu-portable}/tricu-linux-x86_64.tar.gz \ 439 --system ${self.packages.${system}.tricu-portable-test-system} \ 440 --source ${tricuSource} --worker ${tricuFilecheckBundle} \ 441 --copier ${self.packages.${system}.tricu-haskell-ffi-archive-integration}/copy.arboricx \ 442 --output $out 443 ''; 444 packages.tricu-distro-test-kit = pkgs.runCommand "tricu-distro-test-kit" { 445 nativeBuildInputs = [ pkgs.python3 pkgs.nodejs phpWithFfi ]; 446 } '' 447 mkdir -p $out/tests 448 cp ${self.packages.${system}.tricu-portable}/tricu-linux-x86_64.tar.gz $out/ 449 cp ${./ext/haskell/container_matrix.py} $out/container_matrix.py 450 cp ${./ext/haskell/container_probe.py} $out/container_probe.py 451 cp ${./ext/haskell/container_bindings.py} $out/container_bindings.py 452 mkdir -p $out/bindings/ext/{js,php,haskell/bindings} 453 cp -r ${./ext/js/src} $out/bindings/ext/js/src 454 cp -r ${./ext/js/test} $out/bindings/ext/js/test 455 cp ${./ext/js/package.json} $out/bindings/ext/js/package.json 456 cp ${./ext/js/package-lock.json} $out/bindings/ext/js/package-lock.json 457 cp -r ${./ext/php/src} $out/bindings/ext/php/src 458 cp -r ${./ext/php/tests} $out/bindings/ext/php/tests 459 cp ${./ext/haskell/test_embedding.py} $out/bindings/ext/haskell/test_embedding.py 460 cp ${./ext/haskell/bindings/python.py} $out/bindings/ext/haskell/bindings/python.py 461 cp ${./ext/haskell/bindings/fixtures.json} $out/bindings/ext/haskell/bindings/fixtures.json 462 cp ${./ext/haskell/portable_workload.py} $out/tests/portable_workload.py 463 cp ${./ext/haskell/test_embedding.py} $out/tests/test_embedding.py 464 cp ${./ext/haskell/test_scopes.py} $out/tests/test_scopes.py 465 cp ${./test/python_filecheck.py} $out/tests/python_filecheck.py 466 cp ${./test/process_rss.py} $out/tests/process_rss.py 467 mkdir $out/tests/fixtures 468 for fixture in id append true false notQ; do 469 cp ${tricuSource}/test/fixtures/$fixture.arboricx $out/tests/fixtures/ 470 done 471 cp -r ${tricuSource}/demos/python-filecheck/tricu_filecheck $out/tests/tricu_filecheck 472 chmod -R u+w $out/tests/tricu_filecheck 473 cp ${tricuFilecheckBundle}/worker.arboricx $out/tests/tricu_filecheck/worker.arboricx 474 printf 'BUNDLE_SHA256 = "%s"\n' "$(cat ${tricuFilecheckBundle}/worker.sha256)" \ 475 > $out/tests/tricu_filecheck/_bundle_pin.py 476 cp ${self.packages.${system}.tricu-haskell-ffi-archive-integration}/copy.arboricx $out/tests/ 477 PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=$out python3 -c \ 478 'import sys; from pathlib import Path; from container_matrix import validate_bindings_kit; validate_bindings_kit(Path(sys.argv[1]))' "$out" 479 # Exercise the actual staged consumers and their helper imports. Nix 480 # supplies these smoke runtimes; distro acceptance remains external. 481 cp -r $out/bindings source 482 chmod -R u+w source 483 mkdir -p source/test 484 cp -r $out/tests/fixtures source/test/fixtures 485 ln -s ${tricuJs}/lib/node_modules source/ext/js/node_modules 486 cp ${self.packages.${system}.tricu-portable}/tricu/include/tricu.h source/ext/php/tricu.h 487 PYTHONDONTWRITEBYTECODE=1 \ 488 PYTHONPATH=${self.packages.${system}.tricu-portable}/tricu/share/tricu \ 489 python3 ${./ext/haskell/bindings/check.py} --source "$PWD/source" \ 490 --library ${self.packages.${system}.tricu-portable}/tricu/lib/libtricu-haskell.so \ 491 --python ${pkgs.python3}/bin/python3 --node ${pkgs.nodejs}/bin/node \ 492 --php ${phpWithFfi}/bin/php --copier $out/tests/copy.arboricx \ 493 --report $out/bindings-smoke.json 494 ''; 495 packages.tricu-distro-test = pkgs.writeShellApplication { 496 name = "tricu-distro-test"; 497 runtimeInputs = [ pkgs.python3 ]; 498 text = '' 499 exec python3 ${self.packages.${system}.tricu-distro-test-kit}/container_matrix.py "$@" 500 ''; 501 }; 502 packages.tricu-vm-test-kit = pkgs.runCommand "tricu-vm-test-kit" {} '' 503 mkdir -p $out 504 cp -r ${self.packages.${system}.tricu-distro-test-kit}/. $out/ 505 chmod u+w $out 506 cp ${./ext/haskell/vm_matrix.py} $out/vm_matrix.py 507 cp ${./ext/haskell/vm_guest.py} $out/vm_guest.py 508 ''; 509 packages.tricu-vm-test = pkgs.writeShellApplication { 510 name = "tricu-vm-test"; 511 runtimeInputs = [ pkgs.python3 pkgs.qemu pkgs.cdrkit ]; 512 text = '' 513 exec python3 ${self.packages.${system}.tricu-vm-test-kit}/vm_matrix.py "$@" 514 ''; 515 }; 516 checks.portableVMHarness = pkgs.runCommand "tricu-portable-vm-harness" { 517 nativeBuildInputs = [ pkgs.python3 pkgs.cdrkit ]; 518 } '' 519 mkdir tools 520 cp ${./ext/haskell/vm_matrix.py} tools/vm_matrix.py 521 cp ${./ext/haskell/vm_guest.py} tools/vm_guest.py 522 cp ${./ext/haskell/container_matrix.py} tools/container_matrix.py 523 cp ${./ext/haskell/test_vm_harness.py} tools/test_vm_harness.py 524 PYTHONDONTWRITEBYTECODE=1 python3 tools/test_vm_harness.py 525 mkdir -p $out 526 ''; 527 checks.redistribution = pkgs.runCommand "tricu-redistribution-controls" { 528 nativeBuildInputs = [ pkgs.python3 ]; 529 } '' 530 mkdir tools 531 cp ${./ext/haskell/redistribution.py} tools/redistribution.py 532 cp ${./ext/haskell/portable.py} tools/portable.py 533 cp ${./ext/haskell/verify_redistribution.py} tools/verify_redistribution.py 534 cp ${./ext/haskell/test_redistribution.py} tools/test_redistribution.py 535 PYTHONDONTWRITEBYTECODE=1 python3 tools/test_redistribution.py 536 mkdir -p $out 537 ''; 538 packages.tricu-portable-replacement-test = pkgs.runCommand "tricu-portable-replacement-test" { 539 nativeBuildInputs = [ pkgs.python3 pkgs.bubblewrap pkgs.binutils ]; 540 meta.platforms = [ "x86_64-linux" ]; 541 } '' 542 cp -r ${self.packages.${system}.tricu-portable}/tricu . 543 chmod -R u+w tricu 544 printf 'User-modified ABI-compatible ELF metadata\n' > modification.txt 545 for library in libgmp.so.10 libelf.so.1 libdw.so.1 libnuma.so.1; do 546 objcopy --add-section .tricu-user-modification=modification.txt tricu/lib/$library 547 done 548 python3 - <<'PY' 549 import hashlib, json 550 from pathlib import Path 551 manifest = Path('tricu/share/tricu/portable.json') 552 data = json.loads(manifest.read_text()) 553 replacements = {} 554 for name in ('libgmp.so.10', 'libelf.so.1', 'libdw.so.1', 'libnuma.so.1'): 555 library = Path('tricu/lib')/name 556 checksum = hashlib.sha256(library.read_bytes()).hexdigest() 557 assert checksum != data['libraries'][name]['sha256'] 558 replacements[name] = dict(original_sha256=data['libraries'][name]['sha256'], replacement_sha256=checksum) 559 data['libraries'][name].update(sha256=checksum, bytes=library.stat().st_size) 560 manifest.write_text(json.dumps(data)) 561 Path('replacement.json').write_text(json.dumps(dict( 562 method='Added a non-allocated ELF metadata section; ABI preserved; not a source rebuild', 563 libraries=replacements), indent=2)) 564 PY 565 tar -czf modified.tar.gz tricu 566 python3 ${./ext/haskell/test_portable.py} \ 567 --release "$PWD/modified.tar.gz" \ 568 --system ${self.packages.${system}.tricu-portable-test-system} \ 569 --source ${tricuSource} --worker ${tricuFilecheckBundle} \ 570 --copier ${self.packages.${system}.tricu-haskell-ffi-archive-integration}/copy.arboricx \ 571 --output $out 572 cp replacement.json $out/ 573 ''; 574 checks.portableContainerHarness = pkgs.runCommand "tricu-portable-container-harness" { 575 nativeBuildInputs = [ pkgs.python3 ]; 576 } '' 577 mkdir tools 578 cp ${./ext/haskell/container_matrix.py} tools/container_matrix.py 579 cp ${./ext/haskell/container_probe.py} tools/container_probe.py 580 cp ${./ext/haskell/test_container_harness.py} tools/test_container_harness.py 581 cp ${./ext/haskell/container_bindings.py} tools/container_bindings.py 582 PYTHONDONTWRITEBYTECODE=1 python3 tools/test_container_harness.py 583 mkdir -p $out 584 ''; 585 packages.tricu-generation-ffi-test = pkgs.runCommand "tricu-generation-ffi-test" { 586 nativeBuildInputs = [ pkgs.python3 ]; 587 } '' 588 export PYTHONDONTWRITEBYTECODE=1 589 mkdir -p $out 590 python3 ${tricuSource}/test/shared_library_generation.py \ 591 --tricu ${tricuPackage}/bin/tricu \ 592 --library ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} \ 593 --directory $out/compatibility --compatibility 594 python3 ${tricuSource}/test/shared_library_smoke.py \ 595 --tricu ${tricuPackage}/bin/tricu \ 596 --library ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} \ 597 --directory $out/programs 598 python3 ${tricuSource}/test/io_generation.py ${tricuPackage}/bin/tricu \ 599 --kit ${tricuSource}/bootstrap/rebuild \ 600 --haskell-library ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} \ 601 --directory $out/scoped 602 ''; 603 604 packages.tricu-haskell-linkage-smoke = pkgs.runCommand "tricu-haskell-linkage-smoke" { 605 nativeBuildInputs = [ pkgs.python3 pkgs.stdenv.cc ]; 606 meta.platforms = [ "x86_64-linux" ]; 607 } '' 608 mkdir -p $out/bin 609 $CC -O2 -Wall -Wextra -Werror ${tricuSource}/ext/haskell/core_bench.c \ 610 -I${tricuHaskell}/include -L${tricuHaskell}/lib -ltricu-haskell \ 611 -Wl,-rpath,${tricuHaskell}/lib -o $out/bin/dynamic-core-bench 612 $CC -O2 -Wall -Wextra -Werror ${tricuSource}/ext/haskell/core_bench.c \ 613 -I${tricuHaskellArchive}/include -L${tricuHaskellArchive}/lib -ltricu-haskell \ 614 -Wl,-rpath,${tricuHaskellArchive}/lib -o $out/bin/archive-core-bench 615 PYTHONDONTWRITEBYTECODE=1 python3 ${tricuSource}/ext/haskell/core_bench.py \ 616 --dynamic $out/bin/dynamic-core-bench --archive $out/bin/archive-core-bench \ 617 --output $out/report.json > $out/summary.json 618 ''; 619 packages.tricu-python = tricuPython; 620 packages.tricu-python-tests = tricuPythonTests; 621 packages.tricu-workflow-demo = tricuWorkflow; 622 packages.tricu-workflow-demo-test = pkgs.runCommand "tricu-workflow-demo-test" { 623 nativeBuildInputs = [ pythonWithWorkflow ]; 624 } '' 625 export PYTHONDONTWRITEBYTECODE=1 626 mkdir -p $out 627 cp ${(pkgs.closureInfo { rootPaths = [ tricuWorkflow ]; })}/store-paths $out/runtime-closure 628 if grep -Fx '${tricuPackage}' $out/runtime-closure; then exit 1; fi 629 if grep -Fx '${tricuSource}' $out/runtime-closure; then exit 1; fi 630 timeout 90s python3 ${tricuSource}/test/workflow_planning.py \ 631 --app ${tricuWorkflow}/bin/tricu-workflow-demo --report $out/report.json 632 ''; 633 packages.tricu-filecheck = tricuFilecheck; 634 packages.tricu-filecheck-test = pkgs.runCommand "tricu-filecheck-test" { 635 nativeBuildInputs = [ pythonWithFilecheck ]; 636 } '' 637 export PYTHONDONTWRITEBYTECODE=1 638 mkdir -p $out 639 # Runtime closure must contain neither the source compiler executable 640 # nor the source snapshot used to build it. 641 cp ${(pkgs.closureInfo { rootPaths = [ tricuFilecheck ]; })}/store-paths $out/runtime-closure 642 if grep -Fx '${tricuPackage}' $out/runtime-closure; then exit 1; fi 643 if grep -Fx '${tricuSource}' $out/runtime-closure; then exit 1; fi 644 timeout 120s python3 ${tricuSource}/test/python_filecheck.py \ 645 --app ${tricuFilecheck}/bin/tricu-filecheck --report $out/report.json 646 ''; 647 648 # Source-compiling embedding acceptance stays opt-in, like the other 649 # application compilation checks. Basic C/Python checks run in the library. 650 packages.tricu-haskell-ffi-integration = embeddingIntegration tricuHaskell; 651 packages.tricu-haskell-ffi-archive-integration = embeddingIntegration tricuHaskellArchive; 652 653 packages.tricu-native-bindings-integration = pkgs.runCommand "tricu-native-bindings-integration" { 654 nativeBuildInputs = [ pythonWithTricu pkgs.nodejs phpWithFfi ]; 655 } '' 656 export PYTHONDONTWRITEBYTECODE=1 657 cp -r ${tricuSource} source 658 chmod -R u+w source 659 ln -s ${tricuJs}/lib/node_modules source/ext/js/node_modules 660 mkdir -p $out 661 python3 source/ext/haskell/bindings/check.py \ 662 --source "$PWD/source" \ 663 --library ${tricuHaskell}/lib/libtricu-haskell${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} \ 664 --python ${pythonWithTricu}/bin/python3 --node ${pkgs.nodejs}/bin/node --php ${phpWithFfi}/bin/php \ 665 --copier ${self.packages.${system}.tricu-haskell-ffi-integration}/copy.arboricx \ 666 --report $out/report.json 667 ''; 668 669 # Native reducer smoke preserves full-result and wrong-worker controls. 670 packages.reducerSmoke = pkgs.stdenv.mkDerivation { 671 pname = "tricu-reducer-smoke"; 672 version = "2026.10.24"; 673 src = tricuSource; 674 nativeBuildInputs = [ (haskellPackages.ghcWithPackages (p: [ 675 p.cryptonite p.memory p.base16-bytestring p.vector 676 ])) ]; 677 buildPhase = '' 678 ghc -O2 -threaded -rtsopts -XOverloadedStrings -XScopedTypeVariables \ 679 -XMultiWayIf -XLambdaCase -isrc -outputdir objects \ 680 bench/ReducerSmoke.hs -o haskell-reducer-smoke 681 ''; 682 doCheck = true; 683 checkPhase = '' 684 for kind in id append deep distribution; do 685 fixture=test/fixtures/id.arboricx 686 if [ "$kind" = append ]; then fixture=test/fixtures/append.arboricx; fi 687 ./haskell-reducer-smoke "$kind" 64 2 "$fixture" +RTS -N1 -M512m -K8m -RTS 688 done 689 if ./haskell-reducer-smoke id 256 1 test/fixtures/append.arboricx \ 690 +RTS -N1 -M512m -K8m -RTS >bad-worker.log 2>&1; then exit 1; fi 691 grep -q 'incorrect complete result' bad-worker.log 692 ''; 693 installPhase = '' 694 mkdir -p $out/bin 695 cp haskell-reducer-smoke $out/bin/ 696 ghc --version > $out/compiler-version 697 ''; 698 meta.mainProgram = "haskell-reducer-smoke"; 699 }; 700 packages.inspectorOracle = pkgs.runCommand "arboricx-inspector-oracle" { 701 nativeBuildInputs = [ (haskellPackages.ghcWithPackages (p: [ 702 p.cryptonite p.memory p.base16-bytestring p.vector 703 ])) ]; 704 } '' 705 mkdir -p $out/bin 706 ghc -O1 -XOverloadedStrings -XScopedTypeVariables -XMultiWayIf -XLambdaCase \ 707 -i${./src} -outputdir "$TMPDIR/objects" ${./test/InspectorOracle.hs} \ 708 -o $out/bin/inspector-oracle 709 ''; 710 packages.arboricxSiteJavaScript = siteJavaScript; 711 packages.arboricxArtwork = import ./ext/demo-site/artwork.nix { inherit pkgs; }; 712 packages.arboricxWebkitCheck = import ./ext/demo-site/webkit.nix { inherit pkgs; }; 713 packages.arboricxSite = siteRelease.arboricxSite; 714 packages.arboricxSiteDeps = siteRelease.arboricxSiteDeps; 715 packages.tricu-static = tricuMuslStatic; 716 packages.tricu-static-upx = tricuStatic; 717 packages.tricu-bench = tricuBench; 718 packages.benchmarkWorkers = benchmarkWorkers; 719 packages.benchmarkSmoke = pkgs.runCommand "tricu-benchmark-smoke" {} '' 720 ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 721 "$(cat ${benchmarkWorkers}/sha256)" --verify-only +RTS -N1 -M8192m -RTS 722 if ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 723 "$(printf '%064d' 0)" --verify-only >bad-hash.log 2>&1; then 724 echo "benchmark accepted a wrong digest" >&2; exit 1 725 fi 726 grep -q 'SHA256 mismatch' bad-hash.log 727 if ${tricuBench}/bin/tricu-bench ${./test/fixtures/id.arboricx} \ 728 "$(sha256sum ${./test/fixtures/id.arboricx} | cut -d ' ' -f 1)" \ 729 --verify-only >bad-interface.log 2>&1; then 730 echo "benchmark accepted the wrong interface" >&2; exit 1 731 fi 732 grep -q 'exactly the benchmark export interface' bad-interface.log 733 printf 'not a bundle' > malformed.arboricx 734 if ${tricuBench}/bin/tricu-bench malformed.arboricx \ 735 "$(sha256sum malformed.arboricx | cut -d ' ' -f 1)" \ 736 --verify-only >malformed.log 2>&1; then 737 echo "benchmark accepted authenticated malformed bytes" >&2; exit 1 738 fi 739 ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 740 "$(cat ${benchmarkWorkers}/sha256)" --list >names 741 test "$(grep -c '^contracts/' names)" -eq 12 742 test "$(grep -c '^registry-hash/' names)" -eq 15 743 ${tricuBench}/bin/tricu-bench ${benchmarkWorkers}/workers.arboricx \ 744 "$(cat ${benchmarkWorkers}/sha256)" --iters 1 +RTS -N1 -M8192m -RTS 745 mkdir -p $out 746 ''; 747 748 # Current-source storage semantics and allocation guard, compiled with 749 # the packaged stable compiler. Full compiler-pair acceptance is separate. 750 packages.ioStorageTest = pkgs.runCommand "tricu-io-storage-test" { 751 nativeBuildInputs = [ pkgs.python3 ]; 752 } '' 753 mkdir -p $out 754 export PYTHONDONTWRITEBYTECODE=1 755 python3 ${./.}/test/io_compiler_store.py ${tricuPackage}/bin/tricu \ 756 --directory $out/controls > $out/controls.log 757 python3 ${./.}/test/io_storage_cost.py ${tricuPackage}/bin/tricu \ 758 --directory $out/cost > $out/cost.log 759 ''; 760 761 packages.tricu-php = tricuPhp; 762 packages.tricu-php-tests = tricuPhpTests; 763 packages.tricu-js = tricuJs; 764 packages.tricu-js-tests = tricuJsTests; 765 766 checks.haskellRuntimeSelection = pkgs.runCommand "tricu-haskell-runtime-selection" {} '' 767 test ! -e ${tricuSource}/ext/zig 768 test ! -e ${tricuSource}/ext/wasm 769 test '${builtins.toJSON (builtins.filter (name: pkgs.lib.hasInfix "zig" name || pkgs.lib.hasPrefix "tricu-wasm" name) (builtins.attrNames self.packages.${system}))}' = '[]' 770 mkdir -p $out 771 ''; 772 773 checks.currentIONames = pkgs.runCommand "tricu-current-io-names" { 774 nativeBuildInputs = [ pkgs.python3 ]; 775 } '' 776 python3 ${./.}/test/current_io_names.py 777 mkdir -p $out 778 ''; 779 780 packages.libraryFormatting = pkgs.runCommand "tricu-library-formatting" { 781 nativeBuildInputs = [ pkgs.python3 ]; 782 } '' 783 export PYTHONDONTWRITEBYTECODE=1 784 python3 ${tricuSource}/test/prepare_formatter.py ${tricuPackage}/bin/tricu --directory $out/formatter 785 python3 ${tricuSource}/test/library_format.py ${tricuPackage}/bin/tricu --formatter-directory $out/formatter 786 ''; 787 788 checks.runtimeBoundary = pkgs.runCommand "tricu-runtime-source-boundary" {} '' 789 test -f ${runtimeSource}/src/Runtime/Tree.hs 790 for path in Research.hs Eval.hs FileEval.hs Lexer.hs Parser.hs \ 791 Frontend Module/Resolver.hs Module/Workspace.hs; do 792 test ! -e "${runtimeSource}/src/$path" 793 done 794 mkdir -p $out 795 ''; 796 797 checks.${packageName} = tricuPackageTests; 798 checks.default = tricuPackageTests; 799 checks.haskellEmbedding = tricuHaskell; 800 checks.pythonBinding = tricuPythonTests; 801 checks.jsBinding = tricuJsTests; 802 checks.phpBinding = tricuPhpTests; 803 # Fast packaging and filesystem integrity checks. 804 checks.arboricxSite = pkgs.runCommand "arboricx-site-release-check" { 805 nativeBuildInputs = [ pkgs.python3 ]; 806 } '' 807 python3 ${./ext/demo-site/test/asset-release.py} ${./ext/demo-site/asset-release.py} 808 python3 ${./ext/demo-site/test/release.py} \ 809 --site ${siteRelease.arboricxSite} --deps ${siteRelease.arboricxSiteDeps} \ 810 --seeder ${./ext/demo-site/seed.py} 811 mkdir -p $out 812 ''; 813 checks.rtsMetrics = pkgs.runCommand "tricu-rts-metrics-tests" { 814 nativeBuildInputs = [ pkgs.python3 ]; 815 } '' 816 export PYTHONDONTWRITEBYTECODE=1 817 cd ${tricuSource} 818 timeout 30s python3 test/rts_metrics_test.py 819 timeout 30s python3 test/process_rss_test.py 820 mkdir -p $out 821 ''; 822 checks.bootstrapRetention = pkgs.runCommand "tricu-bootstrap-retention-tests" { 823 nativeBuildInputs = [ pkgs.python3 ]; 824 } '' 825 export PYTHONDONTWRITEBYTECODE=1 826 cd ${tricuSource} 827 python3 test/bootstrap_retention_test.py 828 mkdir -p $out 829 ''; 830 checks.hostPolicy = pkgs.stdenv.mkDerivation { 831 pname = "tricu-host-policy-tests"; 832 version = "0.1.0"; 833 src = tricuSource; 834 nativeBuildInputs = [ pkgs.python3 tricuPackage ]; 835 buildPhase = "true"; 836 doCheck = true; 837 checkPhase = '' 838 test ! -e archive 839 export PYTHONDONTWRITEBYTECODE=1 840 python3 test/unit.py 841 python3 test/shipped_compiler.py 842 python3 test/executable_arguments.py ${tricuPackage}/bin/tricu 843 python3 test/package_registry.py ${tricuPackage}/bin/tricu 844 python3 test/project_dependencies.py ${tricuPackage}/bin/tricu 845 python3 test/project_inspection.py ${tricuPackage}/bin/tricu 846 python3 test/interaction_inspection.py ${tricuPackage}/bin/tricu 847 python3 test/provenance.py ${tricuPackage}/bin/tricu 848 ''; 849 installPhase = "mkdir -p $out"; 850 }; 851 # Source compilation and bootstrap generations remain explicit opt-in 852 # jobs. Haskell package tests above gate the supported host. 853 854 devShells.default = pkgs.mkShell { 855 buildInputs = with pkgs; [ 856 # Package these build tools as separate executables. 857 pkgs.cabal-install 858 pkgs.haskellPackages.ghc-events 859 pkgs.ghcid 860 haskellPackages.ghc 861 upx 862 gcc 863 python3 864 ]; 865 866 inputsFrom = [ 867 tricuPackage 868 tricuPhp 869 ]; 870 }; 871 872 packages.${containerPackageName} = pkgs.dockerTools.buildImage { 873 name = "tricu"; 874 tag = "latest"; 875 876 copyToRoot = pkgs.buildEnv { 877 name = "image-root"; 878 paths = [ tricuStatic ]; 879 pathsToLink = [ "/bin" ]; 880 }; 881 882 config = { 883 Cmd = [ "/bin/tricu" ]; 884 WorkingDir = "/app"; 885 }; 886 }; 887 888 # Opt-in acceptance runs the actual default entrypoint and common v2 gates. 889 packages.arboricxServerTest = mkRegistryTest "arboricx-server" arboricxServerRunner; 890 packages.arboricxStreamingRunner = arboricxStreamingRunner; 891 packages.arboricxStreamingTest = mkRegistryTest "arboricx-streaming" arboricxStreamingRunner; 892 packages.arboricxServerBundle = arboricxServerBundle; 893 packages.arboricxServerRunner = arboricxServerRunner; 894 packages.arboricxServer = pkgs.dockerTools.buildImage { 895 name = "arboricx-server"; 896 tag = "latest"; 897 898 copyToRoot = pkgs.runCommand "arboricx-server-root" {} '' 899 mkdir -p $out/app/store 900 ''; 901 902 config = { 903 Entrypoint = [ "${arboricxServerRunner}/bin/arboricx-server" ]; 904 WorkingDir = "/app"; 905 ExposedPorts = { "8080/tcp" = {}; }; 906 }; 907 }; 908 }); 909 }