lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

common.nix (10144B)


      1 {
      2   crane,
      3   lib,
      4   pkgs,
      5   toolchains,
      6 }:
      7 let
      8   root = ../..;
      9   cargoToml = builtins.fromTOML (builtins.readFile ../../Cargo.toml);
     10   version = cargoToml.workspace.package.version;
     11   darwinBuildInputs = lib.optionals pkgs.stdenv.isDarwin [
     12     pkgs.libiconv
     13   ];
     14   repoSource = lib.sources.cleanSource root;
     15   cargoSource = lib.fileset.toSource {
     16     root = root;
     17     fileset = lib.fileset.intersection (lib.fileset.fromSource repoSource) (
     18       lib.fileset.unions [
     19         ../../Cargo.toml
     20         ../../Cargo.lock
     21         ../../README
     22         ../../rust-toolchain.toml
     23         ../../contracts
     24         ../../crates
     25         ../../tools
     26       ]
     27     );
     28   };
     29   baseEnv = {
     30     CARGO_TERM_COLOR = "always";
     31     LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
     32   }
     33   // lib.optionalAttrs pkgs.stdenv.isDarwin {
     34     CC = "clang";
     35     CXX = "clang++";
     36     SDKROOT = pkgs.apple-sdk_14.sdkroot;
     37     MACOSX_DEPLOYMENT_TARGET = pkgs.stdenv.hostPlatform.darwinMinVersion;
     38   };
     39   sharedEnv =
     40     baseEnv
     41     // {
     42       PKG_CONFIG_PATH = lib.makeSearchPathOutput "dev" "lib/pkgconfig" stableRuntimeInputs;
     43     }
     44     // lib.optionalAttrs pkgs.stdenv.isDarwin {
     45       LIBRARY_PATH = lib.makeLibraryPath darwinBuildInputs;
     46     };
     47   coverageEnv = sharedEnv // {
     48     RADROOTS_COVERAGE_CARGO = "${toolchains.coverage}/bin/cargo";
     49   };
     50   cargoLlvmCov = pkgs.cargo-llvm-cov.overrideAttrs (old: {
     51     doCheck = false;
     52     meta = old.meta // {
     53       broken = false;
     54     };
     55   });
     56   exportEnv =
     57     env:
     58     lib.concatStringsSep "\n" (
     59       lib.mapAttrsToList (name: value: "export ${name}=${lib.escapeShellArg value}") env
     60     );
     61   stableRuntimeInputs =
     62     with pkgs;
     63     [
     64       toolchains.stable
     65       clang
     66       coreutils
     67       curl
     68       findutils
     69       gawk
     70       gitMinimal
     71       gnugrep
     72       gnumake
     73       gnused
     74       jq
     75       libsodium
     76       llvmPackages.llvm
     77       llvmPackages.libclang
     78       pkg-config
     79       python3
     80     ]
     81     ++ darwinBuildInputs;
     82   coverageRuntimeInputs = stableRuntimeInputs ++ [
     83     toolchains.coverage
     84     cargoLlvmCov
     85   ];
     86   releaseRuntimeInputs = coverageRuntimeInputs;
     87   coreContractCrates = [
     88     "xtask"
     89     "radroots_core"
     90     "radroots_types"
     91     "radroots_events"
     92     "radroots_trade"
     93     "radroots_identity"
     94     "radroots_replica_db_schema"
     95     "radroots_events_codec"
     96     "radroots_nostr_connect"
     97     "radroots_nostr_signer"
     98   ];
     99   coreContractCargoArgs = lib.concatStringsSep " " (map (crate: "-p ${crate}") coreContractCrates);
    100   craneLib = (crane.mkLib pkgs).overrideToolchain toolchains.stable;
    101   commonCraneArgs = {
    102     inherit version;
    103     pname = "radroots";
    104     src = cargoSource;
    105     strictDeps = true;
    106     nativeBuildInputs = [
    107       pkgs.pkg-config
    108       pkgs.clang
    109       pkgs.llvmPackages.libclang
    110     ];
    111     buildInputs = [
    112       pkgs.libsodium
    113     ]
    114     ++ darwinBuildInputs;
    115     inherit (sharedEnv)
    116       CARGO_TERM_COLOR
    117       LIBCLANG_PATH
    118       PKG_CONFIG_PATH
    119       ;
    120   };
    121   cargoArtifacts = craneLib.buildDepsOnly commonCraneArgs;
    122   xtaskPackage = craneLib.buildPackage (
    123     commonCraneArgs
    124     // {
    125       inherit cargoArtifacts;
    126       pname = "xtask";
    127       cargoExtraArgs = "-p xtask";
    128       doCheck = false;
    129     }
    130   );
    131   initGitRepo = ''
    132     git init -q .
    133     git config user.email "nix-check@example.invalid"
    134     git config user.name "nix check"
    135     git add -A .
    136   '';
    137   mkRepoCheck =
    138     {
    139       name,
    140       runtimeInputs,
    141       command,
    142       env ? sharedEnv,
    143       initGit ? false,
    144       linuxOnly ? false,
    145     }:
    146     if linuxOnly && !pkgs.stdenv.isLinux then
    147       null
    148     else
    149       pkgs.runCommand name { nativeBuildInputs = runtimeInputs; } ''
    150         export HOME="$TMPDIR/home"
    151         mkdir -p "$HOME"
    152 
    153         cp -R ${repoSource} "$TMPDIR/repo"
    154         chmod -R u+w "$TMPDIR/repo"
    155         cd "$TMPDIR/repo"
    156         export RADROOTS_WORKSPACE_ROOT="$PWD"
    157 
    158         ${exportEnv env}
    159         ${lib.optionalString initGit initGitRepo}
    160 
    161         ${command}
    162 
    163         touch "$out"
    164       '';
    165   ensureRepoRoot = ''
    166     if [ ! -f Cargo.toml ] || [ ! -f flake.nix ]; then
    167       echo "run this command from the radroots workspace checkout" >&2
    168       exit 1
    169     fi
    170     export RADROOTS_WORKSPACE_ROOT="$PWD"
    171   '';
    172   checkCommand = ''
    173     cargo check --workspace
    174   '';
    175   contractCommand = ''
    176     cargo run -q -p xtask -- hygiene forbidden-identifiers
    177     cargo check -q ${coreContractCargoArgs}
    178     cargo test -q ${coreContractCargoArgs}
    179     cargo run -q -p xtask -- contract validate
    180   '';
    181   releasePreflightCommand = ''
    182     cargo check -q
    183     env -u RADROOTS_MOUNTED_RUST_CRATE_PUBLISH_POLICY cargo test -q -p xtask
    184     cargo run -q -p xtask -- contract validate
    185 
    186     required_file="$(mktemp)"
    187     trap 'rm -f "$required_file"' EXIT
    188     cargo run -q -p xtask -- coverage required-crates > "$required_file"
    189 
    190     rm -rf target/coverage
    191     mkdir -p target/coverage
    192 
    193     while IFS= read -r crate; do
    194       [ -n "$crate" ] || continue
    195       safe_crate="''${crate//-/_}"
    196       out_dir="target/coverage/''${safe_crate}"
    197       mkdir -p "$out_dir"
    198 
    199       cargo run -q -p xtask -- coverage run-crate --crate "$crate" --out "$out_dir"
    200       cargo run -q -p xtask -- coverage report \
    201         --scope "$crate" \
    202         --summary "$out_dir/coverage-summary.json" \
    203         --lcov "$out_dir/coverage-lcov.info" \
    204         --out "$out_dir/gate-report.json" \
    205         --policy-gate
    206     done < "$required_file"
    207 
    208     cargo run -q -p xtask -- coverage refresh-summary \
    209       --reports-root target/coverage \
    210       --out target/coverage/coverage-refresh.tsv \
    211       --status-out target/coverage/coverage-refresh-status.tsv
    212 
    213     cargo run -q -p xtask -- release preflight
    214     echo "release preflight complete"
    215   '';
    216   coverageReportCommand = ''
    217         rm -rf target/coverage-report
    218         mkdir -p target/coverage-report
    219         : > target/coverage-report/coverage-report-status.txt
    220 
    221         workspace_crates_file="$(mktemp)"
    222         required_crates_file="$(mktemp)"
    223         trap 'rm -f "$workspace_crates_file" "$required_crates_file"' EXIT
    224 
    225         cargo run -q -p xtask -- coverage workspace-crates > "$workspace_crates_file"
    226         while IFS= read -r crate; do
    227           [ -n "''${crate}" ] || continue
    228           safe_crate="''${crate//-/_}"
    229           run_dir="target/coverage-report/''${safe_crate}"
    230           mkdir -p "''${run_dir}"
    231           status="ok"
    232 
    233           if ! cargo run -q -p xtask -- coverage run-crate --crate "''${crate}" --out "''${run_dir}"; then
    234             status="run-failed"
    235           fi
    236 
    237           if [ "''${status}" = "ok" ] && ! cargo run -q -p xtask -- coverage report \
    238             --scope "''${crate}" \
    239             --summary "''${run_dir}/coverage-summary.json" \
    240             --lcov "''${run_dir}/coverage-lcov.info" \
    241             --out "''${run_dir}/coverage-gate-summary.json" \
    242             --fail-under-exec-lines 0 \
    243             --fail-under-functions 0 \
    244             --fail-under-regions 0 \
    245             --fail-under-branches 0; then
    246             status="report-failed"
    247           fi
    248 
    249           if [ "''${status}" != "ok" ]; then
    250             cat > "''${run_dir}/coverage-gate-summary.json" <<EOF
    251             {
    252               "scope": "''${crate}",
    253               "thresholds": {
    254                 "executable_lines": 0,
    255                 "functions": 0,
    256                 "regions": 0,
    257                 "branches": 0,
    258                 "branches_required": false
    259               },
    260               "measured": {
    261                 "executable_lines_percent": 0,
    262                 "executable_lines_source": "da",
    263                 "functions_percent": 0,
    264                 "branches_percent": null,
    265                 "branches_available": false,
    266                 "summary_lines_percent": 0,
    267                 "summary_regions_percent": 0
    268               },
    269               "counts": {
    270                 "executable_lines": {
    271                   "covered": 0,
    272                   "total": 0
    273                 },
    274                 "branches": {
    275                   "covered": 0,
    276                   "total": 0
    277                 }
    278               },
    279               "result": {
    280                 "pass": false,
    281                 "fail_reasons": [
    282                   "''${status}"
    283                 ]
    284               }
    285             }
    286     EOF
    287           fi
    288 
    289           echo "''${crate}:''${status}" >> target/coverage-report/coverage-report-status.txt
    290         done < "$workspace_crates_file"
    291 
    292         cargo run -q -p xtask -- coverage required-crates > "$required_crates_file"
    293         while IFS= read -r crate; do
    294           [ -n "''${crate}" ] || continue
    295           safe_crate="''${crate//-/_}"
    296           crate_dir="target/coverage-report/''${safe_crate}"
    297           crate_status="$(awk -F: -v crate="''${crate}" '$1 == crate { status = $2 } END { print status }' target/coverage-report/coverage-report-status.txt)"
    298 
    299           if [ ! -f "''${crate_dir}/coverage-summary.json" ] || [ ! -f "''${crate_dir}/coverage-lcov.info" ]; then
    300             fail_reason="missing-coverage-artifacts"
    301             if [ -n "''${crate_status}" ] && [ "''${crate_status}" != "ok" ]; then
    302               fail_reason="''${crate_status}"
    303             fi
    304 
    305             cargo run -q -p xtask -- coverage report-missing \
    306               --scope "''${crate}" \
    307               --out "''${crate_dir}/coverage-gate-blocking.json" \
    308               --reason "''${fail_reason}"
    309             continue
    310           fi
    311 
    312           cargo run -q -p xtask -- coverage report \
    313             --scope "''${crate}" \
    314             --summary "''${crate_dir}/coverage-summary.json" \
    315             --lcov "''${crate_dir}/coverage-lcov.info" \
    316             --out "''${crate_dir}/coverage-gate-blocking.json" \
    317             --policy-gate
    318         done < "$required_crates_file"
    319   '';
    320 in
    321 {
    322   inherit
    323     cargoLlvmCov
    324     cargoArtifacts
    325     checkCommand
    326     commonCraneArgs
    327     contractCommand
    328     coverageEnv
    329     coverageReportCommand
    330     craneLib
    331     ensureRepoRoot
    332     mkRepoCheck
    333     releasePreflightCommand
    334     coreContractCargoArgs
    335     sharedEnv
    336     version
    337     xtaskPackage
    338     ;
    339 
    340   exportCoverageEnv = exportEnv coverageEnv;
    341   exportSharedEnv = exportEnv sharedEnv;
    342 
    343   runtimeInputs = {
    344     stable = stableRuntimeInputs;
    345     coverage = coverageRuntimeInputs;
    346     release = releaseRuntimeInputs;
    347   };
    348 }