lib/customisation.nix: format with nixfmt-rfc-style

This commit is contained in:
Yueh-Shun Li 2024-12-20 20:57:46 +08:00
parent 7071342c52
commit 8788c4bff9

View file

@ -2,19 +2,43 @@
let
inherit (builtins)
intersectAttrs;
intersectAttrs
;
inherit (lib)
functionArgs isFunction mirrorFunctionArgs isAttrs setFunctionArgs
optionalAttrs attrNames filter elemAt concatStringsSep sortOn take length
filterAttrs optionalString flip pathIsDirectory head pipe isDerivation listToAttrs
mapAttrs seq flatten deepSeq warnIf isInOldestRelease extends
functionArgs
isFunction
mirrorFunctionArgs
isAttrs
setFunctionArgs
optionalAttrs
attrNames
filter
elemAt
concatStringsSep
sortOn
take
length
filterAttrs
optionalString
flip
pathIsDirectory
head
pipe
isDerivation
listToAttrs
mapAttrs
seq
flatten
deepSeq
warnIf
isInOldestRelease
extends
;
inherit (lib.strings) levenshtein levenshteinAtMost;
in
rec {
/**
`overrideDerivation drv f` takes a derivation (i.e., the result
of a call to the builtin function `derivation`) and returns a new
@ -40,7 +64,6 @@ rec {
You should in general prefer `drv.overrideAttrs` over this function;
see the nixpkgs manual for more information on overriding.
# Inputs
`drv`
@ -74,20 +97,21 @@ rec {
:::
*/
overrideDerivation = drv: f:
overrideDerivation =
drv: f:
let
newDrv = derivation (drv.drvAttrs // (f drv));
in flip (extendDerivation (seq drv.drvPath true)) newDrv (
{ meta = drv.meta or {};
passthru = if drv ? passthru then drv.passthru else {};
in
flip (extendDerivation (seq drv.drvPath true)) newDrv (
{
meta = drv.meta or { };
passthru = if drv ? passthru then drv.passthru else { };
}
//
(drv.passthru or {})
//
optionalAttrs (drv ? __spliced) {
__spliced = {} // (mapAttrs (_: sDrv: overrideDerivation sDrv f) drv.__spliced);
});
// (drv.passthru or { })
// optionalAttrs (drv ? __spliced) {
__spliced = { } // (mapAttrs (_: sDrv: overrideDerivation sDrv f) drv.__spliced);
}
);
/**
`makeOverridable` takes a function from attribute set to attribute set and
@ -97,7 +121,6 @@ rec {
Please refer to documentation on [`<pkg>.overrideDerivation`](#sec-pkg-overrideDerivation) to learn about `overrideDerivation` and caveats
related to its use.
# Inputs
`f`
@ -128,37 +151,42 @@ rec {
:::
*/
makeOverridable = f:
makeOverridable =
f:
let
# Creates a functor with the same arguments as f
mirrorArgs = mirrorFunctionArgs f;
in
mirrorArgs (origArgs:
let
result = f origArgs;
mirrorArgs (
origArgs:
let
result = f origArgs;
# Changes the original arguments with (potentially a function that returns) a set of new attributes
overrideWith = newArgs: origArgs // (if isFunction newArgs then newArgs origArgs else newArgs);
# Changes the original arguments with (potentially a function that returns) a set of new attributes
overrideWith = newArgs: origArgs // (if isFunction newArgs then newArgs origArgs else newArgs);
# Re-call the function but with different arguments
overrideArgs = mirrorArgs (newArgs: makeOverridable f (overrideWith newArgs));
# Change the result of the function call by applying g to it
overrideResult = g: makeOverridable (mirrorArgs (args: g (f args))) origArgs;
in
# Re-call the function but with different arguments
overrideArgs = mirrorArgs (newArgs: makeOverridable f (overrideWith newArgs));
# Change the result of the function call by applying g to it
overrideResult = g: makeOverridable (mirrorArgs (args: g (f args))) origArgs;
in
if isAttrs result then
result // {
result
// {
override = overrideArgs;
overrideDerivation = fdrv: overrideResult (x: overrideDerivation x fdrv);
${if result ? overrideAttrs then "overrideAttrs" else null} = fdrv:
overrideResult (x: x.overrideAttrs fdrv);
${if result ? overrideAttrs then "overrideAttrs" else null} =
fdrv: overrideResult (x: x.overrideAttrs fdrv);
}
else if isFunction result then
# Transform the result into a functor while propagating its arguments
setFunctionArgs result (functionArgs result) // {
setFunctionArgs result (functionArgs result)
// {
override = overrideArgs;
}
else result);
else
result
);
/**
Call the package function in the file `fn` with the required
@ -188,7 +216,6 @@ rec {
<!-- TODO: Apply "Example:" tag to the examples above -->
# Inputs
`autoArgs`
@ -209,7 +236,8 @@ rec {
callPackageWith :: AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a
```
*/
callPackageWith = autoArgs: fn: args:
callPackageWith =
autoArgs: fn: args:
let
f = if isFunction fn then fn else import fn;
fargs = functionArgs f;
@ -222,59 +250,72 @@ rec {
# wouldn't be passed to it
missingArgs =
# Filter out arguments that have a default value
(filterAttrs (name: value: ! value)
# Filter out arguments that would be passed
(removeAttrs fargs (attrNames allArgs)));
(
filterAttrs (name: value: !value)
# Filter out arguments that would be passed
(removeAttrs fargs (attrNames allArgs))
);
# Get a list of suggested argument names for a given missing one
getSuggestions = arg: pipe (autoArgs // args) [
attrNames
# Only use ones that are at most 2 edits away. While mork would work,
# levenshteinAtMost is only fast for 2 or less.
(filter (levenshteinAtMost 2 arg))
# Put strings with shorter distance first
(sortOn (levenshtein arg))
# Only take the first couple results
(take 3)
# Quote all entries
(map (x: "\"" + x + "\""))
];
getSuggestions =
arg:
pipe (autoArgs // args) [
attrNames
# Only use ones that are at most 2 edits away. While mork would work,
# levenshteinAtMost is only fast for 2 or less.
(filter (levenshteinAtMost 2 arg))
# Put strings with shorter distance first
(sortOn (levenshtein arg))
# Only take the first couple results
(take 3)
# Quote all entries
(map (x: "\"" + x + "\""))
];
prettySuggestions = suggestions:
if suggestions == [] then ""
else if length suggestions == 1 then ", did you mean ${elemAt suggestions 0}?"
else ", did you mean ${concatStringsSep ", " (lib.init suggestions)} or ${lib.last suggestions}?";
prettySuggestions =
suggestions:
if suggestions == [ ] then
""
else if length suggestions == 1 then
", did you mean ${elemAt suggestions 0}?"
else
", did you mean ${concatStringsSep ", " (lib.init suggestions)} or ${lib.last suggestions}?";
errorForArg = arg:
errorForArg =
arg:
let
loc = builtins.unsafeGetAttrPos arg fargs;
# loc' can be removed once lib/minver.nix is >2.3.4, since that includes
# https://github.com/NixOS/nix/pull/3468 which makes loc be non-null
loc' = if loc != null then loc.file + ":" + toString loc.line
else if ! isFunction fn then
loc' =
if loc != null then
loc.file + ":" + toString loc.line
else if !isFunction fn then
toString fn + optionalString (pathIsDirectory fn) "/default.nix"
else "<unknown location>";
in "Function called without required argument \"${arg}\" at "
else
"<unknown location>";
in
"Function called without required argument \"${arg}\" at "
+ "${loc'}${prettySuggestions (getSuggestions arg)}";
# Only show the error for the first missing argument
error = errorForArg (head (attrNames missingArgs));
in if missingArgs == {}
then makeOverridable f allArgs
# This needs to be an abort so it can't be caught with `builtins.tryEval`,
# which is used by nix-env and ofborg to filter out packages that don't evaluate.
# This way we're forced to fix such errors in Nixpkgs,
# which is especially relevant with allowAliases = false
else abort "lib.customisation.callPackageWith: ${error}";
in
if missingArgs == { } then
makeOverridable f allArgs
# This needs to be an abort so it can't be caught with `builtins.tryEval`,
# which is used by nix-env and ofborg to filter out packages that don't evaluate.
# This way we're forced to fix such errors in Nixpkgs,
# which is especially relevant with allowAliases = false
else
abort "lib.customisation.callPackageWith: ${error}";
/**
Like callPackage, but for a function that returns an attribute
set of derivations. The override function is added to the
individual attributes.
# Inputs
`autoArgs`
@ -295,7 +336,8 @@ rec {
callPackagesWith :: AttrSet -> ((AttrSet -> AttrSet) | Path) -> AttrSet -> AttrSet
```
*/
callPackagesWith = autoArgs: fn: args:
callPackagesWith =
autoArgs: fn: args:
let
f = if isFunction fn then fn else import fn;
auto = intersectAttrs (functionArgs f) autoArgs;
@ -304,18 +346,19 @@ rec {
pkgs = f origArgs;
mkAttrOverridable = name: _: makeOverridable (mirrorArgs (newArgs: (f newArgs).${name})) origArgs;
in
if isDerivation pkgs then throw
("function `callPackages` was called on a *single* derivation "
+ ''"${pkgs.name or "<unknown-name>"}";''
+ " did you mean to use `callPackage` instead?")
else mapAttrs mkAttrOverridable pkgs;
if isDerivation pkgs then
throw (
"function `callPackages` was called on a *single* derivation "
+ ''"${pkgs.name or "<unknown-name>"}";''
+ " did you mean to use `callPackage` instead?"
)
else
mapAttrs mkAttrOverridable pkgs;
/**
Add attributes to each output of a derivation without changing
the derivation itself and check a given condition when evaluating.
# Inputs
`condition`
@ -336,34 +379,48 @@ rec {
extendDerivation :: Bool -> Any -> Derivation -> Derivation
```
*/
extendDerivation = condition: passthru: drv:
extendDerivation =
condition: passthru: drv:
let
outputs = drv.outputs or [ "out" ];
commonAttrs = drv // (listToAttrs outputsList) //
({ all = map (x: x.value) outputsList; }) // passthru;
commonAttrs =
drv // (listToAttrs outputsList) // ({ all = map (x: x.value) outputsList; }) // passthru;
outputToAttrListElement = outputName:
{ name = outputName;
value = commonAttrs // {
outputToAttrListElement = outputName: {
name = outputName;
value =
commonAttrs
// {
inherit (drv.${outputName}) type outputName;
outputSpecified = true;
drvPath = assert condition; drv.${outputName}.drvPath;
outPath = assert condition; drv.${outputName}.outPath;
} //
drvPath =
assert condition;
drv.${outputName}.drvPath;
outPath =
assert condition;
drv.${outputName}.outPath;
}
//
# TODO: give the derivation control over the outputs.
# `overrideAttrs` may not be the only attribute that needs
# updating when switching outputs.
optionalAttrs (passthru?overrideAttrs) {
optionalAttrs (passthru ? overrideAttrs) {
# TODO: also add overrideAttrs when overrideAttrs is not custom, e.g. when not splicing.
overrideAttrs = f: (passthru.overrideAttrs f).${outputName};
};
};
};
outputsList = map outputToAttrListElement outputs;
in commonAttrs // {
drvPath = assert condition; drv.drvPath;
outPath = assert condition; drv.outPath;
in
commonAttrs
// {
drvPath =
assert condition;
drv.drvPath;
outPath =
assert condition;
drv.outPath;
};
/**
@ -372,7 +429,6 @@ rec {
result to ensure that there are no thunks kept alive to prevent
garbage collection.
# Inputs
`drv`
@ -385,21 +441,29 @@ rec {
hydraJob :: (Derivation | Null) -> (Derivation | Null)
```
*/
hydraJob = drv:
hydraJob =
drv:
let
outputs = drv.outputs or ["out"];
outputs = drv.outputs or [ "out" ];
commonAttrs =
{ inherit (drv) name system meta; inherit outputs; }
{
inherit (drv) name system meta;
inherit outputs;
}
// optionalAttrs (drv._hydraAggregate or false) {
_hydraAggregate = true;
constituents = map hydraJob (flatten drv.constituents);
}
// (listToAttrs outputsList);
makeOutput = outputName:
let output = drv.${outputName}; in
{ name = outputName;
makeOutput =
outputName:
let
output = drv.${outputName};
in
{
name = outputName;
value = commonAttrs // {
outPath = output.outPath;
drvPath = output.drvPath;
@ -411,8 +475,8 @@ rec {
outputsList = map makeOutput outputs;
drv' = (head outputsList).value;
in if drv == null then null else
deepSeq drv' drv';
in
if drv == null then null else deepSeq drv' drv';
/**
Make an attribute set (a "scope") from functions that take arguments from that same attribute set.
@ -538,19 +602,21 @@ rec {
makeScope :: (AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a) -> (AttrSet -> AttrSet) -> scope
```
*/
makeScope = newScope: f:
let self = f self // {
newScope = scope: newScope (self // scope);
callPackage = self.newScope {};
overrideScope = g: makeScope newScope (extends g f);
packages = f;
};
in self;
makeScope =
newScope: f:
let
self = f self // {
newScope = scope: newScope (self // scope);
callPackage = self.newScope { };
overrideScope = g: makeScope newScope (extends g f);
packages = f;
};
in
self;
/**
backward compatibility with old uncurried form; deprecated
# Inputs
`splicePackages`
@ -579,9 +645,14 @@ rec {
*/
makeScopeWithSplicing =
splicePackages: newScope: otherSplices: keep: extra: f:
makeScopeWithSplicing'
{ inherit splicePackages newScope; }
{ inherit otherSplices keep extra f; };
makeScopeWithSplicing' { inherit splicePackages newScope; } {
inherit
otherSplices
keep
extra
f
;
};
/**
Like makeScope, but aims to support cross compilation. It's still ugly, but
@ -608,30 +679,32 @@ rec {
```
*/
makeScopeWithSplicing' =
{ splicePackages
, newScope
{
splicePackages,
newScope,
}:
{ otherSplices
# Attrs from `self` which won't be spliced.
# Avoid using keep, it's only used for a python hook workaround, added in PR #104201.
# ex: `keep = (self: { inherit (self) aAttr; })`
, keep ? (_self: {})
# Additional attrs to add to the sets `callPackage`.
# When the package is from a subset (but not a subset within a package IS #211340)
# within `spliced0` it will be spliced.
# When using an package outside the set but it's available from `pkgs`, use the package from `pkgs.__splicedPackages`.
# If the package is not available within the set or in `pkgs`, such as a package in a let binding, it will not be spliced
# ex:
# ```
# nix-repl> darwin.apple_sdk.frameworks.CoreFoundation
# «derivation ...CoreFoundation-11.0.0.drv»
# nix-repl> darwin.CoreFoundation
# error: attribute 'CoreFoundation' missing
# nix-repl> darwin.callPackage ({ CoreFoundation }: CoreFoundation) { }
# «derivation ...CoreFoundation-11.0.0.drv»
# ```
, extra ? (_spliced0: {})
, f
{
otherSplices,
# Attrs from `self` which won't be spliced.
# Avoid using keep, it's only used for a python hook workaround, added in PR #104201.
# ex: `keep = (self: { inherit (self) aAttr; })`
keep ? (_self: { }),
# Additional attrs to add to the sets `callPackage`.
# When the package is from a subset (but not a subset within a package IS #211340)
# within `spliced0` it will be spliced.
# When using an package outside the set but it's available from `pkgs`, use the package from `pkgs.__splicedPackages`.
# If the package is not available within the set or in `pkgs`, such as a package in a let binding, it will not be spliced
# ex:
# ```
# nix-repl> darwin.apple_sdk.frameworks.CoreFoundation
# «derivation ...CoreFoundation-11.0.0.drv»
# nix-repl> darwin.CoreFoundation
# error: attribute 'CoreFoundation' missing
# nix-repl> darwin.callPackage ({ CoreFoundation }: CoreFoundation) { }
# «derivation ...CoreFoundation-11.0.0.drv»
# ```
extra ? (_spliced0: { }),
f,
}:
let
spliced0 = splicePackages {
@ -648,13 +721,15 @@ rec {
callPackage = newScope spliced; # == self.newScope {};
# N.B. the other stages of the package set spliced in are *not*
# overridden.
overrideScope = g: (makeScopeWithSplicing'
{ inherit splicePackages newScope; }
{ inherit otherSplices keep extra;
overrideScope =
g:
(makeScopeWithSplicing' { inherit splicePackages newScope; } {
inherit otherSplices keep extra;
f = extends g f;
});
packages = f;
};
in self;
in
self;
}