Browse the docs

silk.system.glob_scan.

Find the files and directories that a glob pattern matches, by walking directories through the FileSystem effect.

When to use#

Use scan to collect every match of a pattern such as src/**/*.silk, or a Walker to take matches one at a time. To test paths you already have, use silk.text.glob directly.

Details#

A scan reads only the directories its pattern can reach. A literal segment is looked up directly, a wildcard segment lists one directory, and ** descends into every directory below. Results are relative to ScanOptions.base, joined with /, with . and .. segments of the pattern resolved, and each one is reported once; the base itself is .. A pattern that starts with / is scanned from the provider's root and reports absolute paths. The order of results is unspecified.

Each segment is matched on its own, so a ! at the start of a segment negates that segment only: !test/*.silk matches files in every directory except test. There is no whole-pattern negation; to leave matches out, test the results with a silk.text.glob pattern.

Names are host bytes and are reported as they are, also when they are not UTF-8.

A literal segment follows a symbolic link, so docs/*.md works when docs is a link to a directory. A link that a wildcard matched is never entered, which also keeps a scan from looping through a cycle of links; it is reported only when ScanOptions.onlyFiles is false.

Every read goes through the FileSystem effect, so a scan sees exactly what the provider shows, and a provider in memory or one that records reads works the same way.

Errors#

  • FileError if the starting directory is missing or is not a directory, or if the provider refuses a lookup or a listing, for example with PermissionDenied. An entry that is missing, is not a directory, or has a name no path can hold is not an error: it matches nothing.

  • OutOfMemoryError from every operation that returns owned paths.

Examples#

Find the Silk sources of a project#

silk
import silk.system.glob_scan { ScanOptions, scan }
import silk.system.filesystem { FileError, FileSystem, Path }
import silk.system.filesystem_native { OsFileSystem }
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.collections.bytes { Bytes }
import silk.collections.list { List }
import silk.core.effect { Effect }

effect fn program() -> i32 ! FileError | OutOfMemoryError ? &mut FileSystem | &mut Allocator {
  let root = run Path.root()
  let scratch = run FileSystem.temporaryDirectory(&root, "silk-glob-")
  run FileSystem.writeFileWithParents(&run Path.join(&scratch.path, "src/main.silk"), b"")
  run FileSystem.writeFileWithParents(&run Path.join(&scratch.path, "src/net/http.silk"), b"")
  run FileSystem.writeFileWithParents(&run Path.join(&scratch.path, "README.md"), b"")
  let options = run ScanOptions.make(&scratch.path)
  let found = run scan("src/**/*.silk", move options)
  let count = List<Bytes>.length(&found)
  drop found
  run FileSystem.release(move scratch)
  if count != 2 {
    return 1
  }
  return 0
}

effect fn failed<E>(error: E) -> i32 {
  drop error
  return 2
}

effect fn withFiles() -> i32 ! FileError | OutOfMemoryError ? &mut Allocator {
  let mut files = run OsFileSystem.make("/tmp")
  return run program() |> Effect.provideMut<FileSystem>(&mut files)
}

pub fn main() -> i32 {
  let mut allocator = Allocator.systemAllocatorProvider()
  return run Effect.catchAll(withFiles(), failed) |> Effect.provideMut<Allocator>(&mut allocator)
}

Import as glob_scan with import silk.system.glob_scan as glob_scan.

Public declarations: 4.

ScanOptions#

silk
pub struct ScanOptions

What a scan starts from and which entries it reports.

Field base#

silk
pub base: Path

The directory relative patterns start from. Results are relative to it.

Field dot#

silk
pub dot: bool

Whether wildcards match names that start with .. A component that starts with a literal . matches such names either way.

Field onlyFiles#

silk
pub onlyFiles: bool

Whether only regular files are reported. When false, directories and symbolic links that a wildcard matched are reported too.

Implementation ScanOptions#

silk
impl ScanOptions

Associated function make#

silk
pub effect fn make(base: &Path) -> ScanOptions
    ! OutOfMemoryError
    ? &mut Allocator

Options that scan from base, skip hidden names, and report regular files only.

Errors#

  • OutOfMemoryError if the Allocator cannot copy base.

Walker#

silk
pub struct Walker

A scan in progress: the directories still to read and the matches not yet returned.

Implementation Walker#

silk
impl Walker

Associated function make#

silk
pub effect fn make(written: string, options: ScanOptions) -> Walker
    ! FileError | OutOfMemoryError
    ? &mut FileSystem | &mut Allocator

Starts a scan for the pattern written below options.base, or below the provider's root when written starts with /.

Details#

Results are relative to options.base, joined with /, with . and .. segments of the pattern resolved, and each path is reported once; the base itself is .. A pattern that starts with / reports absolute paths. The order is unspecified.

The pattern is split at / into segments, and each directory is read only when a segment can match below it: src/*.silk lists src and nothing else. Braces and groups work within one segment. A / inside braces still splits the pattern, so {a/b,c} becomes the segments {a and b,c}, which match those names literally. A ! at the start of a segment negates that segment only. A pattern that ends with / reports directories only, and so reports nothing while onlyFiles is set. An empty pattern reports nothing.

A literal segment follows a symbolic link, so a link it names counts as what it points to. A link that a wildcard matched is never entered and is reported only when onlyFiles is false.

Errors#

  • FileError if the starting directory does not exist or is not a directory, or if the provider refuses to look it up.

  • OutOfMemoryError if the Allocator cannot supply the walker.

Associated function makeBytes#

silk
pub effect fn makeBytes(pattern: &[u8], options: ScanOptions) -> Walker
    ! FileError | OutOfMemoryError
    ? &mut FileSystem | &mut Allocator

Starts a scan for the host-byte pattern pattern, which need not be UTF-8, below options.base, or below the provider's root when pattern starts with /.

Details#

Results are relative to options.base, joined with /, with . and .. segments of the pattern resolved, and each path is reported once; the base itself is .. A pattern that starts with / reports absolute paths. The order is unspecified.

The pattern is split at / into segments, and each directory is read only when a segment can match below it: src/*.silk lists src and nothing else. Braces and groups work within one segment. A / inside braces still splits the pattern, so {a/b,c} becomes the segments {a and b,c}, which match those names literally. A ! at the start of a segment negates that segment only. A pattern that ends with / reports directories only, and so reports nothing while onlyFiles is set. An empty pattern reports nothing.

A literal segment follows a symbolic link, so a link it names counts as what it points to. A link that a wildcard matched is never entered and is reported only when onlyFiles is false.

Errors#

  • FileError if the starting directory does not exist or is not a directory, or if the provider refuses to look it up.

  • OutOfMemoryError if the Allocator cannot supply the walker.

Method next#

silk
pub effect fn next(self: &mut Self) -> Option<Bytes>
    ! FileError | OutOfMemoryError
    ? &mut FileSystem | &mut Allocator

Returns the next match, or none once the scan is done.

Details#

A match is a path relative to the base, joined with /, or an absolute path for an absolute pattern; the base itself is .. Each path is returned once, in unspecified order. Once it returns none, it keeps returning none.

Errors#

  • FileError if the provider refuses to look up or list an entry the scan reaches, for example with PermissionDenied. An entry that is missing or is not a directory matches nothing instead.

  • OutOfMemoryError if the Allocator cannot supply a listing or a result.

Method collect#

silk
pub effect fn collect(self: &mut Self) -> List<Bytes>
    ! FileError | OutOfMemoryError
    ? &mut FileSystem | &mut Allocator

Returns every match the scan has not returned yet, in unspecified order, as Walker.next would return them one at a time.

Errors#

scan#

silk
pub effect fn scan(pattern: string, options: ScanOptions) -> List<Bytes>
  ! FileError | OutOfMemoryError
  ? &mut FileSystem | &mut Allocator

Returns every path that pattern matches below options.base, in unspecified order.

Details#

Results are relative to options.base, joined with /, with . and .. segments of the pattern resolved, and each path is reported once; the base itself is .. A pattern that starts with / is scanned from the provider's root and reports absolute paths. Each segment is matched on its own: a / inside braces still splits the pattern, and a ! at the start of a segment negates that segment only. A literal segment follows a symbolic link; a link that a wildcard matched is never entered and is reported only when onlyFiles is false.

Errors#

  • FileError if the starting directory does not exist or is not a directory, or if the provider refuses to look up or list an entry the scan reaches.

  • OutOfMemoryError if the Allocator cannot supply a listing or a result.

scanBytes#

silk
pub effect fn scanBytes(pattern: &[u8], options: ScanOptions) -> List<Bytes>
  ! FileError | OutOfMemoryError
  ? &mut FileSystem | &mut Allocator

Returns every path that the host-byte pattern pattern, which need not be UTF-8, matches below options.base, in unspecified order.

Details#

Results are relative to options.base, joined with /, with . and .. segments of the pattern resolved, and each path is reported once; the base itself is .. A pattern that starts with / is scanned from the provider's root and reports absolute paths. Each segment is matched on its own: a / inside braces still splits the pattern, and a ! at the start of a segment negates that segment only. A literal segment follows a symbolic link; a link that a wildcard matched is never entered and is reported only when onlyFiles is false.

Errors#

  • FileError if the starting directory does not exist or is not a directory, or if the provider refuses to look up or list an entry the scan reaches.

  • OutOfMemoryError if the Allocator cannot supply a listing or a result.

Category: System.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.

View the source of this page