scanForDartProjects function

List<String> scanForDartProjects(
  1. String dir, {
  2. bool recursive = false,
  3. bool includeTestProjects = false,
  4. bool verbose = false,
})

Scan a directory for Dart projects (directories containing pubspec.yaml).

When recursive is true, performs a controlled recursive walk that:

  • Skips hidden directories (names starting with .)
  • Skips known non-project directories (build, node_modules, etc.)
  • Skips zom_* test folders (unless includeTestProjects is true)
  • Stops at workspace boundaries (buildkit_master.yaml)
  • Respects skip markers (tom_skip.yaml, buildkit_skip.yaml)

When recursive is false, only checks immediate subdirectories and the root itself.

Implementation

List<String> scanForDartProjects(
  String dir, {
  bool recursive = false,
  bool includeTestProjects = false,
  bool verbose = false,
}) {
  final root = Directory(dir);
  if (!root.existsSync()) return [];

  final results = <String>[];
  if (recursive) {
    _scanRecursive(
      root,
      results,
      isRoot: true,
      includeTestProjects: includeTestProjects,
      verbose: verbose,
    );
  } else {
    // Non-recursive: check immediate children + root itself
    final rootPubspec = File(p.join(dir, 'pubspec.yaml'));
    if (rootPubspec.existsSync()) results.add(dir);

    try {
      for (final entity in root.listSync()) {
        if (entity is Directory) {
          final name = p.basename(entity.path);
          if (name.startsWith('.')) continue;
          if (kAlwaysSkipDirectories.contains(name)) continue;
          if (!includeTestProjects && name.startsWith('zom_')) continue;
          final pubspec = File(p.join(entity.path, 'pubspec.yaml'));
          if (pubspec.existsSync()) results.add(entity.path);
        }
      }
    } on FileSystemException {
      // Permission denied or other filesystem error
    }
  }
  return results;
}