0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-13 21:50:33 +03:00

Revert "Merge branch 'improved-make-overridable' of git://github.com/ElvishJerricco/nixpkgs"

This reverts commit c3af1210b4, reversing
changes made to 49f175cd0c.
This commit is contained in:
Shea Levy 2017-09-29 09:11:26 -04:00
parent 8f33315f8f
commit 1a1ad1a17d
9 changed files with 113 additions and 206 deletions

View file

@ -50,50 +50,10 @@ rec {
}
else { }));
# A more powerful version of `makeOverridable` with features similar
# to `makeExtensibleWithInterface`.
makeOverridableWithInterface = interface: f: origArgs: let
addOverrideFuncs = {val, args, ...}: overridePackage:
(lib.optionalAttrs (builtins.isAttrs val) (val // {
extend = f: overridePackage (_: self: super: {
val = super.val // f self.val super.val;
});
overrideDerivation = newArgs: overridePackage (_: self: super: {
val = lib.overrideDerivation super.val newArgs;
});
${if val ? overrideAttrs then "overrideAttrs" else null} = fdrv:
overridePackage (_: self: super: {
val = super.val.overrideAttrs fdrv;
});
})) // (lib.optionalAttrs (builtins.isFunction val) {
__functor = _: val;
extend = throw "extend not yet supported for functors";
overrideDerivation = throw "overrideDerivation not yet supported for functors";
}) // {
inherit overridePackage;
override = newArgs: overridePackage (_: self: super: {
args = super.args //
(if builtins.isFunction newArgs then newArgs super.args else newArgs);
});
};
in lib.makeExtensibleWithInterface (x: o: interface (addOverrideFuncs x o) o) (output: self: {
args = origArgs;
val = f output self.args self.val;
});
/* `makeOverridable` takes a function from attribute set to
attribute set and injects 4 attributes which can be used to
override arguments and return values of the function.
1. `override` allows you to change what arguments were passed to
the function and acquire the new result.
/* `makeOverridable` takes a function from attribute set to attribute set and
injects `override` attibute which can be used to override arguments of
the function.
nix-repl> x = {a, b}: { result = a + b; }
@ -105,75 +65,28 @@ rec {
nix-repl> y.override { a = 10; }
{ override = «lambda»; overrideDerivation = «lambda»; result = 12; }
2. `extend` changes the results of the function, giving you a
view of the original result and a view of the eventual final
result. It is meant to do the same thing as
`makeExtensible`. That is, it lets you add to or change the
return value, such that previous extensions are consistent with
the final view, rather than being based on outdated
values. "Outdated" values come from the `super` argument, which
must be used when you are attempting to modify and old value. And
the final values come from the `self` argument, which recursively
refers to what all extensions combined return.
nix-repl> obj = makeOverridable (args: { }) { }
nix-repl> obj = obj.extend (self: super: { foo = "foo"; })
nix-repl> obj.foo
"foo"
nix-repl> obj = obj.extend (self: super: { foo = super.foo + " + "; bar = "bar"; foobar = self.foo + self.bar; })
nix-repl> obj
{ bar = "bar"; foo = "foo + "; foobar = "foo + bar"; ... } # Excess omitted
3. `overrideDerivation`: Please refer to "Nixpkgs Contributors
Guide" section "<pkg>.overrideDerivation" to learn about
`overrideDerivation` and caveats related to its use.
4. `overridePackage` is by far the most powerful of the four, as
it exposes a deeper structure. It provides `self` and `super`
views of both the arguments and return value of the function,
allowing you to change both in one override; you can even have
overrides for one based on overrides for the other. It also
provides the `output` view, which is the view of `self` after
passing it through the `makeOverridable` interface and adding all
the `overrideX` functions. `output` is necessary when your
overrides depend on the overridable structure of `output`.
nix-repl> obj = makeOverridable ({a, b}: {inherit a b;}) {a = 1; b = 3;}
nix-repl> obj = obj.overridePackage (output: self: super: { args = super.args // {b = self.val.a;}; })
nix-repl> obj.b
1
nix-repl> obj = obj.overridePackage (output: self: super: { val = super.val // {a = self.args.a + 10;}; })
nix-repl> obj.b
11
Please refer to "Nixpkgs Contributors Guide" section
"<pkg>.overrideDerivation" to learn about `overrideDerivation` and caveats
related to its use.
*/
makeOverridable = fn: makeOverridableWithInterface (x: _: x) (_: args: _: fn args);
callPackageCommon = functionArgs: scope: f: args:
makeOverridable = f: origArgs:
let
intersect = builtins.intersectAttrs functionArgs;
interface = val: overridePackage: val // {
overrideScope = newScope: overridePackage (_: self: super: {
scope = super.scope.extend newScope;
});
};
in (makeOverridableWithInterface interface f (intersect scope // args))
.overridePackage (output: self: super: {
inherit scope;
# Don't use super.args because that contains the original scope.
args = intersect self.scope // args;
});
ff = f origArgs;
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
in
if builtins.isAttrs ff then (ff // {
override = newArgs: makeOverridable f (overrideWith newArgs);
overrideDerivation = fdrv:
makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
})
else if builtins.isFunction ff then {
override = newArgs: makeOverridable f (overrideWith newArgs);
__functor = self: ff;
overrideDerivation = throw "overrideDerivation not yet supported for functors";
}
else ff;
/* Call the package function in the file `fn' with the required
@ -196,35 +109,12 @@ rec {
libfoo = null;
enableX11 = true;
};
On top of the additions from `makeOverridable`, an `overrideScope`
function is also added to the result. It is similar to `override`,
except that it provides `self` and `super` views to the
scope. This can't be done in `makeOverridable` because the scope
is filtered to just the arguments needed by the function before
entering `makeOverridable`. It is useful to have a view of the
scope before restriction; for example, to change versions for a
particular dependency.
foo.overrideScope (self: super: {
llvm = self.llvm_37;
})
`llvm_37` would not exist in the scope after restriction.
*/
callPackageWith = autoArgs: fn: args:
let f = if builtins.isFunction fn then fn else import fn;
in callPackageCommon (builtins.functionArgs f) autoArgs (output: x: _: f x) args;
# Like `callPackageWith`, but provides the function with a `self`
# view of the output, which has the override functions
# injected. `fn` is called with the new output whenever an override
# or extension is added.
callPackageWithOutputWith = autoArgs: fn: args:
let f = if builtins.isFunction fn then fn else import fn;
in callPackageCommon (builtins.functionArgs f) autoArgs (output: args: _: f args output ) args;
let
f = if builtins.isFunction fn then fn else import fn;
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
in makeOverridable f (auto // args);
/* Like callPackage, but for a function that returns an attribute