diff --git a/doc/functions/fileset.section.md b/doc/functions/fileset.section.md index b24ebe26cc3b..08b9ba9eaedc 100644 --- a/doc/functions/fileset.section.md +++ b/doc/functions/fileset.section.md @@ -9,7 +9,7 @@ File sets are easy and safe to use, providing obvious and composable semantics w These sections apply to the entire library. See the [function reference](#sec-functions-library-fileset) for function-specific documentation. -The file set library is currently very limited but is being expanded to include more functions over time. +The file set library is currently somewhat limited but is being expanded to include more functions over time. ## Implicit coercion from paths to file sets {#sec-fileset-path-coercion} diff --git a/lib/fileset/README.md b/lib/fileset/README.md index 306dcdaa421d..a75efc496c4e 100644 --- a/lib/fileset/README.md +++ b/lib/fileset/README.md @@ -177,15 +177,9 @@ Arguments: ## To update in the future Here's a list of places in the library that need to be updated in the future: -- > The file set library is currently very limited but is being expanded to include more functions over time. +- > The file set library is currently somewhat limited but is being expanded to include more functions over time. in [the manual](../../doc/functions/fileset.section.md) -- > Currently the only way to construct file sets is using implicit coercion from paths. - - in [the `toSource` reference](./default.nix) -- > For now filesets are always paths - - in [the `toSource` implementation](./default.nix), also update the variable name there - Once a tracing function exists, `__noEval` in [internal.nix](./internal.nix) should mention it - If/Once a function to convert `lib.sources` values into file sets exists, the `_coerce` and `toSource` functions should be updated to mention that function in the error when such a value is passed - If/Once a function exists that can optionally include a path depending on whether it exists, the error message for the path not existing in `_coerce` should mention the new function diff --git a/lib/fileset/default.nix b/lib/fileset/default.nix index 1bda8ef789a4..2c8997d71fc2 100644 --- a/lib/fileset/default.nix +++ b/lib/fileset/default.nix @@ -58,16 +58,51 @@ in { } -> SourceLike Example: - # Import the current directory into the store but only include files under ./src - toSource { root = ./.; fileset = ./src; } + # Import the current directory into the store + # but only include files under ./src + toSource { + root = ./.; + fileset = ./src; + } => "/nix/store/...-source" - # The file set coerced from path ./bar could contain files outside the root ./foo, which is not allowed - toSource { root = ./foo; fileset = ./bar; } + # Import the current directory into the store + # but only include ./Makefile and all files under ./src + toSource { + root = ./.; + fileset = union + ./Makefile + ./src; + } + => "/nix/store/...-source" + + # Trying to include a file outside the root will fail + toSource { + root = ./.; + fileset = unions [ + ./Makefile + ./src + ../LICENSE + ]; + } => + # The root needs to point to a directory that contains all the files + toSource { + root = ../.; + fileset = unions [ + ./Makefile + ./src + ../LICENSE + ]; + } + => "/nix/store/...-source" + # The root has to be a local filesystem path - toSource { root = "/nix/store/...-source"; fileset = ./.; } + toSource { + root = "/nix/store/...-source"; + fileset = ./.; + } => */ toSource = { @@ -85,18 +120,24 @@ The only way to change which files get added to the store is by changing the `fi root, /* (required) The file set whose files to import into the store. - Currently the only way to construct file sets is using [implicit coercion from paths](#sec-fileset-path-coercion). - If a directory does not recursively contain any file, it is omitted from the store path contents. + File sets can be created using other functions in this library. + This argument can also be a path, + which gets [implicitly coerced to a file set](#sec-fileset-path-coercion). + + +:::{.note} +If a directory does not recursively contain any file, it is omitted from the store path contents. +::: + */ fileset, }: let # We cannot rename matched attribute arguments, so let's work around it with an extra `let in` statement - # For now filesets are always paths - filesetPath = fileset; + maybeFileset = fileset; in let - fileset = _coerce "lib.fileset.toSource: `fileset`" filesetPath; + fileset = _coerce "lib.fileset.toSource: `fileset`" maybeFileset; rootFilesystemRoot = (splitRoot root).root; filesetFilesystemRoot = (splitRoot fileset._internalBase).root; filter = _toSourceFilter fileset; diff --git a/lib/fileset/tests.sh b/lib/fileset/tests.sh index d4a175acf6c7..69ce29bbbfb3 100755 --- a/lib/fileset/tests.sh +++ b/lib/fileset/tests.sh @@ -265,7 +265,7 @@ expectFailure 'toSource { root = ./.; fileset = "/some/path"; }' 'lib.fileset.to expectFailure 'toSource { root = ./.; fileset = ./a; }' 'lib.fileset.toSource: `fileset` '"$work"'/a does not exist.' # File sets cannot be evaluated directly -expectFailure '_create ./. null' 'lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.' +expectFailure 'union ./. ./.' 'lib.fileset: Directly evaluating a file set is not supported. Use `lib.fileset.toSource` to turn it into a usable source instead.' # Past versions of the internal representation are supported expectEqual '_coerce ": value" { _type = "fileset"; _internalVersion = 0; _internalBase = ./.; }' \