[builder] Apply null-safety migration
Change-Id: Ibb83865687702f6a5712759a8c73f898ec27cf35
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/224204
Reviewed-by: Alexander Thomas <athom@google.com>
diff --git a/builder/bin/update_results_database.dart b/builder/bin/update_results_database.dart
index 41a14f0..946bf96 100644
--- a/builder/bin/update_results_database.dart
+++ b/builder/bin/update_results_database.dart
@@ -1,5 +1,3 @@
-// @dart = 2.9
-
import 'dart:convert';
import 'dart:io';
@@ -13,11 +11,11 @@
import 'package:googleapis_auth/auth_io.dart';
import 'package:http/http.dart' as http;
-BuildInfo buildInfo;
+late BuildInfo buildInfo;
Future<List<Map<String, dynamic>>> readChangedResults(File resultsFile) async {
final lines = (await resultsFile.readAsLines())
- .map((line) => jsonDecode(line) /*!*/ as Map<String, dynamic>);
+ .map((line) => jsonDecode(line)! as Map<String, dynamic>);
if (lines.isEmpty) {
print('Empty input results.json file');
exit(1);
@@ -43,12 +41,12 @@
Future<void> processResults(options, client, firestore) async {
final inputFile = fileOption(options, 'results');
final results = await readChangedResults(inputFile);
- final String buildbucketID = options['buildbucket_id'];
- final String baseRevision = options['base_revision'];
+ final String? buildbucketID = options['buildbucket_id'];
+ final String? baseRevision = options['base_revision'];
final commitCache = CommitsCache(firestore, client);
if (buildInfo is TryBuildInfo) {
- await Tryjob(buildInfo, buildbucketID, baseRevision, commitCache, firestore,
- client)
+ await Tryjob(buildInfo as TryBuildInfo, buildbucketID!, baseRevision!,
+ commitCache, firestore, client)
.process(results);
} else {
await Build(buildInfo, commitCache, firestore).process(results);
diff --git a/builder/lib/src/builder.dart b/builder/lib/src/builder.dart
index 91223d2..9aeb495 100644
--- a/builder/lib/src/builder.dart
+++ b/builder/lib/src/builder.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:collection/collection.dart' show IterableExtension;
import 'package:pool/pool.dart';
import 'commits_cache.dart';
@@ -15,20 +16,20 @@
/// [FirestoreService] object.
/// Tryjob builds are represented by the class [Tryjob] instead.
class Build {
- final FirestoreService /*!*/ firestore;
- final CommitsCache /*!*/ commitsCache;
- final BuildInfo /*!*/ info;
+ final FirestoreService firestore;
+ final CommitsCache commitsCache;
+ final BuildInfo info;
final TestNameLock testNameLock = TestNameLock();
- /*late final*/ int /*!*/ startIndex;
- /*late*/ int /*!*/ endIndex;
- /*late*/ Commit /*!*/ endCommit;
- List<Commit /*!*/ > commits;
+ late final int startIndex;
+ late int endIndex;
+ late Commit endCommit;
+ late List<Commit> commits;
Map<String, int> tryApprovals = {};
List<RevertedChanges> allRevertedChanges = [];
bool success = true; // Changed to false if any unapproved failure is seen.
int countChanges = 0;
- int commitsFetched;
+ int? commitsFetched;
List<String> approvalMessages = [];
int countApprovalsCopied = 0;
@@ -36,7 +37,7 @@
void log(String string) => firestore.log(string);
- Future<void> process(List<Map<String, dynamic> /*!*/ > changes) async {
+ Future<void> process(List<Map<String, dynamic>> changes) async {
log('store build commits info');
await storeBuildCommitsInfo();
log('update build info');
@@ -47,9 +48,8 @@
// TODO(karlklose): add a flag to overwrite builder results.
return;
}
- final configurations = changes
- .map((change) => change['configuration'] as String /*!*/)
- .toSet();
+ final configurations =
+ changes.map((change) => change['configuration'] as String).toSet();
await update(configurations);
log('storing ${changes.length} change(s)');
await Pool(30).forEach(changes, guardedStoreChange).drain();
@@ -73,7 +73,7 @@
log(report.join('\n'));
}
- Future<void> update(Iterable<String /*!*/ > configurations) async {
+ Future<void> update(Iterable<String> configurations) async {
await storeConfigurationsInfo(configurations);
}
@@ -92,8 +92,9 @@
if (info.previousCommitHash == null) {
startIndex = endIndex;
} else {
- final startCommit = await commitsCache.getCommit(info.previousCommitHash);
- startIndex = startCommit /*!*/ .index + 1;
+ final startCommit =
+ await commitsCache.getCommit(info.previousCommitHash!);
+ startIndex = startCommit!.index + 1;
if (startIndex > endIndex) {
throw ArgumentError('Results received with empty blamelist\n'
'previous commit: ${info.previousCommitHash}\n'
@@ -111,7 +112,7 @@
endCommit
];
for (final commit in commits) {
- final index = commit /*!*/ .index;
+ final index = commit!.index;
final review = commit.review;
final reverted = commit.revertOf;
if (review != null) {
@@ -141,16 +142,15 @@
await fetchReviewsAndReverts();
transformChange(change);
final failure = isFailure(change);
- bool /*!*/ approved;
+ bool approved;
var result = await firestore.findResult(change, startIndex, endIndex);
var activeResults = await firestore.findActiveResults(
change['name'], change['configuration']);
if (result == null) {
final approvingIndex = tryApprovals[testResult(change)] ??
allRevertedChanges
- .firstWhere(
- (revertedChange) => revertedChange.approveRevert(change),
- orElse: () => null)
+ .firstWhereOrNull(
+ (revertedChange) => revertedChange.approveRevert(change))
?.revertIndex;
approved = approvingIndex != null;
final newResult = constructResult(change, startIndex, endIndex,
@@ -191,7 +191,7 @@
Map<String, dynamic> constructResult(
Map<String, dynamic> change, int startIndex, int endIndex,
- {bool /*!*/ approved, int landedReviewIndex, bool failure}) {
+ {required bool approved, int? landedReviewIndex, required bool failure}) {
return {
fName: change[fName],
fResult: change[fResult],
@@ -200,9 +200,9 @@
fBlamelistStartIndex: startIndex,
fBlamelistEndIndex: endIndex,
if (startIndex != endIndex && approved) fPinnedIndex: landedReviewIndex,
- fConfigurations: <String /*!*/ >[change['configuration']],
+ fConfigurations: <String>[change['configuration']],
fApproved: approved,
if (failure) fActive: true,
- if (failure) fActiveConfigurations: <String /*!*/ >[change['configuration']]
+ if (failure) fActiveConfigurations: <String>[change['configuration']]
};
}
diff --git a/builder/lib/src/commits_cache.dart b/builder/lib/src/commits_cache.dart
index 7fe9043..530d0cc 100644
--- a/builder/lib/src/commits_cache.dart
+++ b/builder/lib/src/commits_cache.dart
@@ -16,16 +16,16 @@
/// The class fetches commits from Firestore if they are present,
/// and fetches them from gitiles if not, and saves them to Firestore.
class CommitsCache {
- FirestoreService /*!*/ firestore;
- final http.Client /*!*/ httpClient;
- Map<String /*!*/, Commit> byHash = {};
+ FirestoreService firestore;
+ final http.Client httpClient;
+ Map<String, Commit> byHash = {};
Map<int, Commit> byIndex = {};
- int startIndex;
- int endIndex;
+ int? startIndex;
+ int? endIndex;
CommitsCache(this.firestore, this.httpClient);
- Future<Commit /*!*/ > getCommit(String /*!*/ hash) async {
+ Future<Commit> getCommit(String hash) async {
var commit = byHash[hash] ?? await _fetchByHash(hash);
if (commit == null) {
await _getNewCommits();
@@ -37,7 +37,7 @@
return commit;
}
- Future<Commit /*!*/ > getCommitByIndex(int /*!*/ index) async {
+ Future<Commit> getCommitByIndex(int index) async {
var commit = byIndex[index] ?? await _fetchByIndex(index);
if (commit == null) {
await _getNewCommits();
@@ -67,7 +67,7 @@
if (startIndex == null || startIndex == index + 1) {
startIndex = index;
endIndex ??= index;
- } else if (endIndex + 1 == index) {
+ } else if (endIndex! + 1 == index) {
endIndex = index;
} else {
return;
@@ -76,25 +76,25 @@
byIndex[index] = commit;
}
- Future<Commit> _fetchByHash(String /*!*/ hash) async {
+ Future<Commit?> _fetchByHash(String hash) async {
final commit = await firestore.getCommit(hash);
if (commit == null) return null;
final index = commit.index;
if (startIndex == null) {
_cacheCommit(commit);
- } else if (index < startIndex) {
- for (var fetchIndex = startIndex - 1; fetchIndex > index; --fetchIndex) {
+ } else if (index < startIndex!) {
+ for (var fetchIndex = startIndex! - 1; fetchIndex > index; --fetchIndex) {
// Other invocations may be fetching simultaneously.
- if (fetchIndex < startIndex) {
+ if (fetchIndex < startIndex!) {
final infillCommit = await firestore.getCommitByIndex(fetchIndex);
_cacheCommit(infillCommit);
}
}
_cacheCommit(commit);
- } else if (index > endIndex) {
- for (var fetchIndex = endIndex + 1; fetchIndex < index; ++fetchIndex) {
+ } else if (index > endIndex!) {
+ for (var fetchIndex = endIndex! + 1; fetchIndex < index; ++fetchIndex) {
// Other invocations may be fetching simultaneously.
- if (fetchIndex > endIndex) {
+ if (fetchIndex > endIndex!) {
final infillCommit = await firestore.getCommitByIndex(fetchIndex);
_cacheCommit(infillCommit);
}
@@ -104,7 +104,7 @@
return commit;
}
- Future<Commit> _fetchByIndex(int /*!*/ index) => firestore
+ Future<Commit?> _fetchByIndex(int index) => firestore
.getCommitByIndex(index)
.then((commit) => _fetchByHash(commit.hash));
@@ -173,7 +173,7 @@
/// This function is idempotent and may be called multiple times
/// concurrently.
Future<void> landReview(Map<String, dynamic> commit, int index) async {
- final review = _review(commit);
+ final review = _review(commit)!;
// Optimization to avoid duplicate work: if another instance has linked
// the review to its landed commit, do nothing.
if (await firestore.reviewIsLanded(review)) return;
@@ -220,20 +220,20 @@
'^Reviewed-on: https://dart-review.googlesource.com/c/sdk/\\+/(\\d+)\$',
multiLine: true);
-int _review(Map<String, dynamic> commit) {
+int? _review(Map<String, dynamic> commit) {
final match = reviewRegExp.firstMatch(commit['message']);
- if (match != null) return int.parse(match.group(1));
+ if (match != null) return int.parse(match.group(1)!);
return null;
}
final revertRegExp =
RegExp('^This reverts commit ([\\da-f]+)\\.\$', multiLine: true);
-String _revert(Map<String, dynamic> commit) =>
+String? _revert(Map<String, dynamic> commit) =>
revertRegExp.firstMatch(commit['message'])?.group(1);
final relandRegExp =
RegExp('^This is a reland of ([\\da-f]+)\\.?\$', multiLine: true);
-String _reland(Map<String, dynamic> commit) =>
+String? _reland(Map<String, dynamic> commit) =>
relandRegExp.firstMatch(commit['message'])?.group(1);
diff --git a/builder/lib/src/firestore.dart b/builder/lib/src/firestore.dart
index 13d6824..0c69cd9 100644
--- a/builder/lib/src/firestore.dart
+++ b/builder/lib/src/firestore.dart
@@ -7,6 +7,7 @@
import 'dart:math' show max, min;
import 'package:builder/src/result.dart';
+import 'package:collection/collection.dart' show IterableExtension;
import 'package:googleapis/firestore/v1.dart';
import 'package:http/http.dart' as http;
@@ -20,18 +21,18 @@
Commit(this.hash, this.document);
Commit.fromJson(this.hash, Map<String, dynamic> data)
: document = SafeDocument(Document(fields: taggedMap(data), name: ''));
- int /*!*/ get index => document.getInt('index');
- String get revertOf => document.getString(fRevertOf);
- bool /*!*/ get isRevert => document.fields.containsKey(fRevertOf);
- int get review => document.getInt(fReview);
+ int get index => document.getInt('index')!;
+ String? get revertOf => document.getString(fRevertOf);
+ bool get isRevert => document.fields.containsKey(fRevertOf);
+ int? get review => document.getInt(fReview);
- Map<String, Object> toJson() => untagMap(document.fields);
+ Map<String, Object?> toJson() => untagMap(document.fields);
}
class FirestoreService {
- final String /*!*/ project;
- final FirestoreApi /*!*/ firestore;
- final http.Client /*!*/ client;
+ final String project;
+ final FirestoreApi firestore;
+ final http.Client client;
int documentsFetched = 0;
int documentsWritten = 0;
@@ -50,11 +51,11 @@
}
Future<List<SafeDocument>> query(
- {String /*!*/ from,
- Filter where,
- Order orderBy,
- int limit,
- String parent}) async {
+ {required String from,
+ Filter? where,
+ Order? orderBy,
+ int? limit,
+ String? parent}) async {
final query = StructuredQuery();
if (from != null) {
query.from = inCollection(from);
@@ -71,7 +72,7 @@
return runQuery(query, parent: parent);
}
- Future<Document /*!*/ > getDocument(String path) async {
+ Future<Document> getDocument(String path) async {
try {
final document = await firestore.projects.databases.documents.get(path);
documentsFetched++;
@@ -82,7 +83,7 @@
}
}
- Future<Document /*?*/ > getDocumentOrNull(
+ Future<Document?> getDocumentOrNull(
String path,
) async {
try {
@@ -107,7 +108,7 @@
String get documents => '$database/documents';
Future<List<SafeDocument>> runQuery(StructuredQuery query,
- {String parent}) async {
+ {String? parent}) async {
final request = RunQueryRequest()..structuredQuery = query;
final parentPath = parent == null ? documents : '$documents/$parent';
final queryResponse = await firestore.projects.databases.documents
@@ -116,7 +117,7 @@
documentsFetched += queryResponse.length;
return [
for (final responseElement in queryResponse)
- SafeDocument(responseElement.document /*!*/)
+ SafeDocument(responseElement.document!)
];
}
@@ -128,7 +129,7 @@
Future<bool> isStaging() => Future.value(project == 'dart-ci-staging');
- Future<bool> hasPatchset(String /*!*/ review, String /*!*/ patchset) {
+ Future<bool> hasPatchset(String review, String patchset) {
return documentExists('$documents/reviews/$review/patchsets/$patchset');
}
@@ -137,7 +138,7 @@
return Commit(document.name.split('/').last, document);
}
- Future<Commit> getCommit(String hash) async {
+ Future<Commit?> getCommit(String hash) async {
final document = await getDocumentOrNull('$documents/commits/$hash');
return document != null ? Commit(hash, SafeDocument(document)) : null;
}
@@ -154,7 +155,7 @@
return _commit(lastCommit.first);
}
- Future<void> addCommit(String /*!*/ id, Map<String, dynamic> data) async {
+ Future<void> addCommit(String id, Map<String, dynamic> data) async {
try {
final document = Document()..fields = taggedMap(data);
await firestore.projects.databases.documents
@@ -183,7 +184,7 @@
} else {
final originalBuilder = SafeDocument(record).getString('builder');
if (originalBuilder != builder) {
- record.fields['builder'].stringValue = builder;
+ record.fields!['builder']!.stringValue = builder;
await updateFields(record, ['builder']);
log('Configuration document changed: $configuration -> $builder '
'(was $originalBuilder)');
@@ -242,12 +243,12 @@
documentsWritten++;
}
- Future<String> findResult(
+ Future<String?> findResult(
Map<String, dynamic> change, int startIndex, int endIndex) async {
- final name = change['name'] as String /*!*/;
- final result = change['result'] as String /*!*/;
- final previousResult = change['previous_result'] as String /*!*/;
- final expected = change['expected'] as String /*!*/;
+ final name = change['name'] as String;
+ final result = change['result'] as String;
+ final previousResult = change['previous_result'] as String;
+ final expected = change['expected'] as String;
final snapshot = await query(
from: 'results',
orderBy: orderBy('blamelist_end_index', false),
@@ -260,17 +261,15 @@
limit: 5);
bool blamelistIncludesChange(SafeDocument document) {
- final before = endIndex < document.getInt('blamelist_start_index');
- final after = startIndex > document.getInt('blamelist_end_index');
+ final before = endIndex < document.getInt('blamelist_start_index')!;
+ final after = startIndex > document.getInt('blamelist_end_index')!;
return !before && !after;
}
- return snapshot
- .firstWhere(blamelistIncludesChange, orElse: () => null)
- ?.name;
+ return snapshot.firstWhereOrNull(blamelistIncludesChange)?.name;
}
- Future<Document /*!*/ > storeResult(Map<String, dynamic> result) async {
+ Future<Document> storeResult(Map<String, dynamic> result) async {
final document = Document()..fields = taggedMap(result);
final createdDocument = await firestore.projects.databases.documents
.createDocument(document, documents, 'results');
@@ -279,18 +278,18 @@
return createdDocument;
}
- Future<bool /*!*/ > updateResult(
- String result, String configuration, int startIndex, int endIndex,
- {/*required*/ bool failure}) async {
- bool approved;
+ Future<bool> updateResult(
+ String result, String? configuration, int startIndex, int endIndex,
+ {required bool failure}) async {
+ late bool approved;
await retryCommit(() async {
final document = await getDocument(result);
- final data = SafeDocument(document /*!*/);
+ final data = SafeDocument(document!);
// Allow missing 'approved' field during transition period.
approved = data.getBool('approved') ?? false;
// Add the new configuration and narrow the blamelist.
- final newStart = max(startIndex, data.getInt('blamelist_start_index'));
- final newEnd = min(endIndex, data.getInt('blamelist_end_index'));
+ final newStart = max(startIndex, data.getInt('blamelist_start_index')!);
+ final newEnd = min(endIndex, data.getInt('blamelist_end_index')!);
// TODO(karlklose): check for pinned, and remove the pin if the new range
// doesn't include it?
final updates = [
@@ -298,10 +297,10 @@
'blamelist_end_index',
if (failure) 'active'
];
- document.fields['blamelist_start_index'] = taggedValue(newStart);
- document.fields['blamelist_end_index'] = taggedValue(newEnd);
+ document.fields!['blamelist_start_index'] = taggedValue(newStart);
+ document.fields!['blamelist_end_index'] = taggedValue(newEnd);
if (failure) {
- document.fields['active'] = taggedValue(true);
+ document.fields!['active'] = taggedValue(true);
}
final addConfiguration = ArrayValue()
..values = [taggedValue(configuration)];
@@ -343,7 +342,7 @@
/// Returns all results which are either pinned to or have a range that is
/// this single index. // TODO: rename this function
- Future<List<Map<String, Value> /*!*/ >> findRevertedChanges(int index) async {
+ Future<List<Map<String, Value>>> findRevertedChanges(int index) async {
final pinnedResults =
await query(from: 'results', where: fieldEquals('pinned_index', index));
final results = pinnedResults.map((response) => response.fields).toList();
@@ -360,11 +359,11 @@
Future<bool> storeTryChange(
Map<String, dynamic> change, int review, int patchset) async {
- final name = change['name'] as String /*!*/;
- final result = change['result'] as String /*!*/;
- final expected = change['expected'] as String /*!*/;
- final previousResult = change['previous_result'] as String /*!*/;
- final configuration = change['configuration'] as String /*!*/;
+ final name = change['name'] as String;
+ final result = change['result'] as String;
+ final expected = change['expected'] as String;
+ final previousResult = change['previous_result'] as String;
+ final configuration = change['configuration'] as String;
// Find an existing result record for this test on this patchset.
final responses = await query(
@@ -409,7 +408,7 @@
'expected': expected,
'review': review,
'patchset': patchset,
- 'configurations': <String /*!*/ >[configuration],
+ 'configurations': <String>[configuration],
'approved': approved
});
await firestore.projects.databases.documents
@@ -442,7 +441,7 @@
}
Future<void> approveResult(Document document) async {
- document.fields['approved'] = taggedValue(true);
+ document.fields!['approved'] = taggedValue(true);
await _executeWrite([
Write()
..update = document
@@ -453,13 +452,13 @@
/// Removes [configuration] from the active configurations and marks the
/// active result inactive when we remove the last active config.
Future<void> removeActiveConfiguration(
- SafeDocument activeResult, String configuration) async {
- final configurations = activeResult.getList('active_configurations');
+ SafeDocument activeResult, String? configuration) async {
+ final configurations = activeResult.getList('active_configurations')!;
assert(configurations.contains(configuration));
await removeArrayEntry(
activeResult, 'active_configurations', taggedValue(configuration));
final document = await getDocument(activeResult.name);
- activeResult = SafeDocument(document /*!*/);
+ activeResult = SafeDocument(document!);
if (activeResult.getList('active_configurations')?.isEmpty == true) {
activeResult.fields.remove('active_configurations');
activeResult.fields.remove('active');
@@ -485,8 +484,8 @@
]);
}
- Future<List<SafeDocument /*!*/ >> findActiveResults(
- String /*!*/ name, String /*!*/ configuration) async {
+ Future<List<SafeDocument>> findActiveResults(
+ String name, String configuration) async {
final results = await query(
from: 'results',
where: compositeFilter([
@@ -514,7 +513,7 @@
.createDocument(document, documents, 'reviews', documentId: review);
}
- Future<void> deleteDocument(String /*!*/ name) async {
+ Future<void> deleteDocument(String name) async {
return _executeWrite([Write()..delete = name]);
}
@@ -532,8 +531,7 @@
return firestore.projects.databases.documents.batchWrite(request, database);
}
- Future<void> updateFields(
- Document /*!*/ document, List<String> fields) async {
+ Future<void> updateFields(Document document, List<String> fields) async {
await _executeWrite([
Write()
..update = document
@@ -541,13 +539,8 @@
]);
}
- Future<void> storePatchset(
- String /*!*/ review,
- int /*!*/ patchset,
- String /*!*/ kind,
- String /*!*/ description,
- int /*!*/ patchsetGroup,
- int /*!*/ number) async {
+ Future<void> storePatchset(String review, int patchset, String kind,
+ String description, int patchsetGroup, int number) async {
final document = Document()
..name = '$documents/reviews/$review/patchsets/$patchset'
..fields = taggedMap({
@@ -558,28 +551,28 @@
});
await _executeWrite([Write()..update = document]);
log('Stored patchset: $documents/reviews/$review/patchsets/$patchset\n'
- '${untagMap(document.fields)}');
+ '${untagMap(document.fields!)}');
documentsWritten++;
}
/// Returns true if a review record in the database has a landed_index field,
/// or if there is no record for the review in the database. Reviews with no
/// test failures have no record, and don't need to be linked when landing.
- Future<bool> reviewIsLanded(int /*!*/ review) async {
+ Future<bool> reviewIsLanded(int review) async {
final document = await getDocumentOrNull('$documents/reviews/$review');
if (document == null) {
return true;
}
- return document.fields.containsKey('landed_index');
+ return document.fields!.containsKey('landed_index');
}
- Future<void> linkReviewToCommit(int /*!*/ review, int index) async {
+ Future<void> linkReviewToCommit(int review, int index) async {
final document = await getDocument('$documents/reviews/$review');
- document.fields['landed_index'] = taggedValue(index);
+ document.fields!['landed_index'] = taggedValue(index);
await updateFields(document, ['landed_index']);
}
- Future<void> linkCommentsToCommit(int /*!*/ review, int index) async {
+ Future<void> linkCommentsToCommit(int review, int index) async {
final comments =
await query(from: 'comments', where: fieldEquals('review', review));
if (comments.isEmpty) return;
@@ -595,7 +588,7 @@
await _executeWrite(writes);
}
- Future<List<SafeDocument /*!*/ >> tryApprovals(int review) async {
+ Future<List<SafeDocument>> tryApprovals(int review) async {
final patchsets = await query(
from: 'patchsets',
parent: 'reviews/$review',
@@ -614,7 +607,7 @@
]));
}
- Future<List<SafeDocument /*!*/ >> tryResults(
+ Future<List<SafeDocument>> tryResults(
int review, String configuration) async {
final patchsets = await query(
from: 'patchsets',
@@ -641,13 +634,12 @@
String builder, int index, bool success) async {
final path = '$documents/builds/$builder:$index';
final document = await getDocument(path);
- await _completeBuilderRecord(document /*!*/, success);
+ await _completeBuilderRecord(document!, success);
}
- Future<void> _completeBuilderRecord(
- Document /*!*/ document, bool success) async {
+ Future<void> _completeBuilderRecord(Document document, bool success) async {
await retryCommit(() async {
- document.fields['success'] = taggedValue(success);
+ document.fields!['success'] = taggedValue(success);
final write = Write()
..update = document
..updateMask = (DocumentMask()
diff --git a/builder/lib/src/firestore_helpers.dart b/builder/lib/src/firestore_helpers.dart
index aa4a92b..ea52654 100644
--- a/builder/lib/src/firestore_helpers.dart
+++ b/builder/lib/src/firestore_helpers.dart
@@ -5,15 +5,15 @@
import 'package:googleapis/firestore/v1.dart';
class SafeDocument {
- final String /*!*/ name;
- final Map<String, Value> /*!*/ fields;
+ final String name;
+ final Map<String, Value> fields;
SafeDocument(Document document)
- : name = document.name /*!*/,
- fields = document.fields /*!*/;
+ : name = document.name!,
+ fields = document.fields!;
Document toDocument() => Document(name: name, fields: fields);
- int getInt(String name) {
+ int? getInt(String name) {
final value = fields[name]?.integerValue;
if (value == null) {
return null;
@@ -21,15 +21,15 @@
return int.parse(value);
}
- String getString(String name) {
+ String? getString(String name) {
return fields[name]?.stringValue;
}
- bool getBool(String name) {
+ bool? getBool(String name) {
return fields[name]?.booleanValue;
}
- List<dynamic> getList(String name) {
+ List<dynamic>? getList(String name) {
final arrayValue = fields[name]?.arrayValue;
if (arrayValue == null) return null;
return arrayValue.values?.map(getValue)?.toList() ?? [];
@@ -37,7 +37,7 @@
bool isNull(String name) {
return !fields.containsKey(name) ||
- fields['name'].nullValue == 'NULL_VALUE';
+ fields['name']!.nullValue == 'NULL_VALUE';
}
}
@@ -67,15 +67,15 @@
dynamic getValue(Value value) {
if (value.integerValue != null) {
- return int.parse(value.integerValue);
+ return int.parse(value.integerValue!);
} else if (value.stringValue != null) {
return value.stringValue;
} else if (value.booleanValue != null) {
return value.booleanValue;
} else if (value.arrayValue != null) {
- return value.arrayValue.values.map(getValue).toList();
+ return value.arrayValue!.values!.map(getValue).toList();
} else if (value.timestampValue != null) {
- return DateTime.parse(value.timestampValue);
+ return DateTime.parse(value.timestampValue!);
} else if (value.nullValue != null) {
return null;
}
diff --git a/builder/lib/src/gerrit_change.dart b/builder/lib/src/gerrit_change.dart
index 0cd189e..8025584 100644
--- a/builder/lib/src/gerrit_change.dart
+++ b/builder/lib/src/gerrit_change.dart
@@ -21,7 +21,7 @@
final http.Client httpClient;
final FirestoreService firestore;
- final String /*!*/ review;
+ final String review;
final String patchset;
GerritInfo(int review, int patchset, this.firestore, this.httpClient)
@@ -53,7 +53,7 @@
..sort((a, b) => (a['_number'] as int).compareTo(b['_number']));
int patchsetGroupFirst = 1;
for (Map<String, dynamic> revision in revisions) {
- int number = revision['_number'] /*!*/;
+ int number = revision['_number']!;
if (!trivialKinds.contains(revision['kind'])) {
patchsetGroupFirst = number;
}
@@ -62,7 +62,7 @@
}
}
- static String revert(Map<String, dynamic> reviewInfo) {
+ static String? revert(Map<String, dynamic> reviewInfo) {
final current = reviewInfo['current_revision'];
final commit = reviewInfo['revisions'][current]['commit'];
final regExp =
diff --git a/builder/lib/src/result.dart b/builder/lib/src/result.dart
index 20a95a2..d3eecf5 100644
--- a/builder/lib/src/result.dart
+++ b/builder/lib/src/result.dart
@@ -10,21 +10,21 @@
import 'package:googleapis/firestore/v1.dart' show Value;
class ResultRecord {
- final Map<String, Value> /*!*/ fields;
+ final Map<String, Value> fields;
ResultRecord(this.fields);
- bool /*!*/ get approved => fields['approved'].booleanValue;
+ bool get approved => fields['approved']!.booleanValue!;
@override
String toString() => jsonEncode(fields);
int get blamelistEndIndex {
- return int.parse(fields['blamelist_end_index'].integerValue);
+ return int.parse(fields['blamelist_end_index']!.integerValue!);
}
- bool containsActiveConfiguration(String /*!*/ configuration) {
- for (final value in fields['active_configurations'].arrayValue.values) {
+ bool containsActiveConfiguration(String configuration) {
+ for (final value in fields['active_configurations']!.arrayValue!.values!) {
if (value.stringValue != null && value.stringValue == configuration) {
return true;
}
@@ -50,7 +50,7 @@
const fConfigurations = 'configurations';
const fActiveConfigurations = 'active_configurations';
-bool isChangedResult(Map<String, dynamic> /*!*/ change) =>
+bool isChangedResult(Map<String, dynamic> change) =>
change[fChanged] && (!change[fFlaky] || !change[fPreviousFlaky]);
/// Whether the change will be marked as an active failure.
@@ -70,7 +70,7 @@
}
}
-String fromStringOrValue(dynamic value) {
+String? fromStringOrValue(dynamic value) {
return value is Value ? value.stringValue : value;
}
@@ -96,10 +96,10 @@
class BuildInfo {
static final commitRefRegExp = RegExp(r'refs/changes/(\d*)/(\d*)');
- final String /*!*/ builderName;
+ final String builderName;
final int buildNumber;
- final String /*!*/ commitRef;
- final String previousCommitHash;
+ final String commitRef;
+ final String? previousCommitHash;
BuildInfo(Map<String, dynamic> result)
: builderName = result['builder_name'],
@@ -113,7 +113,7 @@
if (match == null) {
return BuildInfo(result);
} else {
- return TryBuildInfo(result, int.parse(match[1]), int.parse(match[2]));
+ return TryBuildInfo(result, int.parse(match[1]!), int.parse(match[2]!));
}
}
}
@@ -126,11 +126,11 @@
}
class TestNameLock {
- final locks = <String /*!*/, Future<void>>{};
+ final locks = <String, Future<void>>{};
Future<void> guardedCall(Future<void> Function(Map<String, dynamic> change) f,
- Map<String, dynamic> /*!*/ change) async {
- final name = change[fName] /*!*/;
+ Map<String, dynamic> change) async {
+ final name = change[fName]!;
while (locks.containsKey(name)) {
await locks[name];
}
diff --git a/builder/lib/src/reverted_changes.dart b/builder/lib/src/reverted_changes.dart
index e16304b..eb80ec2 100644
--- a/builder/lib/src/reverted_changes.dart
+++ b/builder/lib/src/reverted_changes.dart
@@ -17,14 +17,14 @@
final index = revertedCommit.index;
final changes = await firestore.findRevertedChanges(index);
return RevertedChanges(index, revertIndex, changes,
- groupBy(changes, (change) => getValue(change[fName])));
+ groupBy(changes, (change) => getValue(change[fName]!)));
}
class RevertedChanges {
final int index;
final int revertIndex;
- final List<Map<String, Value> /*!*/ > changes;
- final Map<String /*!*/, List<Map<String, Value> /*!*/ >> changesForTest;
+ final List<Map<String, Value>> changes;
+ final Map<String, List<Map<String, Value>>> changesForTest;
RevertedChanges(
this.index, this.revertIndex, this.changes, this.changesForTest);
@@ -34,6 +34,6 @@
return isFailure(revert) &&
reverted != null &&
reverted.any(
- (change) => revert[fResult] == getValue(change[fPreviousResult]));
+ (change) => revert[fResult] == getValue(change[fPreviousResult]!));
}
}
diff --git a/builder/lib/src/tryjob.dart b/builder/lib/src/tryjob.dart
index 31e371b..f88c014 100644
--- a/builder/lib/src/tryjob.dart
+++ b/builder/lib/src/tryjob.dart
@@ -57,17 +57,17 @@
}
class Tryjob {
- final http.Client /*!*/ httpClient;
- final FirestoreService /*!*/ firestore;
- final CommitsCache /*!*/ commits;
+ final http.Client httpClient;
+ final FirestoreService firestore;
+ final CommitsCache commits;
final counter = ChangeCounter();
- TryBuildInfo /*!*/ info;
+ TryBuildInfo info;
final TestNameLock testNameLock = TestNameLock();
- String /*!*/ baseRevision;
+ String baseRevision;
bool success = true;
- List<SafeDocument /*!*/ > landedResults;
- Map<String /*!*/, SafeDocument /*!*/ > lastLandedResultByName = {};
- final String /*!*/ buildbucketID;
+ late List<SafeDocument> landedResults;
+ Map<String, SafeDocument> lastLandedResultByName = {};
+ final String buildbucketID;
Tryjob(this.info, this.buildbucketID, this.baseRevision, this.commits,
this.firestore, this.httpClient);
@@ -79,29 +79,28 @@
.update();
}
- bool isNotLandedResult(Map<String, dynamic> /*!*/ change) {
+ bool isNotLandedResult(Map<String, dynamic> change) {
return !lastLandedResultByName.containsKey(change[fName]) ||
change[fResult] !=
- lastLandedResultByName[change[fName]].getString(fResult);
+ lastLandedResultByName[change[fName]]!.getString(fResult);
}
- Future<void> process(List<Map<String, dynamic> /*!*/ > results) async {
+ Future<void> process(List<Map<String, dynamic>> results) async {
await update();
log('storing ${results.length} change(s)');
- final resultsByConfiguration =
- groupBy<Map<String, dynamic> /*!*/, String /*!*/ >(
- results, (result) => result['configuration']);
+ final resultsByConfiguration = groupBy<Map<String, dynamic>, String>(
+ results, (result) => result['configuration']);
for (final configuration in resultsByConfiguration.keys) {
if (baseRevision != null && info.previousCommitHash != null) {
landedResults = await fetchLandedResults(configuration);
// Map will contain the last result with each name.
lastLandedResultByName = {
- for (final result in landedResults) result.getString(fName): result
+ for (final result in landedResults) result.getString(fName)!: result
};
}
final changes =
- resultsByConfiguration[configuration].where(isNotLandedResult);
+ resultsByConfiguration[configuration]!.where(isNotLandedResult);
await Pool(30).forEach(changes, guardedStoreChange).drain();
}
@@ -121,7 +120,7 @@
log(report.join('\n'));
}
- Future<void> guardedStoreChange(Map<String, dynamic> /*!*/ change) =>
+ Future<void> guardedStoreChange(Map<String, dynamic> change) =>
testNameLock.guardedCall(storeChange, change);
Future<void> storeChange(Map<String, dynamic> change) async {
@@ -136,11 +135,10 @@
}
}
- Future<List<SafeDocument /*!*/ >> fetchLandedResults(
- String configuration) async {
- final resultsBase = await commits.getCommit(info.previousCommitHash);
+ Future<List<SafeDocument>> fetchLandedResults(String configuration) async {
+ final resultsBase = await commits.getCommit(info.previousCommitHash!);
final rebaseBase = await commits.getCommit(baseRevision);
- if (resultsBase /*!*/ .index > rebaseBase /*!*/ .index) {
+ if (resultsBase!.index > rebaseBase!.index) {
print('Try build is rebased on $baseRevision, which is before '
'the commit ${info.previousCommitHash} with CI comparison results');
return [];
diff --git a/builder/pubspec.yaml b/builder/pubspec.yaml
index ade43a4..6b3244f 100644
--- a/builder/pubspec.yaml
+++ b/builder/pubspec.yaml
@@ -3,7 +3,7 @@
version: 0.1.0
environment:
- sdk: '^2.10.0'
+ sdk: '>=2.12.0 <3.0.0'
dependencies:
args: ^2.3.0
@@ -12,6 +12,7 @@
http: ^0.13.0
pool: ^1.5.0
retry: 3.1.0
+ collection: ^1.15.0-nullsafety.4
dev_dependencies:
lints: ^1.0.0
diff --git a/builder/test/approvals_test.dart b/builder/test/approvals_test.dart
index c85a444..ddc955e 100644
--- a/builder/test/approvals_test.dart
+++ b/builder/test/approvals_test.dart
@@ -22,41 +22,40 @@
// To run against the staging database, use a service account.
// with write access to dart_ci_staging datastore.
-/*late final*/ FirestoreService /*!*/ firestore;
-/*late final*/ http.Client /*!*/ client;
-/*late final*/ CommitsCache /*!*/ commitsCache;
+late final FirestoreService firestore;
+late final http.Client client;
+late final CommitsCache commitsCache;
// The real commits and reviews we will test on, fetched from Firestore.
// These globals are populated by loadTestCommits().
const testCommitsStart = 80801;
const reviewWithComments = '215021';
-/*late final*/ String /*!*/ index1; // Index of the final commit in the test range
-/*late final*/ String /*!*/ commit1; // Hash of that commit
-/*late final*/ String review; // CL number of that commit's Gerrit review
-/*late final*/ String /*!*/ lastPatchset; // Final patchset in that review
-/*late final*/ String lastPatchsetRef; // 'refs/changes/[review]/[patchset]'
-/*late final*/ String /*!*/
- patchsetGroup; // First patchset in the final patchset group
-/*late final*/ String patchsetGroupRef;
-/*late final*/ String earlyPatchset; // Patchset not in the final patchset group
-/*late final*/ String earlyPatchsetRef;
+late final String index1; // Index of the final commit in the test range
+late final String commit1; // Hash of that commit
+late final String review; // CL number of that commit's Gerrit review
+late final String lastPatchset; // Final patchset in that review
+late final String lastPatchsetRef; // 'refs/changes/[review]/[patchset]'
+late final String patchsetGroup; // First patchset in the final patchset group
+late final String patchsetGroupRef;
+late final String earlyPatchset; // Patchset not in the final patchset group
+late final String earlyPatchsetRef;
// Earlier commit with a review
-/*late final*/ String /*!*/ index2;
-/*late final*/ String /*!*/ commit2;
-/*late final*/ String review2;
-/*late final*/ String /*!*/ patchset2;
-/*late final*/ String patchset2Ref;
+late final String index2;
+late final String commit2;
+late final String review2;
+late final String patchset2;
+late final String patchset2Ref;
// Commits before commit2
-/*late final*/ String index3;
-/*late final*/ String /*!*/ commit3;
-/*late final*/ String index4;
-/*late final*/ String /*!*/ commit4;
+late final String index3;
+late final String commit3;
+late final String index4;
+late final String commit4;
-final buildersToRemove = <String /*!*/ >{};
-final testsToRemove = <String /*!*/ >{};
+final buildersToRemove = <String>{};
+final testsToRemove = <String>{};
void registerChangeForDeletion(Map<String, dynamic> change) {
- buildersToRemove.add(change['builder_name'] as String /*!*/);
- testsToRemove.add(change['name'] as String /*!*/);
+ buildersToRemove.add(change['builder_name'] as String);
+ testsToRemove.add(change['name'] as String);
}
Future<void> removeBuildersAndResults() async {
@@ -96,10 +95,10 @@
where: fieldLessThanOrEqual('landed_index', startIndex),
limit: 2);
final firstReview = reviews.first;
- index1 = firstReview.fields['landed_index'].integerValue;
+ index1 = firstReview.fields['landed_index']!.integerValue!;
review = firstReview.name.split('/').last;
final secondReview = reviews.last;
- index2 = secondReview.fields['landed_index'].integerValue;
+ index2 = secondReview.fields['landed_index']!.integerValue!;
review2 = secondReview.name.split('/').last;
index3 = (int.parse(index2) - 1).toString();
index4 = (int.parse(index2) - 2).toString();
@@ -110,9 +109,9 @@
orderBy: orderBy('number', true),
);
final patchsetFields = patchsets.last.fields;
- lastPatchset = patchsetFields['number'].integerValue;
+ lastPatchset = patchsetFields['number']!.integerValue!;
lastPatchsetRef = 'refs/changes/$review/$lastPatchset';
- patchsetGroup = patchsetFields['patchset_group'].integerValue;
+ patchsetGroup = patchsetFields['patchset_group']!.integerValue!;
patchsetGroupRef = 'refs/changes/$review/$patchsetGroup';
earlyPatchset = '1';
earlyPatchsetRef = 'refs/changes/$review/$earlyPatchset';
@@ -121,7 +120,7 @@
parent: 'reviews/$review2',
orderBy: orderBy('number', true),
);
- patchset2 = patchsets2.last.fields['number'].integerValue;
+ patchset2 = patchsets2.last.fields['number']!.integerValue!;
patchset2Ref = 'refs/changes/$review/$patchset2';
// Get commit hashes for the landed reviews, and for a commit before them
@@ -136,21 +135,21 @@
.split('/')
.last
};
- commit1 = commits[index1];
- commit2 = commits[index2];
- commit3 = commits[index3];
- commit4 = commits[index4];
+ commit1 = commits[index1]!;
+ commit2 = commits[index2]!;
+ commit3 = commits[index3]!;
+ commit4 = commits[index4]!;
}
Tryjob makeTryjob(String name, Map<String, dynamic> firstChange,
- {String baseCommit}) =>
- Tryjob(BuildInfo.fromResult(firstChange), 'bbID_$name',
+ {String? baseCommit}) =>
+ Tryjob(BuildInfo.fromResult(firstChange) as TryBuildInfo, 'bbID_$name',
baseCommit ?? commit4, commitsCache, firestore, client);
const newFailure = 'Pass/RuntimeError/Pass';
Map<String, dynamic> makeTryChange(
String name, String result, String patchsetRef,
- {String testName}) {
+ {String? testName}) {
final results = result.split('/');
final previous = results[0];
final current = results[1];
@@ -183,7 +182,7 @@
Map<String, dynamic> makeChange(
String name, String result, String commit, String previousCommit,
- {String testName}) {
+ {String? testName}) {
final change = {
...makeTryChange(name, result, '', testName: testName),
'commit_hash': commit,
@@ -280,12 +279,12 @@
from: 'comments',
where: fieldEquals('review', int.parse(reviewWithComments)));
final landedIndex =
- commentsQuery.first.fields[fBlamelistStartIndex].integerValue;
+ commentsQuery.first.fields[fBlamelistStartIndex]!.integerValue!;
for (final item in commentsQuery) {
final fields = item.fields;
- expect(fields[fBlamelistStartIndex].integerValue, landedIndex);
- expect(fields[fBlamelistEndIndex].integerValue, landedIndex);
- expect(fields[fReview].integerValue, reviewWithComments);
+ expect(fields[fBlamelistStartIndex]!.integerValue, landedIndex);
+ expect(fields[fBlamelistEndIndex]!.integerValue, landedIndex);
+ expect(fields[fReview]!.integerValue, reviewWithComments);
fields.remove(fBlamelistStartIndex);
fields.remove(fBlamelistEndIndex);
await firestore.updateFields(
@@ -293,8 +292,8 @@
}
var reviewDocument = await firestore
.getDocument('${firestore.documents}/reviews/$reviewWithComments');
- expect(reviewDocument.fields['landed_index'].integerValue, landedIndex);
- reviewDocument.fields.remove('landed_index');
+ expect(reviewDocument.fields!['landed_index']!.integerValue, landedIndex);
+ reviewDocument.fields!.remove('landed_index');
await firestore.updateFields(reviewDocument, ['landed_index']);
await firestore.linkReviewToCommit(
@@ -306,17 +305,18 @@
where: fieldEquals('review', int.parse(reviewWithComments)));
for (final item in commentsQuery) {
final fields = item.fields;
- expect(fields[fBlamelistStartIndex].integerValue, landedIndex);
- expect(fields[fBlamelistEndIndex].integerValue, landedIndex);
- expect(fields[fReview].integerValue, reviewWithComments);
+ expect(fields[fBlamelistStartIndex]!.integerValue, landedIndex);
+ expect(fields[fBlamelistEndIndex]!.integerValue, landedIndex);
+ expect(fields[fReview]!.integerValue, reviewWithComments);
}
reviewDocument = await firestore
.getDocument('${firestore.documents}/reviews/$reviewWithComments');
- expect(reviewDocument.fields['landed_index'].integerValue, landedIndex);
+ expect(reviewDocument.fields!['landed_index']!.integerValue, landedIndex);
});
}
-Future<void> checkTryBuild(String name, {bool success, bool truncated}) async {
+Future<void> checkTryBuild(String name,
+ {bool? success, bool? truncated}) async {
final buildbucketId = 'bbID_$name';
final buildDocuments = await firestore.query(
from: 'try_builds', where: fieldEquals('buildbucket_id', buildbucketId));
@@ -330,10 +330,10 @@
}
}
-Future<void> checkBuild(String builder, String index, {bool success}) async {
+Future<void> checkBuild(String? builder, String index, {bool? success}) async {
final document = await firestore
.getDocument('${firestore.documents}/builds/$builder:$index');
- expect(document.fields['success'].booleanValue, success);
+ expect(document.fields!['success']!.booleanValue, success);
}
Future<void> checkResult(Map<String, dynamic> change, String startIndex,
@@ -342,8 +342,8 @@
final resultName = await firestore.findResult(
change, int.parse(startIndex), int.parse(endIndex));
expect(resultName, isNotNull);
- final resultDocument = await firestore.getDocument(resultName /*!*/);
- final data = untagMap(resultDocument.fields);
+ final resultDocument = await firestore.getDocument(resultName!);
+ final data = untagMap(resultDocument.fields!);
expect(data[fName], change[fName]);
expect(data[fBlamelistStartIndex], int.parse(startIndex));
expect(data[fBlamelistEndIndex], int.parse(endIndex));
diff --git a/builder/test/fakes.dart b/builder/test/fakes.dart
index 8502ea7..72a0dc3 100644
--- a/builder/test/fakes.dart
+++ b/builder/test/fakes.dart
@@ -17,8 +17,8 @@
class BuilderTest {
final client = HttpClientMock();
final firestore = FirestoreServiceFake();
- CommitsCache commitsCache;
- Build builder;
+ late CommitsCache commitsCache;
+ late Build builder;
Map<String, dynamic> firstChange;
BuilderTest(this.firstChange) {
@@ -51,16 +51,16 @@
Future<bool> isStaging() async => false;
@override
- Future<Commit> getCommit(String hash) async {
+ Future<Commit?> getCommit(String hash) async {
final commit = commits[hash];
if (commit == null) {
return null;
}
- return Commit.fromJson(hash, commits[hash]);
+ return Commit.fromJson(hash, commits[hash]!);
}
@override
- Future<Commit> getCommitByIndex(int index) {
+ Future<Commit> getCommitByIndex(int? index) {
for (final entry in commits.entries) {
if (entry.value[fIndex] == index) {
return Future.value(Commit.fromJson(entry.key, entry.value));
@@ -71,7 +71,7 @@
@override
Future<Commit> getLastCommit() => getCommitByIndex(
- commits.values.map<int>((commit) => commit[fIndex]).reduce(max));
+ commits.values.map<int?>((commit) => commit[fIndex]).reduce(max));
@override
Future<void> addCommit(String id, Map<String, dynamic> data) async {
@@ -81,8 +81,8 @@
@override
Future<String> findResult(
Map<String, dynamic> change, int startIndex, int endIndex) {
- String resultId;
- int resultEndIndex;
+ String? resultId;
+ int? resultEndIndex;
for (final entry in results.entries) {
final result = entry.value;
if (result[fName] == change[fName] &&
@@ -103,20 +103,20 @@
@override
Future<List<SafeDocument>> findActiveResults(
- String name, String configuration) async {
+ String? name, String? configuration) async {
return [
for (final id in results.keys)
- if (results[id][fName] == name &&
- results[id][fActiveConfigurations] != null &&
- results[id][fActiveConfigurations].contains(configuration))
+ if (results[id]![fName] == name &&
+ results[id]![fActiveConfigurations] != null &&
+ results[id]![fActiveConfigurations].contains(configuration))
SafeDocument(Document()
- ..fields = taggedMap(Map.from(results[id]))
+ ..fields = taggedMap(Map.from(results[id]!))
..name = id)
];
}
@override
- Future<Document> storeResult(Map<String, dynamic> result) async {
+ Future<Document?> storeResult(Map<String, dynamic> result) async {
final id = 'resultDocumentID$addedResultIdCounter';
addedResultIdCounter++;
results[id] = result;
@@ -125,16 +125,16 @@
@override
Future<bool> updateResult(
- String resultId, String configuration, int startIndex, int endIndex,
- {bool failure}) {
- final result = Map<String, dynamic>.from(results[resultId]);
+ String resultId, String? configuration, int startIndex, int endIndex,
+ {required bool failure}) {
+ final result = Map<String, dynamic>.from(results[resultId]!);
result[fBlamelistStartIndex] =
max<int>(startIndex, result[fBlamelistStartIndex]);
result[fBlamelistEndIndex] = min<int>(endIndex, result[fBlamelistEndIndex]);
if (!result[fConfigurations].contains(configuration)) {
- result[fConfigurations] = List<String>.from(result[fConfigurations])
+ result[fConfigurations] = List<String?>.from(result[fConfigurations])
..add(configuration)
..sort();
}
@@ -142,7 +142,7 @@
result[fActive] = true;
if (!result[fActiveConfigurations].contains(configuration)) {
result[fActiveConfigurations] =
- List<String>.from(result[fActiveConfigurations])
+ List<String?>.from(result[fActiveConfigurations])
..add(configuration)
..sort();
}
@@ -153,8 +153,8 @@
@override
Future<void> removeActiveConfiguration(
- SafeDocument activeResult, String configuration) async {
- final result = Map<String, dynamic>.from(results[activeResult.name]);
+ SafeDocument activeResult, String? configuration) async {
+ final result = Map<String, dynamic>.from(results[activeResult.name]!);
result[fActiveConfigurations] = List.from(result[fActiveConfigurations])
..remove(configuration);
if (result[fActiveConfigurations].isEmpty) {
diff --git a/builder/test/firestore_test.dart b/builder/test/firestore_test.dart
index 57f0516..3c9add7 100644
--- a/builder/test/firestore_test.dart
+++ b/builder/test/firestore_test.dart
@@ -93,10 +93,10 @@
expect(activeResult.fields, contains('active'));
await firestore.removeActiveConfiguration(
activeResult, 'configuration 2');
- final document = await firestore.getDocument(createdResultDocument.name);
+ final document = await firestore.getDocument(createdResultDocument.name!);
expect(document.fields, isNot(contains('active')));
expect(document.fields, isNot(contains('active_configurations')));
- await firestore.deleteDocument(createdResultDocument.name);
+ await firestore.deleteDocument(createdResultDocument.name!);
});
test('approved try result fetching', () async {
diff --git a/builder/test/results_test.dart b/builder/test/results_test.dart
index a3e4b97..98379e3 100644
--- a/builder/test/results_test.dart
+++ b/builder/test/results_test.dart
@@ -27,7 +27,7 @@
final builderTest = BuilderTest(landedCommitChange);
builderTest.firestore.commits
.removeWhere((key, value) => value[fIndex] > existingCommitIndex);
- when(builderTest.client.get(any))
+ when(builderTest.client.get(any!))
.thenAnswer((_) => Future(() => ResponseFake(gitilesLog)));
await builderTest.storeBuildCommitsInfo();
await builderTest.builder.fetchReviewsAndReverts();
@@ -35,9 +35,9 @@
expect(builderTest.builder.startIndex, existingCommitIndex + 1);
expect(builderTest.builder.tryApprovals,
{testResult(review44445Result): 54, testResult(review77779Result): 53});
- expect((await builderTest.firestore.getCommit(commit53Hash)).toJson(),
+ expect((await builderTest.firestore.getCommit(commit53Hash))!.toJson(),
commit53);
- expect((await builderTest.firestore.getCommit(landedCommitHash)).toJson(),
+ expect((await builderTest.firestore.getCommit(landedCommitHash))!.toJson(),
landedCommit);
});
@@ -56,8 +56,11 @@
..['configuration'] = 'another configuration';
await builderTest.storeChange(changeAnotherConfiguration);
expect(builderTest.builder.success, true);
- expect(builderTest.firestore.results['activeResultID'],
- Map.from(activeResult)..remove(fActiveConfigurations)..remove(fActive));
+ expect(
+ builderTest.firestore.results['activeResultID'],
+ Map.from(activeResult)
+ ..remove(fActiveConfigurations)
+ ..remove(fActive));
expect(builderTest.builder.countApprovalsCopied, 1);
expect(builderTest.builder.countChanges, 2);
expect(
diff --git a/builder/test/revert_test.dart b/builder/test/revert_test.dart
index 91e6fdc..968edf5 100644
--- a/builder/test/revert_test.dart
+++ b/builder/test/revert_test.dart
@@ -15,13 +15,13 @@
test('fetch commit that is a revert', () async {
final builderTest = BuilderTest(revertUnchangedChange);
builderTest.firestore.commits[revertedCommitHash] = revertedCommit;
- when(builderTest.client.get(any))
+ when(builderTest.client.get(any!))
.thenAnswer((_) => Future(() => ResponseFake(revertGitilesLog)));
await builderTest.storeBuildCommitsInfo();
expect(builderTest.builder.endIndex, revertCommit['index']);
expect(builderTest.builder.startIndex, landedCommit['index'] + 1);
expect(
- (await builderTest.builder.firestore.getCommit(revertCommitHash))
+ (await builderTest.builder.firestore.getCommit(revertCommitHash))!
.toJson(),
revertCommit);
});
@@ -29,33 +29,33 @@
test('fetch commit that is a reland (as a reland)', () async {
final builderTest = BuilderTest(relandUnchangedChange);
builderTest.firestore.commits[revertedCommitHash] = revertedCommit;
- when(builderTest.client.get(any)).thenAnswer(
+ when(builderTest.client.get(any!)).thenAnswer(
(_) => Future(() => ResponseFake(revertAndRelandGitilesLog)));
await builderTest.storeBuildCommitsInfo();
expect(builderTest.builder.endIndex, relandCommit['index']);
expect(builderTest.builder.startIndex, revertCommit['index'] + 1);
expect(
- (await builderTest.builder.firestore.getCommit(revertCommitHash))
+ (await builderTest.builder.firestore.getCommit(revertCommitHash))!
.toJson(),
revertCommit);
expect(
- (await builderTest.builder.firestore.getCommit(commit56Hash)).toJson(),
+ (await builderTest.builder.firestore.getCommit(commit56Hash))!.toJson(),
commit56);
expect(
- (await builderTest.builder.firestore.getCommit(relandCommitHash))
+ (await builderTest.builder.firestore.getCommit(relandCommitHash))!
.toJson(),
relandCommit);
});
test('fetch commit that is a reland (as a revert)', () async {
final builderTest = RevertBuilderTest(relandUnchangedChange);
- when(builderTest.client.get(any))
+ when(builderTest.client.get(any!))
.thenAnswer((_) => Future(() => ResponseFake(relandGitilesLog)));
await builderTest.storeBuildCommitsInfo();
expect(builderTest.builder.endIndex, relandCommit['index']);
expect(builderTest.builder.startIndex, revertCommit['index'] + 1);
expect(
- (await builderTest.builder.firestore.getCommit(relandCommitHash))
+ (await builderTest.builder.firestore.getCommit(relandCommitHash))!
.toJson(),
relandCommit);
});
@@ -257,7 +257,7 @@
};
// Git logs
-String escape(s) => s.replaceAll('"', '\\"');
+String? escape(s) => s.replaceAll('"', '\\"');
String revertGitilesLog = gitilesLog([revertCommitJson]);
String relandGitilesLog = gitilesLog([relandCommitJson(relandAsRevert)]);
String revertAndRelandGitilesLog = gitilesLog(
diff --git a/builder/test/tryjob_test.dart b/builder/test/tryjob_test.dart
index 08718ff..69c3e87 100644
--- a/builder/test/tryjob_test.dart
+++ b/builder/test/tryjob_test.dart
@@ -21,15 +21,15 @@
// To run against the staging database, use a service account.
// with write access to dart_ci_staging datastore.
-FirestoreService firestore;
-http.Client client;
-CommitsCache commitsCache;
+late FirestoreService firestore;
+late http.Client client;
+late CommitsCache commitsCache;
// The real commits and reviews we will test on, fetched from Firestore
const testCommitsStart = 80836;
-Map<String, String> data;
+late Map<String, String?> data;
-final buildersToRemove = <String>{};
-final testsToRemove = <String>{};
+final buildersToRemove = <String?>{};
+final testsToRemove = <String?>{};
void registerChangeForDeletion(Map<String, dynamic> change) {
buildersToRemove.add(change['builder_name']);
@@ -53,7 +53,7 @@
}
}
-Future<Map<String, String>> loadTestCommits(int startIndex) async {
+Future<Map<String, String?>> loadTestCommits(int startIndex) async {
// Get review data for the last two landed CLs before or at startIndex.
final reviews = await firestore.query(
from: 'reviews',
@@ -61,10 +61,10 @@
where: fieldLessThanOrEqual('landed_index', startIndex),
limit: 2);
final firstReview = reviews.first;
- final String index = firstReview.fields['landed_index'].integerValue;
+ final String? index = firstReview.fields['landed_index']!.integerValue;
final String review = firstReview.name.split('/').last;
final secondReview = reviews.last;
- final String landedIndex = secondReview.fields['landed_index'].integerValue;
+ final String landedIndex = secondReview.fields['landed_index']!.integerValue!;
final String landedReview = secondReview.name.split('/').last;
// expect(int.parse(index), greaterThan(int.parse(landedIndex)));
final String baseIndex = (int.parse(landedIndex) - 1).toString();
@@ -74,21 +74,21 @@
parent: 'reviews/$review',
orderBy: orderBy('number', true),
);
- final patchset = patchsets.last.fields['number'].integerValue;
+ final patchset = patchsets.last.fields['number']!.integerValue;
final previousPatchset = '1';
final landedPatchsets = await firestore.query(
from: 'patchsets',
parent: 'reviews/$landedReview',
orderBy: orderBy('number', true),
);
- final landedPatchset = landedPatchsets.last.fields['number'].integerValue;
+ final landedPatchset = landedPatchsets.last.fields['number']!.integerValue;
// Get commit hashes for the landed reviews, and for a commit before them
var commits = {
for (final index in [index, landedIndex, baseIndex])
index: (await firestore.query(
from: 'commits',
- where: fieldEquals('index', int.parse(index)),
+ where: fieldEquals('index', int.parse(index!)),
limit: 1))
.first
.name
@@ -113,16 +113,16 @@
}
Tryjob makeTryjob(String name, Map<String, dynamic> firstChange) => Tryjob(
- BuildInfo.fromResult(firstChange),
+ BuildInfo.fromResult(firstChange) as TryBuildInfo,
'bbID_$name',
- data['landedCommit'],
+ data['landedCommit']!,
commitsCache,
firestore,
client);
Tryjob makeLandedTryjob(String name, Map<String, dynamic> firstChange) =>
- Tryjob(BuildInfo.fromResult(firstChange), 'bbID_$name', data['baseCommit'],
- commitsCache, firestore, client);
+ Tryjob(BuildInfo.fromResult(firstChange) as TryBuildInfo, 'bbID_$name',
+ data['baseCommit']!, commitsCache, firestore, client);
Map<String, dynamic> makeChange(String name, String result,
{bool flaky = false}) {
@@ -160,14 +160,15 @@
return makeChange(name, result)..['commit_hash'] = data['landedPatchsetRef'];
}
-Future<void> checkTryBuild(String name, {bool success, bool truncated}) async {
+Future<void> checkTryBuild(String name,
+ {bool? success, bool? truncated}) async {
final buildbucketId = 'bbID_$name';
final buildDocuments = await firestore.query(
from: 'try_builds', where: fieldEquals('buildbucket_id', buildbucketId));
expect(buildDocuments.length, 1);
- expect(buildDocuments.single.fields['success'].booleanValue, success);
+ expect(buildDocuments.single.fields['success']!.booleanValue, success);
if (truncated != null) {
- expect(buildDocuments.single.fields['truncated'].booleanValue, truncated);
+ expect(buildDocuments.single.fields['truncated']!.booleanValue, truncated);
} else {
expect(buildDocuments.single.fields.containsKey('truncated'), isFalse);
}
@@ -210,7 +211,7 @@
final result = await firestore.query(
from: 'try_results', where: fieldEquals('name', 'failure_test'));
expect(result.length, 1);
- expect(result.single.getList('configurations').length, 2);
+ expect(result.single.getList('configurations')!.length, 2);
});
test('landedFailure', () async {
@@ -284,21 +285,21 @@
test('patchsets', () async {
final document = await firestore.getDocument(
'${firestore.documents}/reviews/${data['review']}/patchsets/${data['patchset']}');
- final fields = untagMap(document.fields);
+ final fields = untagMap(document.fields!);
expect(fields['number'].toString(), data['patchset']);
await firestore.storePatchset(
- data['review'],
+ data['review']!,
fields['number'],
fields['kind'],
fields['description'],
fields['patchset_group'],
fields['number']);
- final document1 = await firestore.getDocument(document.name);
- expect(untagMap(document1.fields), equals(fields));
+ final document1 = await firestore.getDocument(document.name!);
+ expect(untagMap(document1.fields!), equals(fields));
fields['number'] += 1;
fields['description'] = 'test description';
await firestore.storePatchset(
- data['review'],
+ data['review']!,
fields['number'],
fields['kind'],
fields['description'],
@@ -307,7 +308,7 @@
final name =
'${firestore.documents}/reviews/${data['review']}/patchsets/${fields['number']}';
final document2 = await firestore.getDocument(name);
- final fields2 = untagMap(document2.fields);
+ final fields2 = untagMap(document2.fields!);
expect(fields2, equals(fields));
await firestore.deleteDocument(name);
});