mirror of
https://github.com/NixOS/nix.git
synced 2025-11-11 21:16:02 +01:00
Merge pull request #14321 from roberth/nix-flake-check-track-attribute
Track attributes in `nix flake check`
This commit is contained in:
commit
7a60f1429f
2 changed files with 55 additions and 5 deletions
|
|
@ -362,7 +362,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
throw;
|
throw;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
if (settings.keepGoing) {
|
if (settings.keepGoing) {
|
||||||
ignoreExceptionExceptInterrupt();
|
logError(e.info());
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
} else
|
} else
|
||||||
throw;
|
throw;
|
||||||
|
|
@ -418,7 +418,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<DerivedPath> drvPaths;
|
std::map<DerivedPath, std::vector<AttrPath>> attrPathsByDrv;
|
||||||
|
|
||||||
auto checkApp = [&](const std::string & attrPath, Value & v, const PosIdx pos) {
|
auto checkApp = [&](const std::string & attrPath, Value & v, const PosIdx pos) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -616,7 +616,13 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
.drvPath = makeConstantStorePathRef(*drvPath),
|
.drvPath = makeConstantStorePathRef(*drvPath),
|
||||||
.outputs = OutputsSpec::All{},
|
.outputs = OutputsSpec::All{},
|
||||||
};
|
};
|
||||||
drvPaths.push_back(std::move(path));
|
|
||||||
|
// Build and store the attribute path for error reporting
|
||||||
|
AttrPath attrPath;
|
||||||
|
attrPath.push_back(AttrName(state->symbols.create(name)));
|
||||||
|
attrPath.push_back(AttrName(attr.name));
|
||||||
|
attrPath.push_back(AttrName(attr2.name));
|
||||||
|
attrPathsByDrv[path].push_back(std::move(attrPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -780,7 +786,9 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build && !drvPaths.empty()) {
|
if (build && !attrPathsByDrv.empty()) {
|
||||||
|
auto keys = std::views::keys(attrPathsByDrv);
|
||||||
|
std::vector<DerivedPath> drvPaths(keys.begin(), keys.end());
|
||||||
// TODO: This filtering of substitutable paths is a temporary workaround until
|
// TODO: This filtering of substitutable paths is a temporary workaround until
|
||||||
// https://github.com/NixOS/nix/issues/5025 (union stores) is implemented.
|
// https://github.com/NixOS/nix/issues/5025 (union stores) is implemented.
|
||||||
//
|
//
|
||||||
|
|
@ -804,7 +812,28 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, actUnknown, fmt("running %d flake checks", toBuild.size()));
|
Activity act(*logger, lvlInfo, actUnknown, fmt("running %d flake checks", toBuild.size()));
|
||||||
store->buildPaths(toBuild);
|
auto results = store->buildPathsWithResults(toBuild);
|
||||||
|
|
||||||
|
// Report build failures with attribute paths
|
||||||
|
for (auto & result : results) {
|
||||||
|
if (auto * failure = result.tryGetFailure()) {
|
||||||
|
auto it = attrPathsByDrv.find(result.path);
|
||||||
|
if (it != attrPathsByDrv.end() && !it->second.empty()) {
|
||||||
|
for (auto & attrPath : it->second) {
|
||||||
|
auto attrPathStr = showAttrPath(state->symbols, attrPath);
|
||||||
|
reportError(Error(
|
||||||
|
"failed to build attribute '%s', build of '%s' failed: %s",
|
||||||
|
attrPathStr,
|
||||||
|
result.path.to_string(*store),
|
||||||
|
failure->errorMsg));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Derivation has no attribute path (e.g., a build dependency)
|
||||||
|
reportError(
|
||||||
|
Error("build of '%s' failed: %s", result.path.to_string(*store), failure->errorMsg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hasErrors)
|
if (hasErrors)
|
||||||
throw Error("some errors were encountered during the evaluation");
|
throw Error("some errors were encountered during the evaluation");
|
||||||
|
|
|
||||||
|
|
@ -192,3 +192,24 @@ EOF
|
||||||
# shellcheck disable=SC2015
|
# shellcheck disable=SC2015
|
||||||
checkRes=$(nix flake check "$flakeDir" 2>&1 && fail "nix flake check should have failed" || true)
|
checkRes=$(nix flake check "$flakeDir" 2>&1 && fail "nix flake check should have failed" || true)
|
||||||
echo "$checkRes" | grepQuiet -E "builder( for .*)? failed with exit code 1"
|
echo "$checkRes" | grepQuiet -E "builder( for .*)? failed with exit code 1"
|
||||||
|
|
||||||
|
# Test that attribute paths are shown in error messages
|
||||||
|
cat > "$flakeDir"/flake.nix <<EOF
|
||||||
|
{
|
||||||
|
outputs = { self }: with import ./config.nix; {
|
||||||
|
checks.${system}.failingCheck = mkDerivation {
|
||||||
|
name = "failing-check";
|
||||||
|
buildCommand = "echo 'This check fails'; exit 1";
|
||||||
|
};
|
||||||
|
checks.${system}.anotherFailingCheck = mkDerivation {
|
||||||
|
name = "another-failing-check";
|
||||||
|
buildCommand = "echo 'This also fails'; exit 1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# shellcheck disable=SC2015
|
||||||
|
checkRes=$(nix flake check --keep-going "$flakeDir" 2>&1 && fail "nix flake check should have failed" || true)
|
||||||
|
echo "$checkRes" | grepQuiet "checks.${system}.failingCheck"
|
||||||
|
echo "$checkRes" | grepQuiet "checks.${system}.anotherFailingCheck"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue