Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/cli/lib/src/cli/cli.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ final class Cli {
? const SentryPerformance()
: const CelestPerformance();
ctx.storage = storage ?? Storage();
ctx.connectionMonitor.init();
await ctx.connectionMonitor.stream.first;

try {
_logger.finest('Initializing secure storage');
Expand Down Expand Up @@ -401,6 +403,7 @@ final class Cli {
await _logFile?.close();
await ctx.performance.close();
ctx.httpClient.close();
ctx.connectionMonitor.close();
exit(exitCode);
}
}
3 changes: 3 additions & 0 deletions apps/cli/lib/src/context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:celest_cli/src/project/project_paths.dart';
import 'package:celest_cli/src/serialization/json_generator.dart';
import 'package:celest_cli/src/storage/storage.dart';
import 'package:celest_cli/src/types/type_helper.dart';
import 'package:celest_cli/src/utils/connection_monitor.dart';
import 'package:celest_cli/src/version.dart';
import 'package:celest_cloud/celest_cloud.dart';
import 'package:file/file.dart';
Expand Down Expand Up @@ -223,3 +224,5 @@ NativeSecureStorage secureStorage = storage.secure;

/// The isolated [secureStorage] interface.
IsolatedNativeStorage get isolatedSecureStorage => secureStorage.isolated;

ConnectionMonitor connectionMonitor = ConnectionMonitor();
8 changes: 7 additions & 1 deletion apps/cli/lib/src/pub/pub_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ Future<void> runPub({
? Sdk.current.dart
: (await celestProject.determineProjectType()).executable;

final command = <String>[exe, 'pub', action.name, if (verbose) '--verbose'];
final command = <String>[
exe,
'pub',
action.name,
if (verbose) '--verbose',
if (!connectionMonitor.isConnected) '--offline',
];
final logger = Logger(command.join(' '));
logger.fine('Running `${command.join(' ')}` in "$workingDirectory"...');
final process = await processManager.start(
Expand Down
50 changes: 50 additions & 0 deletions apps/cli/lib/src/utils/connection_monitor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'dart:async';

import 'package:celest_cli/src/context.dart';

/// Monitors the local connection to the Internet.
final class ConnectionMonitor {
/// We use pub.dev to check if an Internet connection is available generally
/// since this is mostly used to determine if we need to pass `--offline`
/// to pub commands.
static final Uri _checkUri = Uri.parse('https://pub.dev/');

final _connectionStream = StreamController<bool>.broadcast();

bool _isConnected = true;
bool get isConnected => _isConnected;
Stream<bool> get stream => _connectionStream.stream;

void init() {
_checkConnection();
Timer.periodic(const Duration(seconds: 5), (timer) {
if (_connectionStream.isClosed) {
timer.cancel();
return;
}
_checkConnection();
});
}

Future<void> _checkConnection() async {
final status = await checkConnection();
_isConnected = status;
if (!_connectionStream.isClosed) {
_connectionStream.add(status);
}
}

Future<bool> checkConnection() async {
try {
final result =
await httpClient.head(_checkUri).timeout(const Duration(seconds: 1));
return result.statusCode == 200;
} on Object {
return false;
}
}

void close() {
_connectionStream.close();
}
}