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
This commit is contained in:
@@ -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.
|
||||
@@ -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() + "."
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+7
-3
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+3
-3
@@ -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<LockedFlake>(lockFlake(*state));
|
||||
auto localSystem = std::string(settings.thisSystem.get());
|
||||
auto localSystem = std::string(evalSettings.getCurrentSystem());
|
||||
|
||||
std::function<bool(
|
||||
eval_cache::AttrCursor & visitor,
|
||||
|
||||
@@ -22,6 +22,7 @@ struct CmdFmt : SourceExprCommand {
|
||||
Category category() override { return catSecondary; }
|
||||
|
||||
Strings getDefaultFlakeAttrPaths() override {
|
||||
// We are running it locally so it should be the actual system
|
||||
return Strings{"formatter." + settings.thisSystem.get()};
|
||||
}
|
||||
|
||||
|
||||
@@ -188,6 +188,7 @@ struct CmdRun : InstallableCommand
|
||||
|
||||
Strings getDefaultFlakeAttrPaths() override
|
||||
{
|
||||
// We are running it locally so it should be the actual system
|
||||
Strings res{
|
||||
"apps." + settings.thisSystem.get() + ".default",
|
||||
"defaultApp." + settings.thisSystem.get(),
|
||||
@@ -199,6 +200,7 @@ struct CmdRun : InstallableCommand
|
||||
|
||||
Strings getDefaultFlakeAttrPathPrefixes() override
|
||||
{
|
||||
// We are running it locally so it should be the actual system
|
||||
Strings res{"apps." + settings.thisSystem.get() + "."};
|
||||
for (auto & s : SourceExprCommand::getDefaultFlakeAttrPathPrefixes())
|
||||
res.push_back(s);
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||
Strings getDefaultFlakeAttrPaths() override
|
||||
{
|
||||
return {
|
||||
"packages." + settings.thisSystem.get(),
|
||||
"legacyPackages." + settings.thisSystem.get()
|
||||
"packages." + evalSettings.getCurrentSystem(),
|
||||
"legacyPackages." + evalSettings.getCurrentSystem()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,11 @@ cat > $flakeDir/flake.nix <<EOF
|
||||
EOF
|
||||
|
||||
nix flake check $flakeDir
|
||||
# --eval-system should be considered for which the local system is for flake
|
||||
# purposes, and thus it should fail checking that attr
|
||||
(! nix flake check --eval-system system-1 $flakeDir)
|
||||
# likewise with --system
|
||||
(! nix flake check --system system-1 $flakeDir)
|
||||
|
||||
checkRes=$(nix flake check --all-systems --keep-going $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
|
||||
echo "$checkRes" | grepQuiet "packages.system-1.default"
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 '
|
||||
|
||||
Reference in New Issue
Block a user