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(projectPath, projectConfig.featuresPath);
if (!Directory(featuresPath).existsSync()) {
_logger.info(
'No features directory found under ${projectConfig.featuresPath}. 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, featuresPath);
if (sourceLayer == null) continue;
final fileViolations = _auditFile(
file: file,
sourceLayer: sourceLayer,
projectName: projectName,
libPath: libPath,
featuresPath: featuresPath,
);
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;
}