lib.fileset: add isFileset helper

This commit is contained in:
Niols
2025-07-10 13:58:26 +02:00
parent f2946a2661
commit a99adc7c06
2 changed files with 70 additions and 12 deletions

View File

@@ -101,6 +101,7 @@ let
inherit (import ./internal.nix { inherit lib; }) inherit (import ./internal.nix { inherit lib; })
_coerce _coerce
_coerceResult
_singleton _singleton
_coerceMany _coerceMany
_toSourceFilter _toSourceFilter
@@ -1005,4 +1006,38 @@ in
{ {
submodules = recurseSubmodules; submodules = recurseSubmodules;
}; };
/**
Tests whether a given value is a fileset, or can be used in place of a fileset.
# Inputs
`value`
: The value to test
# Type
```
isFileset :: Any -> Bool
```
# Examples
:::{.example}
## `lib.fileset.isFileset` usage example
```nix
isFileset ./.
=> true
isFileset (unions [ ])
=> true
isFileset 1
=> false
```
:::
*/
isFileset = x: (_coerceResult "" x).success;
} }

View File

@@ -165,14 +165,27 @@ rec {
_noEval = throw _noEvalMessage; _noEval = throw _noEvalMessage;
}; };
# Coerce a value to a fileset, erroring when the value cannot be coerced. # Coerce a value to a fileset. Return a set containing the attribute `success`
# The string gives the context for error messages. # indicating whether coercing succeeded, and either `value` when `success ==
# Type: String -> (fileset | Path) -> fileset # true`, or an error `message` when `success == false`. The string gives the
_coerce = # context for error messages.
#
# Type: String -> (fileset | Path) -> { success :: Bool, value :: fileset } ] -> { success :: Bool, message :: String }
_coerceResult =
let
ok = value: {
success = true;
inherit value;
};
error = message: {
success = false;
inherit message;
};
in
context: value: context: value:
if value._type or "" == "fileset" then if value._type or "" == "fileset" then
if value._internalVersion > _currentVersion then if value._internalVersion > _currentVersion then
throw '' error ''
${context} is a file set created from a future version of the file set library with a different internal representation: ${context} is a file set created from a future version of the file set library with a different internal representation:
- Internal version of the file set: ${toString value._internalVersion} - Internal version of the file set: ${toString value._internalVersion}
- Internal version of the library: ${toString _currentVersion} - Internal version of the library: ${toString _currentVersion}
@@ -184,27 +197,37 @@ rec {
_currentVersion - value._internalVersion _currentVersion - value._internalVersion
) migrations; ) migrations;
in in
foldl' (value: migration: migration value) value migrationsToApply ok (foldl' (value: migration: migration value) value migrationsToApply)
else else
value ok value
else if !isPath value then else if !isPath value then
if value ? _isLibCleanSourceWith then if value ? _isLibCleanSourceWith then
throw '' error ''
${context} is a `lib.sources`-based value, but it should be a file set or a path instead. ${context} is a `lib.sources`-based value, but it should be a file set or a path instead.
To convert a `lib.sources`-based value to a file set you can use `lib.fileset.fromSource`. To convert a `lib.sources`-based value to a file set you can use `lib.fileset.fromSource`.
Note that this only works for sources created from paths.'' Note that this only works for sources created from paths.''
else if isStringLike value then else if isStringLike value then
throw '' error ''
${context} ("${toString value}") is a string-like value, but it should be a file set or a path instead. ${context} ("${toString value}") is a string-like value, but it should be a file set or a path instead.
Paths represented as strings are not supported by `lib.fileset`, use `lib.sources` or derivations instead.'' Paths represented as strings are not supported by `lib.fileset`, use `lib.sources` or derivations instead.''
else else
throw ''${context} is of type ${typeOf value}, but it should be a file set or a path instead.'' error ''${context} is of type ${typeOf value}, but it should be a file set or a path instead.''
else if !pathExists value then else if !pathExists value then
throw '' error ''
${context} (${toString value}) is a path that does not exist. ${context} (${toString value}) is a path that does not exist.
To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.'' To create a file set from a path that may not exist, use `lib.fileset.maybeMissing`.''
else else
_singleton value; ok (_singleton value);
# Coerce a value to a fileset, erroring when the value cannot be coerced.
# The string gives the context for error messages.
# Type: String -> (fileset | Path) -> fileset
_coerce =
context: value:
let
result = _coerceResult context value;
in
if result.success then result.value else throw result.message;
# Coerce many values to filesets, erroring when any value cannot be coerced, # Coerce many values to filesets, erroring when any value cannot be coerced,
# or if the filesystem root of the values doesn't match. # or if the filesystem root of the values doesn't match.