blob: 7e2896425318f2b1b4d5e36e09b47c1a7385424a [file] [log] [blame]
// Copyright 2023 The Flutter Authors. 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:async';
import 'dart:io';
import 'package:github/github.dart';
const Duration clockSkew = Duration(seconds: 5);
int minApiPoints = 250; // number of points to leave for debugging, etc
class Abort implements Exception {}
enum Mode { full, abbreviated, aborted }
Mode mode = Mode.full;
final Completer<void> aborter = Completer<void>();
Future<void> rateLimit(final GitHub github, final String status, final String next) async {
if (mode == Mode.aborted) {
throw Abort();
}
stdout.write(
'$status${github.rateLimitRemaining != null ? ". Rate limits: ${github.rateLimitRemaining}/${github.rateLimitLimit} per hour" : ""}.\x1B[K\r',
);
if (github.rateLimitRemaining != null && github.rateLimitRemaining! < minApiPoints) {
Duration delay = github.rateLimitReset!.difference(DateTime.now());
if (delay > Duration.zero) {
delay += clockSkew;
print('\nWaiting until ${DateTime.now().add(delay).toLocal()} to continue with $next...');
await Future.any<void>(<Future<void>>[
Future<void>.delayed(delay),
aborter.future,
]);
minApiPoints = 50;
}
}
}
void verifyStringSanity(final String value, final Set<String> disallowedSubstrings) {
for (final String substring in disallowedSubstrings) {
if (value.contains(substring)) {
throw FormatException('Found "$disallowedSubstrings" in "$value".');
}
}
}
DateTime maxAge(final Duration maxAge) => DateTime.now().subtract(maxAge);