blob: a3ae381b7c2777a19ea61c18f306d21ae9262e4a [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) {
var 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 substring in disallowedSubstrings) {
if (value.contains(substring)) {
throw FormatException('Found "$disallowedSubstrings" in "$value".');
}
}
}
DateTime maxAge(final Duration maxAge) => DateTime.now().subtract(maxAge);