Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

feat: improve checkstyle report, added metrics entries #896

Merged
merged 1 commit into from Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@
* feat: add [`avoid-banned-imports`](https://dartcodemetrics.dev/docs/rules/common/avoid-banned-imports) rule
* fix: resolve package with imported analysis options.
* feat: add configuration to [`prefer-extracting-callbacks`](https://dartcodemetrics.dev/docs/rules/flutter/prefer-extracting-callbacks)
* feat: improve [`checkstyle`](https://dartcodemetrics.dev/docs/cli/analyze#checkstyle) report, added metrics entries.

## 4.15.2

Expand Down
Expand Up @@ -3,6 +3,7 @@ import 'dart:io';
import 'package:xml/xml.dart';

import '../../../../../reporters/models/checkstyle_reporter.dart';
import '../../../metrics/models/metric_value_level.dart';
import '../../../models/lint_file_report.dart';
import '../../../models/severity.dart';
import '../../../models/summary_lint_report_record.dart';
Expand Down Expand Up @@ -39,22 +40,8 @@ class LintCheckstyleReporter extends CheckstyleReporter<LintFileReport,
'file',
attributes: {'name': record.relativePath},
nest: () {
final issues = [...record.issues, ...record.antiPatternCases];

for (final issue in issues) {
final locationStart = issue.location.start;
builder.element(
'error',
attributes: {
'line': '${locationStart.line}',
if (locationStart.column > 0)
'column': '${locationStart.column}',
'severity': _severityMapping[issue.severity] ?? 'ignore',
'message': issue.message,
'source': issue.ruleId,
},
);
}
_reportIssues(builder, record);
_reportMetrics(builder, record);
},
);
}
Expand All @@ -63,14 +50,84 @@ class LintCheckstyleReporter extends CheckstyleReporter<LintFileReport,
output.writeln(builder.buildDocument().toXmlString(pretty: true));
}

void _reportIssues(XmlBuilder builder, LintFileReport report) {
final issues = [...report.issues, ...report.antiPatternCases];

for (final issue in issues) {
final locationStart = issue.location.start;
builder.element(
'error',
attributes: {
'line': '${locationStart.line}',
if (locationStart.column > 0) 'column': '${locationStart.column}',
'severity': _issueSeverityMapping[issue.severity] ?? 'ignore',
'message': issue.message,
'source': issue.ruleId,
},
);
}
}

void _reportMetrics(XmlBuilder builder, LintFileReport record) {
for (final metric in record.file.metrics) {
if (_isMetricNeedToReport(metric.level)) {
builder.element(
'error',
attributes: {
'line': '0',
'severity': _metricSeverityMapping[metric.level] ?? 'ignore',
'message': metric.comment,
'source': metric.metricsId,
},
);
}
}

final metricRecords =
{...record.classes, ...record.functions}.entries.toList();
for (final record in metricRecords) {
if (!_isMetricNeedToReport(record.value.metricsLevel)) {
continue;
}

final location = record.value.location;

for (final metricValue in record.value.metrics) {
builder.element(
'error',
attributes: {
'line': '${location.start.line}',
if (record.value.location.start.column > 0)
'column': '${record.value.location.start.column}',
'severity': _metricSeverityMapping[metricValue.level] ?? 'ignore',
'message': metricValue.comment,
'source': metricValue.metricsId,
},
);
}
}
}

bool _needToReport(LintFileReport report) =>
report.issues.isNotEmpty || report.antiPatternCases.isNotEmpty;
report.issues.isNotEmpty ||
report.antiPatternCases.isNotEmpty ||
_isMetricNeedToReport(report.file.metricsLevel);

bool _isMetricNeedToReport(MetricValueLevel level) =>
level > MetricValueLevel.none;
}

const _severityMapping = {
const _issueSeverityMapping = {
Severity.error: 'error',
Severity.warning: 'warning',
Severity.style: 'info',
Severity.performance: 'warning',
Severity.none: 'ignore',
};

const _metricSeverityMapping = {
MetricValueLevel.alarm: 'error',
MetricValueLevel.warning: 'warning',
MetricValueLevel.noted: 'info',
MetricValueLevel.none: 'ignore',
};
Expand Up @@ -35,22 +35,41 @@ void main() {
final file = report.findAllElements('file');
expect(
file.first.getAttribute('name'),
equals('test/resources/abstract_class.dart'),
);
expect(
file.last.getAttribute('name'),
equals('test/resources/class_with_factory_constructors.dart'),
);

final errors = report.findAllElements('error');
var errors = file.first.findAllElements('error').toList();
expect(errors.first.getAttribute('line'), equals('0'));
expect(errors.first.getAttribute('severity'), equals('warning'));
expect(errors.first.getAttribute('message'), equals('metric comment'));
expect(errors.first.getAttribute('source'), equals('file-metric-id'));
expect(errors.last.getAttribute('line'), equals('0'));
expect(errors.last.getAttribute('severity'), equals('error'));
expect(errors.last.getAttribute('message'), equals('metric comment'));
expect(errors.last.getAttribute('source'), equals('id'));

errors = file.last.findAllElements('error').toList();
expect(errors.first.getAttribute('line'), equals('0'));
expect(errors.first.getAttribute('severity'), equals('warning'));
expect(errors.first.getAttribute('message'), equals('simple message'));
expect(errors.first.getAttribute('source'), equals('id'));

expect(errors.last.getAttribute('line'), equals('0'));
expect(errors.last.getAttribute('severity'), equals('info'));
expect(errors[1].getAttribute('line'), equals('0'));
expect(errors[1].getAttribute('severity'), equals('info'));
expect(
errors.last.getAttribute('message'),
errors[1].getAttribute('message'),
equals('simple design message'),
);
expect(errors.last.getAttribute('source'), equals('designId'));
expect(errors[1].getAttribute('source'), equals('designId'));

expect(errors.last.getAttribute('line'), equals('0'));
expect(errors.last.getAttribute('severity'), equals('warning'));
expect(errors.last.getAttribute('message'), equals('metric comment'));
expect(errors.last.getAttribute('source'), equals('id'));
});
});
}