diff --git a/webdev/example/pubspec.yaml b/webdev/example/pubspec.yaml
deleted file mode 100644
index 5e4f3719d..000000000
--- a/webdev/example/pubspec.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: webdev_example_app
-description: A web app example for webdev CLI.
-version: 0.0.1
-
-environment:
- sdk: ">=2.0.0-dev.3.0 <2.0.0"
-
-dependencies:
- angular: ^5.0.0-alpha+3
- browser: ^0.10.0
-
-dev_dependencies:
- webdev:
- path: ../
- ##############################################################################
- # Temporary until build_runner exposes a function to generate it's script.
- build_runner:
- git:
- url: https://github.com/dart-lang/build.git
- path: build_runner
- ##############################################################################
-
-dependency_overrides:
- # Necessary with angular: ^5.0.0-alpha+1 dependency.
- analyzer: ^0.31.0-alpha.1
diff --git a/webdev/example/web/main.dart b/webdev/example/web/main.dart
deleted file mode 100644
index 78477ff34..000000000
--- a/webdev/example/web/main.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:angular/angular.dart';
-import 'package:webdev_example_app/app_component.dart';
-import 'main.template.dart' as ng;
-
-main() {
- bootstrapStatic(AppComponent, [/*providers*/], ng.initReflector);
-}
diff --git a/webdev/lib/src/command/build_command.dart b/webdev/lib/src/command/build_command.dart
index ac1b646ca..d98c5fbe3 100644
--- a/webdev/lib/src/command/build_command.dart
+++ b/webdev/lib/src/command/build_command.dart
@@ -1,6 +1,8 @@
-import 'dart:async';
-import 'dart:isolate';
+// Copyright (c) 2018, 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.
+import 'dart:async';
import 'build_runner_command_base.dart';
/// Command to execute pub run build_runner build.
@@ -12,12 +14,5 @@ class BuildCommand extends BuildRunnerCommandBase {
final description = 'Run builders to build a package.';
@override
- Future run() async {
- final arguments = ['build'];
- arguments.addAll(argResults.arguments);
- var exitPort = new ReceivePort();
- await Isolate.spawnUri(await buildRunnerScript, arguments, null,
- onExit: exitPort.sendPort, automaticPackageResolution: true);
- await exitPort.first;
- }
+ Future run() => runCore('build');
}
diff --git a/webdev/lib/src/command/build_runner_command_base.dart b/webdev/lib/src/command/build_runner_command_base.dart
index 88f2fc0eb..a03bace6a 100644
--- a/webdev/lib/src/command/build_runner_command_base.dart
+++ b/webdev/lib/src/command/build_runner_command_base.dart
@@ -1,7 +1,13 @@
+// Copyright (c) 2018, 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.
+
import 'dart:async';
import 'dart:io';
+import 'dart:isolate';
import 'package:args/command_runner.dart';
+import 'package:stack_trace/stack_trace.dart';
/// Extend to get a command with the arguments common to all build_runner
/// commands.
@@ -19,13 +25,97 @@ abstract class BuildRunnerCommandBase extends Command {
help: 'Enables verbose logging.');
}
- Future
get buildRunnerScript async {
- // TODO(nshahan) build_runner will expose this as a function call that will
- // be imported to avoid running a binary in a transitive dependency with
- // pub run.
- final executable = 'pub';
- final arguments = ['run', 'build_runner', 'generate-build-script'];
- final results = await Process.run(executable, arguments);
- return new Uri.file(results.stdout.toString().trim());
+ Future runCore(String command) async {
+ final arguments = [command]..addAll(argResults.arguments);
+
+ // Heavily inspired by dart-lang/build @ 0c77443dd7
+ // /build_runner/bin/build_runner.dart#L58-L85
+ var exitPort = new ReceivePort();
+ var errorPort = new ReceivePort();
+ var messagePort = new ReceivePort();
+ var errorListener = errorPort.listen((e) {
+ stderr.writeln('\n\nYou have hit a bug in build_runner');
+ stderr.writeln('Please file an issue with reproduction steps at '
+ 'https://github.com/dart-lang/build/issues\n\n');
+ final error = e[0];
+ final trace = e[1] as String;
+ stderr.writeln(error);
+ stderr.writeln(new Trace.parse(trace).terse);
+ if (exitCode == 0) exitCode = 1;
+ });
+ await Isolate.spawnUri(
+ await _buildRunnerScript(), arguments, messagePort.sendPort,
+ onExit: exitPort.sendPort,
+ onError: errorPort.sendPort,
+ automaticPackageResolution: true);
+ StreamSubscription exitCodeListener;
+ exitCodeListener = messagePort.listen((isolateExitCode) {
+ if (isolateExitCode is! int) {
+ throw new StateError(
+ 'Bad response from isolate, expected an exit code but got '
+ '$isolateExitCode');
+ }
+ exitCode = isolateExitCode as int;
+ exitCodeListener.cancel();
+ exitCodeListener = null;
+ });
+ await exitPort.first;
+ await errorListener.cancel();
+ await exitCodeListener?.cancel();
}
}
+
+Future _buildRunnerScript() async {
+ var dataUri = new Uri.dataFromString(_bootstrapScript);
+
+ var messagePort = new ReceivePort();
+ var exitPort = new ReceivePort();
+ var errorPort = new ReceivePort();
+
+ await Isolate.spawnUri(dataUri, [], messagePort.sendPort,
+ onExit: exitPort.sendPort,
+ onError: errorPort.sendPort,
+ errorsAreFatal: true,
+ packageConfig: new Uri.file('.packages'));
+
+ var allErrorsFuture = errorPort.forEach((error) {
+ var errorList = error as List;
+ var message = errorList[0] as String;
+ var stack = new StackTrace.fromString(errorList[1] as String);
+
+ stderr.writeln(message);
+ stderr.writeln(stack);
+ });
+
+ var items = await Future.wait([
+ messagePort.toList(),
+ allErrorsFuture,
+ exitPort.first.whenComplete(() {
+ messagePort.close();
+ errorPort.close();
+ })
+ ]);
+
+ var messages = items[0] as List;
+ if (messages.isEmpty) {
+ throw new StateError('An error occurred while running booting.');
+ }
+
+ assert(messages.length == 1);
+ return new Uri.file(messages.single as String);
+}
+
+const _bootstrapScript = r'''
+import 'dart:io';
+import 'dart:isolate';
+
+import 'package:build_runner/build_script_generate.dart';
+import 'package:path/path.dart' as p;
+
+void main(List args, [SendPort sendPort]) async {
+ var buildScript = await generateBuildScript();
+ var scriptFile = new File(scriptLocation)..createSync(recursive: true);
+ scriptFile.writeAsStringSync(buildScript);
+ sendPort.send(p.absolute(scriptLocation));
+}
+''';
diff --git a/webdev/lib/src/command/serve_command.dart b/webdev/lib/src/command/serve_command.dart
index a8ba022b7..790d52b97 100644
--- a/webdev/lib/src/command/serve_command.dart
+++ b/webdev/lib/src/command/serve_command.dart
@@ -1,5 +1,8 @@
+// Copyright (c) 2018, 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.
+
import 'dart:async';
-import 'dart:isolate';
import 'build_runner_command_base.dart';
@@ -12,21 +15,21 @@ class ServeCommand extends BuildRunnerCommandBase {
final description = 'Run a local web development server and a file system'
' watcher that re-builds on changes.';
+ @override
+ String get invocation => '${super.invocation} [[:]]...';
+
ServeCommand() {
// TODO(nshahan) Expose more args passed to build_runner serve.
// build_runner might expose args for use in wrapping scripts like this one.
argParser
..addOption('hostname',
- defaultsTo: 'localhost', help: 'Specify the hostname to serve on.');
+ help: 'Specify the hostname to serve on', defaultsTo: 'localhost')
+ ..addFlag('log-requests',
+ defaultsTo: false,
+ negatable: false,
+ help: 'Enables logging for each request to the server.');
}
@override
- Future run() async {
- final arguments = ['serve'];
- arguments.addAll(argResults.arguments);
- var exitPort = new ReceivePort();
- await Isolate.spawnUri(await buildRunnerScript, arguments, null,
- onExit: exitPort.sendPort, automaticPackageResolution: true);
- await exitPort.first;
- }
+ Future run() => runCore('serve');
}
diff --git a/webdev/lib/src/webdev_command_runner.dart b/webdev/lib/src/webdev_command_runner.dart
index 1dbdd4133..c2a7c02b5 100644
--- a/webdev/lib/src/webdev_command_runner.dart
+++ b/webdev/lib/src/webdev_command_runner.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2018, 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.
+
import 'package:args/command_runner.dart';
import 'command/build_command.dart';
diff --git a/webdev/lib/webdev.dart b/webdev/lib/webdev.dart
deleted file mode 100644
index 97ed18291..000000000
--- a/webdev/lib/webdev.dart
+++ /dev/null
@@ -1 +0,0 @@
-export 'src/webdev_command_runner.dart';
diff --git a/webdev/pubspec.yaml b/webdev/pubspec.yaml
index 5796813f4..eadcaa2df 100644
--- a/webdev/pubspec.yaml
+++ b/webdev/pubspec.yaml
@@ -2,17 +2,15 @@ name: webdev
description: A CLI for Dart web development.
author: Dart Team
homepage: https://github.com/dart-lang/webdev
+version: 0.1.0-dev
environment:
- sdk: ">=2.0.0-dev.3.0 <2.0.0"
+ sdk: ">=2.0.0-dev.32.0 <2.0.0"
dependencies:
args: ^1.2.0
- build_runner:
- git:
- url: https://github.com/dart-lang/build.git
- path: build_runner
- build_web_compilers: ^0.1.1
+ io: ^0.3.2+1
+ stack_trace: ^1.9.2
-dev_dependencies:
- test: "^0.12.0"
+executables:
+ webdev: