discoverCommandsInDir function
Scans commandsDir for *.dart files (excluding _index.g.dart and
anything else starting with _), extracts ArtisanCommand subclass
names, returns one DiscoveredCommand per match.
Multiple matching classes in the same file are returned in declaration order. The result is sorted by file name to keep the generated index deterministic across runs.
Implementation
List<DiscoveredCommand> discoverCommandsInDir(Directory commandsDir) {
if (!commandsDir.existsSync()) return const <DiscoveredCommand>[];
final entries = commandsDir.listSync().whereType<File>().where((f) {
final base = p.basename(f.path);
if (!base.endsWith('.dart')) return false;
if (base.startsWith('_')) return false; // _index.g.dart + any private file
return true;
}).toList()
..sort((a, b) => a.path.compareTo(b.path));
final out = <DiscoveredCommand>[];
for (final file in entries) {
final source = file.readAsStringSync();
for (final match in _classPattern.allMatches(source)) {
final className = match.group(1)!;
out.add(
DiscoveredCommand(
className: className,
fileName: p.basename(file.path),
),
);
}
}
return out;
}