diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-03-01 11:40:12 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-03-01 11:40:12 +0100 |
commit | bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86 (patch) | |
tree | 8eb035cbab19794f6415cc460fac7226f7a58afc /nixpkgs/lib | |
parent | 66f707d69f1e423db5a35c2fe43b32781125a9af (diff) | |
parent | 09c1497ce5d4ed4a0edfdd44450d3048074cb300 (diff) | |
download | nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.gz nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.bz2 nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.lz nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.xz nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.tar.zst nixlib-bf6d657e5dbcb5e39fda280ef7e86b2a7794ca86.zip |
Merge branch 'nixos-unstable-small' of https://github.com/NixOS/nixpkgs
Diffstat (limited to 'nixpkgs/lib')
-rw-r--r-- | nixpkgs/lib/attrsets.nix | 15 | ||||
-rw-r--r-- | nixpkgs/lib/default.nix | 4 | ||||
-rw-r--r-- | nixpkgs/lib/fileset/default.nix | 37 | ||||
-rw-r--r-- | nixpkgs/lib/fileset/internal.nix | 23 | ||||
-rwxr-xr-x | nixpkgs/lib/fileset/tests.sh | 124 | ||||
-rw-r--r-- | nixpkgs/lib/fixed-points.nix | 13 | ||||
-rw-r--r-- | nixpkgs/lib/lists.nix | 31 | ||||
-rw-r--r-- | nixpkgs/lib/meta.nix | 8 | ||||
-rw-r--r-- | nixpkgs/lib/strings.nix | 3 | ||||
-rw-r--r-- | nixpkgs/lib/tests/release.nix | 55 | ||||
-rw-r--r-- | nixpkgs/lib/tests/test-with-nix.nix | 70 | ||||
-rw-r--r-- | nixpkgs/lib/trivial.nix | 19 | ||||
-rw-r--r-- | nixpkgs/lib/versions.nix | 2 | ||||
-rw-r--r-- | nixpkgs/lib/zip-int-bits.nix | 39 |
14 files changed, 236 insertions, 207 deletions
diff --git a/nixpkgs/lib/attrsets.nix b/nixpkgs/lib/attrsets.nix index 0e896a93156d..4f7d795c397f 100644 --- a/nixpkgs/lib/attrsets.nix +++ b/nixpkgs/lib/attrsets.nix @@ -2,10 +2,10 @@ { lib }: let - inherit (builtins) head tail length; - inherit (lib.trivial) id mergeAttrs warn; + inherit (builtins) head length; + inherit (lib.trivial) mergeAttrs warn; inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName; - inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all partition groupBy take foldl; + inherit (lib.lists) foldr foldl' concatMap elemAt all partition groupBy take foldl; in rec { @@ -369,7 +369,7 @@ rec { Type: attrValues :: AttrSet -> [Any] */ - attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs); + attrValues = builtins.attrValues; /* Given a set of attribute names, return the set of the corresponding @@ -398,8 +398,7 @@ rec { Type: catAttrs :: String -> [AttrSet] -> [Any] */ - catAttrs = builtins.catAttrs or - (attr: l: concatLists (map (s: if s ? ${attr} then [s.${attr}] else []) l)); + catAttrs = builtins.catAttrs; /* Filter an attribute set by removing all attributes for which the @@ -608,9 +607,7 @@ rec { Type: mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet */ - mapAttrs = builtins.mapAttrs or - (f: set: - listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))); + mapAttrs = builtins.mapAttrs; /* Like `mapAttrs`, but allows the name of each attribute to be diff --git a/nixpkgs/lib/default.nix b/nixpkgs/lib/default.nix index a17307be6e07..668c29640f9f 100644 --- a/nixpkgs/lib/default.nix +++ b/nixpkgs/lib/default.nix @@ -84,8 +84,8 @@ let mapAttrs' mapAttrsToList attrsToList concatMapAttrs mapAttrsRecursive mapAttrsRecursiveCond genAttrs isDerivation toDerivation optionalAttrs zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil - recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin - getLib getDev getMan chooseDevOutputs zipWithNames zip + recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput + getBin getLib getDev getMan chooseDevOutputs zipWithNames zip recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets updateManyAttrsByPath; inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 diff --git a/nixpkgs/lib/fileset/default.nix b/nixpkgs/lib/fileset/default.nix index c007b60def0a..ce9afc796a3f 100644 --- a/nixpkgs/lib/fileset/default.nix +++ b/nixpkgs/lib/fileset/default.nix @@ -23,6 +23,10 @@ Add files in file sets to the store to use as derivation sources. + - [`lib.fileset.toList`](#function-library-lib.fileset.toList): + + The list of files contained in a file set. + Combinators: - [`lib.fileset.union`](#function-library-lib.fileset.union)/[`lib.fileset.unions`](#function-library-lib.fileset.unions): @@ -102,6 +106,7 @@ let _coerceMany _toSourceFilter _fromSourceFilter + _toList _unionMany _fileFilter _printFileset @@ -412,6 +417,38 @@ in { filter = sourceFilter; }; + + /* + The list of file paths contained in the given file set. + + :::{.note} + This function is strict in the entire file set. + This is in contrast with combinators [`lib.fileset.union`](#function-library-lib.fileset.union), + [`lib.fileset.intersection`](#function-library-lib.fileset.intersection) and [`lib.fileset.difference`](#function-library-lib.fileset.difference). + + Thus it is recommended to call `toList` on file sets created using the combinators, + instead of doing list processing on the result of `toList`. + ::: + + The resulting list of files can be turned back into a file set using [`lib.fileset.unions`](#function-library-lib.fileset.unions). + + Type: + toList :: FileSet -> [ Path ] + + Example: + toList ./. + [ ./README.md ./Makefile ./src/main.c ./src/main.h ] + + toList (difference ./. ./src) + [ ./README.md ./Makefile ] + */ + toList = + # The file set whose file paths to return. + # This argument can also be a path, + # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion). + fileset: + _toList (_coerce "lib.fileset.toList: Argument" fileset); + /* The file set containing all files that are in either of two given file sets. This is the same as [`unions`](#function-library-lib.fileset.unions), diff --git a/nixpkgs/lib/fileset/internal.nix b/nixpkgs/lib/fileset/internal.nix index f4fcc83e1012..0d97ef174568 100644 --- a/nixpkgs/lib/fileset/internal.nix +++ b/nixpkgs/lib/fileset/internal.nix @@ -18,6 +18,7 @@ let attrNames attrValues mapAttrs + mapAttrsToList optionalAttrs zipAttrsWith ; @@ -29,6 +30,7 @@ let inherit (lib.lists) all commonPrefix + concatLists elemAt filter findFirst @@ -539,6 +541,27 @@ rec { ${baseNameOf root} = rootPathType; }; + # Turns a file set into the list of file paths it includes. + # Type: fileset -> [ Path ] + _toList = fileset: + let + recurse = path: tree: + if isAttrs tree then + concatLists (mapAttrsToList (name: value: + recurse (path + "/${name}") value + ) tree) + else if tree == "directory" then + recurse path (readDir path) + else if tree == null then + [ ] + else + [ path ]; + in + if fileset._internalIsEmptyWithoutBase then + [ ] + else + recurse fileset._internalBase fileset._internalTree; + # Transforms the filesetTree of a file set to a shorter base path, e.g. # _shortenTreeBase [ "foo" ] (_create /foo/bar null) # => { bar = null; } diff --git a/nixpkgs/lib/fileset/tests.sh b/nixpkgs/lib/fileset/tests.sh index af8338eb7855..405fa04d8e06 100755 --- a/nixpkgs/lib/fileset/tests.sh +++ b/nixpkgs/lib/fileset/tests.sh @@ -275,7 +275,6 @@ createTree() { # ) # checkFileset './a' # Pass the fileset as the argument checkFileset() { - # New subshell so that we can have a separate trap handler, see `trap` below local fileset=$1 # Create the tree @@ -283,16 +282,20 @@ checkFileset() { # Process the tree into separate arrays for included paths, excluded paths and excluded files. local -a included=() + local -a includedFiles=() local -a excluded=() local -a excludedFiles=() for p in "${!tree[@]}"; do case "${tree[$p]}" in 1) included+=("$p") + # If keys end with a `/` we treat them as directories, otherwise files + if [[ ! "$p" =~ /$ ]]; then + includedFiles+=("$p") + fi ;; 0) excluded+=("$p") - # If keys end with a `/` we treat them as directories, otherwise files if [[ ! "$p" =~ /$ ]]; then excludedFiles+=("$p") fi @@ -302,6 +305,10 @@ checkFileset() { esac done + # Test that lib.fileset.toList contains exactly the included files. + # The /#/./ part prefixes each element with `./` + expectEqual "toList ($fileset)" "sort lessThan [ ${includedFiles[*]/#/./} ]" + expression="toSource { root = ./.; fileset = $fileset; }" # We don't have lambda's in bash unfortunately, @@ -338,13 +345,17 @@ checkFileset() { #### Error messages ##### +# We're using [[:blank:]] here instead of \s, because only the former is POSIX +# (see https://pubs.opengroup.org/onlinepubs/007908799/xbd/re.html#tag_007_003_005). +# And indeed, Darwin's bash only supports the former + # Absolute paths in strings cannot be passed as `root` expectFailure 'toSource { root = "/nix/store/foobar"; fileset = ./.; }' 'lib.fileset.toSource: `root` \(/nix/store/foobar\) is a string-like value, but it should be a path instead. -\s*Paths in strings are not supported by `lib.fileset`, use `lib.sources` or derivations instead.' +[[:blank:]]*Paths in strings are not supported by `lib.fileset`, use `lib.sources` or derivations instead.' expectFailure 'toSource { root = cleanSourceWith { src = ./.; }; fileset = ./.; }' 'lib.fileset.toSource: `root` is a `lib.sources`-based value, but it should be a path instead. -\s*To use a `lib.sources`-based value, convert it to a file set using `lib.fileset.fromSource` and pass it as `fileset`. -\s*Note that this only works for sources created from paths.' +[[:blank:]]*To use a `lib.sources`-based value, convert it to a file set using `lib.fileset.fromSource` and pass it as `fileset`. +[[:blank:]]*Note that this only works for sources created from paths.' # Only paths are accepted as `root` expectFailure 'toSource { root = 10; fileset = ./.; }' 'lib.fileset.toSource: `root` is of type int, but it should be a path instead.' @@ -354,9 +365,9 @@ mkdir -p {foo,bar}/mock-root expectFailure 'with ((import <nixpkgs/lib>).extend (import <nixpkgs/lib/fileset/mock-splitRoot.nix>)).fileset; toSource { root = ./foo/mock-root; fileset = ./bar/mock-root; } ' 'lib.fileset.toSource: Filesystem roots are not the same for `fileset` and `root` \('"$work"'/foo/mock-root\): -\s*`root`: Filesystem root is "'"$work"'/foo/mock-root" -\s*`fileset`: Filesystem root is "'"$work"'/bar/mock-root" -\s*Different filesystem roots are not supported.' +[[:blank:]]*`root`: Filesystem root is "'"$work"'/foo/mock-root" +[[:blank:]]*`fileset`: Filesystem root is "'"$work"'/bar/mock-root" +[[:blank:]]*Different filesystem roots are not supported.' rm -rf -- * # `root` needs to exist @@ -365,8 +376,8 @@ expectFailure 'toSource { root = ./a; fileset = ./.; }' 'lib.fileset.toSource: ` # `root` needs to be a file touch a expectFailure 'toSource { root = ./a; fileset = ./a; }' 'lib.fileset.toSource: `root` \('"$work"'/a\) is a file, but it should be a directory instead. Potential solutions: -\s*- If you want to import the file into the store _without_ a containing directory, use string interpolation or `builtins.path` instead of this function. -\s*- If you want to import the file into the store _with_ a containing directory, set `root` to the containing directory, such as '"$work"', and set `fileset` to the file path.' +[[:blank:]]*- If you want to import the file into the store _without_ a containing directory, use string interpolation or `builtins.path` instead of this function. +[[:blank:]]*- If you want to import the file into the store _with_ a containing directory, set `root` to the containing directory, such as '"$work"', and set `fileset` to the file path.' rm -rf -- * # The fileset argument should be evaluated, even if the directory is empty @@ -375,36 +386,36 @@ expectFailure 'toSource { root = ./.; fileset = abort "This should be evaluated" # Only paths under `root` should be able to influence the result mkdir a expectFailure 'toSource { root = ./a; fileset = ./.; }' 'lib.fileset.toSource: `fileset` could contain files in '"$work"', which is not under the `root` \('"$work"'/a\). Potential solutions: -\s*- Set `root` to '"$work"' or any directory higher up. This changes the layout of the resulting store path. -\s*- Set `fileset` to a file set that cannot contain files outside the `root` \('"$work"'/a\). This could change the files included in the result.' +[[:blank:]]*- Set `root` to '"$work"' or any directory higher up. This changes the layout of the resulting store path. +[[:blank:]]*- Set `fileset` to a file set that cannot contain files outside the `root` \('"$work"'/a\). This could change the files included in the result.' rm -rf -- * # non-regular and non-symlink files cannot be added to the Nix store mkfifo a expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` contains a file that cannot be added to the store: '"$work"'/a -\s*This file is neither a regular file nor a symlink, the only file types supported by the Nix store. -\s*Therefore the file set cannot be added to the Nix store as is. Make sure to not include that file to avoid this error.' +[[:blank:]]*This file is neither a regular file nor a symlink, the only file types supported by the Nix store. +[[:blank:]]*Therefore the file set cannot be added to the Nix store as is. Make sure to not include that file to avoid this error.' rm -rf -- * # Path coercion only works for paths expectFailure 'toSource { root = ./.; fileset = 10; }' 'lib.fileset.toSource: `fileset` is of type int, but it should be a file set or a path instead.' expectFailure 'toSource { root = ./.; fileset = "/some/path"; }' 'lib.fileset.toSource: `fileset` \("/some/path"\) is a string-like value, but it should be a file set or a path instead. -\s*Paths represented as strings are not supported by `lib.fileset`, use `lib.sources` or derivations instead.' +[[:blank:]]*Paths represented as strings are not supported by `lib.fileset`, use `lib.sources` or derivations instead.' expectFailure 'toSource { root = ./.; fileset = cleanSourceWith { src = ./.; }; }' 'lib.fileset.toSource: `fileset` is a `lib.sources`-based value, but it should be a file set or a path instead. -\s*To convert a `lib.sources`-based value to a file set you can use `lib.fileset.fromSource`. -\s*Note that this only works for sources created from paths.' +[[:blank:]]*To convert a `lib.sources`-based value to a file set you can use `lib.fileset.fromSource`. +[[:blank:]]*Note that this only works for sources created from paths.' # Path coercion errors for non-existent paths expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` \('"$work"'/a\) is a path that does not exist. -\s*To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.' +[[:blank:]]*To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.' # File sets cannot be evaluated directly expectFailure 'union ./. ./.' 'lib.fileset: Directly evaluating a file set is not supported. -\s*To turn it into a usable source, use `lib.fileset.toSource`. -\s*To pretty-print the contents, use `lib.fileset.trace` or `lib.fileset.traceVal`.' +[[:blank:]]*To turn it into a usable source, use `lib.fileset.toSource`. +[[:blank:]]*To pretty-print the contents, use `lib.fileset.trace` or `lib.fileset.traceVal`.' expectFailure '_emptyWithoutBase' 'lib.fileset: Directly evaluating a file set is not supported. -\s*To turn it into a usable source, use `lib.fileset.toSource`. -\s*To pretty-print the contents, use `lib.fileset.trace` or `lib.fileset.traceVal`.' +[[:blank:]]*To turn it into a usable source, use `lib.fileset.toSource`. +[[:blank:]]*To pretty-print the contents, use `lib.fileset.trace` or `lib.fileset.traceVal`.' # Past versions of the internal representation are supported expectEqual '_coerce "<tests>: value" { _type = "fileset"; _internalVersion = 0; _internalBase = ./.; }' \ @@ -416,9 +427,9 @@ expectEqual '_coerce "<tests>: value" { _type = "fileset"; _internalVersion = 2; # Future versions of the internal representation are unsupported expectFailure '_coerce "<tests>: value" { _type = "fileset"; _internalVersion = 4; }' '<tests>: value is a file set created from a future version of the file set library with a different internal representation: -\s*- Internal version of the file set: 4 -\s*- Internal version of the library: 3 -\s*Make sure to update your Nixpkgs to have a newer version of `lib.fileset`.' +[[:blank:]]*- Internal version of the file set: 4 +[[:blank:]]*- Internal version of the library: 3 +[[:blank:]]*Make sure to update your Nixpkgs to have a newer version of `lib.fileset`.' # _create followed by _coerce should give the inputs back without any validation expectEqual '{ @@ -511,6 +522,19 @@ expectEqual '_toSourceFilter (_create /. { foo = "regular"; }) "/foo" ""' 'true' expectEqual '_toSourceFilter (_create /. { foo = null; }) "/foo" ""' 'false' +## lib.fileset.toList +# This function is mainly tested in checkFileset + +# The error context for an invalid argument must be correct +expectFailure 'toList null' 'lib.fileset.toList: Argument is of type null, but it should be a file set or a path instead.' + +# Works for the empty fileset +expectEqual 'toList _emptyWithoutBase' '[ ]' + +# Works on empty paths +expectEqual 'toList ./.' '[ ]' + + ## lib.fileset.union, lib.fileset.unions @@ -519,16 +543,16 @@ mkdir -p {foo,bar}/mock-root expectFailure 'with ((import <nixpkgs/lib>).extend (import <nixpkgs/lib/fileset/mock-splitRoot.nix>)).fileset; toSource { root = ./.; fileset = union ./foo/mock-root ./bar/mock-root; } ' 'lib.fileset.union: Filesystem roots are not the same: -\s*First argument: Filesystem root is "'"$work"'/foo/mock-root" -\s*Second argument: Filesystem root is "'"$work"'/bar/mock-root" -\s*Different filesystem roots are not supported.' +[[:blank:]]*First argument: Filesystem root is "'"$work"'/foo/mock-root" +[[:blank:]]*Second argument: Filesystem root is "'"$work"'/bar/mock-root" +[[:blank:]]*Different filesystem roots are not supported.' expectFailure 'with ((import <nixpkgs/lib>).extend (import <nixpkgs/lib/fileset/mock-splitRoot.nix>)).fileset; toSource { root = ./.; fileset = unions [ ./foo/mock-root ./bar/mock-root ]; } ' 'lib.fileset.unions: Filesystem roots are not the same: -\s*Element 0: Filesystem root is "'"$work"'/foo/mock-root" -\s*Element 1: Filesystem root is "'"$work"'/bar/mock-root" -\s*Different filesystem roots are not supported.' +[[:blank:]]*Element 0: Filesystem root is "'"$work"'/foo/mock-root" +[[:blank:]]*Element 1: Filesystem root is "'"$work"'/bar/mock-root" +[[:blank:]]*Different filesystem roots are not supported.' rm -rf -- * # Coercion errors show the correct context @@ -632,9 +656,9 @@ mkdir -p {foo,bar}/mock-root expectFailure 'with ((import <nixpkgs/lib>).extend (import <nixpkgs/lib/fileset/mock-splitRoot.nix>)).fileset; toSource { root = ./.; fileset = intersection ./foo/mock-root ./bar/mock-root; } ' 'lib.fileset.intersection: Filesystem roots are not the same: -\s*First argument: Filesystem root is "'"$work"'/foo/mock-root" -\s*Second argument: Filesystem root is "'"$work"'/bar/mock-root" -\s*Different filesystem roots are not supported.' +[[:blank:]]*First argument: Filesystem root is "'"$work"'/foo/mock-root" +[[:blank:]]*Second argument: Filesystem root is "'"$work"'/bar/mock-root" +[[:blank:]]*Different filesystem roots are not supported.' rm -rf -- * # Coercion errors show the correct context @@ -741,8 +765,8 @@ rm -rf -- * # Also not the other way around mkdir a expectFailure 'toSource { root = ./a; fileset = difference ./. ./a; }' 'lib.fileset.toSource: `fileset` could contain files in '"$work"', which is not under the `root` \('"$work"'/a\). Potential solutions: -\s*- Set `root` to '"$work"' or any directory higher up. This changes the layout of the resulting store path. -\s*- Set `fileset` to a file set that cannot contain files outside the `root` \('"$work"'/a\). This could change the files included in the result.' +[[:blank:]]*- Set `root` to '"$work"' or any directory higher up. This changes the layout of the resulting store path. +[[:blank:]]*- Set `fileset` to a file set that cannot contain files outside the `root` \('"$work"'/a\). This could change the files included in the result.' rm -rf -- * # Difference actually works @@ -819,7 +843,7 @@ expectFailure 'fileFilter null (abort "this is not needed")' 'lib.fileset.fileFi # The second argument needs to be an existing path expectFailure 'fileFilter (file: abort "this is not needed") _emptyWithoutBase' 'lib.fileset.fileFilter: Second argument is a file set, but it should be a path instead. -\s*If you need to filter files in a file set, use `intersection fileset \(fileFilter pred \./\.\)` instead.' +[[:blank:]]*If you need to filter files in a file set, use `intersection fileset \(fileFilter pred \./\.\)` instead.' expectFailure 'fileFilter (file: abort "this is not needed") null' 'lib.fileset.fileFilter: Second argument is of type null, but it should be a path instead.' expectFailure 'fileFilter (file: abort "this is not needed") ./a' 'lib.fileset.fileFilter: Second argument \('"$work"'/a\) is a path that does not exist.' @@ -1083,7 +1107,7 @@ rm -rf -- * # String-like values are not supported expectFailure 'fromSource (lib.cleanSource "")' 'lib.fileset.fromSource: The source origin of the argument is a string-like value \(""\), but it should be a path instead. -\s*Sources created from paths in strings cannot be turned into file sets, use `lib.sources` or derivations instead.' +[[:blank:]]*Sources created from paths in strings cannot be turned into file sets, use `lib.sources` or derivations instead.' # Wrong type expectFailure 'fromSource null' 'lib.fileset.fromSource: The source origin of the argument is of type null, but it should be a path instead.' @@ -1400,10 +1424,10 @@ expectEqual '(import '"$storePath"' { fs = lib.fileset; }).outPath' \""$storePat ## But it fails if the path is imported with a fetcher that doesn't remove .git (like just using "${./.}") expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTracked: The argument \(.*\) is a store path within a working tree of a Git repository. -\s*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. -\s*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. -\s*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. -\s*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' +[[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. +[[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. +[[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. +[[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' ## Even with submodules if [[ -n "$fetchGitSupportsSubmodules" ]]; then @@ -1427,15 +1451,15 @@ if [[ -n "$fetchGitSupportsSubmodules" ]]; then ## But it fails if the path is imported with a fetcher that doesn't remove .git (like just using "${./.}") expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTrackedWith: The second argument \(.*\) is a store path within a working tree of a Git repository. - \s*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. - \s*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. - \s*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. - \s*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' + [[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. + [[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. + [[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. + [[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' expectFailure 'import "${./.}/sub" { fs = lib.fileset; }' 'lib.fileset.gitTracked: The argument \(.*/sub\) is a store path within a working tree of a Git repository. - \s*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. - \s*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. - \s*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. - \s*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' + [[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. + [[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. + [[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. + [[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' fi rm -rf -- * diff --git a/nixpkgs/lib/fixed-points.nix b/nixpkgs/lib/fixed-points.nix index 3370b55a4ab9..3bd18fdd2a5a 100644 --- a/nixpkgs/lib/fixed-points.nix +++ b/nixpkgs/lib/fixed-points.nix @@ -145,6 +145,12 @@ rec { in fix g ``` + :::{.note} + The argument to the given fixed-point function after applying an overlay will *not* refer to its own return value, but rather to the value after evaluating the overlay function. + + The given fixed-point function is called with a separate argument than if it was evaluated with `lib.fix`. + ::: + :::{.example} # Extend a fixed-point function with an overlay @@ -230,13 +236,6 @@ rec { fix (extends (final: prev: { c = final.a + final.b; }) f) => { a = 1; b = 3; c = 4; } - - :::{.note} - The argument to the given fixed-point function after applying an overlay will *not* refer to its own return value, but rather to the value after evaluating the overlay function. - - The given fixed-point function is called with a separate argument than if it was evaluated with `lib.fix`. - The new argument - ::: */ extends = # The overlay to apply to the fixed-point function diff --git a/nixpkgs/lib/lists.nix b/nixpkgs/lib/lists.nix index b612bc16697e..05216c1a66eb 100644 --- a/nixpkgs/lib/lists.nix +++ b/nixpkgs/lib/lists.nix @@ -4,7 +4,6 @@ let inherit (lib.strings) toInt; inherit (lib.trivial) compare min id warn; inherit (lib.attrsets) mapAttrs; - inherit (lib.lists) sort; in rec { @@ -172,7 +171,7 @@ rec { concatMap (x: [x] ++ ["z"]) ["a" "b"] => [ "a" "z" "b" "z" ] */ - concatMap = builtins.concatMap or (f: list: concatLists (map f list)); + concatMap = builtins.concatMap; /* Flatten the argument into a single list; that is, nested lists are spliced into the top-level lists. @@ -316,7 +315,7 @@ rec { any isString [ 1 { } ] => false */ - any = builtins.any or (pred: foldr (x: y: if pred x then true else y) false); + any = builtins.any; /* Return true if function `pred` returns true for all elements of `list`. @@ -329,7 +328,7 @@ rec { all (x: x < 3) [ 1 2 3 ] => false */ - all = builtins.all or (pred: foldr (x: y: if pred x then y else false) true); + all = builtins.all; /* Count how many elements of `list` match the supplied predicate function. @@ -428,12 +427,7 @@ rec { partition (x: x > 2) [ 5 1 2 3 4 ] => { right = [ 5 3 4 ]; wrong = [ 1 2 ]; } */ - partition = builtins.partition or (pred: - foldr (h: t: - if pred h - then { right = [h] ++ t.right; wrong = t.wrong; } - else { right = t.right; wrong = [h] ++ t.wrong; } - ) { right = []; wrong = []; }); + partition = builtins.partition; /* Splits the elements of a list into many lists, using the return value of a predicate. Predicate should return a string which becomes keys of attrset `groupBy` returns. @@ -602,22 +596,7 @@ rec { Type: sort :: (a -> a -> Bool) -> [a] -> [a] */ - sort = builtins.sort or ( - strictLess: list: - let - len = length list; - first = head list; - pivot' = n: acc@{ left, right }: let el = elemAt list n; next = pivot' (n + 1); in - if n == len - then acc - else if strictLess first el - then next { inherit left; right = [ el ] ++ right; } - else - next { left = [ el ] ++ left; inherit right; }; - pivot = pivot' 1 { left = []; right = []; }; - in - if len < 2 then list - else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right)); + sort = builtins.sort; /* Sort a list based on the default comparison of a derived property `b`. diff --git a/nixpkgs/lib/meta.nix b/nixpkgs/lib/meta.nix index 5d5f71d6c3cb..675e1912d4be 100644 --- a/nixpkgs/lib/meta.nix +++ b/nixpkgs/lib/meta.nix @@ -87,6 +87,10 @@ rec { We can inject these into a pattern for the whole of a structured platform, and then match that. + + Example: + lib.meta.platformMatch { system = "aarch64-darwin"; } "aarch64-darwin" + => true */ platformMatch = platform: elem: ( # Check with simple string comparison if elem was a string. @@ -112,6 +116,10 @@ rec { platform, or `meta.platforms` is not present. 2. None of `meta.badPlatforms` pattern matches the given platform. + + Example: + lib.meta.availableOn { system = "aarch64-darwin"; } pkg.zsh + => true */ availableOn = platform: pkg: ((!pkg?meta.platforms) || any (platformMatch platform) pkg.meta.platforms) && diff --git a/nixpkgs/lib/strings.nix b/nixpkgs/lib/strings.nix index 7083576dd529..47ee095f1b68 100644 --- a/nixpkgs/lib/strings.nix +++ b/nixpkgs/lib/strings.nix @@ -95,8 +95,7 @@ rec { concatStringsSep "/" ["usr" "local" "bin"] => "usr/local/bin" */ - concatStringsSep = builtins.concatStringsSep or (separator: list: - lib.foldl' (x: y: x + y) "" (intersperse separator list)); + concatStringsSep = builtins.concatStringsSep; /* Maps a function over a list of strings and then concatenates the result with the specified separator interspersed between diff --git a/nixpkgs/lib/tests/release.nix b/nixpkgs/lib/tests/release.nix index 96d34be8c2d3..5b2a9df1635c 100644 --- a/nixpkgs/lib/tests/release.nix +++ b/nixpkgs/lib/tests/release.nix @@ -9,60 +9,7 @@ let lib = import ../.; testWithNix = nix: - pkgs.runCommand "nixpkgs-lib-tests-nix-${nix.version}" { - buildInputs = [ - (import ./check-eval.nix) - (import ./maintainers.nix { - inherit pkgs; - lib = import ../.; - }) - (import ./teams.nix { - inherit pkgs; - lib = import ../.; - }) - (import ../path/tests { - inherit pkgs; - }) - ]; - nativeBuildInputs = [ - nix - pkgs.gitMinimal - ] ++ lib.optional pkgs.stdenv.isLinux pkgs.inotify-tools; - strictDeps = true; - } '' - datadir="${nix}/share" - export TEST_ROOT=$(pwd)/test-tmp - export HOME=$(mktemp -d) - export NIX_BUILD_HOOK= - export NIX_CONF_DIR=$TEST_ROOT/etc - export NIX_LOCALSTATE_DIR=$TEST_ROOT/var - export NIX_LOG_DIR=$TEST_ROOT/var/log/nix - export NIX_STATE_DIR=$TEST_ROOT/var/nix - export NIX_STORE_DIR=$TEST_ROOT/store - export PAGER=cat - cacheDir=$TEST_ROOT/binary-cache - - nix-store --init - - cp -r ${../.} lib - echo "Running lib/tests/modules.sh" - bash lib/tests/modules.sh - - echo "Running lib/tests/filesystem.sh" - TEST_LIB=$PWD/lib bash lib/tests/filesystem.sh - - echo "Running lib/tests/sources.sh" - TEST_LIB=$PWD/lib bash lib/tests/sources.sh - - echo "Running lib/fileset/tests.sh" - TEST_LIB=$PWD/lib bash lib/fileset/tests.sh - - echo "Running lib/tests/systems.nix" - [[ $(nix-instantiate --eval --strict lib/tests/systems.nix | tee /dev/stderr) == '[ ]' ]]; - - mkdir $out - echo success > $out/${nix.version} - ''; + import ./test-with-nix.nix { inherit lib nix pkgs; }; in pkgs.symlinkJoin { diff --git a/nixpkgs/lib/tests/test-with-nix.nix b/nixpkgs/lib/tests/test-with-nix.nix new file mode 100644 index 000000000000..fd2e7532e697 --- /dev/null +++ b/nixpkgs/lib/tests/test-with-nix.nix @@ -0,0 +1,70 @@ +/** + * Instantiate the library tests for a given Nix version. + * + * IMPORTANT: + * This is used by the github.com/NixOS/nix CI. + * + * Try not to change the interface of this file, or if you need to, ping the + * Nix maintainers for help. Thank you! + */ +{ + pkgs, + lib, + # Only ever use this nix; see comment at top + nix, +}: + +pkgs.runCommand "nixpkgs-lib-tests-nix-${nix.version}" { + buildInputs = [ + (import ./check-eval.nix) + (import ./maintainers.nix { + inherit pkgs; + lib = import ../.; + }) + (import ./teams.nix { + inherit pkgs; + lib = import ../.; + }) + (import ../path/tests { + inherit pkgs; + }) + ]; + nativeBuildInputs = [ + nix + pkgs.gitMinimal + ] ++ lib.optional pkgs.stdenv.isLinux pkgs.inotify-tools; + strictDeps = true; +} '' + datadir="${nix}/share" + export TEST_ROOT=$(pwd)/test-tmp + export HOME=$(mktemp -d) + export NIX_BUILD_HOOK= + export NIX_CONF_DIR=$TEST_ROOT/etc + export NIX_LOCALSTATE_DIR=$TEST_ROOT/var + export NIX_LOG_DIR=$TEST_ROOT/var/log/nix + export NIX_STATE_DIR=$TEST_ROOT/var/nix + export NIX_STORE_DIR=$TEST_ROOT/store + export PAGER=cat + cacheDir=$TEST_ROOT/binary-cache + + nix-store --init + + cp -r ${../.} lib + echo "Running lib/tests/modules.sh" + bash lib/tests/modules.sh + + echo "Running lib/tests/filesystem.sh" + TEST_LIB=$PWD/lib bash lib/tests/filesystem.sh + + echo "Running lib/tests/sources.sh" + TEST_LIB=$PWD/lib bash lib/tests/sources.sh + + echo "Running lib/fileset/tests.sh" + TEST_LIB=$PWD/lib bash lib/fileset/tests.sh + + echo "Running lib/tests/systems.nix" + [[ $(nix-instantiate --eval --strict lib/tests/systems.nix | tee /dev/stderr) == '[ ]' ]]; + + mkdir $out + echo success > $out/${nix.version} +'' diff --git a/nixpkgs/lib/trivial.nix b/nixpkgs/lib/trivial.nix index 58620006de15..fa499cbbf028 100644 --- a/nixpkgs/lib/trivial.nix +++ b/nixpkgs/lib/trivial.nix @@ -95,21 +95,6 @@ in { /* boolean “and” */ and = x: y: x && y; - /* bitwise “and” */ - bitAnd = builtins.bitAnd - or (import ./zip-int-bits.nix - (a: b: if a==1 && b==1 then 1 else 0)); - - /* bitwise “or” */ - bitOr = builtins.bitOr - or (import ./zip-int-bits.nix - (a: b: if a==1 || b==1 then 1 else 0)); - - /* bitwise “xor” */ - bitXor = builtins.bitXor - or (import ./zip-int-bits.nix - (a: b: if a!=b then 1 else 0)); - /* bitwise “not” */ bitNot = builtins.sub (-1); @@ -165,8 +150,8 @@ in { inherit (builtins) pathExists readFile isBool isInt isFloat add sub lessThan - seq deepSeq genericClosure; - + seq deepSeq genericClosure + bitAnd bitOr bitXor; ## nixpkgs version strings diff --git a/nixpkgs/lib/versions.nix b/nixpkgs/lib/versions.nix index 986e7e5f9b37..720d19e8ca29 100644 --- a/nixpkgs/lib/versions.nix +++ b/nixpkgs/lib/versions.nix @@ -9,7 +9,7 @@ rec { splitVersion "1.2.3" => ["1" "2" "3"] */ - splitVersion = builtins.splitVersion or (lib.splitString "."); + splitVersion = builtins.splitVersion; /* Get the major version string from a string. diff --git a/nixpkgs/lib/zip-int-bits.nix b/nixpkgs/lib/zip-int-bits.nix deleted file mode 100644 index 53efd2bb0a04..000000000000 --- a/nixpkgs/lib/zip-int-bits.nix +++ /dev/null @@ -1,39 +0,0 @@ -/* Helper function to implement a fallback for the bit operators - `bitAnd`, `bitOr` and `bitXor` on older nix version. - See ./trivial.nix -*/ -f: x: y: - let - # (intToBits 6) -> [ 0 1 1 ] - intToBits = x: - if x == 0 || x == -1 then - [] - else - let - headbit = if (x / 2) * 2 != x then 1 else 0; # x & 1 - tailbits = if x < 0 then ((x + 1) / 2) - 1 else x / 2; # x >> 1 - in - [headbit] ++ (intToBits tailbits); - - # (bitsToInt [ 0 1 1 ] 0) -> 6 - # (bitsToInt [ 0 1 0 ] 1) -> -6 - bitsToInt = l: signum: - if l == [] then - (if signum == 0 then 0 else -1) - else - (builtins.head l) + (2 * (bitsToInt (builtins.tail l) signum)); - - xsignum = if x < 0 then 1 else 0; - ysignum = if y < 0 then 1 else 0; - zipListsWith' = fst: snd: - if fst==[] && snd==[] then - [] - else if fst==[] then - [(f xsignum (builtins.head snd))] ++ (zipListsWith' [] (builtins.tail snd)) - else if snd==[] then - [(f (builtins.head fst) ysignum )] ++ (zipListsWith' (builtins.tail fst) [] ) - else - [(f (builtins.head fst) (builtins.head snd))] ++ (zipListsWith' (builtins.tail fst) (builtins.tail snd)); - in - assert (builtins.isInt x) && (builtins.isInt y); - bitsToInt (zipListsWith' (intToBits x) (intToBits y)) (f xsignum ysignum) |