blob: 71f99f4486e5bd948a329639e809408c36f961d3 [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 'package:path/path.dart';
import 'sdk.dart';
class DDSRunner {
Uri? ddsUri;
Future<bool> start({
required Uri vmServiceUri,
required String ddsHost,
required String ddsPort,
required bool disableServiceAuthCodes,
required bool enableDevTools,
required bool debugDds,
required bool enableServicePortFallback,
}) async {
final sdkDir = dirname(sdk.dart);
final fullSdk = sdkDir.endsWith('bin');
final execName = sdk.dart;
final snapshotName =
fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot');
if (!Sdk.checkArtifactExists(snapshotName)) {
return false;
}
final process = await Process.start(
execName,
[
if (debugDds) '--enable-vm-service=0',
snapshotName,
'--vm-service-uri=$vmServiceUri',
'--bind-address=$ddsHost',
'--bind-port=$ddsPort',
if (disableServiceAuthCodes) '--disable-service-auth-codes',
if (enableDevTools) '--serve-devtools',
if (debugDds) '--enable-logging',
if (enableServicePortFallback) '--enable-service-port-fallback',
],
mode: ProcessStartMode.detachedWithStdio,
);
final completer = Completer<void>();
const devToolsMessagePrefix =
'The Dart DevTools debugger and profiler is available at:';
if (debugDds) {
late StreamSubscription stdoutSub;
stdoutSub = process.stdout.transform(utf8.decoder).listen((event) {
if (event.startsWith(devToolsMessagePrefix)) {
final ddsDebuggingUri = event.split(' ').last;
print(
'A DevTools debugger for DDS is available at: $ddsDebuggingUri',
);
stdoutSub.cancel();
}
});
}
late StreamSubscription stderrSub;
stderrSub = process.stderr.transform(utf8.decoder).listen((event) {
final result = json.decode(event) as Map<String, dynamic>;
final state = result['state'];
if (state == 'started') {
if (result.containsKey('devToolsUri')) {
final devToolsUri = result['devToolsUri'];
print('$devToolsMessagePrefix $devToolsUri');
}
ddsUri = Uri.parse(result['ddsUri']);
stderrSub.cancel();
completer.complete();
} else {
stderrSub.cancel();
final error = result['error'] ?? event;
final stacktrace = result['stacktrace'] ?? '';
String message = 'Could not start the VM service: ';
if (error.contains('Failed to create server socket')) {
message += '$ddsHost:$ddsPort is already in use.\n';
} else {
message += '$error\n$stacktrace\n';
}
completer.completeError(message);
}
});
try {
await completer.future;
return true;
} catch (e) {
stderr.write(e);
return false;
}
}
}