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 { })); else { }));
# A more powerful version of `makeOverridable` with features similar
# to `makeExtensibleWithInterface`.
makeOverridableWithInterface = interface: f: origArgs: let
addOverrideFuncs = {val, args, ...}: overridePackage: /* `makeOverridable` takes a function from attribute set to attribute set and
(lib.optionalAttrs (builtins.isAttrs val) (val // { injects `override` attibute which can be used to override arguments of
extend = f: overridePackage (_: self: super: { the function.
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.
nix-repl> x = {a, b}: { result = a + b; } nix-repl> x = {a, b}: { result = a + b; }
@ -105,75 +65,28 @@ rec {
nix-repl> y.override { a = 10; } nix-repl> y.override { a = 10; }
{ override = «lambda»; overrideDerivation = «lambda»; result = 12; } { override = «lambda»; overrideDerivation = «lambda»; result = 12; }
Please refer to "Nixpkgs Contributors Guide" section
2. `extend` changes the results of the function, giving you a "<pkg>.overrideDerivation" to learn about `overrideDerivation` and caveats
view of the original result and a view of the eventual final related to its use.
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
*/ */
makeOverridable = fn: makeOverridableWithInterface (x: _: x) (_: args: _: fn args); makeOverridable = f: origArgs:
callPackageCommon = functionArgs: scope: f: args:
let let
intersect = builtins.intersectAttrs functionArgs; ff = f origArgs;
interface = val: overridePackage: val // { overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
overrideScope = newScope: overridePackage (_: self: super: { in
scope = super.scope.extend newScope; if builtins.isAttrs ff then (ff // {
}); override = newArgs: makeOverridable f (overrideWith newArgs);
}; overrideDerivation = fdrv:
in (makeOverridableWithInterface interface f (intersect scope // args)) makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
.overridePackage (output: self: super: { ${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
inherit scope; makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
# Don't use super.args because that contains the original scope. })
args = intersect self.scope // args; 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 /* Call the package function in the file `fn' with the required
@ -196,35 +109,12 @@ rec {
libfoo = null; libfoo = null;
enableX11 = true; 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: callPackageWith = autoArgs: fn: args:
let f = if builtins.isFunction fn then fn else import fn; let
in callPackageCommon (builtins.functionArgs f) autoArgs (output: x: _: f x) args; f = if builtins.isFunction fn then fn else import fn;
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
in makeOverridable f (auto // 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;
/* Like callPackage, but for a function that returns an attribute /* Like callPackage, but for a function that returns an attribute

View File

@ -72,34 +72,8 @@ rec {
# Same as `makeExtensible` but the name of the extending attribute is # Same as `makeExtensible` but the name of the extending attribute is
# customized. # customized.
makeExtensibleWithCustomName = extenderName: f: makeExtensibleWithInterface makeExtensibleWithCustomName = extenderName: rattrs:
(fixedPoint: extend: fixedPoint // { ${extenderName} = ext: extend (_: ext); }) fix' rattrs // {
(_: f); ${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs);
};
# A version of `makeExtensible` that allows the function being fixed
# to return a different interface than the interface returned to the
# user. Along with `self` and `super` views of the internal
# interface, a `self` view of the output interface is also
# provided. `extend` is not added to the output by default. This is
# the job of the interface.
#
# nix-repl> foo = {a, b}: {c = a + b;}
#
# nix-repl> interface = {args, val, ...}: extend: val // {inherit extend;}
#
# nix-repl> obj = makeExtensibleWithInterface interface (output: self: { args = {a = 1; b = 2;}; val = foo self.args; })
#
# nix-repl> obj.c
# 3
#
# nix-repl> obj = obj.extend (output: self: super: { args = super.args // { b = output.d; }; })
#
# nix-repl> obj = obj.extend (output: self: super: { val = super.val // { d = 10; }; })
#
# nix-repl> { inherit (obj) c d; }
# { c = 11; d = 10; }
makeExtensibleWithInterface = interface: f: let i = interface
(fix' (f i))
(fext: makeExtensibleWithInterface interface (i': (extends (fext i') (f i'))));
in i;
} }

View File

@ -5,9 +5,14 @@ let
lib = pkgs.callPackage ./lib.nix {}; lib = pkgs.callPackage ./lib.nix {};
# FIXME: add support for overrideScope
callPackageWithScope = scope: drv: args: stdenv.lib.callPackageWith scope drv args;
mkScope = scope: pkgs // scope;
packages = self: packages = self:
let let
callPackage = stdenv.lib.callPackageWith (pkgs // self); defaultScope = mkScope self;
callPackage = drv: args: callPackageWithScope defaultScope drv args;
in in
import ./hex-packages.nix { import ./hex-packages.nix {
inherit pkgs stdenv callPackage; inherit pkgs stdenv callPackage;

View File

@ -7,8 +7,6 @@
, configurationNix ? import ./configuration-nix.nix , configurationNix ? import ./configuration-nix.nix
}: }:
self: # Provided by `callPackageWithOutput`
let let
inherit (lib) extends makeExtensible; inherit (lib) extends makeExtensible;
@ -16,15 +14,19 @@ let
haskellPackages = pkgs.callPackage makePackageSet { haskellPackages = pkgs.callPackage makePackageSet {
package-set = initialPackages; package-set = initialPackages;
extensible-self = self; inherit stdenv haskellLib ghc extensible-self;
inherit stdenv haskellLib ghc;
}; };
commonConfiguration = configurationCommon { inherit pkgs haskellLib; }; commonConfiguration = configurationCommon { inherit pkgs haskellLib; };
nixConfiguration = configurationNix { inherit pkgs haskellLib; }; nixConfiguration = configurationNix { inherit pkgs haskellLib; };
in (extends overrides extensible-self = makeExtensible
(extends packageSetConfig (extends overrides
(extends compilerConfig (extends packageSetConfig
(extends commonConfiguration (extends compilerConfig
(extends nixConfiguration haskellPackages))))) self (extends commonConfiguration
(extends nixConfiguration haskellPackages)))));
in
extensible-self

View File

@ -29,7 +29,7 @@ self:
let let
inherit (stdenv.lib) fix' extends makeOverridable callPackageWith; inherit (stdenv.lib) fix' extends makeOverridable;
inherit (haskellLib) overrideCabal; inherit (haskellLib) overrideCabal;
mkDerivationImpl = pkgs.callPackage ./generic-builder.nix { mkDerivationImpl = pkgs.callPackage ./generic-builder.nix {
@ -61,9 +61,39 @@ let
mkDerivation = makeOverridable mkDerivationImpl; mkDerivation = makeOverridable mkDerivationImpl;
# manualArgs are the arguments that were explictly passed to `callPackage`, like:
#
# callPackage foo { bar = null; };
#
# here `bar` is a manual argument.
callPackageWithScope = scope: fn: manualArgs:
let
# this code is copied from callPackage in lib/customisation.nix
#
# we cannot use `callPackage` here because we want to call `makeOverridable`
# on `drvScope` (we cannot add `overrideScope` after calling `callPackage` because then it is
# lost on `.override`) but determine the auto-args based on `drv` (the problem here
# is that nix has no way to "passthrough" args while preserving the reflection
# info that callPackage uses to determine the arguments).
drv = if builtins.isFunction fn then fn else import fn;
auto = builtins.intersectAttrs (builtins.functionArgs drv) scope;
# this wraps the `drv` function to add a `overrideScope` function to the result.
drvScope = allArgs: drv allArgs // {
overrideScope = f:
let newScope = mkScope (fix' (extends f scope.__unfix__));
# note that we have to be careful here: `allArgs` includes the auto-arguments that
# weren't manually specified. If we would just pass `allArgs` to the recursive call here,
# then we wouldn't look up any packages in the scope in the next interation, because it
# appears as if all arguments were already manually passed, so the scope change would do
# nothing.
in callPackageWithScope newScope drv manualArgs;
};
in stdenv.lib.makeOverridable drvScope (auto // manualArgs);
mkScope = scope: pkgs // pkgs.xorg // pkgs.gnome2 // { inherit stdenv; } // scope; mkScope = scope: pkgs // pkgs.xorg // pkgs.gnome2 // { inherit stdenv; } // scope;
defaultScope = mkScope self; defaultScope = mkScope self;
callPackage = drv: args: callPackageWith defaultScope drv args; callPackage = drv: args: callPackageWithScope defaultScope drv args;
withPackages = packages: callPackage ./with-packages-wrapper.nix { withPackages = packages: callPackage ./with-packages-wrapper.nix {
inherit (self) llvmPackages; inherit (self) llvmPackages;

View File

@ -1,8 +1,17 @@
{ pkgs, idris, overrides ? (self: super: {}) }: let { pkgs, idris, overrides ? (self: super: {}) }: let
inherit (pkgs.lib) callPackageWith fix' extends; inherit (pkgs.lib) callPackageWith fix' extends;
/* Taken from haskell-modules/default.nix, should probably abstract this away */
callPackageWithScope = scope: drv: args: (callPackageWith scope drv args) // {
overrideScope = f: callPackageWithScope (mkScope (fix' (extends f scope.__unfix__))) drv args;
};
mkScope = scope : pkgs // pkgs.xorg // pkgs.gnome2 // scope;
idrisPackages = self: let idrisPackages = self: let
callPackage = callPackageWith (pkgs // pkgs.xorg // pkgs.gnome2 // self); defaultScope = mkScope self;
callPackage = callPackageWithScope defaultScope;
builtins_ = pkgs.lib.mapAttrs self.build-builtin-package { builtins_ = pkgs.lib.mapAttrs self.build-builtin-package {
prelude = []; prelude = [];

View File

@ -5710,7 +5710,9 @@ with pkgs;
haskell = callPackage ./haskell-packages.nix { }; haskell = callPackage ./haskell-packages.nix { };
haskellPackages = haskell.packages.ghc802.extend (config.haskellPackageOverrides or (self: super: {})); haskellPackages = haskell.packages.ghc802.override {
overrides = config.haskellPackageOverrides or (self: super: {});
};
inherit (haskellPackages) ghc; inherit (haskellPackages) ghc;

View File

@ -1,4 +1,4 @@
{ pkgs, lib, stdenv, buildPlatform, targetPlatform }: { pkgs, lib, newScope, stdenv, buildPlatform, targetPlatform }:
let let
# These are attributes in compiler and packages that don't support integer-simple. # These are attributes in compiler and packages that don't support integer-simple.
@ -23,8 +23,7 @@ let
inherit pkgs; inherit pkgs;
}; };
callPackage = lib.callPackageWith (pkgs // { inherit haskellLib; }); callPackage = newScope { inherit haskellLib; };
callPackageWithOutput = lib.callPackageWithOutputWith (pkgs // { inherit haskellLib; });
in rec { in rec {
lib = haskellLib; lib = haskellLib;
@ -122,75 +121,75 @@ in rec {
packages = { packages = {
# Support for this compiler is broken, because it can't deal with directory-based package databases. # Support for this compiler is broken, because it can't deal with directory-based package databases.
# ghc6104 = callPackageWithOutput ../development/haskell-modules { ghc = compiler.ghc6104; }; # ghc6104 = callPackage ../development/haskell-modules { ghc = compiler.ghc6104; };
ghc6123 = callPackageWithOutput ../development/haskell-modules { ghc6123 = callPackage ../development/haskell-modules {
ghc = compiler.ghc6123; ghc = compiler.ghc6123;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-6.12.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-6.12.x.nix { };
}; };
ghc704 = callPackageWithOutput ../development/haskell-modules { ghc704 = callPackage ../development/haskell-modules {
ghc = compiler.ghc704; ghc = compiler.ghc704;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.0.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.0.x.nix { };
}; };
ghc722 = callPackageWithOutput ../development/haskell-modules { ghc722 = callPackage ../development/haskell-modules {
ghc = compiler.ghc722; ghc = compiler.ghc722;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.2.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.2.x.nix { };
}; };
ghc742 = callPackageWithOutput ../development/haskell-modules { ghc742 = callPackage ../development/haskell-modules {
ghc = compiler.ghc742; ghc = compiler.ghc742;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.4.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.4.x.nix { };
}; };
ghc763 = callPackageWithOutput ../development/haskell-modules { ghc763 = callPackage ../development/haskell-modules {
ghc = compiler.ghc763; ghc = compiler.ghc763;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.6.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.6.x.nix { };
}; };
ghc783 = callPackageWithOutput ../development/haskell-modules { ghc783 = callPackage ../development/haskell-modules {
ghc = compiler.ghc783; ghc = compiler.ghc783;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.8.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.8.x.nix { };
}; };
ghc784 = callPackageWithOutput ../development/haskell-modules { ghc784 = callPackage ../development/haskell-modules {
ghc = compiler.ghc784; ghc = compiler.ghc784;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.8.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.8.x.nix { };
}; };
ghc7102 = callPackageWithOutput ../development/haskell-modules { ghc7102 = callPackage ../development/haskell-modules {
ghc = compiler.ghc7102; ghc = compiler.ghc7102;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.10.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.10.x.nix { };
}; };
ghc7103 = callPackageWithOutput ../development/haskell-modules { ghc7103 = callPackage ../development/haskell-modules {
ghc = compiler.ghc7103; ghc = compiler.ghc7103;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.10.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.10.x.nix { };
}; };
ghc802 = callPackageWithOutput ../development/haskell-modules { ghc802 = callPackage ../development/haskell-modules {
ghc = compiler.ghc802; ghc = compiler.ghc802;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.0.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.0.x.nix { };
}; };
ghc821 = callPackageWithOutput ../development/haskell-modules { ghc821 = callPackage ../development/haskell-modules {
ghc = compiler.ghc821; ghc = compiler.ghc821;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.2.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.2.x.nix { };
}; };
ghcHEAD = callPackageWithOutput ../development/haskell-modules { ghcHEAD = callPackage ../development/haskell-modules {
ghc = compiler.ghcHEAD; ghc = compiler.ghcHEAD;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-head.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-head.nix { };
}; };
# TODO Support for multiple variants here # TODO Support for multiple variants here
ghcCross = callPackageWithOutput ../development/haskell-modules { ghcCross = callPackage ../development/haskell-modules {
ghc = compiler.ghcHEAD.crossCompiler; ghc = compiler.ghcHEAD.crossCompiler;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-head.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-head.nix { };
}; };
ghcCross821 = callPackageWithOutput ../development/haskell-modules { ghcCross821 = callPackage ../development/haskell-modules {
ghc = compiler.ghc821.crossCompiler; ghc = compiler.ghc821.crossCompiler;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.2.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.2.x.nix { };
}; };
ghcjs = callPackageWithOutput ../development/haskell-modules { ghcjs = callPackage ../development/haskell-modules {
ghc = compiler.ghcjs; ghc = compiler.ghcjs;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.10.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-7.10.x.nix { };
packageSetConfig = callPackage ../development/haskell-modules/configuration-ghcjs.nix { }; packageSetConfig = callPackage ../development/haskell-modules/configuration-ghcjs.nix { };
}; };
ghcjsHEAD = callPackageWithOutput ../development/haskell-modules { ghcjsHEAD = callPackage ../development/haskell-modules {
ghc = compiler.ghcjsHEAD; ghc = compiler.ghcjsHEAD;
compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.0.x.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-8.0.x.nix { };
packageSetConfig = callPackage ../development/haskell-modules/configuration-ghcjs.nix { }; packageSetConfig = callPackage ../development/haskell-modules/configuration-ghcjs.nix { };
}; };
ghcHaLVM240 = callPackageWithOutput ../development/haskell-modules { ghcHaLVM240 = callPackage ../development/haskell-modules {
ghc = compiler.ghcHaLVM240; ghc = compiler.ghcHaLVM240;
compilerConfig = callPackage ../development/haskell-modules/configuration-halvm-2.4.0.nix { }; compilerConfig = callPackage ../development/haskell-modules/configuration-halvm-2.4.0.nix { };
}; };

View File

@ -80,11 +80,7 @@ in
# `newScope' for sets of packages in `pkgs' (see e.g. `gnome' below). # `newScope' for sets of packages in `pkgs' (see e.g. `gnome' below).
callPackage = pkgs.newScope {}; callPackage = pkgs.newScope {};
callPackageWithOutput = pkgs.newScopeWithOutput {};
callPackages = lib.callPackagesWith splicedPackages; callPackages = lib.callPackagesWith splicedPackages;
newScope = extra: lib.callPackageWith (splicedPackages // extra); newScope = extra: lib.callPackageWith (splicedPackages // extra);
newScopeWithOutput = extra: lib.callPackageWithOutputWith (splicedPackages // extra);
} }