iteratePubPath function
Future<void>
iteratePubPath(
- List<
String> dirs, { - IteratePubPathOptions? options,
- required IteratePubPathHandler onPubPath,
Iterate over the pub packages found in dirs.
onPubPath is called for each pub folder found, including dirs
themselves, in alphabetical path order (i.e. the order of the list
returned by recursivePubPath). Return false to stop the iteration.
Contrary to recursivePubPath, the folders are scanned lazily, so the iteration can stop before the whole tree is read.
A folder is never handled twice. Links are resolved and reported using their target path, which is reported where the link is found, so it can break the alphabetical order.
Implementation
Future<void> iteratePubPath(
List<String> dirs, {
IteratePubPathOptions? options,
required IteratePubPathHandler onPubPath,
}) async {
options ??= const IteratePubPathOptions();
var dependencies = options.dependencies;
var readConfig = options.readConfig;
var filterDartProjectOptions = options.filterDartProjectOptions;
var recursive = options.recursive ?? true;
// Folders to visit, sorted by path.
var pending = SplayTreeSet<String>();
// Absolute normalized paths already queued, to avoid duplicates and
// link loops.
var queued = <String>{};
void addPending(String dir) {
if (queued.add(normalize(absolute(dir)))) {
pending.add(dir);
}
}
for (final dir in dirs) {
if (!FileSystemEntity.isDirectorySync(dir)) {
throw ArgumentError('$dir not a directory');
}
addPending(dir);
}
while (pending.isNotEmpty) {
// Smallest path first, any folder found later is a sub folder of one of
// the pending folders, hence greater.
var dir = pending.first;
pending.remove(dir);
final handled = await _checkProjectMatch(
dir,
dependencies: dependencies,
readConfig: readConfig,
filterDartProjectOptions: filterDartProjectOptions,
);
if (handled) {
if (!await onPubPath(dir)) {
return;
}
}
if (recursive) {
for (final subDir in await _listSubDirs(dir)) {
addPending(subDir);
}
}
}
}