Add `--update-files` flag to tool/common_mark_stats.dart
diff --git a/pkgs/markdown/tool/common_mark_stats.dart b/pkgs/markdown/tool/common_mark_stats.dart index 0820e7a..fb3554a 100644 --- a/pkgs/markdown/tool/common_mark_stats.dart +++ b/pkgs/markdown/tool/common_mark_stats.dart
@@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:collection'; import 'dart:convert'; import 'dart:io'; @@ -17,16 +18,38 @@ String get _currentDir => p .dirname((reflect(main) as ClosureMirror).function.location.sourceUri.path); -void main(List<String> args) { +main(List<String> args) async { final parser = new ArgParser() - ..addOption('section', help: 'Restrict tests to one section') - ..addFlag('raw', defaultsTo: false, help: 'raw JSON format') - ..addFlag('verbose', defaultsTo: false, help: 'verbose output'); + ..addOption('section', + help: 'Restrict tests to one section, provided after the option.') + ..addFlag('raw', + defaultsTo: false, help: 'raw JSON format', negatable: false) + ..addFlag('update-files', + defaultsTo: false, + help: 'Update stats files in $_currentDir', + negatable: false) + ..addFlag('verbose', + defaultsTo: false, help: 'verbose output', negatable: false) + ..addFlag('help', defaultsTo: false, negatable: false); + var options = parser.parse(args); - var specifiedSection = options['section']; - var raw = options['raw']; - var verbose = options['verbose']; + if (options['help']) { + print(parser.usage); + return; + } + + var specifiedSection = options['section'] as String; + var raw = options['raw'] as bool; + var verbose = options['verbose'] as bool; + var updateFiles = options['update-files'] as bool; + + if (updateFiles && (raw || verbose || (specifiedSection != null))) { + print('The `update-files` flag must be used by itself'); + print(parser.usage); + exitCode = 64; // unix standard improper usage + return; + } var sections = _loadCommonMarkSections(); @@ -67,17 +90,12 @@ } }); - if (raw) { - var encoder = const JsonEncoder.withIndent(' ', _convert); - try { - print(encoder.convert(scores)); - } on JsonUnsupportedObjectError catch (e) { - print(e.cause); - print(e.unsupportedObject.runtimeType); - rethrow; - } - } else { - _printFriendly(scores); + if (raw || updateFiles) { + _printRaw(scores, updateFiles); + } + + if (!raw || updateFiles) { + _printFriendly(scores, updateFiles); } } @@ -93,12 +111,47 @@ return obj; } -void _printFriendly(SplayTreeMap<String, SplayTreeMap<int, bool>> scores) { +Future _printRaw(scores, bool updateFiles) async { + IOSink sink; + if (updateFiles) { + var path = p.join(_currentDir, 'common_mark_stats.json'); + print('Updating $path'); + var file = new File(path); + sink = file.openWrite(); + } else { + sink = stdout; + } + + var encoder = const JsonEncoder.withIndent(' ', _convert); + try { + sink.writeln(encoder.convert(scores)); + } on JsonUnsupportedObjectError catch (e) { + stderr.writeln(e.cause); + stderr.writeln(e.unsupportedObject.runtimeType); + rethrow; + } + + await sink.flush(); + await sink.close(); +} + +Future _printFriendly(SplayTreeMap<String, SplayTreeMap<int, bool>> scores, + bool updateFiles) async { const countWidth = 4; var totalValid = 0; var totalExamples = 0; + IOSink sink; + if (updateFiles) { + var path = p.join(_currentDir, 'common_mark_stats.txt'); + print('Updating $path'); + var file = new File(path); + sink = file.openWrite(); + } else { + sink = stdout; + } + scores.forEach((section, map) { var total = map.values.length; totalExamples += total; @@ -109,16 +162,19 @@ var pct = (100 * sectionValidCount / total).toStringAsFixed(1).padLeft(5); - print('${sectionValidCount.toString().padLeft(countWidth)} ' + sink.writeln('${sectionValidCount.toString().padLeft(countWidth)} ' 'of ${total.toString().padLeft(countWidth)} ' '– ${pct}% $section'); }); var pct = (100 * totalValid / totalExamples).toStringAsFixed(1).padLeft(5); - print('${totalValid.toString().padLeft(countWidth)} ' + sink.writeln('${totalValid.toString().padLeft(countWidth)} ' 'of ${totalExamples.toString().padLeft(countWidth)} ' '– ${pct}% TOTAL'); + + await sink.flush(); + await sink.close(); } /// Compare two DOM trees for equality.