db42b359c3
- Adds a parameter to DartDevelopmentServiceLauncher.start, as well as DartDevelopmentService.startDevelopmentService - Adds an `--app-name` command line argument to the DDS cli. - Passes this app name through when registering VmService URIs on DTD. Bug: https://github.com/flutter/flutter/issues/184251 Change-Id: Ica4487214a69a165fe891d4b8de12d72b052783c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/491360 Auto-Submit: Jake Macdonald <jakemac@google.com> Commit-Queue: Jake Macdonald <jakemac@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com>
176 lines
5.7 KiB
Dart
176 lines
5.7 KiB
Dart
// 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.
|
|
|
|
// TODO(bkonyi): move this file to lib/dds_cli_entrypoint.dart once package:dds
|
|
// is no longer shipped via pub.
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:path/path.dart' as path;
|
|
|
|
import '../dds.dart';
|
|
import 'arg_parser.dart';
|
|
import 'bazel_uri_converter.dart';
|
|
|
|
Uri _getDevToolsAssetPath() {
|
|
final dartDir = File(Platform.resolvedExecutable).parent.path;
|
|
final fullSdk = dartDir.endsWith('bin');
|
|
return Uri.file(
|
|
fullSdk
|
|
? path.absolute(
|
|
dartDir,
|
|
'resources',
|
|
'devtools',
|
|
)
|
|
: path.absolute(
|
|
dartDir,
|
|
'devtools',
|
|
),
|
|
);
|
|
}
|
|
|
|
// TODO(bkonyi): allow for injection of custom DevTools handlers in google3.
|
|
Future<void> runDartDevelopmentServiceFromCLI(
|
|
List<String> args, {
|
|
String? Function(String)? uriConverter,
|
|
}) async {
|
|
final argParser = DartDevelopmentServiceOptions.createArgParser(
|
|
includeHelp: true,
|
|
);
|
|
final argResults = argParser.parse(args);
|
|
if (args.isEmpty || argResults.wasParsed('help')) {
|
|
print('''
|
|
Starts a Dart Development Service (DDS) instance.
|
|
|
|
Usage:
|
|
${argParser.usage}
|
|
''');
|
|
return;
|
|
}
|
|
|
|
// Check if the remote VM Service address can be resolved to an IPv4 address.
|
|
final remoteVmServiceUri = Uri.parse(
|
|
argResults[DartDevelopmentServiceOptions.vmServiceUriOption],
|
|
);
|
|
bool doesVmServiceAddressResolveToIpv4Address = false;
|
|
try {
|
|
final addresses = await InternetAddress.lookup(remoteVmServiceUri.host);
|
|
for (final address in addresses) {
|
|
if (address.type == InternetAddressType.IPv4) {
|
|
doesVmServiceAddressResolveToIpv4Address = true;
|
|
}
|
|
}
|
|
} on SocketException catch (e, st) {
|
|
writeErrorResponse(
|
|
'Invalid --${DartDevelopmentServiceOptions.vmServiceUriOption} argument: '
|
|
'$remoteVmServiceUri',
|
|
st,
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Ensure that the bind address, which is potentially provided by the user,
|
|
// can be resolved at all, and check whether it can be resolved to an IPv4
|
|
// address.
|
|
final bindAddress =
|
|
argResults[DartDevelopmentServiceOptions.bindAddressOption];
|
|
bool doesBindAddressResolveToIpv4Address = false;
|
|
try {
|
|
final addresses = await InternetAddress.lookup(bindAddress);
|
|
for (final address in addresses) {
|
|
if (address.type == InternetAddressType.IPv4) {
|
|
doesBindAddressResolveToIpv4Address = true;
|
|
}
|
|
}
|
|
} on SocketException catch (e, st) {
|
|
writeErrorResponse('Invalid bind address: $bindAddress', st);
|
|
return;
|
|
}
|
|
|
|
final portString = argResults[DartDevelopmentServiceOptions.bindPortOption];
|
|
int port;
|
|
try {
|
|
port = int.parse(portString);
|
|
} on FormatException catch (e, st) {
|
|
writeErrorResponse('Invalid port: $portString', st);
|
|
return;
|
|
}
|
|
final serviceUri = Uri(
|
|
scheme: 'http',
|
|
host: bindAddress,
|
|
port: port,
|
|
);
|
|
final disableServiceAuthCodes =
|
|
argResults[DartDevelopmentServiceOptions.disableServiceAuthCodesFlag];
|
|
|
|
final serveDevTools =
|
|
argResults[DartDevelopmentServiceOptions.serveDevToolsFlag];
|
|
final devToolsServerAddressStr =
|
|
argResults[DartDevelopmentServiceOptions.devToolsServerAddressOption];
|
|
Uri? devToolsBuildDirectory;
|
|
final devToolsServerAddress = devToolsServerAddressStr == null
|
|
? null
|
|
: Uri.parse(devToolsServerAddressStr);
|
|
if (serveDevTools) {
|
|
devToolsBuildDirectory = _getDevToolsAssetPath();
|
|
}
|
|
final enableServicePortFallback =
|
|
argResults[DartDevelopmentServiceOptions.enableServicePortFallbackFlag];
|
|
|
|
final google3WorkspaceRoot =
|
|
argResults[DartDevelopmentServiceOptions.google3WorkspaceRootOption];
|
|
if (google3WorkspaceRoot != null) {
|
|
uriConverter = BazelUriConverter(google3WorkspaceRoot).uriToPath;
|
|
}
|
|
try {
|
|
final dds = await DartDevelopmentService.startDartDevelopmentService(
|
|
remoteVmServiceUri,
|
|
serviceUri: serviceUri,
|
|
enableAuthCodes: !disableServiceAuthCodes,
|
|
// Only use IPv6 to serve DDS if either the remote VM Service address or
|
|
// the bind address cannot be resolved to an IPv4 address.
|
|
ipv6: !doesVmServiceAddressResolveToIpv4Address ||
|
|
!doesBindAddressResolveToIpv4Address,
|
|
devToolsConfiguration: serveDevTools && devToolsBuildDirectory != null
|
|
? DevToolsConfiguration(
|
|
enable: serveDevTools,
|
|
customBuildDirectoryPath: devToolsBuildDirectory,
|
|
devToolsServerAddress: devToolsServerAddress,
|
|
)
|
|
: null,
|
|
enableServicePortFallback: enableServicePortFallback,
|
|
uriConverter: uriConverter,
|
|
appName: argResults[DartDevelopmentServiceOptions.appNameOption],
|
|
);
|
|
final dtdInfo = dds.hostedDartToolingDaemon;
|
|
stderr.write(json.encode({
|
|
'state': 'started',
|
|
'ddsUri': dds.uri.toString(),
|
|
if (dds.devToolsUri != null) 'devToolsUri': dds.devToolsUri.toString(),
|
|
if (dtdInfo != null)
|
|
'dtd': {
|
|
// For DDS-hosted DTD, there's only ever a local URI since there
|
|
// is no mechanism for exposing URIs.
|
|
'uri': dtdInfo.localUri.toString(),
|
|
},
|
|
'name': dds.appName,
|
|
}));
|
|
} catch (e, st) {
|
|
writeErrorResponse(e, st);
|
|
} finally {
|
|
// Always close stderr to notify tooling that DDS has finished writing
|
|
// launch details.
|
|
await stderr.close();
|
|
}
|
|
}
|
|
|
|
void writeErrorResponse(Object e, StackTrace st) {
|
|
stderr.write(json.encode({
|
|
'state': 'error',
|
|
'error': '$e',
|
|
'stacktrace': '$st',
|
|
if (e is DartDevelopmentServiceException) 'ddsExceptionDetails': e.toJson(),
|
|
}));
|
|
}
|