Skip to content

Instantly share code, notes, and snippets.

@HelloCore
Created August 17, 2021 14:53
Show Gist options
  • Save HelloCore/09337d5593c7ea3d8768f76c3b59d558 to your computer and use it in GitHub Desktop.
Save HelloCore/09337d5593c7ea3d8768f76c3b59d558 to your computer and use it in GitHub Desktop.
Danger Plugin Code Coverage Report Github
import 'dart:io';
import 'package:danger_core/danger_core.dart';
import 'package:lcov_dart/lcov_dart.dart';
class _CodeCovReport {
final String fileName;
final String filePath;
final String rawFilePath;
final double linePercent;
final List<int> uncoveredLines;
_CodeCovReport({
required this.linePercent,
required this.uncoveredLines,
required this.filePath,
required this.fileName,
required this.rawFilePath,
});
String formatPercent(double percent) {
if (percent == 1.0) {
return '100%';
} else {
return '${(percent * 100).toStringAsFixed(2)}%';
}
}
String linkToFile() {
return '<a href="https://github.com/${danger.github.thisPR.owner}/${danger.github.thisPR.repo}/blob/${danger.github.pr.head.sha}/$filePath/$fileName">$filePath/$fileName</a>';
}
String linkToLine(int lineNo) {
return lineNo.toString();
}
String toTable() {
return '''<tr>
<td>${linkToFile()}</td>
<td>${formatPercent(linePercent)}</td>
<td>${uncoveredLines.map((e) => linkToLine(e)).join(', ')}</td>
</tr>''';
}
}
class DangerCodeCov {
static void process(File file, {List<Pattern> ignoredList = const []}) {
final content = file.readAsStringSync();
final report = Report.fromCoverage(content);
/// Filter files based on ignoredList
final effectiveRecords = report.records.where((element) {
if (ignoredList.isEmpty) {
return true;
}
return ignoredList.any((pattern) {
if (element == null) {
return false;
}
final result = pattern.allMatches(element.sourceFile);
return result.isNotEmpty;
}) ==
false;
}).toList();
var lines = 0;
var hits = 0;
effectiveRecords.forEach((record) {
lines += record?.lines?.found ?? 0;
hits += record?.lines?.hit ?? 0;
});
final totalPercent = hits / lines;
var results = effectiveRecords
.where((element) => (element?.lines?.found ?? 0) > 0)
.map((e) {
if (e == null) {
return null;
} else {
final fileComponents = e.sourceFile.split('/');
final fileName = fileComponents.removeLast();
final filePath = fileComponents.join('/');
return _CodeCovReport(
fileName: fileName,
filePath: filePath,
rawFilePath: e.sourceFile,
linePercent: _calPercent(found: e.lines?.found, hit: e.lines?.hit),
uncoveredLines: (e.lines?.data
.map((e) {
if (e.executionCount == 0) {
return e.lineNumber;
} else {
return null;
}
})
.where((element) => element != null)
.toList() ??
[]) as List<int>,
);
}
})
.where((element) => element != null)
.toList();
results.sort((e1, e2) => e1!.linePercent.compareTo(e2!.linePercent));
if (results.length > 30) {
results = results.sublist(0, 30);
}
markdown('''<br><br>Total Coverage: **${(totalPercent * 100).toStringAsFixed(2)}%**
<details>
<summary>Coverage Report</summary>
<p>
<strong>Show only 30 lowest coverage percent file.</strong>
<table>
<thead>
<tr>
<th>File</th>
<th>Percent</th>
<th>Uncovered Lines</th>
</tr>
</thead>
<tbody>
${results.map((e) => e!.toTable()).join('\n')}
</tbody>
</table>
</p>
</details>
''');
}
static double _calPercent({int? found, int? hit}) {
if (found == null || hit == null || found == 0.0 || hit == 0.0) {
return 0.0;
}
return hit / found;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment