nix flake check: skip derivations for foreign systems (#7759)

`nix flake show` now skips derivations for foreign systems: https://github.com/NixOS/nix/pull/6988

This commit borrows from that to implement the same behavior for `nix flake check`.

See "nix flake check breaks on IFD in multi-platform flake" https://github.com/NixOS/nix/issues/4265
This commit is contained in:
Peter Becich 2023-05-22 21:59:44 -07:00 committed by GitHub
parent 494a09c6df
commit a420ccc6a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 40 deletions

View file

@ -259,6 +259,7 @@ struct CmdFlakeInfo : CmdFlakeMetadata
struct CmdFlakeCheck : FlakeCommand struct CmdFlakeCheck : FlakeCommand
{ {
bool build = true; bool build = true;
bool checkAllSystems = false;
CmdFlakeCheck() CmdFlakeCheck()
{ {
@ -267,6 +268,11 @@ struct CmdFlakeCheck : FlakeCommand
.description = "Do not build checks.", .description = "Do not build checks.",
.handler = {&build, false} .handler = {&build, false}
}); });
addFlag({
.longName = "all-systems",
.description = "Check the outputs for all systems.",
.handler = {&checkAllSystems, true}
});
} }
std::string description() override std::string description() override
@ -292,6 +298,7 @@ struct CmdFlakeCheck : FlakeCommand
lockFlags.applyNixConfig = true; lockFlags.applyNixConfig = true;
auto flake = lockFlake(); auto flake = lockFlake();
auto localSystem = std::string(settings.thisSystem.get());
bool hasErrors = false; bool hasErrors = false;
auto reportError = [&](const Error & e) { auto reportError = [&](const Error & e) {
@ -307,6 +314,8 @@ struct CmdFlakeCheck : FlakeCommand
} }
}; };
std::set<std::string> omittedSystems;
// FIXME: rewrite to use EvalCache. // FIXME: rewrite to use EvalCache.
auto resolve = [&] (PosIdx p) { auto resolve = [&] (PosIdx p) {
@ -327,6 +336,15 @@ struct CmdFlakeCheck : FlakeCommand
reportError(Error("'%s' is not a valid system type, at %s", system, resolve(pos))); reportError(Error("'%s' is not a valid system type, at %s", system, resolve(pos)));
}; };
auto checkSystemType = [&](const std::string & system, const PosIdx pos) {
if (!checkAllSystems && system != localSystem) {
omittedSystems.insert(system);
return false;
} else {
return true;
}
};
auto checkDerivation = [&](const std::string & attrPath, Value & v, const PosIdx pos) -> std::optional<StorePath> { auto checkDerivation = [&](const std::string & attrPath, Value & v, const PosIdx pos) -> std::optional<StorePath> {
try { try {
auto drvInfo = getDerivation(*state, v, false); auto drvInfo = getDerivation(*state, v, false);
@ -509,16 +527,18 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, ""); if (checkSystemType(attr_name, attr.pos)) {
for (auto & attr2 : *attr.value->attrs) { state->forceAttrs(*attr.value, attr.pos, "");
auto drvPath = checkDerivation( for (auto & attr2 : *attr.value->attrs) {
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]), auto drvPath = checkDerivation(
*attr2.value, attr2.pos); fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
if (drvPath && attr_name == settings.thisSystem.get()) { *attr2.value, attr2.pos);
drvPaths.push_back(DerivedPath::Built { if (drvPath && attr_name == settings.thisSystem.get()) {
.drvPath = *drvPath, drvPaths.push_back(DerivedPath::Built {
.outputs = OutputsSpec::All { }, .drvPath = *drvPath,
}); .outputs = OutputsSpec::All { },
});
}
} }
} }
} }
@ -529,9 +549,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
checkApp( if (checkSystemType(attr_name, attr.pos)) {
fmt("%s.%s", name, attr_name), checkApp(
*attr.value, attr.pos); fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
} }
} }
@ -540,11 +562,13 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, ""); if (checkSystemType(attr_name, attr.pos)) {
for (auto & attr2 : *attr.value->attrs) state->forceAttrs(*attr.value, attr.pos, "");
checkDerivation( for (auto & attr2 : *attr.value->attrs)
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]), checkDerivation(
*attr2.value, attr2.pos); fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
};
} }
} }
@ -553,11 +577,13 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, ""); if (checkSystemType(attr_name, attr.pos)) {
for (auto & attr2 : *attr.value->attrs) state->forceAttrs(*attr.value, attr.pos, "");
checkApp( for (auto & attr2 : *attr.value->attrs)
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]), checkApp(
*attr2.value, attr2.pos); fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
};
} }
} }
@ -566,9 +592,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
checkDerivation( if (checkSystemType(attr_name, attr.pos)) {
fmt("%s.%s", name, attr_name), checkDerivation(
*attr.value, attr.pos); fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
} }
} }
@ -577,9 +605,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
checkApp( if (checkSystemType(attr_name, attr.pos) ) {
fmt("%s.%s", name, attr_name), checkApp(
*attr.value, attr.pos); fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
} }
} }
@ -587,6 +617,7 @@ struct CmdFlakeCheck : FlakeCommand
state->forceAttrs(vOutput, pos, ""); state->forceAttrs(vOutput, pos, "");
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
checkSystemName(state->symbols[attr.name], attr.pos); checkSystemName(state->symbols[attr.name], attr.pos);
checkSystemType(state->symbols[attr.name], attr.pos);
// FIXME: do getDerivations? // FIXME: do getDerivations?
} }
} }
@ -636,9 +667,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
checkBundler( if (checkSystemType(attr_name, attr.pos)) {
fmt("%s.%s", name, attr_name), checkBundler(
*attr.value, attr.pos); fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
} }
} }
@ -647,12 +680,14 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) { for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name]; const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos); checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, ""); if (checkSystemType(attr_name, attr.pos)) {
for (auto & attr2 : *attr.value->attrs) { state->forceAttrs(*attr.value, attr.pos, "");
checkBundler( for (auto & attr2 : *attr.value->attrs) {
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]), checkBundler(
*attr2.value, attr2.pos); fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
} *attr2.value, attr2.pos);
}
};
} }
} }
@ -685,7 +720,15 @@ struct CmdFlakeCheck : FlakeCommand
} }
if (hasErrors) if (hasErrors)
throw Error("some errors were encountered during the evaluation"); throw Error("some errors were encountered during the evaluation");
}
if (!omittedSystems.empty()) {
warn(
"The check omitted these incompatible systems: %s\n"
"Use '--all-systems' to check all.",
concatStringsSep(", ", omittedSystems)
);
};
};
}; };
static Strings defaultTemplateAttrPathsPrefixes{"templates."}; static Strings defaultTemplateAttrPathsPrefixes{"templates."};

View file

@ -72,6 +72,8 @@ cat > $flakeDir/flake.nix <<EOF
} }
EOF EOF
checkRes=$(nix flake check --keep-going $flakeDir 2>&1 && fail "nix flake check should have failed" || true) nix flake check $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" echo "$checkRes" | grepQuiet "packages.system-1.default"
echo "$checkRes" | grepQuiet "packages.system-2.default" echo "$checkRes" | grepQuiet "packages.system-2.default"