|
| 1 | +import 'dart:convert'; |
| 2 | +import 'dart:io'; |
| 3 | + |
| 4 | +import 'package:git/git.dart'; |
| 5 | +import 'package:metrics_center/flutter.dart'; |
| 6 | + |
| 7 | +const String kNameKey = 'name'; |
| 8 | +const String kTimeUnitKey = 'time_unit'; |
| 9 | +const String kSubResultKey = 'sub_result'; |
| 10 | + |
| 11 | +const List<String> kSkippedSubResults = <String>[ |
| 12 | + kNameKey, |
| 13 | + kTimeUnitKey, |
| 14 | + 'iterations', |
| 15 | + 'big_o', |
| 16 | +]; |
| 17 | + |
| 18 | +Future<List<FlutterEngineMetricsPoint>> _parse(String jsonFileName) async { |
| 19 | + final GitDir gitDir = await GitDir.fromExisting('../../'); |
| 20 | + // Somehow gitDir.currentBranch() doesn't work in Cirrus with "fatal: 'HEAD' - |
| 21 | + // not a valid ref". Therefore, we use "git log" to get the revision manually. |
| 22 | + final ProcessResult logResult = await gitDir |
| 23 | + .runCommand(<String>['log', '--pretty=format:%H]', '-n', '1']); |
| 24 | + if (logResult.exitCode != 0) { |
| 25 | + throw 'Unexpected exit code ${logResult.exitCode}'; |
| 26 | + } |
| 27 | + final String gitRevision = logResult.stdout.toString(); |
| 28 | + |
| 29 | + final Map<String, dynamic> jsonResult = |
| 30 | + jsonDecode(File(jsonFileName).readAsStringSync()); |
| 31 | + |
| 32 | + final Map<String, dynamic> rawContext = jsonResult['context']; |
| 33 | + final Map<String, String> context = rawContext.map<String, String>( |
| 34 | + (String k, dynamic v) => MapEntry<String, String>(k, v.toString()), |
| 35 | + ); |
| 36 | + |
| 37 | + final List<FlutterEngineMetricsPoint> points = <FlutterEngineMetricsPoint>[]; |
| 38 | + for (Map<String, dynamic> item in jsonResult['benchmarks']) { |
| 39 | + final String name = item[kNameKey]; |
| 40 | + final Map<String, String> timeUnitMap = <String, String>{ |
| 41 | + kUnitKey: item[kTimeUnitKey] |
| 42 | + }; |
| 43 | + for (String subResult in item.keys) { |
| 44 | + if (!kSkippedSubResults.contains(subResult)) { |
| 45 | + num rawValue; |
| 46 | + try { |
| 47 | + rawValue = item[subResult]; |
| 48 | + } catch (e) { |
| 49 | + print( |
| 50 | + '$subResult: ${item[subResult]} (${item[subResult].runtimeType}) is not a number'); |
| 51 | + continue; |
| 52 | + } |
| 53 | + |
| 54 | + final double value = rawValue is int ? rawValue.toDouble() : rawValue; |
| 55 | + points.add( |
| 56 | + FlutterEngineMetricsPoint(name, value, gitRevision, |
| 57 | + moreTags: <String, String>{kSubResultKey: subResult} |
| 58 | + ..addAll(context) |
| 59 | + ..addAll(subResult.endsWith('time') |
| 60 | + ? timeUnitMap |
| 61 | + : <String, String>{})), |
| 62 | + ); |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + return points; |
| 68 | +} |
| 69 | + |
| 70 | +Future<void> main(List<String> args) async { |
| 71 | + if (args.length != 1) { |
| 72 | + throw 'Must have one argument: <benchmark_json_file>'; |
| 73 | + } |
| 74 | + final List<FlutterEngineMetricsPoint> points = await _parse(args[0]); |
| 75 | + final FlutterDestination destination = |
| 76 | + await FlutterDestination.makeFromCredentialsJson( |
| 77 | + jsonDecode(Platform.environment['BENCHMARK_GCP_CREDENTIALS']), |
| 78 | + ); |
| 79 | + await destination.update(points); |
| 80 | +} |
0 commit comments