[Nix-dev] Anyone against giving the nixpkgs attrset a reference to itself?

Mathijs Kwik mathijs at bluescreen303.nl
Thu Jul 19 15:03:12 CEST 2012


On Wed, Jul 18, 2012 at 7:12 AM, Nicolas Pierron
<nicolas.b.pierron at gmail.com> wrote:
> Hi Mathijs,
>
> On Mon, Jul 16, 2012 at 12:32 AM, Mathijs Kwik <mathijs at bluescreen303.nl> wrote:
>> I would like to add the final nixpkgs attrset (defaults + overrides)
>> to itself (named finalPkgs).
>> As this is a somewhat strange thing to do, I thought it would be best
>> to ask first :)
>
> strange ?  No, this is the base principle of NixOS.  In fact I would
> almost recommend you to use a similar idea because I think we should
> get rid of __override.
>
> Ideally, all Nixpkgs files should look like [2].
>
>> Extra bonuspoints:
>> Currently, uncommenting the "with" statement on line 3 of [2] leads to
>> "infinite recursion detected".
>> Can anyone find out why? I was under the impression that "with" just
>> brought stuff into scope, so as long as I don't use anything that
>> would recurse to bottom, laziness should save me.
>
> The way names are resolve by the with statement implies that we know
> every attribute of the with statement.  Unfortunately, this is only
> possible when the update operator (//) is finished, which implies
> knowing all attributes of the left-hand-side and the right-hand-side.
>
> So when you write:
>
> let
>   set1 = pkgs: { a = ...; b = ...; };
>   set2 = pkgs: with pkgs; { c = ...; d = ...; };
> in
>   (import <nixpkgs/pkgs/lib>).fix (pkgs: (set1 pkgs // set2 pkgs))
>
> You will cause an infinite recursion because you the with statement in
> set2 need the results of the update (//) to finish.
>
>     with { attr = <LAZY> }
>
> By the way, I will recommend to fold with  recursiveUpdateUntil  with
> a predicate which throw if one of the operand is a derivation.
>
> with (import <nixpkgs/pkgs/lib>);
>
> let
>   noConflictUpdate = path: l: r:
>     if isDerivation l || isDerivation r then
>       throw "Cannot merge a derivation with anything else."
>     else
>        false;
>
>   pkgsMerge = groupOfPackages:
>     fix (pkgs: fold (recursiveUpdateUntil noConflictUpdate) {} groupOfPackages);
> in
>   pkgsMerge [
>     (import ./emacs.nix)
>     (import ./kde.nix)
>   ]
>
> Then we can extend this list with various index files either search at
> default locations, given as arguments or listed in an environment
> variable.

That sounds very extensible indeed.
Can this also be used to override certain attributes of other package
sets (like kde or emacs in your example) in such a way that other
(rec) attributes of the originating package set "see" it (like
__override gives us)?

Because I don't just want to add completely separate package sets, but
modify the behaviour of the "official" set as well.

As an example of this, I would like to be able to create a "video"
overlay, which just overrides a bunch of packages in nixpkgs to give
them more optional dependencies. Currently "packageOverrides" allows
this.

>
> [1] https://github.com/bluescreen303/nix-config/blob/master/bluepkgs/default.nix
> [2] https://github.com/bluescreen303/nix-config/blob/master/bluepkgs/extra.nix
>
> --
> Nicolas Pierron
> http://www.linkedin.com/in/nicolasbpierron - http://nbp.name/


More information about the nix-dev mailing list