| 
									
										
										
										
											2008-12-20 01:20:35 +00:00
										 |  |  | {lib, pkgs} : | 
					
						
							|  |  |  | let inherit (lib) nv nvs; in | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-04-30 20:31:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # composableDerivation basically mixes these features: | 
					
						
							|  |  |  |   # - fix function | 
					
						
							|  |  |  |   # - mergeAttrBy | 
					
						
							|  |  |  |   # - provides shortcuts for "options" such as "--enable-foo" and adding | 
					
						
							|  |  |  |   #   buildInputs, see php example | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # It predates styles which are common today, such as | 
					
						
							|  |  |  |   #  * the config attr | 
					
						
							|  |  |  |   #  * mkDerivation.override feature | 
					
						
							|  |  |  |   #  * overrideDerivation (lib/customization.nix) | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # Some of the most more important usage examples (which could be rewritten if it was important): | 
					
						
							|  |  |  |   # * php | 
					
						
							|  |  |  |   # * postgis | 
					
						
							|  |  |  |   # * vim_configurable | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # A minimal example illustrating most features would look like this: | 
					
						
							|  |  |  |   # let base = composableDerivation { (fixed : let inherit (fixed.fixed) name in { | 
					
						
							|  |  |  |   #    src = fetchurl { | 
					
						
							|  |  |  |   #    } | 
					
						
							|  |  |  |   #    buildInputs = [A]; | 
					
						
							|  |  |  |   #    preConfigre = "echo ${name}"; | 
					
						
							|  |  |  |   #    # attention, "name" attr is missing, thus you cannot instantiate "base". | 
					
						
							|  |  |  |   # } | 
					
						
							|  |  |  |   # in { | 
					
						
							|  |  |  |   #  # These all add name attribute, thus you can instantiate those: | 
					
						
							|  |  |  |   #  v1 = base.merge   ({ name = "foo-add-B"; buildInputs = [B]; });       // B gets merged into buildInputs | 
					
						
							|  |  |  |   #  v2 = base.merge   ({ name = "mix-in-pre-configure-lines" preConfigre = ""; }); | 
					
						
							|  |  |  |   #  v3 = base.replace ({ name = "foo-no-A-only-B;" buildInputs = [B]; }); | 
					
						
							|  |  |  |   # } | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # So yes, you can think about it being something like nixos modules, and | 
					
						
							|  |  |  |   # you'd be merging "features" in one at a time using .merge or .replace | 
					
						
							|  |  |  |   # Thanks Shea for telling me that I rethink the documentation .. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # issues: | 
					
						
							|  |  |  |   # * its complicated to understand | 
					
						
							|  |  |  |   # * some "features" such as exact merge behaviour are burried in mergeAttrBy | 
					
						
							|  |  |  |   #   and defaultOverridableDelayableArgs assuming the default behaviour does | 
					
						
							|  |  |  |   #   the right thing in the common case | 
					
						
							|  |  |  |   # * Eelco once said using such fix style functions are slow to evaluate | 
					
						
							|  |  |  |   # * Too quick & dirty. Hard to understand for others. The benefit was that | 
					
						
							|  |  |  |   #   you were able to create a kernel builder like base derivation and replace | 
					
						
							|  |  |  |   #   / add patches the way you want without having to declare function arguments | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # nice features: | 
					
						
							|  |  |  |   # declaring "optional featuers" is modular. For instance: | 
					
						
							|  |  |  |   #   flags.curl = { | 
					
						
							| 
									
										
										
										
											2016-04-16 19:47:59 +03:00
										 |  |  |   #     configureFlags = ["--with-curl=${curl.dev}" "--with-curlwrappers"]; | 
					
						
							| 
									
										
										
										
											2014-04-30 20:31:40 +02:00
										 |  |  |   #     buildInputs = [curl openssl]; | 
					
						
							|  |  |  |   #   }; | 
					
						
							|  |  |  |   #   flags.other = { .. } | 
					
						
							|  |  |  |   # (Example taken from PHP) | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # alternative styles / related features: | 
					
						
							|  |  |  |   #  * Eg see function supporting building the kernel | 
					
						
							|  |  |  |   #  * versionedDerivation (discussion about this is still going on - or ended) | 
					
						
							|  |  |  |   #  * composedArgsAndFun | 
					
						
							|  |  |  |   #  * mkDerivation.override | 
					
						
							|  |  |  |   #  * overrideDerivation | 
					
						
							|  |  |  |   #  * using { .., *Support ? false }: like configurable options. | 
					
						
							|  |  |  |   # To find those examples use grep | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # To sum up: It exists for historical reasons - and for most commonly used | 
					
						
							|  |  |  |   # tasks the alternatives should be used | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # If you have questions about this code ping Marc Weber. | 
					
						
							| 
									
										
										
										
											2008-12-20 01:20:35 +00:00
										 |  |  |   composableDerivation = { | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:24 +00:00
										 |  |  |         mkDerivation ? pkgs.stdenv.mkDerivation, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # list of functions to be applied before defaultOverridableDelayableArgs removes removeAttrs names | 
					
						
							|  |  |  |         # prepareDerivationArgs handles derivation configurations | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:28 +00:00
										 |  |  |         applyPreTidy ? [ lib.prepareDerivationArgs ], | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:28 +00:00
										 |  |  |         # consider adding addtional elements by derivation.merge { removeAttrs = ["elem"]; }; | 
					
						
							| 
									
										
										
										
											2009-03-06 23:21:24 +00:00
										 |  |  |         removeAttrs ? ["cfg" "flags"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }: (lib.defaultOverridableDelayableArgs ( a: mkDerivation a)  | 
					
						
							|  |  |  |          { | 
					
						
							|  |  |  |            inherit applyPreTidy removeAttrs; | 
					
						
							|  |  |  |          }).merge; | 
					
						
							| 
									
										
										
										
											2008-12-20 01:20:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # some utility functions | 
					
						
							|  |  |  |   # use this function to generate flag attrs for prepareDerivationArgs | 
					
						
							|  |  |  |   # E nable  D isable F eature | 
					
						
							|  |  |  |   edf = {name, feat ? name, enable ? {}, disable ? {} , value ? ""}: | 
					
						
							|  |  |  |     nvs name { | 
					
						
							|  |  |  |     set = { | 
					
						
							|  |  |  |       configureFlags = ["--enable-${feat}${if value == "" then "" else "="}${value}"]; | 
					
						
							|  |  |  |     } // enable; | 
					
						
							|  |  |  |     unset = { | 
					
						
							|  |  |  |       configureFlags = ["--disable-${feat}"]; | 
					
						
							|  |  |  |     } // disable; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # same for --with and --without- | 
					
						
							|  |  |  |   # W ith or W ithout F eature | 
					
						
							|  |  |  |   wwf = {name, feat ? name, enable ? {}, disable ? {}, value ? ""}: | 
					
						
							|  |  |  |     nvs name { | 
					
						
							| 
									
										
										
										
											2010-06-03 15:19:59 +00:00
										 |  |  |     set = enable // { | 
					
						
							|  |  |  |       configureFlags = ["--with-${feat}${if value == "" then "" else "="}${value}"] | 
					
						
							|  |  |  |                        ++ lib.maybeAttr "configureFlags" [] enable; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     unset = disable // { | 
					
						
							|  |  |  |       configureFlags = ["--without-${feat}"] | 
					
						
							|  |  |  |                        ++ lib.maybeAttr "configureFlags" [] disable; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2008-12-20 01:20:35 +00:00
										 |  |  |   }; | 
					
						
							|  |  |  | } |