| 1 | { |
| 2 | lib, |
| 3 | stdenv, |
| 4 | rustPlatform, |
| 5 | pkg-config, |
| 6 | autoPatchelfHook ? null, |
| 7 | openssl, |
| 8 | dbus ? null, |
| 9 | |
| 10 | # for cargo test |
| 11 | python3, |
| 12 | gitMinimal, |
| 13 | cacert, |
| 14 | procps, |
| 15 | |
| 16 | rev ? "dirty", |
| 17 | }: |
| 18 | let |
| 19 | # Shared libraries the check-phase test binaries need at runtime |
| 20 | # (libdbus, libgcc_s). Derived once so LD_LIBRARY_PATH and the patchelf |
| 21 | # RPATH can never drift apart. |
| 22 | runtimeLibraryPath = lib.makeLibraryPath ( |
| 23 | lib.optionals stdenv.isLinux [ |
| 24 | dbus.lib |
| 25 | stdenv.cc.cc.lib |
| 26 | ] |
| 27 | ); |
| 28 | in |
| 29 | rustPlatform.buildRustPackage (finalAttrs: { |
| 30 | pname = "codewhale"; |
| 31 | version = "git-${rev}"; |
| 32 | |
| 33 | src = ../.; |
| 34 | |
| 35 | cargoLock = { |
| 36 | lockFile = ../Cargo.lock; |
| 37 | }; |
| 38 | |
| 39 | nativeBuildInputs = [ |
| 40 | pkg-config |
| 41 | ] ++ lib.optionals stdenv.isLinux [ |
| 42 | autoPatchelfHook |
| 43 | ]; |
| 44 | |
| 45 | buildInputs = [ |
| 46 | openssl |
| 47 | ] ++ lib.optionals stdenv.isLinux [ |
| 48 | dbus.dev |
| 49 | dbus.lib |
| 50 | stdenv.cc.cc.lib |
| 51 | ]; |
| 52 | |
| 53 | nativeCheckInputs = [ |
| 54 | python3 |
| 55 | gitMinimal |
| 56 | cacert |
| 57 | ] |
| 58 | ++ lib.optionals stdenv.isLinux [ |
| 59 | # fleet host memory/zombie sampling shells out to `ps`; NixOS has no |
| 60 | # system-wide /usr/bin/ps, so make it resolvable through PATH. |
| 61 | procps |
| 62 | ]; |
| 63 | |
| 64 | cargoBuildFlags = [ |
| 65 | "--package" |
| 66 | "codewhale-cli" |
| 67 | "--package" |
| 68 | "codewhale-tui" |
| 69 | ]; |
| 70 | cargoTestFlags = finalAttrs.cargoBuildFlags ++ [ |
| 71 | "--lib" |
| 72 | "--bins" |
| 73 | "--" |
| 74 | # Requires the checkout itself to be a git repository (the test walks up |
| 75 | # from the current dir); the Nix source tree has no .git. |
| 76 | "--skip" |
| 77 | "tools::subagent::tests::git_repo_root_reports_attempted_paths_when_no_repo_found" |
| 78 | # The header width table is calibrated against the git chrome label |
| 79 | # populated by the surrounding checkout state, which the sandboxed test |
| 80 | # process does not see. |
| 81 | "--skip" |
| 82 | "tui::underwater::tests::configured_session_tokens_follow_underwater_header_width_priority" |
| 83 | ]; |
| 84 | |
| 85 | preCheck = '' |
| 86 | # Tests write to the default config/home locations; the sandbox HOME |
| 87 | # (/homeless-shelter) is not writable. |
| 88 | export HOME="$(mktemp -d)" |
| 89 | export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt |
| 90 | '' |
| 91 | + lib.optionalString stdenv.isLinux '' |
| 92 | # nixpkgs no longer derives LD_LIBRARY_PATH from buildInputs; the cargo |
| 93 | # test binaries link libdbus/libgcc_s dynamically and have no RPATH until |
| 94 | # autoPatchelfHook runs at fixup (after the check phase). |
| 95 | export LD_LIBRARY_PATH=${runtimeLibraryPath} |
| 96 | ''; |
| 97 | |
| 98 | # Two-stage check: build the harnesses first, give them an explicit RPATH, |
| 99 | # then run. Fleet and shell tests re-execute the test binary through a |
| 100 | # scrubbed environment (no LD_LIBRARY_PATH), so without this the re-spawned |
| 101 | # harness cannot load libdbus and every descendant-tree test times out. |
| 102 | checkPhase = '' |
| 103 | runHook preCheck |
| 104 | |
| 105 | # Tests mutate process-global environment (PATH/HOME/cwd) via the shared |
| 106 | # EnvVarGuard; a concurrent test spawning a shell can then fail to resolve |
| 107 | # the interpreter. Run the harness serially so the check is deterministic. |
| 108 | export RUST_TEST_THREADS=1 |
| 109 | |
| 110 | flagsArray=(-j "$NIX_BUILD_CORES" --profile release --target ${stdenv.hostPlatform.config} --offline) |
| 111 | concatTo flagsArray cargoTestFlags checkFlags |
| 112 | |
| 113 | echo "Building test binaries" |
| 114 | cargo test --no-run "''${flagsArray[@]}" |
| 115 | |
| 116 | ${lib.optionalString stdenv.isLinux '' |
| 117 | echo "Patching runtime RPATH into test binaries" |
| 118 | find "target/${stdenv.hostPlatform.config}/release/deps" \ |
| 119 | -maxdepth 1 -type f -executable \ |
| 120 | -exec patchelf --add-rpath "${runtimeLibraryPath}" {} + |
| 121 | ''} |
| 122 | |
| 123 | echo "Running tests" |
| 124 | cargo test "''${flagsArray[@]}" |
| 125 | |
| 126 | runHook postCheck |
| 127 | ''; |
| 128 | |
| 129 | meta = { |
| 130 | description = "Terminal coding agent for DeepSeek"; |
| 131 | homepage = "https://github.com/Hmbown/CodeWhale"; |
| 132 | license = lib.licenses.mit; |
| 133 | mainProgram = "codewhale"; |
| 134 | }; |
| 135 | }) |
| 136 |