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
{
bool build = true;
bool checkAllSystems = false;
CmdFlakeCheck()
{
@ -267,6 +268,11 @@ struct CmdFlakeCheck : FlakeCommand
.description = "Do not build checks.",
.handler = {&build, false}
});
addFlag({
.longName = "all-systems",
.description = "Check the outputs for all systems.",
.handler = {&checkAllSystems, true}
});
}
std::string description() override
@ -292,6 +298,7 @@ struct CmdFlakeCheck : FlakeCommand
lockFlags.applyNixConfig = true;
auto flake = lockFlake();
auto localSystem = std::string(settings.thisSystem.get());
bool hasErrors = false;
auto reportError = [&](const Error & e) {
@ -307,6 +314,8 @@ struct CmdFlakeCheck : FlakeCommand
}
};
std::set<std::string> omittedSystems;
// FIXME: rewrite to use EvalCache.
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)));
};
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> {
try {
auto drvInfo = getDerivation(*state, v, false);
@ -509,16 +527,18 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
auto drvPath = checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (drvPath && attr_name == settings.thisSystem.get()) {
drvPaths.push_back(DerivedPath::Built {
.drvPath = *drvPath,
.outputs = OutputsSpec::All { },
});
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
auto drvPath = checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (drvPath && attr_name == settings.thisSystem.get()) {
drvPaths.push_back(DerivedPath::Built {
.drvPath = *drvPath,
.outputs = OutputsSpec::All { },
});
}
}
}
}
@ -529,9 +549,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos)) {
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -540,11 +562,13 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkDerivation(
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) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkApp(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkApp(
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) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkDerivation(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos)) {
checkDerivation(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -577,9 +605,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos) ) {
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -587,6 +617,7 @@ struct CmdFlakeCheck : FlakeCommand
state->forceAttrs(vOutput, pos, "");
for (auto & attr : *vOutput.attrs) {
checkSystemName(state->symbols[attr.name], attr.pos);
checkSystemType(state->symbols[attr.name], attr.pos);
// FIXME: do getDerivations?
}
}
@ -636,9 +667,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkBundler(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos)) {
checkBundler(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -647,12 +680,14 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
checkBundler(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
}
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
checkBundler(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
}
};
}
}
@ -685,7 +720,15 @@ struct CmdFlakeCheck : FlakeCommand
}
if (hasErrors)
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."};

View file

@ -72,6 +72,8 @@ cat > $flakeDir/flake.nix <<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-2.default"