haskell: preserve overrideScope on override
We want code such as `(pkg.override {}).overrideScope (self: super: {})` to work. This didn't work before, since `override` will call the original package again, and the attribute `overideScope`, which `callPackageWithScope` added, wasn't added again. The fix for this is to modify the package function itself to include the `callPackageWithScope` attribute, so it'll be re-added whenever the function is overriden for with arguments. There is a small problem here though: since callPackage uses some magic (`builtins.functionArgs`) to determine the auto-arguments of a function, we can't just write `callPackageWith scope drvScope`, since `builtins.functionArgs drvScope` will be `{}`. To fix this, we implement our own `callPackageWith`. Fixes https://github.com/NixOS/nixpkgs/issues/7953. Closes https://github.com/NixOS/nixpkgs/pull/9336.
This commit is contained in:
parent
9b74549c0b
commit
731e0fa742
@ -44,9 +44,23 @@ self: let
|
||||
|
||||
mkDerivation = makeOverridable mkDerivationImpl;
|
||||
|
||||
callPackageWithScope = scope: drv: args: (stdenv.lib.callPackageWith scope drv args) // {
|
||||
overrideScope = f: callPackageWithScope (mkScope (fix' (extends f scope.__unfix__))) drv args;
|
||||
};
|
||||
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;
|
||||
drvScope = allArgs: drv allArgs // {
|
||||
overrideScope = f:
|
||||
let newScope = mkScope (fix' (extends f scope.__unfix__));
|
||||
in callPackageWithScope newScope drv manualArgs;
|
||||
};
|
||||
in stdenv.lib.makeOverridable drvScope (auto // manualArgs);
|
||||
|
||||
mkScope = scope: pkgs // pkgs.xorg // pkgs.gnome2 // scope;
|
||||
defaultScope = mkScope self;
|
||||
|
Loading…
Reference in New Issue
Block a user