|
| 1 | +import 'dart:io'; |
| 2 | + |
| 3 | +import 'package:args/args.dart'; |
| 4 | + |
| 5 | +import 'utils/reg_exp_utils.dart'; |
| 6 | + |
| 7 | +const _outputPath = 'test/coverage_report_test.dart'; |
| 8 | + |
| 9 | +void main(List<String> arguments) async { |
| 10 | + String filepath; |
| 11 | + RegExp regExp; |
| 12 | + |
| 13 | + // setup parser |
| 14 | + final parser = ArgParser() |
| 15 | + ..addSeparator('Generates a dart file of all project files which should be covered by unit tests.') |
| 16 | + ..addOption('output', |
| 17 | + abbr: 'o', help: 'A path to save output file. Defaults to test/coverage_report_test.dart.', valueHelp: 'FILE') |
| 18 | + ..addMultiOption('remove', |
| 19 | + abbr: 'r', splitCommas: true, help: 'A regexp pattern of paths to exclude.', valueHelp: 'PATTERN') |
| 20 | + ..addFlag('help', abbr: 'h', negatable: false, defaultsTo: false, help: 'Displays help.'); |
| 21 | + final args = parser.parse(arguments); |
| 22 | + |
| 23 | + // process arguments |
| 24 | + if (args['help']) { |
| 25 | + exit(0); |
| 26 | + } else { |
| 27 | + filepath = args['output'] ?? _outputPath; |
| 28 | + print(filepath); |
| 29 | + |
| 30 | + if ((args['remove'] as List<String>).isNotEmpty) { |
| 31 | + regExp = RegExpUtils.combinePatterns(args['remove']); |
| 32 | + } |
| 33 | + } |
| 34 | + |
| 35 | + // generate file |
| 36 | + await _createCoverageReportDartFile(filepath, regExp); |
| 37 | +} |
| 38 | + |
| 39 | +const _pubspecPath = 'pubspec.yaml'; |
| 40 | + |
| 41 | +Future<void> _createCoverageReportDartFile(String filepath, RegExp regExpFilesIgnore) async { |
| 42 | + // dtermine contents of pubspec |
| 43 | + File file = File(_pubspecPath); |
| 44 | + if (!file.existsSync()) { |
| 45 | + print('Error! Pubspec not found. Please run from project root. Exiting.'); |
| 46 | + exit(0); |
| 47 | + } |
| 48 | + final contents = file.readAsStringSync(); |
| 49 | + |
| 50 | + // determine project name |
| 51 | + final regExp = RegExp(r'(name: )(\w*)'); |
| 52 | + final matches = regExp.allMatches(contents)?.first; |
| 53 | + final projectName = matches != null && matches.groupCount >= 2 ? matches.group(2) : null; |
| 54 | + if (projectName == null) { |
| 55 | + print('Error! Cannot determine project name. Exiting.'); |
| 56 | + exit(0); |
| 57 | + } |
| 58 | + |
| 59 | + // determine all paths for valid files |
| 60 | + final paths = await _listDir('lib', regExp: regExpFilesIgnore); |
| 61 | + |
| 62 | + // determine output content |
| 63 | + final sb = StringBuffer(); |
| 64 | + sb.write('// GENERATED CODE - DO NOT MODIFY BY HAND\n'); |
| 65 | + sb.write('\n'); |
| 66 | + sb.write('// **************************************************************************\n'); |
| 67 | + sb.write('// All files which should be covered by tests\n'); |
| 68 | + sb.write('// **************************************************************************\n'); |
| 69 | + sb.write('\n'); |
| 70 | + sb.write('// ignore_for_file: unused_import\n'); |
| 71 | + sb.write('\n'); |
| 72 | + for (final path in paths) { |
| 73 | + sb.write('import \'package:$projectName/${path.replaceAll('lib/', '')}\';\n'); |
| 74 | + } |
| 75 | + |
| 76 | + // write to disk |
| 77 | + file = File(filepath); |
| 78 | + if (!await file.exists()) { |
| 79 | + await file.create(recursive: true); |
| 80 | + } |
| 81 | + file.writeAsStringSync(sb.toString()); |
| 82 | +} |
| 83 | + |
| 84 | +/// Lists all files (recursively) in a given folder |
| 85 | +/// |
| 86 | +/// [regExp] is an optional RegExp for files to ignore |
| 87 | +Future<List<String>> _listDir(String folderPath, {RegExp regExp}) async { |
| 88 | + final paths = <String>[]; |
| 89 | + final directory = Directory(folderPath); |
| 90 | + if (await directory.exists()) { |
| 91 | + await for (FileSystemEntity entity in directory.list(recursive: true, followLinks: false)) { |
| 92 | + FileSystemEntityType type = await FileSystemEntity.type(entity.path); |
| 93 | + if (type == FileSystemEntityType.file) { |
| 94 | + if (regExp != null) { |
| 95 | + if (regExp.hasMatch(entity.path)) { |
| 96 | + continue; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + paths.add(entity.path); |
| 101 | + } |
| 102 | + } |
| 103 | + return paths; |
| 104 | + } |
| 105 | + |
| 106 | + return paths; |
| 107 | +} |
0 commit comments