From 29f5ce07db4f94c7bea06d85a3c9d0bcae6d2f9c Mon Sep 17 00:00:00 2001 From: Jade Lovelace Date: Mon, 24 Feb 2025 18:05:11 -0800 Subject: [PATCH] fix: flakes now obey --eval-system This required changing an excessive number of places since flakes code is a delicious bowl of copy pasta. I didn't change all of the usage sites since some of them run things on the local machine and you actually want it to be the real system there. Nevertheless, we probably should have the daemon do something much different when it receives a `system` setting: https://git.lix.systems/lix-project/lix/issues/694 Fixes: https://git.lix.systems/lix-project/lix/issues/692 Fixes: https://git.lix.systems/lix-project/lix/issues/673 Fixes: https://github.com/NixOS/nix/issues/11359 Change-Id: I55e696c09794d2520b60238a84829c98fcad7ccc --- doc/manual/rl-next/flakes-eval-system.md | 18 ++++++++++++++++++ lix/libcmd/installables.cc | 8 ++++---- lix/nix/bundle.cc | 10 +++++++--- lix/nix/develop.cc | 2 ++ lix/nix/flake.cc | 6 +++--- lix/nix/fmt.cc | 1 + lix/nix/run.cc | 2 ++ lix/nix/search.cc | 4 ++-- tests/functional/flakes/check.sh | 5 +++++ tests/functional/flakes/flakes.sh | 5 +++++ tests/functional/flakes/show.sh | 7 +++++++ 11 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 doc/manual/rl-next/flakes-eval-system.md diff --git a/doc/manual/rl-next/flakes-eval-system.md b/doc/manual/rl-next/flakes-eval-system.md new file mode 100644 index 000000000..7899afb49 --- /dev/null +++ b/doc/manual/rl-next/flakes-eval-system.md @@ -0,0 +1,18 @@ +--- +synopsis: 'Flakes follow `--eval-system` where it makes sense' +issues: [fj#673, fj#692, gh#11359] +cls: [2657] +category: Fixes +credits: [jade] +--- + +Most flake commands now follow `--eval-system` when choosing attributes to build/evaluate/etc. + +The exceptions are commands that actually run something on the local machine: +- nix develop +- nix run +- nix upgrade-nix +- nix fmt +- nix bundle + +This is not a principled approach to cross compilation or anything, flakes still impede rather than support cross compilation, but this unbreaks many remote build use cases. diff --git a/lix/libcmd/installables.cc b/lix/libcmd/installables.cc index a46863a43..6f595b3f0 100644 --- a/lix/libcmd/installables.cc +++ b/lix/libcmd/installables.cc @@ -185,8 +185,8 @@ MixReadOnlyOption::MixReadOnlyOption() Strings SourceExprCommand::getDefaultFlakeAttrPaths() { return { - "packages." + settings.thisSystem.get() + ".default", - "defaultPackage." + settings.thisSystem.get() + "packages." + evalSettings.getCurrentSystem() + ".default", + "defaultPackage." + evalSettings.getCurrentSystem() }; } @@ -195,10 +195,10 @@ Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes() return { // As a convenience, look for the attribute in // 'outputs.packages'. - "packages." + settings.thisSystem.get() + ".", + "packages." + evalSettings.getCurrentSystem() + ".", // As a temporary hack until Nixpkgs is properly converted // to provide a clean 'packages' set, look in 'legacyPackages'. - "legacyPackages." + settings.thisSystem.get() + "." + "legacyPackages." + evalSettings.getCurrentSystem() + "." }; } diff --git a/lix/nix/bundle.cc b/lix/nix/bundle.cc index 261cd8416..25cd89ab9 100644 --- a/lix/nix/bundle.cc +++ b/lix/nix/bundle.cc @@ -1,5 +1,6 @@ #include "lix/libcmd/installable-flake.hh" #include "lix/libcmd/command.hh" +#include "lix/libexpr/eval-settings.hh" #include "lix/libmain/common-args.hh" #include "lix/libmain/shared.hh" #include "lix/libstore/store-api.hh" @@ -54,9 +55,10 @@ struct CmdBundle : InstallableCommand // FIXME: cut&paste from CmdRun. Strings getDefaultFlakeAttrPaths() override { + // eval-system, since the app could be remote built and then bundled locally Strings res{ - "apps." + settings.thisSystem.get() + ".default", - "defaultApp." + settings.thisSystem.get() + "apps." + evalSettings.getCurrentSystem() + ".default", + "defaultApp." + evalSettings.getCurrentSystem() }; for (auto & s : SourceExprCommand::getDefaultFlakeAttrPaths()) res.push_back(s); @@ -65,7 +67,8 @@ struct CmdBundle : InstallableCommand Strings getDefaultFlakeAttrPathPrefixes() override { - Strings res{"apps." + settings.thisSystem.get() + "."}; + // eval-system, since the app could be remote built and then bundled locally + Strings res{"apps." + evalSettings.getCurrentSystem() + "."}; for (auto & s : SourceExprCommand::getDefaultFlakeAttrPathPrefixes()) res.push_back(s); return res; @@ -82,6 +85,7 @@ struct CmdBundle : InstallableCommand auto [bundlerFlakeRef, bundlerName, extendedOutputsSpec] = parseFlakeRefWithFragmentAndExtendedOutputsSpec(bundler, absPath(".")); const flake::LockFlags lockFlags{ .writeLockFile = false }; + // Current system, since it needs to run locally InstallableFlake bundler{this, evaluator, std::move(bundlerFlakeRef), bundlerName, std::move(extendedOutputsSpec), {"bundlers." + settings.thisSystem.get() + ".default", diff --git a/lix/nix/develop.cc b/lix/nix/develop.cc index 2ea3aacce..76e0f0a98 100644 --- a/lix/nix/develop.cc +++ b/lix/nix/develop.cc @@ -427,6 +427,7 @@ struct Common : InstallableCommand, MixProfile Strings getDefaultFlakeAttrPaths() override { + // These are current system since they have to run locally from inside the shell Strings paths{ "devShells." + settings.thisSystem.get() + ".default", "devShell." + settings.thisSystem.get(), @@ -621,6 +622,7 @@ struct CmdDevelop : Common, MixEnvironment "bashInteractive", ExtendedOutputsSpec::Default(), Strings{}, + // `system` not `eval-system` since we are actually executing it on the local machine Strings{"legacyPackages." + settings.thisSystem.get() + "."}, nixpkgsLockFlags); diff --git a/lix/nix/flake.cc b/lix/nix/flake.cc index f8419f910..aec484416 100644 --- a/lix/nix/flake.cc +++ b/lix/nix/flake.cc @@ -365,7 +365,7 @@ struct CmdFlakeCheck : FlakeCommand lockFlags.applyNixConfig = true; auto flake = lockFlake(*state); - auto localSystem = std::string(settings.thisSystem.get()); + auto localSystem = std::string(evalSettings.getCurrentSystem()); bool hasErrors = false; auto reportError = [&](const Error & e) { @@ -613,7 +613,7 @@ struct CmdFlakeCheck : FlakeCommand auto drvPath = checkDerivation( fmt("%s.%s.%s", name, attr_name, evaluator->symbols[attr2.name]), *attr2.value, attr2.pos); - if (drvPath && attr_name == settings.thisSystem.get()) { + if (drvPath && attr_name == evalSettings.getCurrentSystem()) { drvPaths.push_back(DerivedPath::Built { .drvPath = makeConstantStorePathRef(*drvPath), .outputs = OutputsSpec::All { }, @@ -1129,7 +1129,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON auto evaluator = getEvaluator(); auto state = evaluator->begin(aio()); auto flake = std::make_shared(lockFlake(*state)); - auto localSystem = std::string(settings.thisSystem.get()); + auto localSystem = std::string(evalSettings.getCurrentSystem()); std::function $flakeDir/flake.nix <&1 && fail "nix flake check --all-systems should have failed" || true) echo "$checkRes" | grepQuiet "packages.system-1.default" diff --git a/tests/functional/flakes/flakes.sh b/tests/functional/flakes/flakes.sh index 85ffacf70..5f102e183 100644 --- a/tests/functional/flakes/flakes.sh +++ b/tests/functional/flakes/flakes.sh @@ -126,6 +126,11 @@ nix build -o $TEST_ROOT/result git+file://$flake1Dir nix build -o $flake1Dir/result git+file://$flake1Dir nix path-info $flake1Dir/result +# Ensure that eval-system affects the chosen attribute +cp -r "$flake1Dir" "$flake1Dir.kittified" +sed -i "s#$system#kitty-kitty#" "$flake1Dir.kittified/flake.nix" +nix build --eval-system kitty-kitty "$flake1Dir.kittified" + # 'getFlake' on an unlocked flakeref should fail in pure mode, but # succeed in impure mode. (! nix build -o $TEST_ROOT/result --expr "(builtins.getFlake \"$flake1Dir\").packages.$system.default") diff --git a/tests/functional/flakes/show.sh b/tests/functional/flakes/show.sh index 3461597ee..53e849a40 100644 --- a/tests/functional/flakes/show.sh +++ b/tests/functional/flakes/show.sh @@ -7,6 +7,8 @@ writeSimpleFlake "$flakeDir" cd "$flakeDir" +# FIXME(jade): the following is rather absurd. we have jq! + # By default: Only show the packages content for the current system and no # legacyPackages at all nix flake show --json > show-output.json @@ -19,6 +21,11 @@ assert show_output.legacyPackages.${builtins.currentSystem} == {}; true ' +# Follow --eval-system for determining the system for flakes +nix flake show --eval-system someOtherSystem --json > show-output.json +drvTitle=$(jq -r '.packages.someOtherSystem.default.name' show-output.json) +[[ $drvTitle == 'simple' ]] + # With `--all-systems`, show the packages for all systems nix flake show --json --all-systems > show-output.json nix eval --impure --expr '