recursivePubPath function

Future<List<String>> recursivePubPath(
  1. List<String> dirs, {
  2. List<String>? dependencies,
  3. bool? readConfig,
  4. FilterDartProjectOptions? filterDartProjectOptions,
})

if forceRecursive is true, we folder going deeper even if the current path is a dart project

if ignoreSdkConstraints is true, it lists the project even if not compatible.

if dependencies is specified, it will only list the project that contains such dependency, use either dependency like path, or 'direct:path', 'dev:path' or 'override:path'. Returns the list of valid pub folder, including me

Implementation

Future<List<String>> recursivePubPath(List<String> dirs,
    {List<String>? dependencies,
    bool? readConfig,
    FilterDartProjectOptions? filterDartProjectOptions}) async {
  var pubDirs = await filterPubPath(dirs,
      dependencies: dependencies,
      readConfig: readConfig,
      filterDartProjectOptions: filterDartProjectOptions);

  Future<List<String>> getSubDirs(String dir) async {
    if (!_isToBeIgnored(basename(dir))) {
      // devPrint('testing: $dir');
      final sub = <String>[];
      final futures = <Future>[];
      await Directory(dir).list().listen((FileSystemEntity fse) {
        var subDir = fse.path;
        // Make sure it is not added even if it is a package root
        if (!_isToBeIgnored(basename(subDir))) {
          if (FileSystemEntity.isDirectorySync(subDir)) {
            // Also handle the case where the directory linked is a dart project
            futures.add(() async {
              var isLink = FileSystemEntity.isLinkSync(subDir);
              if (isLink) {
                if (await isPubPackageRoot(subDir,
                    filterDartProjectOptions: filterDartProjectOptions)) {
                  sub.add(subDir);
                }
                return;
              }
              var subPubDirs = await filterPubPath([subDir],
                  dependencies: dependencies,
                  readConfig: readConfig,
                  filterDartProjectOptions: filterDartProjectOptions);
              sub.addAll(subPubDirs);
              sub.addAll(await getSubDirs(subDir));
            }());
          }
        }
      }).asFuture<void>();
      await Future.wait(futures);
      return sub;
    }
    return <String>[];
  }

  for (final dir in dirs) {
    if (isDirectoryNotLinkSynk(dir)) {
      pubDirs.addAll(await getSubDirs(dir));
    } else {
      throw '$dir not a directory';
    }
  }

  return removeDuplicates(pubDirs)..sort();
}