{ lib, self, jq, nix, linkFarmFromDrvs, runCommandLocal, writableTmpDirAsHomeHook, }: # nixpkgs.nix fetches our pinned nixpkgs using the `fetchTree` primop. # # In this file, we test that it is identical to our `inputs.nixpkgs` flake input. # # The primop is only available with `experimental-features = flakes` or `experimental-features = fetch-tree`, # so we have a `fetchTree` polyfill that delegates to `fetchTarball`. # # Permutations to test: # 1. fetchTree primop # a. attrs # b. outPath derivation # 2. fetchTree polyfill # a. attrs # b. outPath derivation # # As we run this test from a flake, we have `experimental-features = flakes` and `fetchTree` primop is available. # Therefore, we can test the `fetchTree` primop easily. # # By running `nix-instantiate` _within_ a build sandbox, we can configure `experimental-features =` # to test the polyfill's attrs. However, we cannot do an actual fetch in the sandbox. # # Since we can't do an actual fetch in the sandbox, the polyfill's outPath can be tested manually. # These should both evaluate to the same derivation: # nix-instantiate --eval nixpkgs.nix --attr outPath --option experimental-features flakes # nix-instantiate --eval nixpkgs.nix --attr outPath --option experimental-features '' let version-info = lib.importTOML ../version-info.toml; flake-input = self.inputs.nixpkgs.sourceInfo; pinned-input = import ../nixpkgs.nix; in linkFarmFromDrvs "nixpkgs-fetch-test" [ (runCommandLocal "nixpkgs-fetch-test-with-primop" { __structuredAttrs = true; unsafeDiscardReferences.out = true; strictDeps = true; hasPrimop = builtins ? fetchTree; versionInfo = version-info; expected = flake-input; actual = pinned-input; expectedAttrs = removeAttrs flake-input [ "outPath" ]; actualAttrs = removeAttrs pinned-input [ "outPath" ]; nativeBuildInputs = [ jq ]; } '' echo 'Sanity check that `fetchTree` is enabled' if [ -n "$hasPrimop" ]; then echo "fetchTree is available" >&2 else echo "fetchTree is not available" >&2 exit 1 fi if [ "$expected" = "$actual" ]; then echo "Expectation met: '$expected'" >&2 else echo "Expected '$actual' to be '$expected'" >&2 exit 1 fi expectedRev=$(jq --raw-output .expectedAttrs.rev "$NIX_ATTRS_JSON_FILE") versionInfoRev=$(jq --raw-output .versionInfo.nixpkgs_rev "$NIX_ATTRS_JSON_FILE") [ "$expectedRev" = "$versionInfoRev" ] || { echo "Expected version-info nixpkgs_rev '$versionInfoRev' to be '$expectedRev'" >&2 exit 1 } mkdir "$out" jq --sort-keys .expectedAttrs "$NIX_ATTRS_JSON_FILE" > "$out/expected.json" jq --sort-keys .actualAttrs "$NIX_ATTRS_JSON_FILE" > "$out/actual.json" # Compare actual.json and expected.json if ! diff --unified "$out/expected.json" "$out/actual.json"; then echo 'Unexpected difference between `expected.json` and `actual.json`' >&2 exit 1 fi '' ) (runCommandLocal "nixpkgs-fetch-test-with-polyfill" { __structuredAttrs = true; unsafeDiscardReferences.out = true; strictDeps = true; src = lib.fileset.toSource { root = ../.; fileset = lib.fileset.unions [ ../flake.lock ../nixpkgs.nix ]; }; expectedAttrs = removeAttrs flake-input [ "outPath" ]; nativeBuildInputs = [ jq nix writableTmpDirAsHomeHook ]; } '' # Setup nix environment export TEST_ROOT="$PWD/test-tmp" export NIX_CONF_DIR="$TEST_ROOT/etc" export NIX_LOCALSTATE_DIR="$TEST_ROOT/var" export NIX_LOG_DIR="$TEST_ROOT/var/log/nix" export NIX_STATE_DIR="$TEST_ROOT/var/nix" export PAGER=cat mkdir -p "$NIX_CONF_DIR" cat > "$NIX_CONF_DIR/nix.conf" < "$out/expected.json" echo "Evaluating actual" nix-instantiate --eval --strict --json \ --argstr actual "$src/nixpkgs.nix" \ --expr '{ actual }: removeAttrs (import actual) [ "outPath" ]' \ | jq --sort-keys . > "$out/actual.json" # Compare actual.json and expected.json if ! diff --unified "$out/expected.json" "$out/actual.json"; then echo 'Unexpected difference between `expected.json` and `actual.json`' >&2 exit 1 fi '' ) ]