tests.nixpkgs-check-by-name: Fix allowing non-path overrides

An edge case was allowed when it shouldn't be: A package defined in
`pkgs/by-name` could be overridden in `all-packages.nix` if it was of
the form `callPackage (<expr>) { <non-empty> }`.

This is not right, it's required that the first argument be the path
matching the package to be overridden.
This commit is contained in:
Silvan Mosberger 2024-02-19 22:28:01 +01:00
parent 712ac796e5
commit a61c8c9f5c
5 changed files with 26 additions and 18 deletions

@ -195,7 +195,6 @@ fn by_name(
use ByNameAttribute::*; use ByNameAttribute::*;
let relative_package_file = structure::relative_file_for_package(attribute_name); let relative_package_file = structure::relative_file_for_package(attribute_name);
let absolute_package_file = nixpkgs_path.join(&relative_package_file);
// At this point we know that `pkgs/by-name/fo/foo/package.nix` has to exists. // At this point we know that `pkgs/by-name/fo/foo/package.nix` has to exists.
// This match decides whether the attribute `foo` is defined accordingly // This match decides whether the attribute `foo` is defined accordingly
@ -284,23 +283,17 @@ fn by_name(
.call_package_argument_info_at( .call_package_argument_info_at(
location.line, location.line,
location.column, location.column,
// We're passing `pkgs/by-name/fo/foo/package.nix` here, which causes nixpkgs_path,
// the function to verify that `<arg1>` is the same path,
// making `syntactic_call_package.relative_path` end up as `""`
// TODO: This is confusing and should be improved
&absolute_package_file,
)?; )?;
// At this point, we completed two different checks for whether it's a // At this point, we completed two different checks for whether it's a
// `callPackage` // `callPackage`
match (is_semantic_call_package, optional_syntactic_call_package) { match (is_semantic_call_package, optional_syntactic_call_package) {
// Something like `<attr> = { ... }` // Something like `<attr> = { ... }`
// or a `pkgs.callPackage` but with the wrong file
(false, None) (false, None)
// Something like `<attr> = pythonPackages.callPackage ./pkgs/by-name/...` // Something like `<attr> = pythonPackages.callPackage ...`
| (false, Some(_)) | (false, Some(_))
// Something like `<attr> = bar` where `bar = pkgs.callPackage ...` // Something like `<attr> = bar` where `bar = pkgs.callPackage ...`
// or a `callPackage` but with the wrong file
| (true, None) => { | (true, None) => {
// All of these are not of the expected form, so error out // All of these are not of the expected form, so error out
// TODO: Make error more specific, don't lump everything together // TODO: Make error more specific, don't lump everything together
@ -309,18 +302,25 @@ fn by_name(
package_name: attribute_name.to_owned(), package_name: attribute_name.to_owned(),
}.into() }.into()
} }
// Something like `<attr> = pkgs.callPackage ./pkgs/by-name/...`, // Something like `<attr> = pkgs.callPackage ...`
// with the correct file
(true, Some(syntactic_call_package)) => { (true, Some(syntactic_call_package)) => {
Success( if let Some(path) = syntactic_call_package.relative_path {
// Manual definitions with empty arguments are not allowed if path == relative_package_file {
// anymore // Manual definitions with empty arguments are not allowed
if syntactic_call_package.empty_arg { // anymore
Loose(()) Success(if syntactic_call_package.empty_arg { Loose(()) } else { Tight })
} else { } else {
Tight NixpkgsProblem::WrongCallPackage {
relative_package_file: relative_package_file.to_owned(),
package_name: attribute_name.to_owned(),
}.into()
} }
) } else {
NixpkgsProblem::WrongCallPackage {
relative_package_file: relative_package_file.to_owned(),
package_name: attribute_name.to_owned(),
}.into()
}
} }
} }
} else { } else {

@ -0,0 +1,5 @@
self: super: {
foo = self.callPackage ({ someDrv, someFlag }: someDrv) { someFlag = true; };
}

@ -0,0 +1 @@
import <test-nixpkgs> { root = ./.; }

@ -0,0 +1 @@
pkgs.foo: 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 pkgs/by-name/fo/foo/package.nix { ... }` with a non-empty second argument.

@ -0,0 +1 @@
{ someDrv }: someDrv