scloudFileFinder<T> function

FileFinder<T> scloudFileFinder<T>({
  1. required String fileBaseName,
  2. required List<String> supportedExtensions,
  3. String? startingDirectory(
    1. T arg
    )?,
  4. int searchLevelsUp = 2,
  5. int searchLevelsDown = 3,
  6. FileContentCondition? fileContentCondition,
})

Returns a FileFinder function that implements the algorithm for finding scloud project files.

A directory is considered a candidate if it directly contains a file named <fileBaseName>.<ext> (for one of the supportedExtensions) for which fileContentCondition, if provided, returns true. By choosing the file name and content condition the same algorithm can find a Serverpod server directory both with and without an scloud.yaml file.

If startingDirectory is not provided or it returns null, the current directory is used as starting directory.

Starting from the starting directory, the search proceeds as follows: Traverse the directory tree searchLevelsUp levels up, one at a time:

  1. If the directory is a candidate, it is used.
  2. If the directory is a Dart workspace root, search its workspace packages. If exactly one candidate is found it is used, otherwise the search ends.
  3. Search searchLevelsDown levels down. If exactly one candidate is found it is used.
  4. If the directory is a git repository root, or the filesystem root, stop the search.

If multiple candidate files are found at any single step then an AmbiguousSearchException is thrown.

If a single matching file is found then its absolute path is returned, otherwise null.

Implementation

FileFinder<T> scloudFileFinder<T>({
  required final String fileBaseName,
  required final List<String> supportedExtensions,
  final String? Function(T arg)? startingDirectory,
  final int searchLevelsUp = 2,
  final int searchLevelsDown = 3,
  final FileContentCondition? fileContentCondition,
}) {
  final filenames = supportedExtensions
      .map((final ext) => '$fileBaseName.$ext')
      .toList();

  return (final T arg) {
    final startDir = p.absolute(
      p.normalize(startingDirectory?.call(arg) ?? Directory.current.path),
    );
    final finder = _StatefulFileFinder();
    return finder._findProjectFile(
      startDir,
      filenames,
      searchLevelsUp: searchLevelsUp,
      searchLevelsDown: searchLevelsDown,
      fileContentCondition: fileContentCondition,
    );
  };
}