about summary refs log tree commit diff
path: root/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs')
-rw-r--r--nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs50
1 files changed, 41 insertions, 9 deletions
diff --git a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs
index 17e22495b22a..26836501c97a 100644
--- a/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs
+++ b/nixpkgs/pkgs/test/nixpkgs-check-by-name/src/eval.rs
@@ -1,5 +1,6 @@
 use crate::structure;
 use crate::utils::ErrorWriter;
+use crate::Version;
 use std::path::Path;
 
 use anyhow::Context;
@@ -13,16 +14,34 @@ use tempfile::NamedTempFile;
 /// Attribute set of this structure is returned by eval.nix
 #[derive(Deserialize)]
 struct AttributeInfo {
-    call_package_path: Option<PathBuf>,
+    variant: AttributeVariant,
     is_derivation: bool,
 }
 
+#[derive(Deserialize)]
+enum AttributeVariant {
+    /// 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> <args>,
+    /// and overridden by all-packages.nix
+    CallPackage {
+        /// The <path> argument or None if it's not a path
+        path: Option<PathBuf>,
+        /// true if <args> is { }
+        empty_arg: bool,
+    },
+    /// The attribute is not defined as pkgs.callPackage
+    Other,
+}
+
 const EXPR: &str = include_str!("eval.nix");
 
 /// Check that the Nixpkgs attribute values corresponding to the packages in pkgs/by-name are
 /// of the form `callPackage <package_file> { ... }`.
 /// See the `eval.nix` file for how this is achieved on the Nix side
 pub fn check_values<W: io::Write>(
+    version: Version,
     error_writer: &mut ErrorWriter<W>,
     nixpkgs: &structure::Nixpkgs,
     eval_accessible_paths: Vec<&Path>,
@@ -97,16 +116,29 @@ pub fn check_values<W: io::Write>(
         let absolute_package_file = nixpkgs.path.join(&relative_package_file);
 
         if let Some(attribute_info) = actual_files.get(package_name) {
-            let is_expected_file =
-                if let Some(call_package_path) = &attribute_info.call_package_path {
-                    absolute_package_file == *call_package_path
-                } else {
-                    false
-                };
+            let valid = match &attribute_info.variant {
+                AttributeVariant::AutoCalled => true,
+                AttributeVariant::CallPackage { path, empty_arg } => {
+                    let correct_file = if let Some(call_package_path) = path {
+                        absolute_package_file == *call_package_path
+                    } else {
+                        false
+                    };
+                    // Only check for the argument to be non-empty if the version is V1 or
+                    // higher
+                    let non_empty = if version >= Version::V1 {
+                        !empty_arg
+                    } else {
+                        true
+                    };
+                    correct_file && non_empty
+                }
+                AttributeVariant::Other => false,
+            };
 
-            if !is_expected_file {
+            if !valid {
                 error_writer.write(&format!(
-                    "pkgs.{package_name}: This attribute is not defined as `pkgs.callPackage {} {{ ... }}`.",
+                    "pkgs.{package_name}: This attribute is manually defined (most likely in pkgs/top-level/all-packages.nix), which is only allowed if the definition is of the form `pkgs.callPackage {} {{ ... }}` with a non-empty second argument.",
                     relative_package_file.display()
                 ))?;
                 continue;