diff --git a/pkgs/lib/misc.nix b/pkgs/lib/misc.nix index 39a3ad258b04f..43e34b0950d79 100644 --- a/pkgs/lib/misc.nix +++ b/pkgs/lib/misc.nix @@ -315,6 +315,48 @@ rec { ) ]; mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; }; + mergeAttrsByFuncDefaultsClean = list: removeAttrs (mergeAttrsByFuncDefaults list) ["mergeAttrBy"]; + + # merge attrs based on version key into mkDerivation args, see mergeAttrBy to learn about smart merge defaults + # + # This function is best explained by an example: + # + # {version ? "2.x"} : + # + # mkDerivation (mergeAttrsByVersion "package-name" version + # { # version specific settings + # "git" = { src = ..; preConfigre = "autogen.sh"; buildInputs = [automake autoconf libtool]; }; + # "2.x" = { src = ..; }; + # } + # { // shared settings + # buildInputs = [ common build inputs ]; + # meta = { .. } + # } + # ) + # + # Please note that e.g. Eelco Dolstra usually prefers having one file for + # each version. On the other hand there are valuable additional design goals + # - readability + # - do it once only + # - try to avoid duplication + # + # Marc Weber and Michael Raskin sometimes prefer keeping older + # versions around for testing and regression tests - as long as its cheap to + # do so. + # + # Very often it just happens that the "shared" code is the bigger part. + # Then using this function might be appropriate. + # + # Be aware that its easy to cause recompilations in all versions when using + # this function - also if derivations get too complex splitting into multiple + # files is the way to go. + # + # See misc.nix -> versionedDerivation + # discussion: nixpkgs: pull/310 + mergeAttrsByVersion = name: version: attrsByVersion: base: + mergeAttrsByFuncDefaultsClean [ { name = "${name}-${version}"; } base (maybeAttr version (throw "bad version ${version} for ${name}") attrsByVersion)]; + + # sane defaults (same name as attr name so that inherit can be used) mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; } listToAttrs (map (n : nameValuePair n lib.concat) [ "buildNativeInputs" "buildInputs" "propagatedBuildInputs" "configureFlags" "prePhases" "postAll" ]) diff --git a/pkgs/misc/misc.nix b/pkgs/misc/misc.nix index df4a0ce810233..87be974ca9693 100644 --- a/pkgs/misc/misc.nix +++ b/pkgs/misc/misc.nix @@ -6,6 +6,10 @@ in { + # description see mergeAttrsByVersion in lib/misc.nix + versionedDerivation = name: version: attrsByVersion: base: + pkgs.stdenv.mkDerivation (stdenv.lib.mergeAttrsByVersion name version attrsByVersion base); + /* Usage example creating a derivation installing ruby, sup and a lib: diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 8860d409c3675..2eb0ee1d12800 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -176,6 +176,7 @@ let inherit lib config stdenvAdapters; inherit (lib) lowPrio hiPrio appendToName makeOverridable; + inherit (misc) versionedDerivation; # Applying this to an attribute set will cause nix-env to look # inside the set for derivations.