expand static method
Every existing file matching pattern, newest first.
Returns an empty list when nothing matches; the caller decides whether that is an error, because a dry run legitimately has nothing to match yet.
Implementation
static List<File> expand(String pattern, {Directory? from}) {
final normalized = pattern.replaceAll('\\', '/');
final segments = normalized.split('/');
// Everything before the first magic segment is a real directory to start
// from; listing the whole tree from the working directory would be absurd
// for a pattern that named one folder.
final fixed = <String>[];
var index = 0;
while (index < segments.length && !hasMagic(segments[index])) {
fixed.add(segments[index]);
index++;
}
if (index == segments.length) {
// No magic after all — resolve it as the plain path it is, still
// relative to `from` so the two branches agree.
final literal = from == null ? pattern : path.join(from.path, pattern);
final file = File(literal);
return file.existsSync() ? [file] : const [];
}
final rootPath = fixed.isEmpty
? (from?.path ?? '.')
: (from == null
? fixed.join(Platform.pathSeparator)
: path.join(from.path, fixed.join(Platform.pathSeparator)));
final root = Directory(rootPath);
if (!root.existsSync()) return const [];
final remainder = segments.sublist(index).join('/');
final matcher = _toRegExp(remainder);
final recursive = remainder.contains('**') || remainder.contains('/');
final matches = <File>[];
for (final entity in root.listSync(recursive: recursive)) {
if (entity is! File) continue;
final relative =
path.relative(entity.path, from: root.path).replaceAll('\\', '/');
if (matcher.hasMatch(relative)) matches.add(entity);
}
matches.sort(
(a, b) => b.lastModifiedSync().compareTo(a.lastModifiedSync()),
);
return matches;
}