blob: a9ba26db56bec2113b1c6308d5a6e4a663f6b974 [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// 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 'dart:convert';
import 'package:http/http.dart' as http;
import 'firestore.dart';
class GerritInfo {
static const gerritUrl = '';
static const gerritQuery =
static const trivialKinds = {
static const prefix = ")]}'\n";
http.BaseClient httpClient;
FirestoreService firestore;
String review;
String patchset;
GerritInfo(int review, int patchset, this.firestore, this.httpClient) { = review.toString();
this.patchset = patchset.toString();
/// Fetches the owner, changeId, message, and date of a Gerrit change and
/// stores them in the databases.
Future<void> update() async {
if (await firestore.hasPatchset(review, patchset)) return;
// Get the Gerrit change's commit from the Gerrit API.
final url = '$gerritUrl/$review?$gerritQuery';
final response = await httpClient.get(url);
final protectedJson = response.body;
if (!protectedJson.startsWith(prefix)) {
throw Exception('Gerrit response missing prefix $prefix: $protectedJson');
final reviewInfo = jsonDecode(protectedJson.substring(prefix.length))
as Map<String, dynamic>;
final reverted = revert(reviewInfo);
await firestore.storeReview(review, {
'subject': taggedValue(reviewInfo['subject']),
if (reverted != null) 'revert_of': taggedValue(reverted)
// Add the patchset information to the patchsets subcollection.
final revisions = reviewInfo['revisions'].values.toList()
..sort((a, b) => (a['_number'] as int).compareTo(b['_number']));
int patchsetGroupFirst;
for (Map<String, dynamic> revision in revisions) {
int number = revision['_number'];
if (!trivialKinds.contains(revision['kind'])) {
patchsetGroupFirst = number;
await firestore.storePatchset(review, number, revision['kind'],
revision['description'], patchsetGroupFirst, number);
static String revert(Map<String, dynamic> reviewInfo) {
final current = reviewInfo['current_revision'];
final commit = reviewInfo['revisions'][current]['commit'];
final regExp =
RegExp('^This reverts commit ([\\da-f]+)\\.\$', multiLine: true);
return regExp.firstMatch(commit['message'])?.group(1);