blob: 38d2c210faaabb380b0e284d3d6d4d989c07828a [file] [log] [blame]
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. 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:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:devtools_shared/devtools_shared.dart' show DtdInfo;
import 'package:path/path.dart' as path;
import 'utils.dart';
Future<DtdInfo?> startDtd({
required bool machineMode,
required bool printDtdUri,
}) async {
final sdkPath = File(Platform.resolvedExecutable).parent.parent.path;
final dtdSnapshot = path.absolute(
sdkPath,
'bin',
'snapshots',
'dart_tooling_daemon.dart.snapshot',
);
final completer = Completer<DtdInfo?>();
void completeForError() => completer.complete(null);
final exitPort = ReceivePort()
..listen((_) {
completeForError();
});
final errorPort = ReceivePort()
..listen((_) {
completeForError();
});
final receivePort = ReceivePort()
..listen((message) {
try {
// [message] is a JSON encoded String from package:dtd_impl.
final json = jsonDecode(message) as Map<String, Object?>;
if (json
case {
'tooling_daemon_details': {
'uri': String uri,
'trusted_client_secret': String secret,
}
}) {
if (printDtdUri || machineMode) {
DevToolsUtils.printOutput(
'Serving the Dart Tooling Daemon at $uri',
{
'event': 'server.dtdStarted',
'params': {'uri': uri},
},
machineMode: machineMode,
);
}
completer.complete(DtdInfo(Uri.parse(uri), secret: secret));
}
} catch (_) {
completeForError();
}
});
try {
await Isolate.spawnUri(
Uri.file(dtdSnapshot),
['--machine'],
receivePort.sendPort,
onExit: exitPort.sendPort,
onError: errorPort.sendPort,
);
} catch (_, __) {
completeForError();
}
final result = await completer.future.timeout(
const Duration(seconds: 5),
onTimeout: () => null,
);
receivePort.close();
errorPort.close();
exitPort.close();
return result;
}