Skip to content

Commit ef5ffd0

Browse files
authored
Migrate devicelab framework code to null safety. (flutter#86325)
(Attempt to reland flutter#85993)
1 parent 43ed3b6 commit ef5ffd0

28 files changed

+406
-470
lines changed

dev/devicelab/lib/command/test.dart

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.8
6-
75
import 'package:args/command_runner.dart';
86

97
import 'package:flutter_devicelab/framework/runner.dart';
@@ -64,19 +62,19 @@ class TestCommand extends Command<void> {
6462

6563
@override
6664
Future<void> run() async {
67-
final List<String> taskArgsRaw = argResults['task-args'] as List<String>;
65+
final List<String> taskArgsRaw = argResults!['task-args'] as List<String>;
6866
// Prepend '--' to convert args to options when passed to task
6967
final List<String> taskArgs = taskArgsRaw.map((String taskArg) => '--$taskArg').toList();
7068
print(taskArgs);
7169
await runTasks(
72-
<String>[argResults['task'] as String],
73-
deviceId: argResults['device-id'] as String,
74-
gitBranch: argResults['git-branch'] as String,
75-
localEngine: argResults['local-engine'] as String,
76-
localEngineSrcPath: argResults['local-engine-src-path'] as String,
77-
luciBuilder: argResults['luci-builder'] as String,
78-
resultsPath: argResults['results-file'] as String,
79-
silent: argResults['silent'] as bool,
70+
<String>[argResults!['task'] as String],
71+
deviceId: argResults!['device-id'] as String?,
72+
gitBranch: argResults!['git-branch'] as String?,
73+
localEngine: argResults!['local-engine'] as String?,
74+
localEngineSrcPath: argResults!['local-engine-src-path'] as String?,
75+
luciBuilder: argResults!['luci-builder'] as String?,
76+
resultsPath: argResults!['results-file'] as String?,
77+
silent: (argResults!['silent'] as bool?) ?? false,
8078
taskArgs: taskArgs,
8179
);
8280
}

dev/devicelab/lib/command/upload_metrics.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.8
6-
75
import 'package:args/command_runner.dart';
86

97
import '../framework/cocoon.dart';
@@ -25,8 +23,8 @@ class UploadMetricsCommand extends Command<void> {
2523

2624
@override
2725
Future<void> run() async {
28-
final String resultsPath = argResults['results-file'] as String;
29-
final String serviceAccountTokenFile = argResults['service-account-token-file'] as String;
26+
final String resultsPath = argResults!['results-file'] as String;
27+
final String? serviceAccountTokenFile = argResults!['service-account-token-file'] as String?;
3028

3129
final Cocoon cocoon = Cocoon(serviceAccountTokenPath: serviceAccountTokenFile);
3230
return cocoon.sendResultsPath(resultsPath);

dev/devicelab/lib/framework/ab.dart

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.8
6-
75
import 'dart:math' as math;
8-
import 'package:meta/meta.dart';
96

107
import 'task_result.dart';
118

@@ -43,8 +40,8 @@ class ABTest {
4340
final String localEngine;
4441
final String taskName;
4542
final DateTime runStart;
46-
DateTime _runEnd;
47-
DateTime get runEnd => _runEnd;
43+
DateTime? _runEnd;
44+
DateTime? get runEnd => _runEnd;
4845

4946
final Map<String, List<double>> _aResults;
5047
final Map<String, List<double>> _bResults;
@@ -91,26 +88,26 @@ class ABTest {
9188
kLocalEngineKeyName: localEngine,
9289
kTaskNameKeyName: taskName,
9390
kRunStartKeyName: runStart.toIso8601String(),
94-
kRunEndKeyName: runEnd.toIso8601String(),
91+
kRunEndKeyName: runEnd!.toIso8601String(),
9592
kAResultsKeyName: _aResults,
9693
kBResultsKeyName: _bResults,
9794
};
9895

99-
static void updateColumnLengths(List<int> lengths, List<String> results) {
96+
static void updateColumnLengths(List<int> lengths, List<String?> results) {
10097
for (int column = 0; column < lengths.length; column++) {
10198
if (results[column] != null) {
102-
lengths[column] = math.max(lengths[column], results[column].length);
99+
lengths[column] = math.max(lengths[column], results[column]?.length ?? 0);
103100
}
104101
}
105102
}
106103

107104
static void formatResult(StringBuffer buffer,
108105
List<int> lengths,
109106
List<FieldJustification> aligns,
110-
List<String> values) {
107+
List<String?> values) {
111108
for (int column = 0; column < lengths.length; column++) {
112109
final int len = lengths[column];
113-
String value = values[column];
110+
String? value = values[column];
114111
if (value == null) {
115112
value = ''.padRight(len);
116113
} else {
@@ -142,9 +139,9 @@ class ABTest {
142139
final Map<String, _ScoreSummary> summariesA = _summarize(_aResults);
143140
final Map<String, _ScoreSummary> summariesB = _summarize(_bResults);
144141

145-
final List<List<String>> tableRows = <List<String>>[
142+
final List<List<String?>> tableRows = <List<String?>>[
146143
for (final String scoreKey in <String>{...summariesA.keys, ...summariesB.keys})
147-
<String>[
144+
<String?>[
148145
scoreKey,
149146
summariesA[scoreKey]?.averageString, summariesA[scoreKey]?.noiseString,
150147
summariesB[scoreKey]?.averageString, summariesB[scoreKey]?.noiseString,
@@ -167,7 +164,7 @@ class ABTest {
167164

168165
final List<int> lengths = List<int>.filled(6, 0);
169166
updateColumnLengths(lengths, titles);
170-
for (final List<String> row in tableRows) {
167+
for (final List<String?> row in tableRows) {
171168
updateColumnLengths(lengths, row);
172169
}
173170

@@ -177,7 +174,7 @@ class ABTest {
177174
FieldJustification.CENTER,
178175
...alignments.skip(1),
179176
], titles);
180-
for (final List<String> row in tableRows) {
177+
for (final List<String?> row in tableRows) {
181178
formatResult(buffer, lengths, alignments, row);
182179
}
183180

@@ -192,7 +189,7 @@ class ABTest {
192189
buffer.writeln('$scoreKey:');
193190
buffer.write(' A:\t');
194191
if (_aResults.containsKey(scoreKey)) {
195-
for (final double score in _aResults[scoreKey]) {
192+
for (final double score in _aResults[scoreKey]!) {
196193
buffer.write('${score.toStringAsFixed(2)}\t');
197194
}
198195
} else {
@@ -202,7 +199,7 @@ class ABTest {
202199

203200
buffer.write(' B:\t');
204201
if (_bResults.containsKey(scoreKey)) {
205-
for (final double score in _bResults[scoreKey]) {
202+
for (final double score in _bResults[scoreKey]!) {
206203
buffer.write('${score.toStringAsFixed(2)}\t');
207204
}
208205
} else {
@@ -232,8 +229,8 @@ class ABTest {
232229
);
233230

234231
for (final String scoreKey in _allScoreKeys) {
235-
final _ScoreSummary summaryA = summariesA[scoreKey];
236-
final _ScoreSummary summaryB = summariesB[scoreKey];
232+
final _ScoreSummary? summaryA = summariesA[scoreKey];
233+
final _ScoreSummary? summaryB = summariesB[scoreKey];
237234
buffer.write('$scoreKey\t');
238235

239236
if (summaryA != null) {
@@ -261,8 +258,8 @@ class ABTest {
261258

262259
class _ScoreSummary {
263260
_ScoreSummary({
264-
@required this.average,
265-
@required this.noise,
261+
required this.average,
262+
required this.noise,
266263
});
267264

268265
/// Average (arithmetic mean) of a series of values collected by a benchmark.
@@ -275,14 +272,14 @@ class _ScoreSummary {
275272
String get averageString => average.toStringAsFixed(2);
276273
String get noiseString => '(${_ratioToPercent(noise)})';
277274

278-
String improvementOver(_ScoreSummary other) {
275+
String improvementOver(_ScoreSummary? other) {
279276
return other == null ? '' : '${(average / other.average).toStringAsFixed(2)}x';
280277
}
281278
}
282279

283280
void _addResult(TaskResult result, Map<String, List<double>> results) {
284-
for (final String scoreKey in result.benchmarkScoreKeys) {
285-
final double score = (result.data[scoreKey] as num).toDouble();
281+
for (final String scoreKey in result.benchmarkScoreKeys ?? <String>[]) {
282+
final double score = (result.data![scoreKey] as num).toDouble();
286283
results.putIfAbsent(scoreKey, () => <double>[]).add(score);
287284
}
288285
}

dev/devicelab/lib/framework/apk_utils.dart

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.8
6-
75
import 'dart:io';
86

97
import 'package:path/path.dart' as path;
@@ -106,7 +104,7 @@ bool hasMultipleOccurrences(String text, Pattern pattern) {
106104

107105
/// The Android home directory.
108106
String get _androidHome {
109-
final String androidHome = Platform.environment['ANDROID_HOME'] ??
107+
final String? androidHome = Platform.environment['ANDROID_HOME'] ??
110108
Platform.environment['ANDROID_SDK_ROOT'];
111109
if (androidHome == null || androidHome.isEmpty) {
112110
throw Exception('Environment variable `ANDROID_SDK_ROOT` is not set.');
@@ -118,9 +116,9 @@ String get _androidHome {
118116
Future<String> _evalApkAnalyzer(
119117
List<String> args, {
120118
bool printStdout = false,
121-
String workingDirectory,
119+
String? workingDirectory,
122120
}) async {
123-
final String javaHome = await findJavaHome();
121+
final String? javaHome = await findJavaHome();
124122
if (javaHome == null || javaHome.isEmpty) {
125123
throw Exception('No JAVA_HOME set.');
126124
}
@@ -259,7 +257,7 @@ class FlutterProject {
259257
String get androidPath => path.join(rootPath, 'android');
260258
String get iosPath => path.join(rootPath, 'ios');
261259

262-
Future<void> addCustomBuildType(String name, {String initWith}) async {
260+
Future<void> addCustomBuildType(String name, {required String initWith}) async {
263261
final File buildScript = File(
264262
path.join(androidPath, 'app', 'build.gradle'),
265263
);
@@ -276,7 +274,7 @@ android {
276274
''');
277275
}
278276

279-
Future<void> addGlobalBuildType(String name, {String initWith}) async {
277+
Future<void> addGlobalBuildType(String name, {required String initWith}) async {
280278
final File buildScript = File(
281279
path.join(androidPath, 'build.gradle'),
282280
);
@@ -360,11 +358,11 @@ flutter:
360358
pubspec.writeAsStringSync(newContents);
361359
}
362360

363-
Future<void> runGradleTask(String task, {List<String> options}) async {
361+
Future<void> runGradleTask(String task, {List<String>? options}) async {
364362
return _runGradleTask(workingDirectory: androidPath, task: task, options: options);
365363
}
366364

367-
Future<ProcessResult> resultOfGradleTask(String task, {List<String> options}) {
365+
Future<ProcessResult> resultOfGradleTask(String task, {List<String>? options}) {
368366
return _resultOfGradleTask(workingDirectory: androidPath, task: task, options: options);
369367
}
370368

@@ -416,7 +414,11 @@ class FlutterModuleProject {
416414
String get rootPath => path.join(parent.path, name);
417415
}
418416

419-
Future<void> _runGradleTask({String workingDirectory, String task, List<String> options}) async {
417+
Future<void> _runGradleTask({
418+
required String workingDirectory,
419+
required String task,
420+
List<String>? options,
421+
}) async {
420422
final ProcessResult result = await _resultOfGradleTask(
421423
workingDirectory: workingDirectory,
422424
task: task,
@@ -431,10 +433,13 @@ Future<void> _runGradleTask({String workingDirectory, String task, List<String>
431433
throw 'Gradle exited with error';
432434
}
433435

434-
Future<ProcessResult> _resultOfGradleTask({String workingDirectory, String task,
435-
List<String> options}) async {
436+
Future<ProcessResult> _resultOfGradleTask({
437+
required String workingDirectory,
438+
required String task,
439+
List<String>? options,
440+
}) async {
436441
section('Find Java');
437-
final String javaHome = await findJavaHome();
442+
final String? javaHome = await findJavaHome();
438443

439444
if (javaHome == null)
440445
throw TaskResult.failure('Could not find Java');
@@ -465,7 +470,7 @@ Future<ProcessResult> _resultOfGradleTask({String workingDirectory, String task,
465470
}
466471

467472
/// Returns [null] if target matches [expectedTarget], otherwise returns an error message.
468-
String validateSnapshotDependency(FlutterProject project, String expectedTarget) {
473+
String? validateSnapshotDependency(FlutterProject project, String expectedTarget) {
469474
final File snapshotBlob = File(
470475
path.join(project.rootPath, 'build', 'app', 'intermediates',
471476
'flutter', 'debug', 'flutter_build.d'));

0 commit comments

Comments
 (0)