Unverified Commit e934c2fc authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] reland: copy dill after startup (#58455)

* [flutter_tools] only copy cached dill after startup

* shared code

* cleanup artifact directory

* do not copy if dillOutputPath is given
parent 8b5326a9
......@@ -434,6 +434,7 @@ class _ResidentWebRunner extends ResidentWebRunner {
return 1;
}
device.generator.accept();
cacheInitialDillCompilation();
} else {
await buildWeb(
flutterProject,
......
......@@ -1080,6 +1080,22 @@ abstract class ResidentRunner {
);
}
@protected
void cacheInitialDillCompilation() {
if (_dillOutputPath != null) {
return;
}
globals.logger.printTrace('Caching compiled dill');
final File outputDill = globals.fs.file(dillOutputPath);
if (outputDill.existsSync()) {
final String copyPath = getDefaultCachedKernelPath(
trackWidgetCreation: trackWidgetCreation,
);
globals.fs.file(copyPath).parent.createSync(recursive: true);
outputDill.copySync(copyPath);
}
}
/// If the [reloadSources] parameter is not null the 'reloadSources' service
/// will be registered.
//
......@@ -1189,14 +1205,9 @@ abstract class ResidentRunner {
@mustCallSuper
Future<void> preExit() async {
// If _dillOutputPath is null, we created a temporary directory for the dill.
// If _dillOutputPath is null, the tool created a temporary directory for
// the dill.
if (_dillOutputPath == null && artifactDirectory.existsSync()) {
final File outputDill = globals.fs.file(dillOutputPath);
if (outputDill.existsSync()) {
outputDill.copySync(getDefaultCachedKernelPath(
trackWidgetCreation: trackWidgetCreation,
));
}
artifactDirectory.deleteSync(recursive: true);
}
}
......
......@@ -63,7 +63,6 @@ class DeviceReloadReport {
List<vm_service.ReloadReport> reports; // List has one report per Flutter view.
}
// TODO(mklim): Test this, flutter/flutter#23031.
class HotRunner extends ResidentRunner {
HotRunner(
List<FlutterDevice> devices, {
......@@ -379,6 +378,7 @@ class HotRunner extends ResidentRunner {
if (!results.every((bool passed) => passed)) {
return 1;
}
cacheInitialDillCompilation();
} on Exception catch (err) {
globals.printError(err.toString());
return 1;
......
......@@ -608,22 +608,12 @@ void main() {
expect(otherRunner.artifactDirectory.path, contains('foobar'));
}));
test('ResidentRunner copies output dill to cache location during preExit', () => testbed.run(() async {
test('ResidentRunner deletes artifact directory on preExit', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('hello');
residentRunner.artifactDirectory.childFile('app.dill').createSync();
await residentRunner.preExit();
final File cacheDill = globals.fs.file(globals.fs.path.join(getBuildDirectory(), 'cache.dill'));
expect(cacheDill, exists);
expect(cacheDill.readAsStringSync(), 'hello');
}));
test('ResidentRunner handles output dill missing during preExit', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.preExit();
final File cacheDill = globals.fs.file(globals.fs.path.join(getBuildDirectory(), 'cache.dill'));
expect(cacheDill, isNot(exists));
expect(residentRunner.artifactDirectory, isNot(exists));
}));
test('ResidentRunner can run source generation', () => testbed.run(() async {
......@@ -1147,6 +1137,91 @@ void main() {
expect(await globals.fs.file('foo').readAsString(), testUri.toString());
}));
test('HotRunner copies compiled app.dill to cache during startup', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
listViews,
listViews,
]);
setWsAddress(testUri, fakeVmServiceHost.vmService);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
residentRunner = HotRunner(
<FlutterDevice>[
mockFlutterDevice,
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
hotRunner: anyNamed('hotRunner'),
route: anyNamed('route'),
)).thenAnswer((Invocation invocation) async {
return 0;
});
await residentRunner.run();
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
}));
test('HotRunner does not copy app.dill if a dillOutputPath is given', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
listViews,
listViews,
]);
setWsAddress(testUri, fakeVmServiceHost.vmService);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
residentRunner = HotRunner(
<FlutterDevice>[
mockFlutterDevice,
],
stayResident: false,
dillOutputPath: 'test',
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
hotRunner: anyNamed('hotRunner'),
route: anyNamed('route'),
)).thenAnswer((Invocation invocation) async {
return 0;
});
await residentRunner.run();
expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists));
}));
test('HotRunner copies compiled app.dill to cache during startup with --track-widget-creation', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
listViews,
listViews,
]);
setWsAddress(testUri, fakeVmServiceHost.vmService);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
residentRunner = HotRunner(
<FlutterDevice>[
mockFlutterDevice,
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(const BuildInfo(
BuildMode.debug,
'',
treeShakeIcons: false,
trackWidgetCreation: true,
)),
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
hotRunner: anyNamed('hotRunner'),
route: anyNamed('route'),
)).thenAnswer((Invocation invocation) async {
return 0;
});
await residentRunner.run();
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC');
}));
test('HotRunner unforwards device ports', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
listViews,
......
......@@ -257,13 +257,21 @@ void main() {
expect(bufferLogger.statusText, contains('Debug service listening on ws://127.0.0.1/abcd/'));
expect(debugConnectionInfo.wsUri.toString(), 'ws://127.0.0.1/abcd/');
}, overrides: <Type, Generator>{
Logger: () => DelegateLogger(BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
)),
Logger: () => DelegateLogger(BufferLogger.test()),
}));
test('WebRunner copies compiled app.dill to cache during startup', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
_setupMocks();
residentWebRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
unawaited(residentWebRunner.run(
connectionInfoCompleter: connectionInfoCompleter,
));
await connectionInfoCompleter.future;
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
}));
test('Can successfully run without an index.html including status warning', () => testbed.run(() async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment