anchor.diff:    exit(1);
   }
   
  -// Pubsub messages must be < 10MB long.  Because the JSON we send is
  -// Base64 encoded, and we add a final record after checking the size,
  -// the limit must be less than 3/4 of 10MB.
  -// Because we have some Firestore scalability issues when thousands of new
  -// tests are added, we currently use less than half of the maximum size.
  -const messageLengthLimit = 3000000;
  +const resultsPerMessage = 100;
   const postUrl =
       'https://pubsub.googleapis.com/v1/projects/dart-ci/topics/results:publish';
   
  
positive.code: void usage(ArgParser parser) {
    print('''
  Usage: post_results_to_pubsub.dart [OPTIONS]
  Posts Dart CI results as messages to Google cloud pubsub
  
  The options are as follows:
  
  
negative.code:   final lines = await File(options['result_file']).readAsLines();
    final token = await File(options['auth_token']).readAsString();
    final buildbucketID = options['id'];
    if (lines.isEmpty) {
      print('No results in input file');
      return;
    }
    // Record the configurations appearing in these results.
    final configurationRegexp = RegExp('"configuration":"([^"]*)"');
    final configurationsSet = {
      for (final result in lines) configurationRegexp.firstMatch(result)?.group(1)
    };
    if (configurationsSet.contains(null)) {
      print("Error: result without a configuration");
      configurationsSet.remove(null);
    }
    final configurations = configurationsSet.toList()..sort();
    final configurationGroups = {
      for (final configuration in configurations) configuration.split('-').first
    };
    // Construct a link to the results feed that includes a filter showing
    // unapproved failures for those configuration groups.
    String fragment = [
      'showLatestFailures=true',
      'showUnapprovedOnly=true',
      if (configurationGroups.isNotEmpty)
        'configurationGroups=${configurationGroups.join(',')}'
    ].join('&');
    final resultsFeedUrl = 'https://dart-ci.firebaseapp.com/#$fragment';
    // Save them to a file.
    await File('builder_tested_configurations')
        .writeAsString(JsonEncoder.withIndent('  ').convert({
      'configurations': configurations,
      'results_feed_link': resultsFeedUrl,
    }));
  
    final changedPattern = '"changed":true';
    List<String> changedResults =
        lines.where((change) => change.contains(changedPattern)).toList();
    // We need to send at least one result, to save build metadata to Firestore.
    // Send an unchanged result - the cloud function filters these out.
    if (changedResults.isEmpty) changedResults = lines.sublist(0, 1);
  
    final chunks = <List<String>>[];
    final chunkLength = resultsPerMessage;
    var position = 0;
    final lastFullChunkStart = changedResults.length - resultsPerMessage;
    while (position <= lastFullChunkStart) {
      chunks.add(changedResults.sublist(position, position += resultsPerMessage));
    }
    if (position < changedResults.length)
      chunks.add(changedResults.sublist(position));
  
    // Send pubsub messages.
    for (final chunk in chunks) {
      final message = '[\n${chunk.join(",\n")}\n]';
      final base64data = base64Encode(utf8.encode(message.toString()));
      final attributes = {
        if (chunk == chunks.last) 'num_chunks': chunks.length.toString(),
        if (buildbucketID != null) 'buildbucket_id': buildbucketID
      };
      final jsonMessage = jsonEncode({
        'messages': [
          {'attributes': attributes, 'data': base64data}
        ]
      });
      final headers = {'Authorization': 'Bearer $token'};
      final response =
          await client.post(postUrl, headers: headers, body: jsonMessage);
  
      print('Sent pubsub message containing ${chunk.length} results');
      print('Status ${response.statusCode}');
      print('Response: ${response.body}');
    }
    print('Number of Pub/Sub messages sent: ${chunks.length}');
    client.close();
  }
  