tests.nixpkgs-check-by-name: auto-calling differentiation

Allows detecting whether attributes are overridden in all-packages.nix.
In a future commit we'll use this to detect empty arguments being set in
all-packages.nix and complain about that.
This commit is contained in:
Silvan Mosberger 2023-10-12 01:00:37 +02:00
parent f394f738fa
commit fcaa408d00
4 changed files with 43 additions and 7 deletions

View File

@ -35,6 +35,23 @@ let
else
# It's very rare that callPackage doesn't return an attribute set, but it can occur.
variantInfo;
_internalCallByNamePackageFile = file:
let
result = super._internalCallByNamePackageFile file;
variantInfo._attributeVariant = {
# This name is used by the deserializer on the Rust side
AutoCalled = null;
};
in
if builtins.isAttrs result then
# If this was the last overlay to be applied, we could just only return the `_callPackagePath`,
# but that's not the case because stdenv has another overlays on top of user-provided ones.
# So to not break the stdenv build we need to return the mostly proper result here
result // variantInfo
else
# It's very rare that callPackage doesn't return an attribute set, but it can occur.
variantInfo;
};
pkgs = import nixpkgsPath {

View File

@ -19,7 +19,11 @@ struct AttributeInfo {
#[derive(Deserialize)]
enum AttributeVariant {
/// The attribute is defined as a pkgs.callPackage <path>
/// The attribute is auto-called as pkgs.callPackage using pkgs/by-name,
/// and it is not overridden by a definition in all-packages.nix
AutoCalled,
/// The attribute is defined as a pkgs.callPackage <path>,
/// and overridden by all-packages.nix
/// The path is None when the <path> argument isn't a path
CallPackage { path: Option<PathBuf> },
/// The attribute is not defined as pkgs.callPackage
@ -107,6 +111,7 @@ pub fn check_values<W: io::Write>(
if let Some(attribute_info) = actual_files.get(package_name) {
let valid = match &attribute_info.variant {
AttributeVariant::AutoCalled => true,
AttributeVariant::CallPackage { path } => {
if let Some(call_package_path) = path {
absolute_package_file == *call_package_path

View File

@ -75,9 +75,14 @@ let
# Turns autoCalledPackageFiles into an overlay that `callPackage`'s all of them
autoCalledPackages = self: super:
builtins.mapAttrs (name: file:
self.callPackage file { }
) autoCalledPackageFiles;
{
# Needed to be able to detect empty arguments in all-packages.nix
# See a more detailed description in pkgs/top-level/by-name-overlay.nix
_internalCallByNamePackageFile = file: self.callPackage file { };
}
// builtins.mapAttrs
(name: self._internalCallByNamePackageFile)
autoCalledPackageFiles;
# A list optionally containing the `all-packages.nix` file from the test case as an overlay
optionalAllPackagesOverlay =

View File

@ -45,6 +45,15 @@ in
# Currently this would be hard to measure until we have more packages
# and ideally https://github.com/NixOS/nix/pull/8895
self: super:
mapAttrs (name: file:
self.callPackage file { }
) packageFiles
{
# This attribute is necessary to allow CI to ensure that all packages defined in `pkgs/by-name`
# don't have an overriding definition in `all-packages.nix` with an empty (`{ }`) second `callPackage` argument.
# It achieves that with an overlay that modifies both `callPackage` and this attribute to signal whether `callPackage` is used
# and whether it's defined by this file here or `all-packages.nix`.
# TODO: This can be removed once `pkgs/by-name` can handle custom `callPackage` arguments without `all-packages.nix` (or any other way of achieving the same result).
# Because at that point the code in ./stage.nix can be changed to not allow definitions in `all-packages.nix` to override ones from `pkgs/by-name` anymore and throw an error if that happens instead.
_internalCallByNamePackageFile = file: self.callPackage file { };
}
// mapAttrs
(name: self._internalCallByNamePackageFile)
packageFiles