diff --git a/lib/src/command/build.dart b/lib/src/command/build.dart index 93537b61d2816efa8fdcee1e527eb0eff422d107..f8ce3821aed22a22f2c585a90a7f125b81233728 100644 --- a/lib/src/command/build.dart +++ b/lib/src/command/build.dart @@ -69,10 +69,12 @@ class BuildCommand extends BarbackCommand { var environment = await AssetEnvironment.create(entrypoint, mode, environmentConstants: environmentConstants, useDart2JS: true); + var hasError = false; // Show in-progress errors, but not results. Those get handled // implicitly by getAllAssets(). environment.barback.errors.listen((error) { log.error(log.red("Build error:\n$error")); + hasError = true; if (log.json.enabled) { // Wrap the error in a map in case we end up decorating it with @@ -111,12 +113,19 @@ class BuildCommand extends BarbackCommand { log.message('Built $builtFiles ${pluralize('file', builtFiles)} ' 'to "$outputDirectory".'); - log.json.message({ - "buildResult": "success", - "outputDirectory": outputDirectory, - "numFiles": builtFiles, - "log": logJson - }); + if (hasError) { + log.error(log.red("Build failed.")); + log.json.message( + {"buildResult": "failure", "errors": errorsJson, "log": logJson}); + return flushThenExit(exit_codes.DATA); + } else { + log.json.message({ + "buildResult": "success", + "outputDirectory": outputDirectory, + "numFiles": builtFiles, + "log": logJson + }); + } } on BarbackException catch (_) { // If [getAllAssets()] throws a BarbackException, the error has already // been reported. diff --git a/test/build/reports_failures_test.dart b/test/build/reports_failures_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b50e01027c780656c652a66fa0ddb5e29fa9b68a --- /dev/null +++ b/test/build/reports_failures_test.dart @@ -0,0 +1,45 @@ +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.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 '../descriptor.dart' as d; +import '../test_pub.dart'; + +const _failingTransformer = """ +import 'dart:async'; + +import 'package:barback/barback.dart'; + +class FailingTransformer extends Transformer { + FailingTransformer.asPlugin(); + + String get allowedExtensions => '.txt'; + + Future apply(Transform transform) { + throw 'FAIL!'; + } +} +"""; + +main() { + integration("reports failures in transformers which don't output dart", () { + // Test for https://github.com/dart-lang/pub/issues/1336 + serveBarback(); + + d.dir(appPath, [ + d.pubspec({ + "name": "myapp", + "transformers": ["myapp/src/transformer"], + "dependencies": {"barback": "any"} + }), + d.dir("lib", [ + d.dir("src", [d.file("transformer.dart", _failingTransformer)]) + ]), + d.dir("web", + [d.file("foo.txt", "foo"), d.file("main.dart", "void main() {}")]) + ]).create(); + + pubGet(); + schedulePub(args: ["build"], exitCode: 65); + }); +}