run method
Run the full doctor workflow.
If dryRun is true, scans and reports but does not delete or regenerate.
Implementation
Future<DoctorResult> run({bool dryRun = false}) async {
final dirs = sourceDirs;
// Step 1: Find all .zorphy.dart files
final generatedFiles = _doFindFiles(projectDir, sourceDirs: dirs);
// Step 2: Delete files (unless dry-run)
final deletedFiles = <String>[];
if (dryRun) {
deletedFiles.addAll(generatedFiles);
} else {
for (final filePath in generatedFiles) {
if (_doDeleteFile(filePath)) {
deletedFiles.add(filePath);
}
}
}
// Step 3: Run build_runner (unless dry-run)
var buildOutput = '';
int? buildExitCode;
if (!dryRun) {
final result = await _doRunProcess('dart', [
'run',
'build_runner',
'build',
'--delete-conflicting-outputs',
], workingDirectory: projectDir);
buildOutput = '${result.stdout}\n${result.stderr}';
buildExitCode = result.exitCode;
}
// Step 4: Count regenerated files and check for InvalidType
int regeneratedCount = 0;
final remainingInvalidTypeFiles = <String>[];
final filesAfterBuild = _doFindFiles(projectDir, sourceDirs: dirs);
if (!dryRun) {
// Count files that exist now but weren't in the original set
// (or simply count all current .zorphy.dart files as regenerated)
regeneratedCount = filesAfterBuild.length;
// Scan for InvalidType in the regenerated files
for (final filePath in filesAfterBuild) {
try {
final content = _doReadFile(filePath);
if (content.contains('InvalidType')) {
remainingInvalidTypeFiles.add(filePath);
}
} catch (_) {
// If we can't read a file, skip it
}
}
}
return DoctorResult(
deletedFiles: deletedFiles,
regeneratedCount: regeneratedCount,
remainingInvalidTypeFiles: remainingInvalidTypeFiles,
dryRun: dryRun,
projectDir: projectDir,
buildOutput: buildOutput,
buildExitCode: buildExitCode,
);
}