makeScope
lib.customisation.makeScope
Make an attribute set (a "scope") from functions that take arguments from that same attribute set. See for how to use it.
Inputs
-
newScope
(AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a
)A function that takes an attribute set
attrs
and returns what ends up ascallPackage
in the output.Typical values are
callPackageWith
or the output attributenewScope
. -
f
(AttrSet -> AttrSet
)A function that takes an attribute set as returned by
makeScope newScope f
(a "scope") and returns any attribute set.This function is used to compute the fixpoint of the resulting scope using
callPackage
. Its argument is the lazily evaluated reference to the value of that fixpoint, and is typically calledself
orfinal
.See for how to use it. See for details on fixpoint computation.
Output
makeScope
returns an attribute set of a form called scope
, which also contains the final attributes produced by f
:
scope :: {
callPackage :: ((AttrSet -> a) | Path) -> AttrSet -> a
newScope = AttrSet -> scope
overrideScope = (scope -> scope -> AttrSet) -> scope
packages :: AttrSet -> AttrSet
}
-
callPackage
(((AttrSet -> a) | Path) -> AttrSet -> a
)A function that
- Takes a function
p
, or a path to a Nix file that contains a functionp
, which takes an attribute set and returns value of arbitrary typea
, - Takes an attribute set
args
with explicit attributes to pass top
, - Calls
f
with attributes from the original attribute setattrs
passed tonewScope
updated withargs
, i.e.attrs // args
, if they match the attributes in the argument ofp
.
All such functions
p
will be called with the same value forattrs
. - Takes a function
-
newScope
(AttrSet -> scope
)Takes an attribute set
attrs
and returns a scope that extends the original scope. -
overrideScope
((scope -> scope -> AttrSet) -> scope
)Takes a function
g
of the formfinal: prev: { # attributes }
to act as an overlay onf
, and returns a new scope with values determined byextends g f
. See for details.This allows subsequent modification of the final attribute set in a consistent way, i.e. all functions
p
invoked withcallPackage
will be called with the modified values. -
packages
(AttrSet -> AttrSet
)The value of the argument
f
tomakeScope
. -
final attributes
The final values returned by
f
.
Examples
Create an interdependent package set on top of pkgs
The functions in foo.nix
and bar.nix
can depend on each other, in the sense that foo.nix
can contain a function that expects bar
as an attribute in its argument.
let
pkgs = import <nixpkgs> { };
in
pkgs.lib.makeScope pkgs.newScope (self: {
foo = self.callPackage ./foo.nix { };
bar = self.callPackage ./bar.nix { };
})
evaluates to
{
callPackage = «lambda»;
newScope = «lambda»;
overrideScope = «lambda»;
packages = «lambda»;
foo = «derivation»;
bar = «derivation»;
}
Using callPackage
from a scope
let
pkgs = import <nixpkgs> { };
inherit (pkgs) lib;
scope = lib.makeScope lib.callPackageWith (self: { a = 1; b = 2; });
three = scope.callPackage ({ a, b }: a + b) { };
four = scope.callPackage ({ a, b }: a + b) { a = 2; };
in
[ three four ]
evaluates to
[ 3 4 ]
Type
makeScope :: (AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a) -> (AttrSet -> AttrSet) -> scope
Noogle detected
Implementation
The following is the current implementation of this function.
makeScope =
newScope: f:
let
self = f self // {
newScope = scope: newScope (self // scope);
callPackage = self.newScope { };
overrideScope = g: makeScope newScope (extends g f);
packages = f;
};
in
self;