Unverified Commit 25a81311 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] reload dart_sdk when sources update (#51067)

parent 29306b08
......@@ -45,6 +45,9 @@ class WebAssetServer implements AssetReader {
/// Start the web asset server on a [hostname] and [port].
///
/// If [testMode] is true, do not actually initialize dwds or the shelf static
/// server.
///
/// Unhandled exceptions will throw a [ToolExit] with the error and stack
/// trace.
static Future<WebAssetServer> start(
......@@ -53,14 +56,18 @@ class WebAssetServer implements AssetReader {
UrlTunneller urlTunneller,
BuildMode buildMode,
bool enableDwds,
Uri entrypoint,
) async {
Uri entrypoint, {
bool testMode = false,
}) async {
try {
final InternetAddress address = (await InternetAddress.lookup(hostname)).first;
final HttpServer httpServer = await HttpServer.bind(address, port);
final Packages packages = await loadPackagesFile(
Uri.base.resolve('.packages'), loader: (Uri uri) => globals.fs.file(uri).readAsBytes());
final WebAssetServer server = WebAssetServer(httpServer, packages, address);
if (testMode) {
return server;
}
// In release builds deploy a simpler proxy server.
if (buildMode != BuildMode.debug) {
......@@ -244,8 +251,31 @@ class WebAssetServer implements AssetReader {
return modules;
}
@visibleForTesting
final File dartSdk = globals.fs.file(globals.fs.path.join(
globals.artifacts.getArtifactPath(Artifact.flutterWebSdk),
'kernel',
'amd',
'dart_sdk.js',
));
@visibleForTesting
final File dartSdkSourcemap = globals.fs.file(globals.fs.path.join(
globals.artifacts.getArtifactPath(Artifact.flutterWebSdk),
'kernel',
'amd',
'dart_sdk.js.map',
));
// Attempt to resolve `path` to a dart file.
File _resolveDartFile(String path) {
// Return the actual file objects so that local engine changes are automatically picked up.
switch (path) {
case '/dart_sdk.js':
return dartSdk;
case '.dart_sdk.js.map':
return dartSdkSourcemap;
}
// If this is a dart file, it must be on the local file system and is
// likely coming from a source map request. The tool doesn't currently
// consider the case of Dart files as assets.
......@@ -309,7 +339,12 @@ class ConnectionResult {
final DebugConnection debugConnection;
}
/// The web specific DevFS implementation.
class WebDevFS implements DevFS {
/// Create a new [WebDevFS] instance.
///
/// [testMode] is true, do not actually initialize dwds or the shelf static
/// server.
WebDevFS({
@required this.hostname,
@required this.port,
......@@ -318,6 +353,7 @@ class WebDevFS implements DevFS {
@required this.buildMode,
@required this.enableDwds,
@required this.entrypoint,
this.testMode = false,
});
final Uri entrypoint;
......@@ -327,6 +363,7 @@ class WebDevFS implements DevFS {
final UrlTunneller urlTunneller;
final BuildMode buildMode;
final bool enableDwds;
final bool testMode;
@visibleForTesting
WebAssetServer webAssetServer;
......@@ -387,6 +424,7 @@ class WebDevFS implements DevFS {
buildMode,
enableDwds,
entrypoint,
testMode: testMode,
);
return Uri.parse('http://$hostname:$port');
}
......@@ -450,8 +488,7 @@ class WebDevFS implements DevFS {
);
// TODO(jonahwilliams): switch to DWDS provided APIs when they are ready.
webAssetServer.writeFile('/basic.digests', '{}');
webAssetServer.writeFile('/dart_sdk.js', dartSdk.readAsStringSync());
webAssetServer.writeFile('/dart_sdk.js.map', dartSdkSourcemap.readAsStringSync());
// TODO(jonahwilliams): refactor the asset code in this and the regular devfs to
// be shared.
if (bundle != null) {
......@@ -498,6 +535,7 @@ class WebDevFS implements DevFS {
} on FileSystemException catch (err) {
throwToolExit('Failed to load recompiled sources:\n$err');
}
return UpdateFSReport(
success: true,
syncedBytes: codeFile.lengthSync(),
......@@ -515,22 +553,6 @@ class WebDevFS implements DevFS {
'require.js',
));
@visibleForTesting
final File dartSdk = globals.fs.file(globals.fs.path.join(
globals.artifacts.getArtifactPath(Artifact.flutterWebSdk),
'kernel',
'amd',
'dart_sdk.js',
));
@visibleForTesting
final File dartSdkSourcemap = globals.fs.file(globals.fs.path.join(
globals.artifacts.getArtifactPath(Artifact.flutterWebSdk),
'kernel',
'amd',
'dart_sdk.js.map',
));
@visibleForTesting
final File stackTraceMapper = globals.fs.file(globals.fs.path.join(
globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath),
......
......@@ -18,7 +18,6 @@ import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:shelf/shelf.dart';
import '../../src/common.dart';
import '../../src/io.dart';
import '../../src/testbed.dart';
const List<int> kTransparentImage = <int>[
......@@ -278,55 +277,63 @@ void main() {
}));
test('Can start web server with specified assets', () => testbed.run(() async {
await IOOverrides.runWithIOOverrides(() async {
final File outputFile = globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
..createSync(recursive: true);
outputFile.parent.childFile('a.sources').writeAsStringSync('');
outputFile.parent.childFile('a.json').writeAsStringSync('{}');
outputFile.parent.childFile('a.map').writeAsStringSync('{}');
outputFile.parent.childFile('.packages').writeAsStringSync('\n');
final ResidentCompiler residentCompiler = MockResidentCompiler();
when(residentCompiler.recompile(
any,
any,
outputPath: anyNamed('outputPath'),
packagesFilePath: anyNamed('packagesFilePath'),
)).thenAnswer((Invocation invocation) async {
return const CompilerOutput('a', 0, <Uri>[]);
});
final WebDevFS webDevFS = WebDevFS(
hostname: 'localhost',
port: 0,
packagesFilePath: '.packages',
urlTunneller: null,
buildMode: BuildMode.debug,
enableDwds: false,
entrypoint: Uri.base,
);
webDevFS.requireJS.createSync(recursive: true);
webDevFS.dartSdk.createSync(recursive: true);
webDevFS.dartSdkSourcemap.createSync(recursive: true);
webDevFS.stackTraceMapper.createSync(recursive: true);
await webDevFS.create();
await webDevFS.update(
mainPath: globals.fs.path.join('lib', 'main.dart'),
generator: residentCompiler,
trackWidgetCreation: true,
bundleFirstUpload: true,
invalidatedFiles: <Uri>[],
);
expect(webDevFS.webAssetServer.getFile('/main.dart'), isNotNull);
expect(webDevFS.webAssetServer.getFile('/manifest.json'), isNotNull);
expect(webDevFS.webAssetServer.getFile('/flutter_service_worker.js'), isNotNull);
await webDevFS.destroy();
await webDevFS.dwds.stop();
}, FlutterIOOverrides(fileSystem: globals.fs));
}), skip: true); // Not clear the best way to test this, since shelf hits the real filesystem.
final File outputFile = globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
..createSync(recursive: true);
outputFile.parent.childFile('a.sources').writeAsStringSync('');
outputFile.parent.childFile('a.json').writeAsStringSync('{}');
outputFile.parent.childFile('a.map').writeAsStringSync('{}');
outputFile.parent.childFile('.packages').writeAsStringSync('\n');
final ResidentCompiler residentCompiler = MockResidentCompiler();
when(residentCompiler.recompile(
any,
any,
outputPath: anyNamed('outputPath'),
packagesFilePath: anyNamed('packagesFilePath'),
)).thenAnswer((Invocation invocation) async {
return const CompilerOutput('a', 0, <Uri>[]);
});
final WebDevFS webDevFS = WebDevFS(
hostname: 'localhost',
port: 0,
packagesFilePath: '.packages',
urlTunneller: null,
buildMode: BuildMode.debug,
enableDwds: false,
entrypoint: Uri.base,
testMode: true,
);
webDevFS.requireJS.createSync(recursive: true);
webDevFS.stackTraceMapper.createSync(recursive: true);
await webDevFS.create();
webDevFS.webAssetServer.dartSdk
..createSync(recursive: true)
..writeAsStringSync('HELLO');
webDevFS.webAssetServer.dartSdkSourcemap.createSync(recursive: true);
await webDevFS.update(
mainPath: globals.fs.path.join('lib', 'main.dart'),
generator: residentCompiler,
trackWidgetCreation: true,
bundleFirstUpload: true,
invalidatedFiles: <Uri>[],
);
expect(webDevFS.webAssetServer.getFile('/main.dart'), isNotNull);
expect(webDevFS.webAssetServer.getFile('/manifest.json'), isNotNull);
expect(webDevFS.webAssetServer.getFile('/flutter_service_worker.js'), isNotNull);
expect(await webDevFS.webAssetServer.dartSourceContents('/dart_sdk.js'), 'HELLO');
// Update to the SDK.
webDevFS.webAssetServer.dartSdk.writeAsStringSync('BELLOW');
// New SDK should be visible..
expect(await webDevFS.webAssetServer.dartSourceContents('/dart_sdk.js'), 'BELLOW');
await webDevFS.destroy();
}));
}
class MockHttpServer extends Mock implements HttpServer {}
......
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