Skip to content

Commit ec06e5c

Browse files
committed
chore(cli): Add connection monitor
Adds a utility for monitoring the network connection. This primarily lets us know whether we need to add `--offline` to pub commands.
1 parent f67bc03 commit ec06e5c

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

apps/cli/lib/src/cli/cli.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ final class Cli {
8989
? const SentryPerformance()
9090
: const CelestPerformance();
9191
ctx.storage = storage ?? Storage();
92+
ctx.connectionMonitor.init();
93+
await ctx.connectionMonitor.stream.first;
9294

9395
try {
9496
_logger.finest('Initializing secure storage');
@@ -401,6 +403,7 @@ final class Cli {
401403
await _logFile?.close();
402404
await ctx.performance.close();
403405
ctx.httpClient.close();
406+
ctx.connectionMonitor.close();
404407
exit(exitCode);
405408
}
406409
}

apps/cli/lib/src/context.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'package:celest_cli/src/project/project_paths.dart';
1616
import 'package:celest_cli/src/serialization/json_generator.dart';
1717
import 'package:celest_cli/src/storage/storage.dart';
1818
import 'package:celest_cli/src/types/type_helper.dart';
19+
import 'package:celest_cli/src/utils/connection_monitor.dart';
1920
import 'package:celest_cli/src/version.dart';
2021
import 'package:celest_cloud/celest_cloud.dart';
2122
import 'package:file/file.dart';
@@ -223,3 +224,5 @@ NativeSecureStorage secureStorage = storage.secure;
223224

224225
/// The isolated [secureStorage] interface.
225226
IsolatedNativeStorage get isolatedSecureStorage => secureStorage.isolated;
227+
228+
ConnectionMonitor connectionMonitor = ConnectionMonitor();

apps/cli/lib/src/pub/pub_action.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ Future<void> runPub({
5454
? Sdk.current.dart
5555
: (await celestProject.determineProjectType()).executable;
5656

57-
final command = <String>[exe, 'pub', action.name, if (verbose) '--verbose'];
57+
final command = <String>[
58+
exe,
59+
'pub',
60+
action.name,
61+
if (verbose) '--verbose',
62+
if (!connectionMonitor.isConnected) '--offline',
63+
];
5864
final logger = Logger(command.join(' '));
5965
logger.fine('Running `${command.join(' ')}` in "$workingDirectory"...');
6066
final process = await processManager.start(
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import 'dart:async';
2+
3+
import 'package:celest_cli/src/context.dart';
4+
5+
/// Monitors the local connection to the Internet.
6+
final class ConnectionMonitor {
7+
/// We use pub.dev to check if an Internet connection is available generally
8+
/// since this is mostly used to determine if we need to pass `--offline`
9+
/// to pub commands.
10+
static final Uri _checkUri = Uri.parse('https://pub.dev/');
11+
12+
final _connectionStream = StreamController<bool>.broadcast();
13+
14+
bool _isConnected = true;
15+
bool get isConnected => _isConnected;
16+
Stream<bool> get stream => _connectionStream.stream;
17+
18+
void init() {
19+
_checkConnection();
20+
Timer.periodic(const Duration(seconds: 5), (timer) {
21+
if (_connectionStream.isClosed) {
22+
timer.cancel();
23+
return;
24+
}
25+
_checkConnection();
26+
});
27+
}
28+
29+
Future<void> _checkConnection() async {
30+
final status = await checkConnection();
31+
_isConnected = status;
32+
if (!_connectionStream.isClosed) {
33+
_connectionStream.add(status);
34+
}
35+
}
36+
37+
Future<bool> checkConnection() async {
38+
try {
39+
final result =
40+
await httpClient.head(_checkUri).timeout(const Duration(seconds: 1));
41+
return result.statusCode == 200;
42+
} on Object {
43+
return false;
44+
}
45+
}
46+
47+
void close() {
48+
_connectionStream.close();
49+
}
50+
}

0 commit comments

Comments
 (0)