diff --git a/lib/attrsets.nix b/lib/attrsets.nix index c0ac6eeb41bc..8bb4ef972fd8 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -1764,6 +1764,7 @@ rec { /** Get a package output. If no output is found, fallback to `.out` and then to the default. + The function is idempotent: `getOutput "b" (getOutput "a" p) == getOutput "a" p`. # Inputs @@ -1779,7 +1780,7 @@ rec { # Type ``` - getOutput :: String -> Derivation -> String + getOutput :: String -> :: Derivation -> Derivation ``` # Examples @@ -1787,7 +1788,7 @@ rec { ## `lib.attrsets.getOutput` usage example ```nix - getOutput "dev" pkgs.openssl + "${getOutput "dev" pkgs.openssl}" => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev" ``` @@ -1798,6 +1799,49 @@ rec { then pkg.${output} or pkg.out or pkg else pkg; + /** + Get the first of the `outputs` provided by the package, or the default. + This function is alligned with `_overrideFirst()` from the `multiple-outputs.sh` setup hook. + Like `getOutput`, the function is idempotent. + + # Inputs + + `outputs` + + : 1\. Function argument + + `pkg` + + : 2\. Function argument + + # Type + + ``` + getFirstOutput :: [String] -> Derivation -> Derivation + ``` + + # Examples + :::{.example} + ## `lib.attrsets.getFirstOutput` usage example + + ```nix + "${getFirstOutput [ "include" "dev" ] pkgs.openssl}" + => "/nix/store/00000000000000000000000000000000-openssl-1.0.1r-dev" + ``` + + ::: + */ + getFirstOutput = + candidates: pkg: + let + outputs = builtins.filter (name: hasAttr name pkg) candidates; + output = builtins.head outputs; + in + if pkg.outputSpecified or false || outputs == [ ] then + pkg + else + pkg.${output}; + /** Get a package's `bin` output. If the output does not exist, fallback to `.out` and then to the default. @@ -1811,7 +1855,7 @@ rec { # Type ``` - getBin :: Derivation -> String + getBin :: Derivation -> Derivation ``` # Examples @@ -1819,8 +1863,8 @@ rec { ## `lib.attrsets.getBin` usage example ```nix - getBin pkgs.openssl - => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r" + "${getBin pkgs.openssl}" + => "/nix/store/00000000000000000000000000000000-openssl-1.0.1r" ``` ::: @@ -1841,7 +1885,7 @@ rec { # Type ``` - getLib :: Derivation -> String + getLib :: Derivation -> Derivation ``` # Examples @@ -1849,7 +1893,7 @@ rec { ## `lib.attrsets.getLib` usage example ```nix - getLib pkgs.openssl + "${getLib pkgs.openssl}" => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib" ``` @@ -1857,6 +1901,35 @@ rec { */ getLib = getOutput "lib"; + /** + Get a package's `static` output. + If the output does not exist, fallback to `.lib`, then to `.out`, and then to the default. + + # Inputs + + `pkg` + + : The package whose `static` output will be retrieved. + + # Type + + ``` + getStatic :: Derivation -> Derivation + ``` + + # Examples + :::{.example} + ## `lib.attrsets.getStatic` usage example + + ```nix + "${lib.getStatic pkgs.glibc}" + => "/nix/store/00000000000000000000000000000000-glibc-2.39-52-static" + ``` + + ::: + */ + getStatic = getFirstOutput [ "static" "lib" "out" ]; + /** Get a package's `dev` output. @@ -1871,7 +1944,7 @@ rec { # Type ``` - getDev :: Derivation -> String + getDev :: Derivation -> Derivation ``` # Examples @@ -1879,7 +1952,7 @@ rec { ## `lib.attrsets.getDev` usage example ```nix - getDev pkgs.openssl + "${getDev pkgs.openssl}" => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev" ``` @@ -1887,6 +1960,35 @@ rec { */ getDev = getOutput "dev"; + /** + Get a package's `include` output. + If the output does not exist, fallback to `.dev`, then to `.out`, and then to the default. + + # Inputs + + `pkg` + + : The package whose `include` output will be retrieved. + + # Type + + ``` + getInclude :: Derivation -> Derivation + ``` + + # Examples + :::{.example} + ## `lib.attrsets.getInclude` usage example + + ```nix + "${getInclude pkgs.openssl}" + => "/nix/store/00000000000000000000000000000000-openssl-1.0.1r-dev" + ``` + + ::: + */ + getInclude = getFirstOutput [ "include" "dev" "out" ]; + /** Get a package's `man` output. @@ -1901,7 +2003,7 @@ rec { # Type ``` - getMan :: Derivation -> String + getMan :: Derivation -> Derivation ``` # Examples @@ -1909,7 +2011,7 @@ rec { ## `lib.attrsets.getMan` usage example ```nix - getMan pkgs.openssl + "${getMan pkgs.openssl}" => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man" ``` @@ -1929,7 +2031,7 @@ rec { # Type ``` - chooseDevOutputs :: [Derivation] -> [String] + chooseDevOutputs :: [Derivation] -> [Derivation] ``` */ chooseDevOutputs = builtins.map getDev; diff --git a/lib/default.nix b/lib/default.nix index 2605da47679e..ecf4fbb75339 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -86,8 +86,8 @@ let mapAttrs' mapAttrsToList attrsToList concatMapAttrs mapAttrsRecursive mapAttrsRecursiveCond genAttrs isDerivation toDerivation optionalAttrs zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil - recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput - getBin getLib getDev getMan chooseDevOutputs zipWithNames zip + recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput getFirstOutput + getBin getLib getStatic getDev getInclude getMan chooseDevOutputs zipWithNames zip recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets mapCartesianProduct updateManyAttrsByPath listToAttrs hasAttr getAttr isAttrs intersectAttrs removeAttrs; inherit (self.lists) singleton forEach map foldr fold foldl foldl' imap0 imap1