diff options
author | Charles Strahan <charles@cstrahan.com> | 2016-10-26 14:01:13 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-26 14:01:13 -0400 |
commit | ca2b03439f31dca0beee0d9b492dd18db78315cd (patch) | |
tree | 0e3a3830d1b797735f786c6ffce9c4e6ebe397e5 | |
parent | 6f1f1d86c1f6a82b44099d744cc52d150321e07e (diff) | |
parent | 3ca3b145ead9ce528b6b8cbf4db8e2a73a26bbe7 (diff) | |
download | nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.tar nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.tar.gz nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.tar.bz2 nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.tar.lz nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.tar.xz nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.tar.zst nixlib-ca2b03439f31dca0beee0d9b492dd18db78315cd.zip |
Merge pull request #19496 from Ericson2314/overridePackages
Make `overridePackages` extend rather than replace existing overrides
-rw-r--r-- | doc/functions.xml | 14 | ||||
-rw-r--r-- | lib/trivial.nix | 8 | ||||
-rw-r--r-- | pkgs/top-level/all-packages.nix | 14 | ||||
-rw-r--r-- | pkgs/top-level/default.nix | 111 |
4 files changed, 80 insertions, 67 deletions
diff --git a/doc/functions.xml b/doc/functions.xml index 908e9571ed69..e767d01d8431 100644 --- a/doc/functions.xml +++ b/doc/functions.xml @@ -52,6 +52,20 @@ in ...</programlisting> It's equivalent to <varname>pkgs</varname> in the above example. </para> + <para> + Note that in previous versions of nixpkgs, this method replaced any changes from <link + linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>, + along with that from previous calls if this function was called repeatedly. + Now those previous changes will be preserved so this function can be "chained" meaningfully. + To recover the old behavior, make sure <varname>config.packageOverrides<varname> is unset, + and call this only once off a "freshly" imported nixpkgs: + + <programlisting>let + pkgs = import <nixpkgs> { config: {}; }; + newpkgs = pkgs.overridePackages ...; +in ...</programlisting> + </para> + </section> <section xml:id="sec-pkg-override"> diff --git a/lib/trivial.nix b/lib/trivial.nix index dac8b8d0106d..39cbd67fba36 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -69,9 +69,13 @@ rec { # # nix-repl> obj # { __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; } - makeExtensible = rattrs: + makeExtensible = makeExtensibleWithCustomName "extend"; + + # Same as `makeExtensible` but the name of the extending attribute is + # customized. + makeExtensibleWithCustomName = extenderName: rattrs: fix' rattrs // { - extend = f: makeExtensible (extends f rattrs); + ${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs); }; # Flip the order of the arguments of a binary function. diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index abd76cf4a51b..61eb393552b6 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6,7 +6,6 @@ * Hint: ### starts category names. */ { system, bootStdenv, noSysDirs, config, crossSystem, platform, lib -, pkgsWithOverrides , ... }: self: pkgs: @@ -35,19 +34,6 @@ in newScope = extra: lib.callPackageWith (defaultScope // extra); - # Easily override this package set. - # Warning: this function is very expensive and must not be used - # from within the nixpkgs repository. - # - # Example: - # pkgs.overridePackages (self: super: { - # foo = super.foo.override { ... }; - # } - # - # The result is `pkgs' where all the derivations depending on `foo' - # will use the new version. - overridePackages = f: pkgsWithOverrides f; - # Override system. This is useful to build i686 packages on x86_64-linux. forceSystem = system: kernel: (import ../..) { inherit system; diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index 2eb7fb34b4d2..c54b23853c5d 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -61,6 +61,35 @@ let inherit system bootStdenv noSysDirs config crossSystem platform lib; }; + stdenvAdapters = self: super: + let res = import ../stdenv/adapters.nix self; in res // { + stdenvAdapters = res; + }; + + trivialBuilders = self: super: + (import ../build-support/trivial-builders.nix { + inherit lib; inherit (self) stdenv stdenvNoCC; inherit (self.xorg) lndir; + }); + + stdenvDefault = self: super: (import ./stdenv.nix topLevelArguments) {} pkgs; + + allPackages = self: super: + let res = import ./all-packages.nix topLevelArguments res self; + in res; + + aliases = self: super: import ./aliases.nix super; + + # stdenvOverrides is used to avoid circular dependencies for building + # the standard build environment. This mechanism uses the override + # mechanism to implement some staged compilation of the stdenv. + # + # We don't want stdenv overrides in the case of cross-building, or + # otherwise the basic overridden packages will not be built with the + # crossStdenv adapter. + stdenvOverrides = self: super: + lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides) + (super.stdenv.overrides super); + # Allow packages to be overridden globally via the `packageOverrides' # configuration option, which must be a function that takes `pkgs' # as an argument and returns a set of new or overridden packages. @@ -68,54 +97,34 @@ let # (un-overridden) set of packages, allowing packageOverrides # attributes to refer to the original attributes (e.g. "foo = # ... pkgs.foo ..."). - pkgs = pkgsWithOverrides (self: config.packageOverrides or (super: {})); - - # Return the complete set of packages, after applying the overrides - # returned by the `overrider' function (see above). Warning: this - # function is very expensive! - pkgsWithOverrides = overrider: - let - stdenvAdapters = self: super: - let res = import ../stdenv/adapters.nix self; in res // { - stdenvAdapters = res; - }; - - trivialBuilders = self: super: - (import ../build-support/trivial-builders.nix { - inherit lib; inherit (self) stdenv stdenvNoCC; inherit (self.xorg) lndir; - }); - - stdenvDefault = self: super: (import ./stdenv.nix topLevelArguments) {} pkgs; - - allPackagesArgs = topLevelArguments // { inherit pkgsWithOverrides; }; - allPackages = self: super: - let res = import ./all-packages.nix allPackagesArgs res self; - in res; - - aliases = self: super: import ./aliases.nix super; - - # stdenvOverrides is used to avoid circular dependencies for building - # the standard build environment. This mechanism uses the override - # mechanism to implement some staged compilation of the stdenv. - # - # We don't want stdenv overrides in the case of cross-building, or - # otherwise the basic overridden packages will not be built with the - # crossStdenv adapter. - stdenvOverrides = self: super: - lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides) - (super.stdenv.overrides super); - - customOverrides = self: super: - lib.optionalAttrs (bootStdenv == null) (overrider self super); - in - lib.fix' ( - lib.extends customOverrides ( - lib.extends stdenvOverrides ( - lib.extends aliases ( - lib.extends allPackages ( - lib.extends stdenvDefault ( - lib.extends trivialBuilders ( - lib.extends stdenvAdapters ( - self: {})))))))); -in - pkgs + configOverrides = self: super: + lib.optionalAttrs (bootStdenv == null) + ((config.packageOverrides or (super: {})) super); + + # The complete chain of package set builders, applied from top to bottom + toFix = lib.foldl' (lib.flip lib.extends) (self: {}) [ + stdenvAdapters + trivialBuilders + stdenvDefault + allPackages + aliases + stdenvOverrides + configOverrides + ]; + + # Use `overridePackages` to easily override this package set. + # Warning: this function is very expensive and must not be used + # from within the nixpkgs repository. + # + # Example: + # pkgs.overridePackages (self: super: { + # foo = super.foo.override { ... }; + # } + # + # The result is `pkgs' where all the derivations depending on `foo' + # will use the new version. + + # Return the complete set of packages. Warning: this function is very + # expensive! + pkgs = lib.makeExtensibleWithCustomName "overridePackages" toFix; +in pkgs |