1+ import 'dart:io' ;
2+
3+ void main (List <String > args) {
4+ printMessage ('Start filtering the lcov.info file' );
5+ final file = File ('coverage/lcov.info' );
6+ if (! file.existsSync ()) {
7+ printMessage ('${file .path }" does not exist' );
8+ return ;
9+ }
10+ const endOfRecord = 'end_of_record' ;
11+ final sections = < LcovSection > [];
12+ final lines = file.readAsLinesSync ();
13+ LcovSection ? currentSection;
14+ for (final line in lines) {
15+ if (line.endsWith ('.dart' )) {
16+ final filePath = line.replaceAll ('SF:' , '' );
17+ currentSection = LcovSection ()
18+ ..header = line
19+ ..filePath = filePath;
20+ } else if (line == endOfRecord) {
21+ final currentSectionTmp = currentSection;
22+ if (currentSectionTmp != null ) {
23+ currentSectionTmp.footer = line;
24+ sections.add (currentSectionTmp);
25+ }
26+ } else {
27+ currentSection? .body.add (line);
28+ }
29+ }
30+ final filteredSections = getFilteredSections (sections);
31+ final sb = StringBuffer ();
32+ for (final section in filteredSections) {
33+ sb.write (section.toString ());
34+ }
35+ file.writeAsStringSync (sb.toString ());
36+ printMessage ('Filtered the lcov.info file' );
37+ }
38+
39+ class LcovSection {
40+ String ? filePath;
41+ String ? header;
42+ final body = < String > [];
43+ String ? footer;
44+
45+ String ? getBodyString () {
46+ final filePathTmp = filePath;
47+ if (filePathTmp == null ) return null ;
48+ final file = File (filePathTmp);
49+ final content = file.readAsLinesSync ();
50+ final sb = StringBuffer ();
51+ getFilteredBody (body, content).forEach ((item) => sb
52+ ..write (item)
53+ ..write ('\n ' ));
54+ return sb.toString ();
55+ }
56+
57+ @override
58+ String toString () {
59+ return '$header \n ${getBodyString ()}$footer \n ' ;
60+ }
61+ }
62+
63+ List <LcovSection > getFilteredSections (List <LcovSection > sections) {
64+ return sections.where ((section) {
65+ final header = section.header;
66+ if (header == null ) return false ;
67+ if (! header.endsWith ('.dart' )) {
68+ return false ;
69+ } else if (header.endsWith ('.g.dart' )) {
70+ return false ;
71+ } else if (header.endsWith ('.config.dart' )) {
72+ return false ;
73+ } else if (header.endsWith ('injectable.dart' )) {
74+ return false ;
75+ } else if (header.startsWith ('SF:lib/util/locale' )) {
76+ return false ;
77+ } else if (header.startsWith ('SF:lib/widget' )) {
78+ return false ;
79+ } else if (header.startsWith ('SF:lib/screen' )) {
80+ return false ;
81+ } else if (header.startsWith ('SF:lib/navigator' )) {
82+ return false ;
83+ }
84+ return true ;
85+ }).toList ();
86+ }
87+
88+ List <String > getFilteredBody (List <String > body, List <String > lines) {
89+ return body.where ((line) {
90+ if (line.startsWith ('DA:' )) {
91+ final sections = line.split (',' );
92+ final lineNr = int .parse (sections[0 ].replaceAll ('DA:' , '' ));
93+ final callCount = int .parse (sections[1 ]);
94+ if (callCount == 0 ) {
95+ final fileLine = lines[lineNr - 1 ].trim ();
96+ if (excludedLines.contains (fileLine)) {
97+ return false ;
98+ }
99+ for (final line in excludedStartsWithLines) {
100+ if (fileLine.trim ().startsWith (line)) {
101+ return false ;
102+ }
103+ }
104+ }
105+ }
106+ return true ;
107+ }).toList ();
108+ }
109+
110+ const excludedLines = < String > [
111+ 'const TranslationWriter._();' ,
112+ 'const CaseUtil._();' ,
113+ 'const LocaleGenParser._();' ,
114+ 'const LocaleGenSbWriter._();' ,
115+ 'const LocaleGenWriter._();' ,
116+ ];
117+
118+ const excludedStartsWithLines = < String > [];
119+
120+ void printMessage (String message) {
121+ // ignore: avoid_print
122+ print (message);
123+ }
0 commit comments