diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-01-20 12:31:50 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-01-20 12:32:25 +0100 |
commit | b7baf40e099b4215181fe7b0c63083b12ef2c7fb (patch) | |
tree | a6efabd31d05b6d0a36624729e80377bbbfb0149 /nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix | |
parent | 710028664e26e85cb831a869b3da9f6993902255 (diff) | |
parent | 0799f514b1cd74878174939df79ac60ca5036673 (diff) | |
download | nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.gz nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.bz2 nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.lz nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.xz nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.tar.zst nixlib-b7baf40e099b4215181fe7b0c63083b12ef2c7fb.zip |
Merge branch 'nixos-unstable-small' of https://github.com/NixOS/nixpkgs
Conflicts: nixpkgs/pkgs/build-support/rust/build-rust-package/default.nix
Diffstat (limited to 'nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix')
-rw-r--r-- | nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix | 141 |
1 files changed, 87 insertions, 54 deletions
diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix index bf9f19d8e460..87c54b6444ee 100644 --- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix +++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.nix @@ -1,11 +1,7 @@ # Takes a path to nixpkgs and a path to the json-encoded list of attributes to check. -# Returns an attribute set containing information on each requested attribute. -# If the attribute is missing from Nixpkgs it's also missing from the result. -# -# The returned information is an attribute set with: -# - call_package_path: The <path> from `<attr> = callPackage <path> { ... }`, -# or null if it's not defined as with callPackage, or if the <path> is not a path -# - is_derivation: The result of `lib.isDerivation <attr>` +# Returns an value containing information on each requested attribute, +# which is decoded on the Rust side. +# See ./eval.rs for the meaning of the returned values { attrsPath, nixpkgsPath, @@ -13,70 +9,107 @@ let attrs = builtins.fromJSON (builtins.readFile attrsPath); - # This overlay mocks callPackage to persist the path of the first argument - callPackageOverlay = self: super: { + nixpkgsPathLength = builtins.stringLength (toString nixpkgsPath) + 1; + removeNixpkgsPrefix = builtins.substring nixpkgsPathLength (-1); + + # We need access to the `callPackage` arguments of each attribute. + # The only way to do so is to override `callPackage` with our own version that adds this information to the result, + # and then try to access this information. + overlay = final: prev: { + + # Information for attributes defined using `callPackage` callPackage = fn: args: - let - result = super.callPackage fn args; - variantInfo._attributeVariant = { - # These names are used by the deserializer on the Rust side - CallPackage.path = + addVariantInfo (prev.callPackage fn args) { + Manual = { + path = if builtins.isPath fn then - toString fn + removeNixpkgsPrefix (toString fn) else null; - CallPackage.empty_arg = + empty_arg = args == { }; }; - 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; + }; + # Information for attributes that are auto-called from pkgs/by-name. + # This internal attribute is only used by pkgs/by-name _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; + addVariantInfo (prev._internalCallByNamePackageFile file) { + Auto = null; + }; + }; + # We can't just replace attribute values with their info in the overlay, + # because attributes can depend on other attributes, so this would break evaluation. + addVariantInfo = value: variant: + if builtins.isAttrs value then + value // { + _callPackageVariant = variant; + } + else + # It's very rare that callPackage doesn't return an attribute set, but it can occur. + # In such a case we can't really return anything sensible that would include the info, + # so just don't return the info and let the consumer handle it. + value; + pkgs = import nixpkgsPath { # Don't let the users home directory influence this result config = { }; - overlays = [ callPackageOverlay ]; + overlays = [ overlay ]; + # We check evaluation and callPackage only for x86_64-linux. + # Not ideal, but hard to fix + system = "x86_64-linux"; }; - attrInfo = attr: - let - value = pkgs.${attr}; - in - { - # These names are used by the deserializer on the Rust side - variant = value._attributeVariant or { Other = null; }; - is_derivation = pkgs.lib.isDerivation value; - }; + attrInfo = name: value: + if ! builtins.isAttrs value then + { + NonAttributeSet = null; + } + else if ! value ? _callPackageVariant then + { + NonCallPackage = null; + } + else + { + CallPackage = { + call_package_variant = value._callPackageVariant; + is_derivation = pkgs.lib.isDerivation value; + }; + }; - attrInfos = builtins.listToAttrs (map (name: { + byNameAttrs = builtins.listToAttrs (map (name: { inherit name; - value = attrInfo name; + value.ByName = + if ! pkgs ? ${name} then + { Missing = null; } + else + { Existing = attrInfo name pkgs.${name}; }; }) attrs); + # Information on all attributes that exist but are not in pkgs/by-name. + # We need this to enforce pkgs/by-name for new packages + nonByNameAttrs = builtins.mapAttrs (name: value: + let + output = attrInfo name value; + result = builtins.tryEval (builtins.deepSeq output null); + in + { + NonByName = + if result.success then + { EvalSuccess = output; } + else + { EvalFailure = null; }; + } + ) (builtins.removeAttrs pkgs attrs); + + # All attributes + attributes = byNameAttrs // nonByNameAttrs; in -# Filter out attributes not in Nixpkgs -builtins.intersectAttrs pkgs attrInfos +# We output them in the form [ [ <name> <value> ] ]` such that the Rust side +# doesn't need to sort them again to get deterministic behavior (good for testing) +map (name: [ + name + attributes.${name} +]) (builtins.attrNames attributes) |