blob: d10cd4db1d3e6e8bee87254595faab8b086c696a [file] [log] [blame] [edit]
// Copyright 2020 The Dart Authors. 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:frontend_server_client/frontend_server_client.dart';
import 'package:path/path.dart' as p;
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';
void main(List<String> args) async {
try {
watch.start();
if (args.isNotEmpty) {
throw ArgumentError('No command line args are supported');
}
final client = await FrontendServerClient.start(
'org-dartlang-root:///$app',
outputDill,
p.join(sdkDir, 'lib', '_internal', 'vm_platform_strong.dill'),
target: 'vm',
fileSystemRoots: [p.url.current],
fileSystemScheme: 'org-dartlang-root',
verbose: true,
);
_print('compiling $app');
var result = await client.compile();
client.accept();
_print('done compiling $app');
Process appProcess;
final vmServiceCompleter = Completer<VmService>();
appProcess = await Process.start(Platform.resolvedExecutable, [
'--enable-vm-service',
result.dillOutput!,
]);
final sawHelloWorld = Completer();
appProcess.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
stdout.writeln('APP -> $line');
if (line == 'hello/world') {
sawHelloWorld.complete();
}
if (line.startsWith(
'The Dart DevTools debugger and profiler is available at:',
)) {
final observatoryUri =
'${line.split(' ').last.replaceFirst('http', 'ws')}ws';
vmServiceCompleter.complete(vmServiceConnectUri(observatoryUri));
}
});
appProcess.stderr
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
stderr.writeln('APP -> $line');
});
final vmService = await vmServiceCompleter.future;
await sawHelloWorld.future;
_print('editing $app');
final appFile = File(app);
final originalContent = await appFile.readAsString();
final newContent = originalContent.replaceFirst('hello', 'goodbye');
await appFile.writeAsString(newContent);
_print('recompiling $app with edits');
result = await client.compile([Uri.parse('org-dartlang-root:///$app')]);
client.accept();
_print('done recompiling $app');
_print('reloading $app');
final vm = await vmService.getVM();
await vmService.reloadSources(
vm.isolates!.first.id!,
rootLibUri: result.dillOutput!,
);
_print('restoring $app to original contents');
await appFile.writeAsString(originalContent);
_print('exiting');
await client.shutdown().timeout(
const Duration(seconds: 1),
onTimeout: () {
client.kill();
return 1;
},
);
} finally {
Directory(p.join('.dart_tool', 'out')).deleteSync(recursive: true);
}
}
void _print(String message) {
print('${watch.elapsed}: $message');
}
final app = 'example/app/main.dart';
final outputDill = p.join('.dart_tool', 'out', 'example_app.dill');
final sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
final watch = Stopwatch();