Unverified Commit 4d11de3e authored by Silvan Mosberger's avatar Silvan Mosberger Committed by GitHub
Browse files

Merge pull request #288677 from tweag/fileset.toList

lib.fileset.toList: init
parents 6d7b0ddf e3a6e380
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -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),
+23 −0
Original line number Diff line number Diff line
@@ -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; }
+22 −2
Original line number Diff line number Diff line
@@ -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,
@@ -511,6 +518,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