Commit fcaa408d authored by Silvan Mosberger's avatar Silvan Mosberger
Browse files

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.
parent f394f738
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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 {
+6 −1
Original line number Diff line number Diff line
@@ -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
+8 −3
Original line number Diff line number Diff line
@@ -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 =
+12 −3
Original line number Diff line number Diff line
@@ -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