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 projectConfig = _configParser.readConfig(fallbackProjectName: '');
if (projectConfig == null) {
_logger.err('Error: No zuq.yaml configuration found in this directory.');
_logger.err('Make sure you are at the root of a zuq project.');
return 1;
}
final projectName = projectConfig.projectName;
final projectPath = Directory.current.path;
final libPath = p.join(projectPath, 'lib');
final featuresPath = p.join(libPath, 'features');
if (!Directory(featuresPath).existsSync()) {
_logger.info('No features directory found under lib/features. Architecture is clean.');
return 0;
}
_logger.info('Auditing project architectural boundaries for ${lightCyan.wrap(projectName)}...');
final List<DoctorViolation> violations = [];
final dartFiles = _findDartFiles(Directory(featuresPath));
for (final file in dartFiles) {
final sourceLayer = _getLayerOfPath(file.path, libPath);
if (sourceLayer == null) continue;
final fileViolations = _auditFile(
file: file,
sourceLayer: sourceLayer,
projectName: projectName,
libPath: libPath,
);
violations.addAll(fileViolations);
}
if (violations.isEmpty) {
_logger.success('\nā Architecture audit completed: 0 violations found.');
return 0;
}
_logger.err('\nā Architecture audit failed: ${violations.length} violations found:\n');
for (final violation in violations) {
final relativePath = p.relative(violation.filePath, from: projectPath);
_logger.info(
' ${red.wrap('Violation')} in ${lightCyan.wrap('$relativePath:${violation.lineNumber}')}\n'
' Layer: ${yellow.wrap(violation.sourceLayer)} ā Target Layer: ${yellow.wrap(violation.targetLayer)}\n'
' Import: ${red.wrap(violation.importUri)}\n'
' Reason: ${violation.description}\n',
);
}
return 1;
}