Flutter 1.24, attempt 2 (#622)
diff --git a/.gitignore b/.gitignore
index 52f141b..76d99c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@
# compilation artifacts
artifacts/
+project_templates/
# local configuration
config.properties
diff --git a/Dockerfile b/Dockerfile
index 115bcff..4ee5e79 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@
# To retrieve this value, please run the following in your closest shell:
#
# $ (cd flutter && git rev-parse HEAD)
-ARG FLUTTER_COMMIT=198df796aa80073ef22bdf249e614e2ff33c6895
+ARG FLUTTER_COMMIT=022b333a089afb81c471ec43d1f1f4f26305d876
# We install unzip and remove the apt-index again to keep the
# docker image diff small.
diff --git a/cloud_run.Dockerfile b/cloud_run.Dockerfile
index 17877fa..168cd62 100644
--- a/cloud_run.Dockerfile
+++ b/cloud_run.Dockerfile
@@ -6,7 +6,7 @@
# To retrieve this value, please run the following in your closest shell:
#
# $ (cd flutter && git rev-parse HEAD)
-ARG FLUTTER_COMMIT=198df796aa80073ef22bdf249e614e2ff33c6895
+ARG FLUTTER_COMMIT=022b333a089afb81c471ec43d1f1f4f26305d876
# We install unzip and remove the apt-index again to keep the
# docker image diff small.
diff --git a/flutter b/flutter
index 198df79..022b333 160000
--- a/flutter
+++ b/flutter
@@ -1 +1 @@
-Subproject commit 198df796aa80073ef22bdf249e614e2ff33c6895
+Subproject commit 022b333a089afb81c471ec43d1f1f4f26305d876
diff --git a/lib/src/analysis_server.dart b/lib/src/analysis_server.dart
index ba2b9b5..3d2f0d0 100644
--- a/lib/src/analysis_server.dart
+++ b/lib/src/analysis_server.dart
@@ -76,7 +76,7 @@
}
@override
- String get _sourceDirPath => flutterWebManager.projectDirectory.path;
+ String get _sourceDirPath => flutterWebManager.flutterTemplateProject.path;
@override
Future<proto.AnalysisResults> analyze(String source) {
diff --git a/lib/src/analysis_servers.dart b/lib/src/analysis_servers.dart
index 1b89bfb..4895206 100644
--- a/lib/src/analysis_servers.dart
+++ b/lib/src/analysis_servers.dart
@@ -49,9 +49,6 @@
_flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
_flutterAnalysisServer = FlutterAnalysisServerWrapper(_flutterWebManager);
- await _flutterWebManager.warmup();
- _logger.info('FlutterWebManager warmed up');
-
await _dartAnalysisServer.init();
_logger.info('Dart analysis server initialized.');
@@ -93,7 +90,6 @@
_restartingSince = DateTime.now();
return Future.wait(<Future<dynamic>>[
- _flutterWebManager.dispose(),
_flutterAnalysisServer.shutdown(),
_dartAnalysisServer.shutdown(),
]);
diff --git a/lib/src/compiler.dart b/lib/src/compiler.dart
index b45fd9a..061a78a 100644
--- a/lib/src/compiler.dart
+++ b/lib/src/compiler.dart
@@ -9,6 +9,7 @@
import 'dart:io';
import 'package:bazel_worker/driver.dart';
+import 'package:io/io.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
@@ -43,7 +44,6 @@
}
Future<CompilationResults> warmup({bool useHtml = false}) async {
- await _flutterWebManager.warmup();
return compile(useHtml ? sampleCodeWeb : sampleCode);
}
@@ -65,16 +65,19 @@
_logger.info('Temp directory created: ${temp.path}');
try {
+ await copyPath(_flutterWebManager.dartTemplateProject.path, temp.path);
+ await Directory(path.join(temp.path, 'lib')).create(recursive: true);
+
final arguments = <String>[
'--suppress-hints',
'--terse',
if (!returnSourceMap) '--no-source-maps',
- '--packages=${_flutterWebManager.packagesFilePath}',
+ '--packages=${path.join('.dart_tool', 'package_config.json')}',
...['-o', '$kMainDart.js'],
- kMainDart,
+ path.join('lib', kMainDart),
];
- final compileTarget = path.join(temp.path, kMainDart);
+ final compileTarget = path.join(temp.path, 'lib', kMainDart);
final mainDart = File(compileTarget);
await mainDart.writeAsString(input);
@@ -82,7 +85,7 @@
final mainSourceMap = File(path.join(temp.path, '$kMainDart.js.map'));
final dart2JSPath = path.join(_sdk.sdkPath, 'bin', 'dart2js');
- _logger.info('About to exec: $dart2JSPath $arguments');
+ _logger.info('About to exec: $dart2JSPath ${arguments.join(' ')}');
final result = await Process.run(dart2JSPath, arguments,
workingDirectory: temp.path);
@@ -128,9 +131,17 @@
try {
final usingFlutter = _flutterWebManager.usesFlutterWeb(imports);
+ if (usingFlutter) {
+ await copyPath(
+ _flutterWebManager.flutterTemplateProject.path, temp.path);
+ } else {
+ await copyPath(_flutterWebManager.dartTemplateProject.path, temp.path);
+ }
- final mainPath = path.join(temp.path, kMainDart);
- final bootstrapPath = path.join(temp.path, kBootstrapDart);
+ await Directory(path.join(temp.path, 'lib')).create(recursive: true);
+
+ final mainPath = path.join(temp.path, 'lib', kMainDart);
+ final bootstrapPath = path.join(temp.path, 'lib', kBootstrapDart);
final bootstrapContents =
usingFlutter ? kBootstrapFlutterCode : kBootstrapDartCode;
@@ -148,7 +159,7 @@
...['-o', path.join(temp.path, '$kMainDart.js')],
...['--module-name', 'dartpad_main'],
bootstrapPath,
- '--packages=${_flutterWebManager.packagesFilePath}',
+ '--packages=${path.join(temp.path, '.dart_tool', 'package_config.json')}',
];
final mainJs = File(path.join(temp.path, '$kMainDart.js'));
@@ -189,7 +200,6 @@
}
Future<void> dispose() async {
- await _flutterWebManager.dispose();
return _ddcDriver.terminateWorkers();
}
}
diff --git a/lib/src/flutter_web.dart b/lib/src/flutter_web.dart
index 8458400..e078983 100644
--- a/lib/src/flutter_web.dart
+++ b/lib/src/flutter_web.dart
@@ -4,67 +4,21 @@
import 'dart:io';
-import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
import 'sdk_manager.dart';
-Logger _logger = Logger('flutter_web');
-
/// Handle provisioning package:flutter_web and related work.
class FlutterWebManager {
final FlutterSdk flutterSdk;
- Directory _projectDirectory;
+ final Directory flutterTemplateProject = Directory(path.join(
+ Directory.current.path, 'project_templates', 'flutter_project'));
- bool _initedFlutterWeb = false;
+ final Directory dartTemplateProject = Directory(
+ path.join(Directory.current.path, 'project_templates', 'dart_project'));
- FlutterWebManager(this.flutterSdk) {
- _projectDirectory = Directory.systemTemp.createTempSync('dartpad');
- _init();
- }
-
- Future<void> dispose() => _projectDirectory.delete(recursive: true);
-
- Directory get projectDirectory => _projectDirectory;
-
- String get packagesFilePath => path.join(projectDirectory.path, '.packages');
-
- void _init() {
- // create a pubspec.yaml file
- final pubspec = createPubspec(true);
- File(path.join(_projectDirectory.path, 'pubspec.yaml'))
- .writeAsStringSync(pubspec);
-
- // create a .packages file
- final packagesFileContents = '''
-$_samplePackageName:lib/
-''';
- File(path.join(_projectDirectory.path, '.packages'))
- .writeAsStringSync(packagesFileContents);
-
- // and create a lib/ folder for completeness
- Directory(path.join(_projectDirectory.path, 'lib')).createSync();
- }
-
- Future<void> warmup() async {
- try {
- if (_initedFlutterWeb) {
- return;
- }
-
- _logger.info('creating flutter web pubspec');
- final pubspec = createPubspec(true);
- await File(path.join(_projectDirectory.path, 'pubspec.yaml'))
- .writeAsString(pubspec);
-
- await _runPubGet();
-
- _initedFlutterWeb = true;
- } catch (e, s) {
- _logger.warning('Error initializing flutter web', e, s);
- }
- }
+ FlutterWebManager(this.flutterSdk);
String get summaryFilePath {
return path.join('artifacts', 'flutter_web.dill');
@@ -110,81 +64,4 @@
return null;
}
-
- Future<void> _runPubGet() async {
- _logger.info('running flutter pub get (${_projectDirectory.path})');
-
- final observatoryPort = await _findFreePort();
-
- // The DART_VM_OPTIONS flag is included here to override the one sent by the
- // Dart SDK during tests. Without the flag, the Flutter tool will attempt to
- // spin up its own observatory on the same port as the one already
- // instantiated by the Dart SDK running the test, causing a hang.
- //
- // The value should be an available port number.
- final result = await Process.start(
- path.join(flutterSdk.flutterBinPath, 'flutter'),
- ['pub', 'get'],
- workingDirectory: _projectDirectory.path,
- environment: {'DART_VM_OPTIONS': '--enable-vm-service=$observatoryPort'},
- );
-
- _logger.info('${result.stdout}'.trim());
-
- final code = await result.exitCode;
-
- if (code != 0) {
- _logger.warning('pub get failed: ${result.exitCode}');
- _logger.warning(result.stderr);
-
- throw 'pub get failed: ${result.exitCode}: ${result.stderr}';
- }
- }
-
- Future<int> _findFreePort({bool ipv6 = false}) async {
- var port = 0;
- ServerSocket serverSocket;
- final loopback =
- ipv6 ? InternetAddress.loopbackIPv6 : InternetAddress.loopbackIPv4;
-
- try {
- serverSocket = await ServerSocket.bind(loopback, 0);
- port = serverSocket.port;
- } on SocketException catch (e) {
- // If ipv4 loopback bind fails, try ipv6.
- if (!ipv6) {
- return _findFreePort(ipv6: true);
- }
- _logger.severe('Could not find free port for `pub get`: $e');
- } catch (e) {
- // Failures are signaled by a return value of 0 from this function.
- _logger.severe('Could not find free port for `pub get`: $e');
- } finally {
- if (serverSocket != null) {
- await serverSocket.close();
- }
- }
-
- return port;
- }
-
- static const String _samplePackageName = 'dartpad_sample';
-
- static String createPubspec(bool includeFlutterWeb) {
- var content = '''
-name: $_samplePackageName
-''';
-
- if (includeFlutterWeb) {
- content += '''
-dependencies:
- flutter:
- sdk: flutter
- flutter_test:
- sdk: flutter
-''';
- }
-
- return content;
- }
}
diff --git a/pubspec.lock b/pubspec.lock
index 41bef28..3ec38df 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -70,14 +70,14 @@
name: build
url: "https://pub.dartlang.org"
source: hosted
- version: "1.5.1"
+ version: "1.5.2"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
- version: "0.4.3"
+ version: "0.4.4"
build_daemon:
dependency: transitive
description:
@@ -91,21 +91,21 @@
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
- version: "1.4.3"
+ version: "1.4.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
- version: "1.10.6"
+ version: "1.10.7"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
- version: "6.1.1"
+ version: "6.1.2"
built_collection:
dependency: transitive
description:
@@ -310,7 +310,7 @@
source: hosted
version: "0.16.1"
io:
- dependency: transitive
+ dependency: "direct main"
description:
name: io
url: "https://pub.dartlang.org"
@@ -490,7 +490,7 @@
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
- version: "0.9.8"
+ version: "0.9.9"
source_map_stack_trace:
dependency: transitive
description:
@@ -560,7 +560,7 @@
name: test
url: "https://pub.dartlang.org"
source: hosted
- version: "1.15.6"
+ version: "1.15.7"
test_api:
dependency: transitive
description:
@@ -574,7 +574,7 @@
name: test_core
url: "https://pub.dartlang.org"
source: hosted
- version: "0.3.11+3"
+ version: "0.3.11+4"
timing:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 7b947a1..5ae5ba9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -14,6 +14,7 @@
crypto: ^2.0.0
dartis: ^0.5.0
http: ^0.12.0
+ io: ^0.3.4
logging: ^0.11.0
meta: ^1.1.8
path: ^1.6.2
diff --git a/test/flutter_analysis_server_test.dart b/test/flutter_analysis_server_test.dart
index 9791eca..99e3628 100644
--- a/test/flutter_analysis_server_test.dart
+++ b/test/flutter_analysis_server_test.dart
@@ -210,7 +210,6 @@
setUp(() async {
await SdkManager.flutterSdk.init();
flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
- await flutterWebManager.warmup();
analysisServer = FlutterAnalysisServerWrapper(flutterWebManager);
await analysisServer.init();
await analysisServer.warmup();
@@ -218,7 +217,6 @@
tearDown(() async {
await analysisServer.shutdown();
- await flutterWebManager.dispose();
});
test('analyze counter app', () async {
diff --git a/test/flutter_web_test.dart b/test/flutter_web_test.dart
index c5f3c45..ef8b121 100644
--- a/test/flutter_web_test.dart
+++ b/test/flutter_web_test.dart
@@ -2,10 +2,12 @@
// 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:convert';
import 'dart:io';
import 'package:dart_services/src/flutter_web.dart';
import 'package:dart_services/src/sdk_manager.dart';
+import 'package:path/path.dart' as path;
import 'package:test/test.dart';
void main() => defineTests();
@@ -20,14 +22,11 @@
flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
});
- tearDown(() {
- flutterWebManager.dispose();
- });
-
- test('inited', () {
- expect(flutterWebManager.projectDirectory.existsSync(), isTrue);
- final file = File(flutterWebManager.packagesFilePath);
- expect(file.existsSync(), isTrue);
+ test('inited', () async {
+ expect(await flutterWebManager.flutterTemplateProject.exists(), isTrue);
+ final file = File(path.join(flutterWebManager.flutterTemplateProject.path,
+ '.dart_tool', 'package_config.json'));
+ expect(await file.exists(), isTrue);
});
test('usesFlutterWeb', () {
@@ -58,20 +57,20 @@
await SdkManager.sdk.init();
await SdkManager.flutterSdk.init();
flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
- await flutterWebManager.warmup();
});
- tearDownAll(() {
- flutterWebManager.dispose();
- });
-
- test('packagesFilePath', () {
- final packagesPath = flutterWebManager.packagesFilePath;
- expect(packagesPath, isNotEmpty);
-
- final file = File(packagesPath);
- final lines = file.readAsLinesSync();
- expect(lines, anyElement(startsWith('flutter:file://')));
+ test('packagesFilePath', () async {
+ final packageConfig = File(path.join(
+ flutterWebManager.flutterTemplateProject.path,
+ '.dart_tool',
+ 'package_config.json'));
+ expect(await packageConfig.exists(), true);
+ final contents = jsonDecode(await packageConfig.readAsString());
+ expect(contents['packages'], isNotEmpty);
+ expect(
+ (contents['packages'] as List)
+ .where((element) => element['name'] == 'flutter'),
+ isNotEmpty);
});
test('summaryFilePath', () {
diff --git a/tool/grind.dart b/tool/grind.dart
index 8306d10..483b305 100644
--- a/tool/grind.dart
+++ b/tool/grind.dart
@@ -7,12 +7,12 @@
import 'dart:async';
import 'dart:io';
-import 'package:dart_services/src/flutter_web.dart';
import 'package:dart_services/src/sdk_manager.dart';
import 'package:grinder/grinder.dart';
import 'package:grinder/grinder_files.dart';
import 'package:grinder/src/run_utils.dart' show mergeWorkingDirectory;
import 'package:http/http.dart' as http;
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
Future<void> main(List<String> args) async {
@@ -22,8 +22,8 @@
}
@Task()
-void analyze() {
- Pub.run('tuneup', arguments: ['check']);
+void analyze() async {
+ await runWithLogging('dart', arguments: ['analyze']);
}
@Task()
@@ -86,7 +86,52 @@
}
}
+@Task('build the project templates')
+void buildProjectTemplates() async {
+ final templatesPath =
+ Directory(path.join(Directory.current.path, 'project_templates'));
+ final exists = await templatesPath.exists();
+ if (exists) {
+ await templatesPath.delete(recursive: true);
+ }
+
+ final dartProjectPath =
+ Directory(path.join(templatesPath.path, 'dart_project'));
+ final dartProjectDir = await dartProjectPath.create(recursive: true);
+ joinFile(dartProjectDir, ['pubspec.yaml'])
+ .writeAsStringSync(createPubspec(includeFlutterWeb: false));
+ await _runDartPubGet(dartProjectDir);
+
+ final flutterProjectPath =
+ Directory(path.join(templatesPath.path, 'flutter_project'));
+ final flutterProjectDir = await flutterProjectPath.create(recursive: true);
+ joinFile(flutterProjectDir, ['pubspec.yaml'])
+ .writeAsStringSync(createPubspec(includeFlutterWeb: true));
+ await _runFlutterPubGet(flutterProjectDir);
+}
+
+Future<void> _runDartPubGet(Directory dir) async {
+ log('running dart pub get (${dir.path})');
+
+ await runWithLogging(
+ path.join(SdkManager.sdk.sdkPath, 'bin', 'dart'),
+ arguments: ['pub', 'get'],
+ workingDirectory: dir.path,
+ );
+}
+
+Future<void> _runFlutterPubGet(Directory dir) async {
+ log('running flutter pub get (${dir.path})');
+
+ await runWithLogging(
+ path.join(SdkManager.flutterSdk.flutterBinPath, 'flutter'),
+ arguments: ['pub', 'get'],
+ workingDirectory: dir.path,
+ );
+}
+
@Task('build the sdk compilation artifacts for upload to google storage')
+@Depends(buildProjectTemplates)
void buildStorageArtifacts() async {
// build and copy dart_sdk.js, flutter_web.js, and flutter_web.dill
final temp = Directory.systemTemp.createTempSync('flutter_web_sample');
@@ -101,7 +146,7 @@
void _buildStorageArtifacts(Directory dir) async {
final flutterSdkPath =
Directory(path.join(Directory.current.path, 'flutter'));
- final pubspec = FlutterWebManager.createPubspec(true);
+ final pubspec = createPubspec(includeFlutterWeb: true);
joinFile(dir, ['pubspec.yaml']).writeAsStringSync(pubspec);
// run flutter pub get
@@ -142,7 +187,7 @@
// Make sure flutter/bin/cache/flutter_web_sdk/flutter_web_sdk/kernel/flutter_ddc_sdk.dill
// is installed.
await runWithLogging(
- path.join(flutterSdkPath.path, 'bin/flutter'),
+ path.join(flutterSdkPath.path, 'bin', 'flutter'),
arguments: ['precache', '--web'],
workingDirectory: dir.path,
);
@@ -290,3 +335,26 @@
fail('Unable to exec $executable, failed with code $exitCode');
}
}
+
+const String _samplePackageName = 'dartpad_sample';
+
+String createPubspec({@required bool includeFlutterWeb}) {
+ // Mark the samples as not null safe.
+ var content = '''
+name: $_samplePackageName
+environment:
+ sdk: '>=2.10.0 <3.0.0'
+''';
+
+ if (includeFlutterWeb) {
+ content += '''
+dependencies:
+ flutter:
+ sdk: flutter
+ flutter_test:
+ sdk: flutter
+''';
+ }
+
+ return content;
+}