at 25.11-pre 11 kB view raw
1/** 2 Some functions for manipulating meta attributes, as well as the 3 name attribute. 4*/ 5 6{ lib }: 7 8let 9 inherit (lib) 10 matchAttrs 11 any 12 all 13 isDerivation 14 getBin 15 assertMsg 16 ; 17 inherit (lib.attrsets) mapAttrs' filterAttrs; 18 inherit (builtins) isString match typeOf; 19 20in 21rec { 22 23 /** 24 Add to or override the meta attributes of the given 25 derivation. 26 27 # Inputs 28 29 `newAttrs` 30 31 : 1\. Function argument 32 33 `drv` 34 35 : 2\. Function argument 36 37 # Examples 38 :::{.example} 39 ## `lib.meta.addMetaAttrs` usage example 40 41 ```nix 42 addMetaAttrs {description = "Bla blah";} somePkg 43 ``` 44 45 ::: 46 */ 47 addMetaAttrs = newAttrs: drv: drv // { meta = (drv.meta or { }) // newAttrs; }; 48 49 /** 50 Disable Hydra builds of given derivation. 51 52 # Inputs 53 54 `drv` 55 56 : 1\. Function argument 57 */ 58 dontDistribute = drv: addMetaAttrs { hydraPlatforms = [ ]; } drv; 59 60 /** 61 Change the [symbolic name of a derivation](https://nixos.org/manual/nix/stable/language/derivations.html#attr-name). 62 63 :::{.warning} 64 Dependent derivations will be rebuilt when the symbolic name is changed. 65 ::: 66 67 # Inputs 68 69 `name` 70 71 : 1\. Function argument 72 73 `drv` 74 75 : 2\. Function argument 76 */ 77 setName = name: drv: drv // { inherit name; }; 78 79 /** 80 Like `setName`, but takes the previous name as an argument. 81 82 # Inputs 83 84 `updater` 85 86 : 1\. Function argument 87 88 `drv` 89 90 : 2\. Function argument 91 92 # Examples 93 :::{.example} 94 ## `lib.meta.updateName` usage example 95 96 ```nix 97 updateName (oldName: oldName + "-experimental") somePkg 98 ``` 99 100 ::: 101 */ 102 updateName = updater: drv: drv // { name = updater (drv.name); }; 103 104 /** 105 Append a suffix to the name of a package (before the version 106 part). 107 108 # Inputs 109 110 `suffix` 111 112 : 1\. Function argument 113 */ 114 appendToName = 115 suffix: 116 updateName ( 117 name: 118 let 119 x = builtins.parseDrvName name; 120 in 121 "${x.name}-${suffix}-${x.version}" 122 ); 123 124 /** 125 Apply a function to each derivation and only to derivations in an attrset. 126 127 # Inputs 128 129 `f` 130 131 : 1\. Function argument 132 133 `set` 134 135 : 2\. Function argument 136 */ 137 mapDerivationAttrset = 138 f: set: lib.mapAttrs (name: pkg: if lib.isDerivation pkg then (f pkg) else pkg) set; 139 140 /** 141 The default priority of packages in Nix. See `defaultPriority` in [`src/nix/profile.cc`](https://github.com/NixOS/nix/blob/master/src/nix/profile.cc#L47). 142 */ 143 defaultPriority = 5; 144 145 /** 146 Set the nix-env priority of the package. Note that higher values are lower priority, and vice versa. 147 148 # Inputs 149 150 `priority` 151 : 1\. The priority to set. 152 153 `drv` 154 : 2\. Function argument 155 */ 156 setPrio = priority: addMetaAttrs { inherit priority; }; 157 158 /** 159 Decrease the nix-env priority of the package, i.e., other 160 versions/variants of the package will be preferred. 161 162 # Inputs 163 164 `drv` 165 166 : 1\. Function argument 167 */ 168 lowPrio = setPrio 10; 169 170 /** 171 Apply lowPrio to an attrset with derivations. 172 173 # Inputs 174 175 `set` 176 177 : 1\. Function argument 178 */ 179 lowPrioSet = set: mapDerivationAttrset lowPrio set; 180 181 /** 182 Increase the nix-env priority of the package, i.e., this 183 version/variant of the package will be preferred. 184 185 # Inputs 186 187 `drv` 188 189 : 1\. Function argument 190 */ 191 hiPrio = setPrio (-10); 192 193 /** 194 Apply hiPrio to an attrset with derivations. 195 196 # Inputs 197 198 `set` 199 200 : 1\. Function argument 201 */ 202 hiPrioSet = set: mapDerivationAttrset hiPrio set; 203 204 /** 205 Check to see if a platform is matched by the given `meta.platforms` 206 element. 207 208 A `meta.platform` pattern is either 209 210 1. (legacy) a system string. 211 212 2. (modern) a pattern for the entire platform structure (see `lib.systems.inspect.platformPatterns`). 213 214 3. (modern) a pattern for the platform `parsed` field (see `lib.systems.inspect.patterns`). 215 216 We can inject these into a pattern for the whole of a structured platform, 217 and then match that. 218 219 # Inputs 220 221 `platform` 222 223 : 1\. Function argument 224 225 `elem` 226 227 : 2\. Function argument 228 229 # Examples 230 :::{.example} 231 ## `lib.meta.platformMatch` usage example 232 233 ```nix 234 lib.meta.platformMatch { system = "aarch64-darwin"; } "aarch64-darwin" 235 => true 236 ``` 237 238 ::: 239 */ 240 platformMatch = 241 platform: elem: 242 ( 243 # Check with simple string comparison if elem was a string. 244 # 245 # The majority of comparisons done with this function will be against meta.platforms 246 # which contains a simple platform string. 247 # 248 # Avoiding an attrset allocation results in significant performance gains (~2-30) across the board in OfBorg 249 # because this is a hot path for nixpkgs. 250 if isString elem then 251 platform ? system && elem == platform.system 252 else 253 matchAttrs ( 254 # Normalize platform attrset. 255 if elem ? parsed then elem else { parsed = elem; } 256 ) platform 257 ); 258 259 /** 260 Check if a package is available on a given platform. 261 262 A package is available on a platform if both 263 264 1. One of `meta.platforms` pattern matches the given 265 platform, or `meta.platforms` is not present. 266 267 2. None of `meta.badPlatforms` pattern matches the given platform. 268 269 # Inputs 270 271 `platform` 272 273 : 1\. Function argument 274 275 `pkg` 276 277 : 2\. Function argument 278 279 # Examples 280 :::{.example} 281 ## `lib.meta.availableOn` usage example 282 283 ```nix 284 lib.meta.availableOn { system = "aarch64-darwin"; } pkg.zsh 285 => true 286 ``` 287 288 ::: 289 */ 290 availableOn = 291 platform: pkg: 292 pkg != null 293 && ((!pkg ? meta.platforms) || any (platformMatch platform) pkg.meta.platforms) 294 && all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or [ ]); 295 296 /** 297 Mapping of SPDX ID to the attributes in lib.licenses. 298 299 For SPDX IDs, see https://spdx.org/licenses. 300 Note that some SPDX licenses might be missing. 301 302 # Examples 303 :::{.example} 304 ## `lib.meta.licensesSpdx` usage example 305 306 ```nix 307 lib.licensesSpdx.MIT == lib.licenses.mit 308 => true 309 lib.licensesSpdx."MY LICENSE" 310 => error: attribute 'MY LICENSE' missing 311 ``` 312 313 ::: 314 */ 315 licensesSpdx = mapAttrs' (_key: license: { 316 name = license.spdxId; 317 value = license; 318 }) (filterAttrs (_key: license: license ? spdxId) lib.licenses); 319 320 /** 321 Get the corresponding attribute in lib.licenses from the SPDX ID 322 or warn and fallback to `{ shortName = <license string>; }`. 323 324 For SPDX IDs, see https://spdx.org/licenses. 325 Note that some SPDX licenses might be missing. 326 327 # Type 328 329 ``` 330 getLicenseFromSpdxId :: str -> AttrSet 331 ``` 332 333 # Examples 334 :::{.example} 335 ## `lib.meta.getLicenseFromSpdxId` usage example 336 337 ```nix 338 lib.getLicenseFromSpdxId "MIT" == lib.licenses.mit 339 => true 340 lib.getLicenseFromSpdxId "mIt" == lib.licenses.mit 341 => true 342 lib.getLicenseFromSpdxId "MY LICENSE" 343 => trace: warning: getLicenseFromSpdxId: No license matches the given SPDX ID: MY LICENSE 344 => { shortName = "MY LICENSE"; } 345 ``` 346 347 ::: 348 */ 349 getLicenseFromSpdxId = 350 licstr: 351 getLicenseFromSpdxIdOr licstr ( 352 lib.warn "getLicenseFromSpdxId: No license matches the given SPDX ID: ${licstr}" { 353 shortName = licstr; 354 } 355 ); 356 357 /** 358 Get the corresponding attribute in lib.licenses from the SPDX ID 359 or fallback to the given default value. 360 361 For SPDX IDs, see https://spdx.org/licenses. 362 Note that some SPDX licenses might be missing. 363 364 # Inputs 365 366 `licstr` 367 : 1\. SPDX ID string to find a matching license 368 369 `default` 370 : 2\. Fallback value when a match is not found 371 372 # Type 373 374 ``` 375 getLicenseFromSpdxIdOr :: str -> Any -> Any 376 ``` 377 378 # Examples 379 :::{.example} 380 ## `lib.meta.getLicenseFromSpdxIdOr` usage example 381 382 ```nix 383 lib.getLicenseFromSpdxIdOr "MIT" null == lib.licenses.mit 384 => true 385 lib.getLicenseFromSpdxId "mIt" null == lib.licenses.mit 386 => true 387 lib.getLicenseFromSpdxIdOr "MY LICENSE" lib.licenses.free == lib.licenses.free 388 => true 389 lib.getLicenseFromSpdxIdOr "MY LICENSE" null 390 => null 391 lib.getLicenseFromSpdxIdOr "MY LICENSE" (builtins.throw "No SPDX ID matches MY LICENSE") 392 => error: No SPDX ID matches MY LICENSE 393 ``` 394 ::: 395 */ 396 getLicenseFromSpdxIdOr = 397 let 398 lowercaseLicenses = lib.mapAttrs' (name: value: { 399 name = lib.toLower name; 400 inherit value; 401 }) licensesSpdx; 402 in 403 licstr: default: lowercaseLicenses.${lib.toLower licstr} or default; 404 405 /** 406 Get the path to the main program of a package based on meta.mainProgram 407 408 # Inputs 409 410 `x` 411 412 : 1\. Function argument 413 414 # Type 415 416 ``` 417 getExe :: package -> string 418 ``` 419 420 # Examples 421 :::{.example} 422 ## `lib.meta.getExe` usage example 423 424 ```nix 425 getExe pkgs.hello 426 => "/nix/store/g124820p9hlv4lj8qplzxw1c44dxaw1k-hello-2.12/bin/hello" 427 getExe pkgs.mustache-go 428 => "/nix/store/am9ml4f4ywvivxnkiaqwr0hyxka1xjsf-mustache-go-1.3.0/bin/mustache" 429 ``` 430 431 ::: 432 */ 433 getExe = 434 x: 435 getExe' x ( 436 x.meta.mainProgram or ( 437 # This could be turned into an error when 23.05 is at end of life 438 lib.warn 439 "getExe: Package ${ 440 lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name 441 } does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, use getExe' to specify the name to the program, such as lib.getExe' foo \"bar\"." 442 lib.getName 443 x 444 ) 445 ); 446 447 /** 448 Get the path of a program of a derivation. 449 450 # Inputs 451 452 `x` 453 454 : 1\. Function argument 455 456 `y` 457 458 : 2\. Function argument 459 460 # Type 461 462 ``` 463 getExe' :: derivation -> string -> string 464 ``` 465 466 # Examples 467 :::{.example} 468 ## `lib.meta.getExe'` usage example 469 470 ```nix 471 getExe' pkgs.hello "hello" 472 => "/nix/store/g124820p9hlv4lj8qplzxw1c44dxaw1k-hello-2.12/bin/hello" 473 getExe' pkgs.imagemagick "convert" 474 => "/nix/store/5rs48jamq7k6sal98ymj9l4k2bnwq515-imagemagick-7.1.1-15/bin/convert" 475 ``` 476 477 ::: 478 */ 479 getExe' = 480 x: y: 481 assert assertMsg (isDerivation x) 482 "lib.meta.getExe': The first argument is of type ${typeOf x}, but it should be a derivation instead."; 483 assert assertMsg (isString y) 484 "lib.meta.getExe': The second argument is of type ${typeOf y}, but it should be a string instead."; 485 assert assertMsg (match ".*/.*" y == null) 486 "lib.meta.getExe': The second argument \"${y}\" is a nested path with a \"/\" character, but it should just be the name of the executable instead."; 487 "${getBin x}/bin/${y}"; 488}