source common.sh if [[ -z $(type -p git) ]]; then echo "Git not installed; skipping flake tests" exit 99 fi clearStore rm -rf $TEST_HOME/.cache $TEST_HOME/.config registry=$TEST_ROOT/registry.json flake1Dir=$TEST_ROOT/flake1 flake2Dir=$TEST_ROOT/flake2 flake3Dir=$TEST_ROOT/flake3 flake5Dir=$TEST_ROOT/flake5 flake6Dir=$TEST_ROOT/flake6 flake7Dir=$TEST_ROOT/flake7 templatesDir=$TEST_ROOT/templates nonFlakeDir=$TEST_ROOT/nonFlake badFlakeDir=$TEST_ROOT/badFlake flakeA=$TEST_ROOT/flakeA flakeB=$TEST_ROOT/flakeB flakeGitBare=$TEST_ROOT/flakeGitBare flakeFollowsA=$TEST_ROOT/follows/flakeA flakeFollowsB=$TEST_ROOT/follows/flakeA/flakeB flakeFollowsC=$TEST_ROOT/follows/flakeA/flakeB/flakeC flakeFollowsD=$TEST_ROOT/follows/flakeA/flakeD flakeFollowsE=$TEST_ROOT/follows/flakeA/flakeE for repo in $flake1Dir $flake2Dir $flake3Dir $flake7Dir $templatesDir $nonFlakeDir $flakeA $flakeB $flakeFollowsA; do rm -rf $repo $repo.tmp mkdir -p $repo # Give one repo a non-main initial branch. extraArgs= if [[ $repo == $flake2Dir ]]; then extraArgs="--initial-branch=main" fi git -C $repo init $extraArgs git -C $repo config user.email "foobar@example.com" git -C $repo config user.name "Foobar" done cat > $flake1Dir/flake.nix < $flake2Dir/flake.nix < $flake3Dir/flake.nix < $nonFlakeDir/README.md <> $flake1Dir/flake.nix git -C $flake1Dir commit -a -m 'Foo' hash2=$(nix flake metadata flake1 --json --refresh | jq -r .revision) [[ $hash1 != $hash2 ]] # Test 'nix build' on a flake. nix build -o $TEST_ROOT/result flake1#foo [[ -e $TEST_ROOT/result/hello ]] # Test packages.default. nix build -o $TEST_ROOT/result flake1 [[ -e $TEST_ROOT/result/hello ]] nix build -o $TEST_ROOT/result $flake1Dir nix build -o $TEST_ROOT/result git+file://$flake1Dir # Check that store symlinks inside a flake are not interpreted as flakes. nix build -o $flake1Dir/result git+file://$flake1Dir nix path-info $flake1Dir/result # 'getFlake' on a mutable flakeref should fail in pure mode, but succeed in impure mode. (! nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").packages.$system.default") nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").packages.$system.default" --impure # 'getFlake' on an immutable flakeref should succeed even in pure mode. nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"git+file://$flake1Dir?rev=$hash2\").packages.$system.default" # Building a flake with an unlocked dependency should fail in pure mode. (! nix build -o $TEST_ROOT/result flake2#bar --no-registries) (! nix build -o $TEST_ROOT/result flake2#bar --no-use-registries) (! nix eval --expr "builtins.getFlake \"$flake2Dir\"") # But should succeed in impure mode. (! nix build -o $TEST_ROOT/result flake2#bar --impure) nix build -o $TEST_ROOT/result flake2#bar --impure --no-write-lock-file nix eval --expr "builtins.getFlake \"$flake2Dir\"" --impure # Building a local flake with an unlocked dependency should fail with --no-update-lock-file. nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes' # But it should succeed without that flag. nix build -o $TEST_ROOT/result $flake2Dir#bar --no-write-lock-file nix build -o $TEST_ROOT/result $flake2Dir#bar --no-update-lock-file 2>&1 | grep 'requires lock file changes' nix build -o $TEST_ROOT/result $flake2Dir#bar --commit-lock-file [[ -e $flake2Dir/flake.lock ]] [[ -z $(git -C $flake2Dir diff main || echo failed) ]] # Rerunning the build should not change the lockfile. nix build -o $TEST_ROOT/result $flake2Dir#bar [[ -z $(git -C $flake2Dir diff main || echo failed) ]] # Building with a lockfile should not require a fetch of the registry. nix build -o $TEST_ROOT/result --flake-registry file:///no-registry.json $flake2Dir#bar --refresh nix build -o $TEST_ROOT/result --no-registries $flake2Dir#bar --refresh nix build -o $TEST_ROOT/result --no-use-registries $flake2Dir#bar --refresh # Updating the flake should not change the lockfile. nix flake lock $flake2Dir [[ -z $(git -C $flake2Dir diff main || echo failed) ]] # Now we should be able to build the flake in pure mode. nix build -o $TEST_ROOT/result flake2#bar # Or without a registry. nix build -o $TEST_ROOT/result --no-registries git+file://$flake2Dir#bar --refresh nix build -o $TEST_ROOT/result --no-use-registries git+file://$flake2Dir#bar --refresh # Test whether indirect dependencies work. nix build -o $TEST_ROOT/result $flake3Dir#xyzzy git -C $flake3Dir add flake.lock # Add dependency to flake3. rm $flake3Dir/flake.nix cat > $flake3Dir/flake.nix < $flake3Dir/flake.nix < \$out [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]] [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]] ''; }; }; } EOF cp ./config.nix $flake3Dir git -C $flake3Dir add flake.nix config.nix git -C $flake3Dir commit -m 'Add nonFlakeInputs' # Check whether `nix build` works with a lockfile which is missing a # nonFlakeInputs. nix build -o $TEST_ROOT/result $flake3Dir#sth --commit-lock-file nix build -o $TEST_ROOT/result flake3#fnord [[ $(cat $TEST_ROOT/result) = FNORD ]] # Check whether flake input fetching is lazy: flake3#sth does not # depend on flake2, so this shouldn't fail. rm -rf $TEST_HOME/.cache clearStore mv $flake2Dir $flake2Dir.tmp mv $nonFlakeDir $nonFlakeDir.tmp nix build -o $TEST_ROOT/result flake3#sth (! nix build -o $TEST_ROOT/result flake3#xyzzy) (! nix build -o $TEST_ROOT/result flake3#fnord) mv $flake2Dir.tmp $flake2Dir mv $nonFlakeDir.tmp $nonFlakeDir nix build -o $TEST_ROOT/result flake3#xyzzy flake3#fnord # Test doing multiple `lookupFlake`s nix build -o $TEST_ROOT/result flake4#xyzzy # Test 'nix flake update' and --override-flake. nix flake lock $flake3Dir [[ -z $(git -C $flake3Dir diff master || echo failed) ]] nix flake update $flake3Dir --override-flake flake2 nixpkgs [[ ! -z $(git -C $flake3Dir diff master || echo failed) ]] # Make branch "removeXyzzy" where flake3 doesn't have xyzzy anymore git -C $flake3Dir checkout -b removeXyzzy rm $flake3Dir/flake.nix cat > $flake3Dir/flake.nix < \$out ''; }; }; } EOF nix flake lock $flake3Dir git -C $flake3Dir add flake.nix flake.lock git -C $flake3Dir commit -m 'Remove packages.xyzzy' git -C $flake3Dir checkout master # Test whether fuzzy-matching works for registry entries. (! nix build -o $TEST_ROOT/result flake4/removeXyzzy#xyzzy) nix build -o $TEST_ROOT/result flake4/removeXyzzy#sth # Testing the nix CLI nix registry add flake1 flake3 [[ $(nix registry list | wc -l) == 8 ]] nix registry pin flake1 [[ $(nix registry list | wc -l) == 8 ]] nix registry pin flake1 flake3 [[ $(nix registry list | wc -l) == 8 ]] nix registry remove flake1 [[ $(nix registry list | wc -l) == 7 ]] # Test 'nix flake init'. cat > $templatesDir/flake.nix < $templatesDir/trivial/flake.nix < $templatesDir/trivial/a echo b > $templatesDir/trivial/b git -C $templatesDir add flake.nix trivial/ git -C $templatesDir commit -m 'Initial' nix flake check templates nix flake show templates nix flake show templates --json | jq (cd $flake7Dir && nix flake init) (cd $flake7Dir && nix flake init) # check idempotence git -C $flake7Dir add flake.nix nix flake check $flake7Dir nix flake show $flake7Dir nix flake show $flake7Dir --json | jq git -C $flake7Dir commit -a -m 'Initial' # Test 'nix flake init' with benign conflicts rm -rf $flake7Dir && mkdir $flake7Dir && git -C $flake7Dir init echo a > $flake7Dir/a (cd $flake7Dir && nix flake init) # check idempotence # Test 'nix flake init' with conflicts rm -rf $flake7Dir && mkdir $flake7Dir && git -C $flake7Dir init echo b > $flake7Dir/a pushd $flake7Dir (! nix flake init) |& grep "refusing to overwrite existing file '$flake7Dir/a'" popd # Test 'nix flake new'. rm -rf $flake6Dir nix flake new -t templates#trivial $flake6Dir nix flake new -t templates#trivial $flake6Dir # check idempotence nix flake check $flake6Dir # Test 'nix flake clone'. rm -rf $TEST_ROOT/flake1-v2 nix flake clone flake1 --dest $TEST_ROOT/flake1-v2 [ -e $TEST_ROOT/flake1-v2/flake.nix ] # More 'nix flake check' tests. cat > $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix <&1 && fail "nix flake check should have failed" || true) echo "$checkRes" | grep -q "packages.system-1.default" echo "$checkRes" | grep -q "packages.system-2.default" # Test 'follows' inputs. cat > $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake3Dir/flake.nix < $flake5Dir/flake.nix <&1 | grep 'NAR hash mismatch' # Test --override-input. git -C $flake3Dir reset --hard nix flake lock $flake3Dir --override-input flake2/flake1 file://$TEST_ROOT/flake.tar.gz -vvvvv [[ $(jq .nodes.flake1_2.locked.url $flake3Dir/flake.lock) =~ flake.tar.gz ]] nix flake lock $flake3Dir --override-input flake2/flake1 flake1 [[ $(jq -r .nodes.flake1_2.locked.rev $flake3Dir/flake.lock) =~ $hash2 ]] nix flake lock $flake3Dir --override-input flake2/flake1 flake1/master/$hash1 [[ $(jq -r .nodes.flake1_2.locked.rev $flake3Dir/flake.lock) =~ $hash1 ]] # Test --update-input. nix flake lock $flake3Dir [[ $(jq -r .nodes.flake1_2.locked.rev $flake3Dir/flake.lock) = $hash1 ]] nix flake lock $flake3Dir --update-input flake2/flake1 [[ $(jq -r .nodes.flake1_2.locked.rev $flake3Dir/flake.lock) =~ $hash2 ]] # Test 'nix flake metadata --json'. nix flake metadata $flake3Dir --json | jq . # Test circular flake dependencies. cat > $flakeA/flake.nix < $flakeB/flake.nix < $flakeFollowsA/flake.nix < $flakeFollowsB/flake.nix < $flakeFollowsC/flake.nix < $flakeFollowsD/flake.nix < $flakeFollowsE/flake.nix < $flakeFollowsA/flake.nix < $flakeFollowsA/flake.nix <&1 | grep 'points outside' # Test flake in store does not evaluate rm -rf $badFlakeDir mkdir $badFlakeDir echo INVALID > $badFlakeDir/flake.nix nix store delete $(nix store add-path $badFlakeDir) [[ $(nix path-info $(nix store add-path $flake1Dir)) =~ flake1 ]] [[ $(nix path-info path:$(nix store add-path $flake1Dir)) =~ simple ]] # Non-existant follows causes an error cat >$flakeFollowsA/flake.nix <&1 | grep "error: B has a \`follows'-declaration for a non-existant input invalid!"