Commit 1cc2c2f1 authored by Silvan Mosberger's avatar Silvan Mosberger
Browse files

lib.fileset.maybeMissing: init

parent 5d08323d
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -252,8 +252,3 @@ The `fileFilter` function takes a path, and not a file set, as its second argume
    - (+) That can change depending on which files are included, so if it's used for `fileFilter`
      it would change the `subpath`/`components` value depending on which files are included.
- (+) If necessary, this restriction can be relaxed later, the opposite wouldn't be possible

## To update in the future

Here's a list of places in the library that need to be updated in the future:
- 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
+31 −0
Original line number Diff line number Diff line
@@ -11,6 +11,10 @@
  Basics:
  - [Implicit coercion from paths to file sets](#sec-fileset-path-coercion)

  - [`lib.fileset.maybeMissing`](#function-library-lib.fileset.maybeMissing):

    Create a file set from a path that may be missing.

  - [`lib.fileset.trace`](#function-library-lib.fileset.trace)/[`lib.fileset.traceVal`](#function-library-lib.fileset.trace):

    Pretty-print file sets for debugging.
@@ -105,6 +109,7 @@ let
    _difference
    _mirrorStorePath
    _fetchGitSubmodulesMinver
    _emptyWithoutBase
    ;

  inherit (builtins)
@@ -148,6 +153,32 @@ let

in {

  /*
    Create a file set from a path that may or may not exist:
    - If the path does exist, the path is [coerced to a file set](#sec-fileset-path-coercion).
    - If the path does not exist, a file set containing no files is returned.

    Type:
      maybeMissing :: Path -> FileSet

    Example:
      # All files in the current directory, but excluding main.o if it exists
      difference ./. (maybeMissing ./main.o)
  */
  maybeMissing =
    path:
    if ! isPath path then
      if isStringLike path then
        throw ''
          lib.fileset.maybeMissing: Argument ("${toString path}") is a string-like value, but it should be a path instead.''
      else
        throw ''
          lib.fileset.maybeMissing: Argument is of type ${typeOf path}, but it should be a path instead.''
    else if ! pathExists path then
      _emptyWithoutBase
    else
      _singleton path;

  /*
    Incrementally evaluate and trace a file set in a pretty way.
    This function is only intended for debugging purposes.
+2 −1
Original line number Diff line number Diff line
@@ -181,7 +181,8 @@ rec {
          ${context} is of type ${typeOf value}, but it should be a file set or a path instead.''
    else if ! pathExists value then
      throw ''
        ${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`.''
    else
      _singleton value;

+36 −1
Original line number Diff line number Diff line
@@ -413,7 +413,8 @@ expectFailure 'toSource { root = ./.; fileset = cleanSourceWith { src = ./.; };
\s*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.'
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`.'

# File sets cannot be evaluated directly
expectFailure 'union ./. ./.' 'lib.fileset: Directly evaluating a file set is not supported.
@@ -1450,6 +1451,40 @@ checkGitTracked

rm -rf -- *

## lib.fileset.maybeMissing

# Argument must be a path
expectFailure 'maybeMissing "someString"' 'lib.fileset.maybeMissing: Argument \("someString"\) is a string-like value, but it should be a path instead.'
expectFailure 'maybeMissing null' 'lib.fileset.maybeMissing: Argument is of type null, but it should be a path instead.'

tree=(
)
checkFileset 'maybeMissing ./a'
checkFileset 'maybeMissing ./b'
checkFileset 'maybeMissing ./b/c'

# Works on single files
tree=(
    [a]=1
    [b/c]=0
    [b/d]=0
)
checkFileset 'maybeMissing ./a'
tree=(
    [a]=0
    [b/c]=1
    [b/d]=0
)
checkFileset 'maybeMissing ./b/c'

# Works on directories
tree=(
    [a]=0
    [b/c]=1
    [b/d]=1
)
checkFileset 'maybeMissing ./b'

# TODO: Once we have combinators and a property testing library, derive property tests from https://en.wikipedia.org/wiki/Algebra_of_sets

echo >&2 tests ok