Allow options with type "package" to be store paths

For example, this allows writing

nix.package = /nix/store/786mlvhd17xvcp2r4jmmay6jj4wj6b7f-nix-1.10pre4206_896428c;

Also, document types.package in the manual.

+30 -4
+10
lib/attrsets.nix
··· 221 isDerivation = x: isAttrs x && x ? type && x.type == "derivation"; 222 223 224 /* If the Boolean `cond' is true, return the attribute set `as', 225 otherwise an empty attribute set. */ 226 optionalAttrs = cond: as: if cond then as else {};
··· 221 isDerivation = x: isAttrs x && x ? type && x.type == "derivation"; 222 223 224 + /* Convert a store path to a fake derivation. */ 225 + toDerivation = path: 226 + let path' = builtins.storePath path; in 227 + { type = "derivation"; 228 + name = builtins.unsafeDiscardStringContext (builtins.substring 33 (-1) (baseNameOf path')); 229 + outPath = path'; 230 + outputs = [ "out" ]; 231 + }; 232 + 233 + 234 /* If the Boolean `cond' is true, return the attribute set `as', 235 otherwise an empty attribute set. */ 236 optionalAttrs = cond: as: if cond then as else {};
+5
lib/strings.nix
··· 218 219 # Format a number adding leading zeroes up to fixed width. 220 fixedWidthNumber = width: n: fixedWidthString width "0" (toString n); 221 }
··· 218 219 # Format a number adding leading zeroes up to fixed width. 220 fixedWidthNumber = width: n: fixedWidthString width "0" (toString n); 221 + 222 + 223 + # Check whether a value is a store path. 224 + isStorePath = x: builtins.substring 0 1 (toString x) == "/" && dirOf (builtins.toPath x) == builtins.storeDir; 225 + 226 }
+5 -3
lib/types.nix
··· 94 # derivation is a reserved keyword. 95 package = mkOptionType { 96 name = "derivation"; 97 - check = isDerivation; 98 - merge = mergeOneOption; 99 }; 100 101 path = mkOptionType { 102 name = "path"; 103 # Hacky: there is no ‘isPath’ primop. 104 - check = x: builtins.unsafeDiscardStringContext (builtins.substring 0 1 (toString x)) == "/"; 105 merge = mergeOneOption; 106 }; 107
··· 94 # derivation is a reserved keyword. 95 package = mkOptionType { 96 name = "derivation"; 97 + check = x: isDerivation x || isStorePath x; 98 + merge = loc: defs: 99 + let res = mergeOneOption loc defs; 100 + in if isDerivation res then res else toDerivation res; 101 }; 102 103 path = mkOptionType { 104 name = "path"; 105 # Hacky: there is no ‘isPath’ primop. 106 + check = x: builtins.substring 0 1 (toString x) == "/"; 107 merge = mergeOneOption; 108 }; 109
+10 -1
nixos/doc/manual/development/option-declarations.xml
··· 107 </varlistentry> 108 109 <varlistentry> 110 <term><varname>types.listOf</varname> <replaceable>t</replaceable></term> 111 <listitem> 112 <para>A list of elements of type <replaceable>t</replaceable> ··· 138 <varname>mkOptionType</varname>. See 139 <filename>lib/types.nix</filename> in Nixpkgs for details.</para> 140 141 - </section>
··· 107 </varlistentry> 108 109 <varlistentry> 110 + <term><varname>types.package</varname></term> 111 + <listitem> 112 + <para>A derivation (such as <literal>pkgs.hello</literal>) or a 113 + store path (such as 114 + <filename>/nix/store/1ifi1cfbfs5iajmvwgrbmrnrw3a147h9-hello-2.10</filename>).</para> 115 + </listitem> 116 + </varlistentry> 117 + 118 + <varlistentry> 119 <term><varname>types.listOf</varname> <replaceable>t</replaceable></term> 120 <listitem> 121 <para>A list of elements of type <replaceable>t</replaceable> ··· 147 <varname>mkOptionType</varname>. See 148 <filename>lib/types.nix</filename> in Nixpkgs for details.</para> 149 150 + </section>