[Nix-dev] ‘callPackage’ vs. ‘all-packages.nix’
Ludovic Courtès
ludo at gnu.org
Tue Sep 15 16:40:39 CEST 2009
Hi!
Eelco Dolstra <e.dolstra at tudelft.nl> writes:
> * Two primops: builtins.intersectAttrs and builtins.functionArgs.
> intersectAttrs returns the (right-biased) intersection between two
> attribute sets, e.g. every attribute from the second set that also
> exists in the first. functionArgs returns the set of attributes
> expected by a function.
>
> The main goal of these is to allow the elimination of most of
> all-packages.nix. Most package instantiations in all-packages.nix
> have this form:
>
> foo = import ./foo.nix {
> inherit a b c;
> };
>
> With intersectAttrs and functionArgs, this can be written as:
>
> foo = callPackage (import ./foo.nix) { };
>
> where
>
> callPackage = f: args:
> f ((builtins.intersectAttrs (builtins.functionArgs f) pkgs) // args);
>
> I.e., foo.nix is called with all attributes from "pkgs" that it
> actually needs (e.g., pkgs.a, pkgs.b and pkgs.c). (callPackage can
> do any other generic package-level stuff we might want, such as
> applying makeOverridable.) Of course, the automatically supplied
> arguments can be overriden if needed, e.g.
>
> foo = callPackage (import ./foo.nix) {
> c = c_version_2;
> };
>
> but for the vast majority of packages, this won't be needed.
>
> The advantages are to reduce the amount of typing needed to add a
> dependency (from three sites to two), and to reduce the number of
> trivial commits to all-packages.nix. For the former, there have
> been two previous attempts:
>
> - Use "args: with args;" in the package's function definition.
> This however obscures the actual expected arguments of a
> function, which is very bad.
>
> - Use "{ arg1, arg2, ... }:" in the package's function definition
> (i.e. use the ellipis "..." to allow arbitrary additional
> arguments), and then call the function with all of "pkgs" as an
> argument. But this inhibits error detection if you call it with
> an misspelled (or obsolete) argument.
(I think the above text belongs in a document in the repository, more
than in a commit log, so that it’s available for future reference.)
This is good news!
So what’s the plan now? Clearly, ‘all-packages.nix’ can’t be entirely
generated, because there are cases where the second argument to
‘callPackage’ won’t be ‘{ }’, and also things like Michael’s
‘builderDefsPackage’, ‘selectVersion’, etc.
The other question is when do things get generated? Will one have to
run an ad hoc script manually when adding/changing a package?
Thoughts?
Thanks,
Ludo’.
More information about the nix-dev
mailing list