run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<int> run() async {
final scanner = ProjectScanner();
final context = scanner.scan();
if (context == null) {
print('✗ Current directory is not a Flutter project.');
return 1;
}
final registry = const AuditRegistry();
final engine = AuditEngine(audits: registry.getAudits());
final spinner = Spinner('Running audits...')..start();
final rawResults = await engine.run(context);
spinner.stop();
final ignoreConfig = await IgnoreConfigHelper.load(context);
final (afterIgnore, suppressedCount) = ignoreConfig.apply(
rawResults,
context,
);
if (suppressedCount > 0) {
print(
'ⓘ $suppressedCount finding(s) suppressed by .flutter_auditor_ignore.yaml',
);
print('');
}
if (argResults!.flag('update-baseline')) {
await BaselineHelper.write(afterIgnore, context);
final total = afterIgnore.fold<int>(
0,
(sum, run) => sum + run.result.issues.length,
);
print(
'✅ Baseline written to ${context.baselineFile.path} '
'($total finding(s) recorded).',
);
print(' Future runs will only fail on newly introduced findings.');
return 0;
}
final baselineConfig = await BaselineHelper.load(context);
final (results, baselinedCount, exemptFromFailOn) = baselineConfig.apply(
afterIgnore,
context,
);
if (baselinedCount > 0) {
final visibleCount = exemptFromFailOn.length;
print(
'ⓘ $baselinedCount pre-existing finding(s) accepted via '
'.flutter_auditor_baseline.json'
'${visibleCount > 0 ? ' ($visibleCount critical/high still shown, non-blocking)' : ''}',
);
print('');
}
final reporter = const ConsoleReporter();
final verbose = argResults!.flag('verbose');
final failOnArg = argResults!.option('fail-on')!;
final failOn = failOnArg == 'none'
? null
: Severity.values.firstWhere((severity) => severity.name == failOnArg);
final exitCode = reporter.printReport(
results,
context: context,
verbose: verbose,
failOn: failOn,
exemptFromFailOn: exemptFromFailOn,
);
final htmlPath = argResults!.option('html');
if (htmlPath != null) {
final htmlReporter = const HtmlReporter();
final file = htmlReporter.writeReport(
results,
context: context,
outputPath: htmlPath,
);
print('');
print('📊 HTML report written to: ${file.path}');
if (argResults!.flag('open')) {
await _openInBrowser(file.path);
}
}
final jsonPath = argResults!.option('json');
if (jsonPath != null) {
final jsonReporter = const JsonReporter();
final file = jsonReporter.writeReport(
results,
context: context,
outputPath: jsonPath,
);
print('');
print('📄 JSON report written to: ${file.path}');
}
final sarifPath = argResults!.option('sarif');
if (sarifPath != null) {
final sarifReporter = const SarifReporter();
final file = sarifReporter.writeReport(
results,
context: context,
outputPath: sarifPath,
);
print('');
print('📄 SARIF report written to: ${file.path}');
}
return exitCode;
}