[manual roll] update third party packages for latest flutter roll
Change-Id: I4df4dc3c19f0559edf4e49ac6a186dbac62aac1e
diff --git a/bazel_worker/.gitignore b/bazel_worker/.gitignore
deleted file mode 100644
index 00035d7..0000000
--- a/bazel_worker/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.buildlog
-.DS_Store
-.idea
-.pub/
-.settings/
-build/
-packages
-.packages
-pubspec.lock
-.dart_tool
diff --git a/bazel_worker/.travis.yml b/bazel_worker/.travis.yml
deleted file mode 100644
index f21e9b1..0000000
--- a/bazel_worker/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: dart
-
-script: ./tool/travis.sh
-
-dart:
- - dev
-
-# Speed up builds by using containerization. Disable this if you need to use
-# sudo in your scripts.
-sudo: false
-
-branches:
- only:
- - master
-
-cache:
- directories:
- - $HOME/.pub-cache
diff --git a/bazel_worker/AUTHORS b/bazel_worker/AUTHORS
deleted file mode 100644
index e8063a8..0000000
--- a/bazel_worker/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Below is a list of people and organizations that have contributed
-# to the project. Names should be added to the list like so:
-#
-# Name/Organization <email address>
-
-Google Inc.
diff --git a/bazel_worker/BUILD.gn b/bazel_worker/BUILD.gn
deleted file mode 100644
index f34a3f5..0000000
--- a/bazel_worker/BUILD.gn
+++ /dev/null
@@ -1,19 +0,0 @@
-# This file is generated by importer.py for bazel_worker-0.1.23+1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("bazel_worker") {
- package_name = "bazel_worker"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/async",
- "//third_party/dart-pkg/pub/pedantic",
- "//third_party/dart-pkg/pub/protobuf",
- ]
-}
diff --git a/bazel_worker/CHANGELOG.md b/bazel_worker/CHANGELOG.md
deleted file mode 100644
index 6a6fed5..0000000
--- a/bazel_worker/CHANGELOG.md
+++ /dev/null
@@ -1,129 +0,0 @@
-## 0.1.23+1
-
-* Don't rely on `exitCode` to know when a worker terminates, instead wait for
- the input stream to close.
- * The SDK may also start throwing instead of returning a `null` here, so this
- pre-emptively guards against that.
-
-## 0.1.23
-
-* Support protobuf `1.x`.
-* Added a tool for updating generated proto files and updated them
- using the latest version of the protoc_plugin package.
- * This required a lower bound bump of the `protobuf` package to `0.14.4`.
-
-## 0.1.22
-
-* Require protobuf 0.14.0.
-
-## 0.1.21
-
-* Make `TestStdinAsync` behave like a `Stream<Uint8List>`
-
-## 0.1.20
-
-* Close worker `outputStream` on `cancel`.
-
-## 0.1.19
-
-* Work around https://github.com/dart-lang/sdk/issues/35874.
-
-## 0.1.18
-
-* Add a `trackWork` optional named argument to `BazelDriver.doWork`. This allows
- the caller to know when a work request is actually sent to a worker.
-
-## 0.1.17
-
-* Allow protobuf 0.13.0.
-
-## 0.1.16
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-* Require protobuf 0.11.0.
-
-## 0.1.15
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-* Require protobuf 0.10.4.
-
-## 0.1.14
-
-* Allow workers to support running in isolates. To support running in isolates,
- workers must modify their `main` method to accept a `SendPort` then use it
- when creating the `AsyncWorkerConnection`. See `async_worker` in `e2e_test`.
-
-## 0.1.13
-
-* Support protobuf 0.10.0.
-
-## 0.1.12
-
-* Set max SDK version to `<3.0.0`.
-
-## 0.1.11
-
-* Added support for protobuf 0.9.0.
-
-## 0.1.10
-
-* Update the SDK dependency to 2.0.0-dev.17.0.
-* Update to protobuf version 0.8.0
-* Remove usages of deprecated upper-case constants from the SDK.
-
-## 0.1.9
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-
-## 0.1.8
-
-* Add `Future cancel()` method to `DriverConnection`, which in the case of a
- `StdDriverConnection` closes the input stream.
- * The `terminateWorkers` method on `BazelWorkerDriver` now calls `cancel` on
- all worker connections to ensure the vm can exit correctly.
-
-## 0.1.7
-
-* Update the `BazelWorkerDriver` class to handle worker crashes, and retry work
- requests. The number of retries is configurable with the new `int maxRetries`
- optional arg to the `BazelWorkerDriver` constructor.
-
-## 0.1.6
-
-* Update the worker_protocol.pb.dart file with the latest proto generator.
-* Add support for package:async 2.x and package:protobuf 6.x.
-
-## 0.1.5
-
-* Change TestStdinAsync.controller to StreamController<List<int>> (instead of
- using dynamic as the type argument).
-
-## 0.1.4
-
-* Added `BazelWorkerDriver` class, which can be used to implement the bazel side
- of the protocol. This allows you to speak to any process which knows the bazel
- protocol from your own process.
-* Changed `WorkerConnection#readRequest` to return a `FutureOr<WorkRequest>`
- instead of dynamic.
-
-## 0.1.3
-
-* Add automatic intercepting of print calls and append them to
- `response.output`. This makes more libraries work out of the box, as printing
- would previously cause an error due to communication over stdin/stdout.
- * Note that using stdin/stdout directly will still cause an error, but that is
- less common.
-
-## 0.1.2
-
-* Add better handling for the case where stdin gives an error instead of an EOF.
-
-## 0.1.1
-
-* Export `AsyncMessageGrouper` and `SyncMessageGrouper` as part of the testing
- library. These can assist when writing e2e tests and communicating with a
- worker process.
-
-## 0.1.0
-
-* Initial version.
diff --git a/bazel_worker/CONTRIBUTING.md b/bazel_worker/CONTRIBUTING.md
deleted file mode 100644
index 6f5e0ea..0000000
--- a/bazel_worker/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
- // Copyright (c) 2015, 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.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
diff --git a/bazel_worker/LICENSE b/bazel_worker/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/bazel_worker/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/bazel_worker/README.md b/bazel_worker/README.md
deleted file mode 100644
index 41a6784..0000000
--- a/bazel_worker/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-Tools for creating a persistent worker loop for [bazel](http://bazel.io/).
-
-## Usage
-
-There are two abstract classes provided by this package, `AsyncWorkerLoop` and
-`SyncWorkerLoop`. These each have a `performRequest` method which you must
-implement.
-
-Lets look at a simple example of a `SyncWorkerLoop` implementation:
-
-```dart
-import 'dart:io';
-import 'package:bazel_worker/bazel_worker.dart';
-
-void main() {
- // Blocks until it gets an EOF from stdin.
- new SyncSimpleWorker().run();
-}
-
-class SyncSimpleWorker extends SyncWorkerLoop {
- /// Must synchronously return a [WorkResponse], since this is a
- /// [SyncWorkerLoop].
- WorkResponse performRequest(WorkRequest request) {
- new File('hello.txt').writeAsStringSync('hello world!');
- return new WorkResponse()..exitCode = EXIT_CODE_OK;
- }
-}
-```
-
-And now the same thing, implemented as an `AsyncWorkerLoop`:
-
-```dart
-import 'dart:io';
-import 'package:bazel_worker/bazel_worker.dart';
-
-void main() {
- // Doesn't block, runs tasks async as they are received on stdin.
- new AsyncSimpleWorker().run();
-}
-
-class AsyncSimpleWorker extends AsyncWorkerLoop {
- /// Must return a [Future<WorkResponse>], since this is an
- /// [AsyncWorkerLoop].
- Future<WorkResponse> performRequest(WorkRequest request) async {
- await new File('hello.txt').writeAsString('hello world!');
- return new WorkResponse()..exitCode = EXIT_CODE_OK;
- }
-}
-```
-
-As you can see, these are nearly identical, it mostly comes down to the
-constraints on your package and personal preference which one you choose to
-implement.
-
-## Testing
-
-A `package:bazel_worker/testing.dart` file is also provided, which can greatly
-assist with writing unit tests for your worker. See the
-`test/worker_loop_test.dart` test included in this package for an example of how
-the helpers can be used.
-
-## Features and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/bazel_worker/issues
diff --git a/bazel_worker/analysis_options.yaml b/bazel_worker/analysis_options.yaml
deleted file mode 100644
index 9781e73..0000000
--- a/bazel_worker/analysis_options.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-include: package:pedantic/analysis_options.yaml
-
-analyzer:
-
-linter:
- rules:
- - always_declare_return_types
- # - annotate_overrides
- - avoid_empty_else
- - avoid_init_to_null
- # - avoid_return_types_on_setters
- - camel_case_types
- # - constant_identifier_names
- - empty_constructor_bodies
- - hash_and_equals
- - library_names
- - library_prefixes
- # - non_constant_identifier_names
- - package_api_docs
- - package_names
- - package_prefixed_library_names
- - prefer_is_not_empty
- - slash_for_doc_comments
- # - type_annotate_public_apis
- - type_init_formals
- - unnecessary_brace_in_string_interps
- - unnecessary_getters_setters
diff --git a/bazel_worker/e2e_test/bin/async_worker.dart b/bazel_worker/e2e_test/bin/async_worker.dart
deleted file mode 100644
index ddd530c..0000000
--- a/bazel_worker/e2e_test/bin/async_worker.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2017, 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 'package:e2e_test/async_worker.dart';
-
-/// This worker can run in one of two ways: normally, using stdin/stdout, or
-/// in an isolate, communicating over a [SendPort].
-Future main(List<String> args, [SendPort sendPort]) async {
- await ExampleAsyncWorker(sendPort).run();
-}
diff --git a/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart b/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
deleted file mode 100644
index fce1eff..0000000
--- a/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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 'package:e2e_test/forwards_to_isolate_async_worker.dart';
-
-/// Wraps the worker provided by `async_worker.dart`, launching it in an
-/// isolate. Requests are forwarded to the isolate and responses are returned
-/// directly from the isolate.
-///
-/// Anyone actually using the facility to wrap a worker in an isolate will want
-/// to use this code to do additional work, for example post processing one of
-/// the output files.
-Future main(List<String> args, SendPort message) async {
- var receivePort = ReceivePort();
- await Isolate.spawnUri(
- Uri.file('async_worker.dart'), [], receivePort.sendPort);
-
- var worker = await ForwardsToIsolateAsyncWorker.create(receivePort);
- await worker.run();
-}
diff --git a/bazel_worker/e2e_test/bin/sync_worker.dart b/bazel_worker/e2e_test/bin/sync_worker.dart
deleted file mode 100644
index 9bdcc77..0000000
--- a/bazel_worker/e2e_test/bin/sync_worker.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2017, 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:e2e_test/sync_worker.dart';
-
-void main() {
- ExampleSyncWorker().run();
-}
diff --git a/bazel_worker/e2e_test/lib/async_worker.dart b/bazel_worker/e2e_test/lib/async_worker.dart
deleted file mode 100644
index 075a5e6..0000000
--- a/bazel_worker/e2e_test/lib/async_worker.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2017, 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 'package:bazel_worker/bazel_worker.dart';
-
-/// Example worker that just returns in its response all the arguments passed
-/// separated by newlines.
-class ExampleAsyncWorker extends AsyncWorkerLoop {
- /// Set [sendPort] to run in an isolate.
- ExampleAsyncWorker([SendPort sendPort])
- : super(connection: AsyncWorkerConnection(sendPort: sendPort));
-
- @override
- Future<WorkResponse> performRequest(WorkRequest request) async {
- return WorkResponse()
- ..exitCode = 0
- ..output = request.arguments.join('\n');
- }
-}
diff --git a/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart b/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
deleted file mode 100644
index bb937b2..0000000
--- a/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, 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 'package:bazel_worker/bazel_worker.dart';
-import 'package:bazel_worker/driver.dart';
-
-/// Example worker that just forwards requests to an isolate.
-class ForwardsToIsolateAsyncWorker extends AsyncWorkerLoop {
- final IsolateDriverConnection _isolateDriverConnection;
-
- static Future<ForwardsToIsolateAsyncWorker> create(
- ReceivePort receivePort) async {
- return ForwardsToIsolateAsyncWorker(
- await IsolateDriverConnection.create(receivePort));
- }
-
- ForwardsToIsolateAsyncWorker(this._isolateDriverConnection);
-
- @override
- Future<WorkResponse> performRequest(WorkRequest request) {
- _isolateDriverConnection.writeRequest(request);
- return _isolateDriverConnection.readResponse();
- }
-}
diff --git a/bazel_worker/e2e_test/lib/sync_worker.dart b/bazel_worker/e2e_test/lib/sync_worker.dart
deleted file mode 100644
index 789f780..0000000
--- a/bazel_worker/e2e_test/lib/sync_worker.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2017, 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:bazel_worker/bazel_worker.dart';
-
-/// Example worker that just returns in its response all the arguments passed
-/// separated by newlines.
-class ExampleSyncWorker extends SyncWorkerLoop {
- @override
- WorkResponse performRequest(WorkRequest request) {
- return WorkResponse()
- ..exitCode = 0
- ..output = request.arguments.join('\n');
- }
-}
diff --git a/bazel_worker/e2e_test/pubspec.yaml b/bazel_worker/e2e_test/pubspec.yaml
deleted file mode 100644
index d9c3577..0000000
--- a/bazel_worker/e2e_test/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: e2e_test
-dependencies:
- bazel_worker:
- path: ../
-dev_dependencies:
- cli_util: ^0.1.0
- path: ^1.4.1
- test: ^1.0.0
-environment:
- sdk: '>=2.0.0 <3.0.0'
diff --git a/bazel_worker/e2e_test/test/e2e_test.dart b/bazel_worker/e2e_test/test/e2e_test.dart
deleted file mode 100644
index faae0d3..0000000
--- a/bazel_worker/e2e_test/test/e2e_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2017, 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 'package:bazel_worker/driver.dart';
-import 'package:cli_util/cli_util.dart';
-import 'package:path/path.dart' as p;
-import 'package:test/test.dart';
-
-void main() {
- var sdkPath = getSdkPath();
- var dart = p.join(sdkPath, 'bin', 'dart');
- runE2eTestForWorker('sync worker',
- () => Process.start(dart, [p.join('bin', 'sync_worker.dart')]));
- runE2eTestForWorker('async worker',
- () => Process.start(dart, [p.join('bin', 'async_worker.dart')]));
- runE2eTestForWorker(
- 'async worker in isolate',
- () =>
- Process.start(dart, [p.join('bin', 'async_worker_in_isolate.dart')]));
-}
-
-void runE2eTestForWorker(String groupName, SpawnWorker spawnWorker) {
- BazelWorkerDriver driver;
- group(groupName, () {
- setUp(() {
- driver = BazelWorkerDriver(spawnWorker);
- });
-
- tearDown(() async {
- await driver.terminateWorkers();
- });
-
- test('single work request', () async {
- await _doRequests(driver, count: 1);
- });
-
- test('lots of requests', () async {
- await _doRequests(driver, count: 1000);
- });
- });
-}
-
-/// Runs [count] work requests through [driver], and asserts that they all
-/// completed with the correct response.
-Future _doRequests(BazelWorkerDriver driver, {int count}) async {
- count ??= 100;
- var requests = List.generate(count, (requestNum) {
- var request = WorkRequest();
- request.arguments.addAll(List.generate(requestNum, (argNum) => '$argNum'));
- return request;
- });
- var responses = await Future.wait(requests.map(driver.doWork));
- for (var i = 0; i < responses.length; i++) {
- var request = requests[i];
- var response = responses[i];
- expect(response.exitCode, EXIT_CODE_OK);
- expect(response.output, request.arguments.join('\n'));
- }
-}
diff --git a/bazel_worker/lib/bazel_worker.dart b/bazel_worker/lib/bazel_worker.dart
deleted file mode 100644
index 0b00408..0000000
--- a/bazel_worker/lib/bazel_worker.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2016, 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.
-
-export 'src/worker/async_worker_loop.dart';
-export 'src/constants.dart';
-export 'src/message_grouper.dart';
-export 'src/worker/sync_worker_loop.dart';
-export 'src/worker/worker_connection.dart';
-export 'src/worker/worker_loop.dart';
-export 'src/worker_protocol.pb.dart';
diff --git a/bazel_worker/lib/driver.dart b/bazel_worker/lib/driver.dart
deleted file mode 100644
index 7453491..0000000
--- a/bazel_worker/lib/driver.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/driver/driver.dart';
-export 'src/driver/driver_connection.dart';
-export 'src/constants.dart';
-export 'src/message_grouper.dart';
-export 'src/worker_protocol.pb.dart';
diff --git a/bazel_worker/lib/src/async_message_grouper.dart b/bazel_worker/lib/src/async_message_grouper.dart
deleted file mode 100644
index 310a7f9..0000000
--- a/bazel_worker/lib/src/async_message_grouper.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2016, 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:collection';
-
-import 'package:async/async.dart';
-import 'package:pedantic/pedantic.dart';
-
-import 'message_grouper.dart';
-import 'message_grouper_state.dart';
-
-/// Collects stream data into messages by interpreting it as
-/// base-128 encoded lengths interleaved with raw data.
-class AsyncMessageGrouper implements MessageGrouper {
- /// Current state for reading in messages;
- final _state = MessageGrouperState();
-
- /// The input stream.
- final StreamQueue<List<int>> _inputQueue;
-
- /// The current buffer.
- final Queue<int> _buffer = Queue<int>();
-
- /// Completes after [cancel] is called or [inputStream] is closed.
- Future<void> get done => _done.future;
- final _done = Completer<void>();
-
- AsyncMessageGrouper(Stream<List<int>> inputStream)
- : _inputQueue = StreamQueue(inputStream);
-
- /// Returns the next full message that is received, or null if none are left.
- @override
- Future<List<int>> get next async {
- try {
- List<int> message;
- while (message == null &&
- (_buffer.isNotEmpty || await _inputQueue.hasNext)) {
- if (_buffer.isEmpty) _buffer.addAll(await _inputQueue.next);
- var nextByte = _buffer.removeFirst();
- if (nextByte == -1) return null;
- message = _state.handleInput(nextByte);
- }
-
- // If there is nothing left in the queue then cancel the subscription.
- if (message == null) unawaited(cancel());
-
- return message;
- } catch (e) {
- // It appears we sometimes get an exception instead of -1 as expected when
- // stdin closes, this handles that in the same way (returning a null
- // message)
- return null;
- }
- }
-
- /// Stop listening to the stream for further updates.
- Future cancel() {
- if (!_done.isCompleted) {
- _done.complete(null);
- return _inputQueue.cancel();
- }
- return done;
- }
-}
diff --git a/bazel_worker/lib/src/constants.dart b/bazel_worker/lib/src/constants.dart
deleted file mode 100644
index 30113d3..0000000
--- a/bazel_worker/lib/src/constants.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) 2016, 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.
-
-const int EXIT_CODE_OK = 0;
-const int EXIT_CODE_ERROR = 15;
diff --git a/bazel_worker/lib/src/driver/driver.dart b/bazel_worker/lib/src/driver/driver.dart
deleted file mode 100644
index 16cbc96..0000000
--- a/bazel_worker/lib/src/driver/driver.dart
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-import 'dart:io';
-
-import '../constants.dart';
-import '../worker_protocol.pb.dart';
-import 'driver_connection.dart';
-
-typedef SpawnWorker = Future<Process> Function();
-
-/// A driver for talking to a bazel worker.
-///
-/// This allows you to use any binary that supports the bazel worker protocol in
-/// the same way that bazel would, but from another dart process instead.
-class BazelWorkerDriver {
- /// Idle worker processes.
- final _idleWorkers = <Process>[];
-
- /// The maximum number of idle workers at any given time.
- final int _maxIdleWorkers;
-
- /// The maximum number of times to retry a [WorkAttempt] if there is an error.
- final int _maxRetries;
-
- /// The maximum number of concurrent workers to run at any given time.
- final int _maxWorkers;
-
- /// The number of currently active workers.
- int get _numWorkers => _readyWorkers.length + _spawningWorkers.length;
-
- /// All workers that are fully spawned and ready to handle work.
- final _readyWorkers = <Process>[];
-
- /// All workers that are in the process of being spawned.
- final _spawningWorkers = <Future<Process>>[];
-
- /// Work requests that haven't been started yet.
- final _workQueue = Queue<_WorkAttempt>();
-
- /// Factory method that spawns a worker process.
- final SpawnWorker _spawnWorker;
-
- BazelWorkerDriver(this._spawnWorker,
- {int maxIdleWorkers, int maxWorkers, int maxRetries})
- : _maxIdleWorkers = maxIdleWorkers ?? 4,
- _maxWorkers = maxWorkers ?? 4,
- _maxRetries = maxRetries ?? 4;
-
- /// Waits for an available worker, and then sends [WorkRequest] to it.
- ///
- /// If [trackWork] is provided it will be invoked with a [Future] once the
- /// [request] has been actually sent to the worker. This allows the caller
- /// to determine when actual work is being done versus just waiting for an
- /// available worker.
- Future<WorkResponse> doWork(WorkRequest request,
- {Function(Future<WorkResponse>) trackWork}) {
- var attempt = _WorkAttempt(request, trackWork: trackWork);
- _workQueue.add(attempt);
- _runWorkQueue();
- return attempt.response;
- }
-
- /// Calls `kill` on all worker processes.
- Future terminateWorkers() async {
- for (var worker in _readyWorkers.toList()) {
- _killWorker(worker);
- }
- await Future.wait(_spawningWorkers.map((worker) async {
- _killWorker(await worker);
- }));
- }
-
- /// Runs as many items in [_workQueue] as possible given the number of
- /// available workers.
- ///
- /// Will spawn additional workers until [_maxWorkers] has been reached.
- ///
- /// This method synchronously drains the [_workQueue] and [_idleWorkers], but
- /// some tasks may not actually start right away if they need to wait for a
- /// worker to spin up.
- void _runWorkQueue() {
- // Bail out conditions, we will continue to call ourselves indefinitely
- // until one of these is met.
- if (_workQueue.isEmpty) return;
- if (_numWorkers == _maxWorkers && _idleWorkers.isEmpty) return;
- if (_numWorkers > _maxWorkers) {
- throw StateError('Internal error, created to many workers. Please '
- 'file a bug at https://github.com/dart-lang/bazel_worker/issues/new');
- }
-
- // At this point we definitely want to run a task, we just need to decide
- // whether or not we need to start up a new worker.
- var attempt = _workQueue.removeFirst();
- if (_idleWorkers.isNotEmpty) {
- _runWorker(_idleWorkers.removeLast(), attempt);
- } else {
- // No need to block here, we want to continue to synchronously drain the
- // work queue.
- var futureWorker = _spawnWorker();
- _spawningWorkers.add(futureWorker);
- futureWorker.then((worker) {
- _spawningWorkers.remove(futureWorker);
- _readyWorkers.add(worker);
-
- var connection = StdDriverConnection.forWorker(worker);
- _workerConnections[worker] = connection;
- _runWorker(worker, attempt);
-
- // When the worker exits we should retry running the work queue in case
- // there is more work to be done. This is primarily just a defensive
- // thing but is cheap to do.
- //
- // We don't use `exitCode` because it is null for detached processes (
- // which is common for workers).
- connection.done.then((_) {
- _idleWorkers.remove(worker);
- _readyWorkers.remove(worker);
- _runWorkQueue();
- });
- });
- }
- // Recursively calls itself until one of the bail out conditions are met.
- _runWorkQueue();
- }
-
- /// Sends [request] to [worker].
- ///
- /// Once the worker responds then it will be added back to the pool of idle
- /// workers.
- void _runWorker(Process worker, _WorkAttempt attempt) {
- var rescheduled = false;
-
- runZoned(() async {
- var connection = _workerConnections[worker];
-
- connection.writeRequest(attempt.request);
- var responseFuture = connection.readResponse();
- if (attempt.trackWork != null) {
- attempt.trackWork(responseFuture);
- }
- var response = await responseFuture;
-
- // It is possible for us to complete with an error response due to an
- // unhandled async error before we get here.
- if (!attempt.responseCompleter.isCompleted) {
- if (response == null) {
- rescheduled = _tryReschedule(attempt);
- if (rescheduled) return;
- stderr.writeln('Failed to run request ${attempt.request}');
- response = WorkResponse()
- ..exitCode = EXIT_CODE_ERROR
- ..output =
- 'Invalid response from worker, this probably means it wrote '
- 'invalid output or died.';
- }
- attempt.responseCompleter.complete(response);
- _cleanUp(worker);
- }
- }, onError: (e, s) {
- // Note that we don't need to do additional cleanup here on failures. If
- // the worker dies that is already handled in a generic fashion, we just
- // need to make sure we complete with a valid response.
- if (!attempt.responseCompleter.isCompleted) {
- rescheduled = _tryReschedule(attempt);
- if (rescheduled) return;
- var response = WorkResponse()
- ..exitCode = EXIT_CODE_ERROR
- ..output = 'Error running worker:\n$e\n$s';
- attempt.responseCompleter.complete(response);
- _cleanUp(worker);
- }
- });
- }
-
- /// Performs post-work cleanup for [worker].
- void _cleanUp(Process worker) {
- // If the worker crashes, it won't be in `_readyWorkers` any more, and
- // we don't want to add it to _idleWorkers.
- if (_readyWorkers.contains(worker)) {
- _idleWorkers.add(worker);
- }
-
- // Do additional work if available.
- _runWorkQueue();
-
- // If the worker wasn't immediately used we might have to many idle
- // workers now, kill one if necessary.
- if (_idleWorkers.length > _maxIdleWorkers) {
- // Note that whenever we spawn a worker we listen for its exit code
- // and clean it up so we don't need to do that here.
- var worker = _idleWorkers.removeLast();
- _killWorker(worker);
- }
- }
-
- /// Attempts to reschedule a failed [attempt].
- ///
- /// Returns whether or not the job was successfully rescheduled.
- bool _tryReschedule(_WorkAttempt attempt) {
- if (attempt.timesRetried >= _maxRetries) return false;
- stderr.writeln('Rescheduling failed request...');
- attempt.timesRetried++;
- _workQueue.add(attempt);
- _runWorkQueue();
- return true;
- }
-
- void _killWorker(Process worker) {
- _workerConnections[worker].cancel();
- _readyWorkers.remove(worker);
- _idleWorkers.remove(worker);
- worker.kill();
- }
-}
-
-/// Encapsulates an attempt to fulfill a [WorkRequest], a completer for the
-/// [WorkResponse], and the number of times it has been retried.
-class _WorkAttempt {
- final WorkRequest request;
- final responseCompleter = Completer<WorkResponse>();
- final Function(Future<WorkResponse>) trackWork;
-
- Future<WorkResponse> get response => responseCompleter.future;
-
- int timesRetried = 0;
-
- _WorkAttempt(this.request, {this.trackWork});
-}
-
-final _workerConnections = Expando<DriverConnection>('connection');
diff --git a/bazel_worker/lib/src/driver/driver_connection.dart b/bazel_worker/lib/src/driver/driver_connection.dart
deleted file mode 100644
index b282aec..0000000
--- a/bazel_worker/lib/src/driver/driver_connection.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:io';
-import 'dart:isolate';
-
-import '../async_message_grouper.dart';
-import '../worker_protocol.pb.dart';
-import '../constants.dart';
-import '../utils.dart';
-
-/// A connection from a `BazelWorkerDriver` to a worker.
-///
-/// Unlike `WorkerConnection` there is no synchronous version of this class.
-/// This is because drivers talk to multiple workers, so they should never block
-/// when waiting for the response of any individual worker.
-abstract class DriverConnection {
- Future<WorkResponse> readResponse();
-
- void writeRequest(WorkRequest request);
-
- Future cancel();
-}
-
-/// Default implementation of [DriverConnection] that works with [Stdin]
-/// and [Stdout].
-class StdDriverConnection implements DriverConnection {
- final AsyncMessageGrouper _messageGrouper;
- final StreamSink<List<int>> _outputStream;
-
- Future<void> get done => _messageGrouper.done;
-
- StdDriverConnection(
- {Stream<List<int>> inputStream, StreamSink<List<int>> outputStream})
- : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
- _outputStream = outputStream ?? stdout;
-
- factory StdDriverConnection.forWorker(Process worker) => StdDriverConnection(
- inputStream: worker.stdout, outputStream: worker.stdin);
-
- /// Note: This will attempts to recover from invalid proto messages by parsing
- /// them as strings. This is a common error case for workers (they print a
- /// message to stdout on accident). This isn't perfect however as it only
- /// happens if the parsing throws, you can still hang indefinitely if the
- /// [MessageGrouper] doesn't find what it thinks is the end of a proto
- /// message.
- @override
- Future<WorkResponse> readResponse() async {
- var buffer = await _messageGrouper.next;
- if (buffer == null) return null;
-
- WorkResponse response;
- try {
- response = WorkResponse.fromBuffer(buffer);
- } catch (_) {
- try {
- // Try parsing the message as a string and set that as the output.
- var output = utf8.decode(buffer);
- var response = WorkResponse()
- ..exitCode = EXIT_CODE_ERROR
- ..output = 'Worker sent an invalid response:\n$output';
- return response;
- } catch (_) {
- // Fall back to original exception and rethrow if we fail to parse as
- // a string.
- }
- rethrow;
- }
- return response;
- }
-
- @override
- void writeRequest(WorkRequest request) {
- _outputStream.add(protoToDelimitedBuffer(request));
- }
-
- @override
- Future cancel() async {
- await _outputStream.close();
- await _messageGrouper.cancel();
- }
-}
-
-/// [DriverConnection] that works with an isolate via a [SendPort].
-class IsolateDriverConnection implements DriverConnection {
- final StreamIterator _receivePortIterator;
- final SendPort _sendPort;
-
- IsolateDriverConnection._(this._receivePortIterator, this._sendPort);
-
- /// Creates a driver connection for a worker in an isolate. Provide the
- /// [receivePort] attached to the [SendPort] that the isolate was created
- /// with.
- static Future<IsolateDriverConnection> create(ReceivePort receivePort) async {
- var receivePortIterator = StreamIterator(receivePort);
- await receivePortIterator.moveNext();
- var sendPort = receivePortIterator.current as SendPort;
- return IsolateDriverConnection._(receivePortIterator, sendPort);
- }
-
- @override
- Future<WorkResponse> readResponse() async {
- await _receivePortIterator.moveNext();
- return WorkResponse.fromBuffer(_receivePortIterator.current as List<int>);
- }
-
- @override
- void writeRequest(WorkRequest request) {
- _sendPort.send(request.writeToBuffer());
- }
-
- @override
- Future cancel() async {}
-}
diff --git a/bazel_worker/lib/src/message_grouper.dart b/bazel_worker/lib/src/message_grouper.dart
deleted file mode 100644
index 635983e..0000000
--- a/bazel_worker/lib/src/message_grouper.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2016, 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.
-
-/// Interface for a [MessageGrouper], which groups bytes in delimited proto
-/// format into the bytes for each message.
-///
-/// This interface should not generally be implemented directly, instead use
-/// the [SyncMessageGrouper] or [AsyncMessageGrouper] implementations.
-abstract class MessageGrouper {
- /// Returns either a [List<int>] or a [Future<List<int>>].
- dynamic get next;
-}
diff --git a/bazel_worker/lib/src/message_grouper_state.dart b/bazel_worker/lib/src/message_grouper_state.dart
deleted file mode 100644
index 5cbf933..0000000
--- a/bazel_worker/lib/src/message_grouper_state.dart
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2016, 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:typed_data';
-
-import 'package:protobuf/protobuf.dart';
-
-/// State held by the [MessageGrouper] while waiting for additional data to
-/// arrive.
-class MessageGrouperState {
- /// Reads the initial length.
- _LengthReader _lengthReader;
-
- /// Reads messages from a stream of bytes.
- _MessageReader _messageReader;
-
- MessageGrouperState() {
- reset();
- }
-
- /// Handle one byte at a time.
- ///
- /// Returns a [List<int>] of message bytes if [byte] was the last byte in a
- /// message, otherwise returns [null].
- List<int> handleInput(int byte) {
- if (!_lengthReader.done) {
- _lengthReader.readByte(byte);
- if (_lengthReader.done) {
- _messageReader = _MessageReader(_lengthReader.length);
- }
- } else {
- assert(_messageReader != null);
- _messageReader.readByte(byte);
- }
-
- if (_lengthReader.done && _messageReader.done) {
- var message = _messageReader.message;
- reset();
- return message;
- }
-
- return null;
- }
-
- /// Reset the state so that we are ready to receive the next message.
- void reset() {
- _lengthReader = _LengthReader();
- _messageReader = null;
- }
-}
-
-/// Reads a length one byte at a time.
-///
-/// The base-128 encoding is in little-endian order, with the high bit set on
-/// all bytes but the last. This was chosen since it's the same as the
-/// base-128 encoding used by protobufs, so it allows a modest amount of code
-/// reuse at the other end of the protocol.
-class _LengthReader {
- /// Whether or not we are done reading the length.
- bool get done => _done;
- bool _done = false;
-
- /// If [_done] is `true`, the decoded value of the length bytes received so
- /// far (if any). If [_done] is `false`, the decoded length that was most
- /// recently received.
- int _length;
-
- /// The length read in. You are only allowed to read this if [_done] is
- /// `true`.
- int get length {
- assert(_done);
- return _length;
- }
-
- final List<int> _buffer = <int>[];
-
- /// Read a single byte into [_length].
- void readByte(int byte) {
- assert(!_done);
- _buffer.add(byte);
-
- // Check for the last byte in the length, and then read it.
- if ((byte & 0x80) == 0) {
- _done = true;
- var reader = CodedBufferReader(_buffer);
- _length = reader.readInt32();
- }
- }
-}
-
-/// Reads some number of bytes from a stream, one byte at a time.
-class _MessageReader {
- /// Whether or not we are done reading bytes from the stream.
- bool get done => _done;
- bool _done;
-
- /// The total length of the message to be read.
- final int _length;
-
- /// A [Uint8List] which holds the message data. You are only allowed to read
- /// this if [_done] is `true`.
- Uint8List get message {
- assert(_done);
- return _message;
- }
-
- final Uint8List _message;
-
- /// If [_done] is `false`, the number of message bytes that have been received
- /// so far. Otherwise zero.
- int _numMessageBytesReceived = 0;
-
- _MessageReader(int length)
- : _message = Uint8List(length),
- _length = length,
- _done = length == 0;
-
- /// Reads [byte] into [_message].
- void readByte(int byte) {
- assert(!done);
-
- _message[_numMessageBytesReceived++] = byte;
- if (_numMessageBytesReceived == _length) _done = true;
- }
-}
diff --git a/bazel_worker/lib/src/sync_message_grouper.dart b/bazel_worker/lib/src/sync_message_grouper.dart
deleted file mode 100644
index c0d11f0..0000000
--- a/bazel_worker/lib/src/sync_message_grouper.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016, 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:io';
-
-import 'message_grouper.dart';
-import 'message_grouper_state.dart';
-
-/// Groups bytes in delimited proto format into the bytes for each message.
-class SyncMessageGrouper implements MessageGrouper {
- final _state = MessageGrouperState();
- final Stdin _stdin;
-
- SyncMessageGrouper(this._stdin);
-
- /// Blocks until the next full message is received, and then returns it.
- ///
- /// Returns null at end of file.
- @override
- List<int> get next {
- try {
- List<int> message;
- while (message == null) {
- var nextByte = _stdin.readByteSync();
- if (nextByte == -1) return null;
- message = _state.handleInput(nextByte);
- }
- return message;
- } catch (e) {
- // It appears we sometimes get an exception instead of -1 as expected when
- // stdin closes, this handles that in the same way (returning a null
- // message)
- return null;
- }
- }
-}
diff --git a/bazel_worker/lib/src/utils.dart b/bazel_worker/lib/src/utils.dart
deleted file mode 100644
index 609b435..0000000
--- a/bazel_worker/lib/src/utils.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, 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:typed_data';
-
-import 'package:protobuf/protobuf.dart';
-
-List<int> protoToDelimitedBuffer(GeneratedMessage message) {
- var messageBuffer = CodedBufferWriter();
- message.writeToCodedBufferWriter(messageBuffer);
-
- var delimiterBuffer = CodedBufferWriter();
- delimiterBuffer.writeInt32NoTag(messageBuffer.lengthInBytes);
-
- var result =
- Uint8List(messageBuffer.lengthInBytes + delimiterBuffer.lengthInBytes);
-
- delimiterBuffer.writeTo(result);
- messageBuffer.writeTo(result, delimiterBuffer.lengthInBytes);
-
- return result;
-}
diff --git a/bazel_worker/lib/src/worker/async_worker_loop.dart b/bazel_worker/lib/src/worker/async_worker_loop.dart
deleted file mode 100644
index 9405c4f..0000000
--- a/bazel_worker/lib/src/worker/async_worker_loop.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016, 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 '../constants.dart';
-import '../worker_protocol.pb.dart';
-import 'worker_connection.dart';
-import 'worker_loop.dart';
-
-/// Persistent Bazel worker loop.
-///
-/// Extend this class and implement the `performRequest` method.
-abstract class AsyncWorkerLoop implements WorkerLoop {
- final AsyncWorkerConnection connection;
-
- AsyncWorkerLoop({AsyncWorkerConnection connection})
- : connection = connection ?? StdAsyncWorkerConnection();
-
- /// Perform a single [WorkRequest], and return a [WorkResponse].
- @override
- Future<WorkResponse> performRequest(WorkRequest request);
-
- /// Run the worker loop. The returned [Future] doesn't complete until
- /// [connection#readRequest] returns `null`.
- @override
- Future run() async {
- while (true) {
- WorkResponse response;
- try {
- var request = await connection.readRequest();
- if (request == null) break;
- var printMessages = StringBuffer();
- response = await runZoned(() => performRequest(request),
- zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- printMessages.writeln();
- printMessages.write(message);
- }));
- if (printMessages.isNotEmpty) {
- response.output = '${response.output}$printMessages';
- }
- // In case they forget to set this.
- response.exitCode ??= EXIT_CODE_OK;
- } catch (e, s) {
- response = WorkResponse()
- ..exitCode = EXIT_CODE_ERROR
- ..output = '$e\n$s';
- }
-
- connection.writeResponse(response);
- }
- }
-}
diff --git a/bazel_worker/lib/src/worker/sync_worker_loop.dart b/bazel_worker/lib/src/worker/sync_worker_loop.dart
deleted file mode 100644
index 2d287b0..0000000
--- a/bazel_worker/lib/src/worker/sync_worker_loop.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2016, 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 '../constants.dart';
-import '../worker_protocol.pb.dart';
-import 'worker_connection.dart';
-import 'worker_loop.dart';
-
-/// Persistent Bazel worker loop.
-///
-/// Extend this class and implement the `performRequest` method.
-abstract class SyncWorkerLoop implements WorkerLoop {
- final SyncWorkerConnection connection;
-
- SyncWorkerLoop({SyncWorkerConnection connection})
- : connection = connection ?? StdSyncWorkerConnection();
-
- /// Perform a single [WorkRequest], and return a [WorkResponse].
- @override
- WorkResponse performRequest(WorkRequest request);
-
- /// Run the worker loop. Blocks until [connection#readRequest] returns `null`.
- @override
- void run() {
- while (true) {
- WorkResponse response;
- try {
- var request = connection.readRequest();
- if (request == null) break;
- var printMessages = StringBuffer();
- response = runZoned(() => performRequest(request), zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- printMessages.writeln();
- printMessages.write(message);
- }));
- if (printMessages.isNotEmpty) {
- response.output = '${response.output}$printMessages';
- }
- // In case they forget to set this.
- response.exitCode ??= EXIT_CODE_OK;
- } catch (e, s) {
- response = WorkResponse()
- ..exitCode = EXIT_CODE_ERROR
- ..output = '$e\n$s';
- }
-
- connection.writeResponse(response);
- }
- }
-}
diff --git a/bazel_worker/lib/src/worker/worker_connection.dart b/bazel_worker/lib/src/worker/worker_connection.dart
deleted file mode 100644
index a429cfe..0000000
--- a/bazel_worker/lib/src/worker/worker_connection.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2016, 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 'dart:typed_data';
-
-import '../async_message_grouper.dart';
-import '../sync_message_grouper.dart';
-import '../utils.dart';
-import '../worker_protocol.pb.dart';
-
-/// A connection from a worker to a driver (driver could be bazel, a dart
-/// program using `BazelWorkerDriver`, or any other process that speaks the
-/// protocol).
-abstract class WorkerConnection {
- /// Reads a [WorkRequest] or returns [null] if there are none left.
- ///
- /// See [AsyncWorkerConnection] and [SyncWorkerConnection] for more narrow
- /// interfaces.
- FutureOr<WorkRequest> readRequest();
-
- void writeResponse(WorkResponse response);
-}
-
-abstract class AsyncWorkerConnection implements WorkerConnection {
- /// Creates a [StdAsyncWorkerConnection] with the specified [inputStream]
- /// and [outputStream], unless [sendPort] is specified, in which case
- /// creates a [SendPortAsyncWorkerConnection].
- factory AsyncWorkerConnection(
- {Stream<List<int>> inputStream,
- StreamSink<List<int>> outputStream,
- SendPort sendPort}) =>
- sendPort == null
- ? StdAsyncWorkerConnection(
- inputStream: inputStream, outputStream: outputStream)
- : SendPortAsyncWorkerConnection(sendPort);
-
- @override
- Future<WorkRequest> readRequest();
-}
-
-abstract class SyncWorkerConnection implements WorkerConnection {
- @override
- WorkRequest readRequest();
-}
-
-/// Default implementation of [AsyncWorkerConnection] that works with [Stdin]
-/// and [Stdout].
-class StdAsyncWorkerConnection implements AsyncWorkerConnection {
- final AsyncMessageGrouper _messageGrouper;
- final StreamSink<List<int>> _outputStream;
-
- StdAsyncWorkerConnection(
- {Stream<List<int>> inputStream, StreamSink<List<int>> outputStream})
- : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
- _outputStream = outputStream ?? stdout;
-
- @override
- Future<WorkRequest> readRequest() async {
- var buffer = await _messageGrouper.next;
- if (buffer == null) return null;
-
- return WorkRequest.fromBuffer(buffer);
- }
-
- @override
- void writeResponse(WorkResponse response) {
- _outputStream.add(protoToDelimitedBuffer(response));
- }
-}
-
-/// Implementation of [AsyncWorkerConnection] for running in an isolate.
-class SendPortAsyncWorkerConnection implements AsyncWorkerConnection {
- final ReceivePort receivePort;
- final StreamIterator<Uint8List> receivePortIterator;
- final SendPort sendPort;
-
- factory SendPortAsyncWorkerConnection(SendPort sendPort) {
- var receivePort = ReceivePort();
- sendPort.send(receivePort.sendPort);
- return SendPortAsyncWorkerConnection._(receivePort, sendPort);
- }
-
- SendPortAsyncWorkerConnection._(this.receivePort, this.sendPort)
- : receivePortIterator = StreamIterator(receivePort.cast());
-
- @override
- Future<WorkRequest> readRequest() async {
- if (!await receivePortIterator.moveNext()) return null;
- return WorkRequest.fromBuffer(receivePortIterator.current);
- }
-
- @override
- void writeResponse(WorkResponse response) {
- sendPort.send(response.writeToBuffer());
- }
-}
-
-/// Default implementation of [SyncWorkerConnection] that works with [Stdin] and
-/// [Stdout].
-class StdSyncWorkerConnection implements SyncWorkerConnection {
- final SyncMessageGrouper _messageGrouper;
- final Stdout _stdoutStream;
-
- StdSyncWorkerConnection({Stdin stdinStream, Stdout stdoutStream})
- : _messageGrouper = SyncMessageGrouper(stdinStream ?? stdin),
- _stdoutStream = stdoutStream ?? stdout;
-
- @override
- WorkRequest readRequest() {
- var buffer = _messageGrouper.next;
- if (buffer == null) return null;
-
- return WorkRequest.fromBuffer(buffer);
- }
-
- @override
- void writeResponse(WorkResponse response) {
- _stdoutStream.add(protoToDelimitedBuffer(response));
- }
-}
diff --git a/bazel_worker/lib/src/worker/worker_loop.dart b/bazel_worker/lib/src/worker/worker_loop.dart
deleted file mode 100644
index 2e4a023..0000000
--- a/bazel_worker/lib/src/worker/worker_loop.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016, 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 '../worker_protocol.pb.dart';
-
-/// Interface for a [WorkerLoop].
-///
-/// This interface should not generally be implemented directly, instead use
-/// the [SyncWorkerLoop] or [AsyncWorkerLoop] implementations.
-abstract class WorkerLoop {
- /// Perform a single [WorkRequest], and return either a [WorkResponse] or
- /// a [Future<WorkResponse>].
- dynamic performRequest(WorkRequest request);
-
- /// Run the worker loop. Should return either a [Future] or [null].
- dynamic run();
-}
diff --git a/bazel_worker/lib/src/worker_protocol.pb.dart b/bazel_worker/lib/src/worker_protocol.pb.dart
deleted file mode 100644
index 90e4381..0000000
--- a/bazel_worker/lib/src/worker_protocol.pb.dart
+++ /dev/null
@@ -1,182 +0,0 @@
-///
-// Generated code. Do not modify.
-// source: worker_protocol.proto
-//
-// @dart = 2.3
-// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
-// ignore_for_file: annotate_overrides
-
-import 'dart:core' as $core;
-
-import 'package:protobuf/protobuf.dart' as $pb;
-
-class Input extends $pb.GeneratedMessage {
- static final $pb.BuilderInfo _i = $pb.BuilderInfo('Input',
- package: const $pb.PackageName('blaze.worker'),
- createEmptyInstance: create)
- ..aOS(1, 'path')
- ..a<$core.List<$core.int>>(2, 'digest', $pb.PbFieldType.OY)
- ..hasRequiredFields = false;
-
- Input._() : super();
- factory Input() => create();
- factory Input.fromBuffer($core.List<$core.int> i,
- [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
- create()..mergeFromBuffer(i, r);
- factory Input.fromJson($core.String i,
- [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
- create()..mergeFromJson(i, r);
- Input clone() => Input()..mergeFromMessage(this);
- Input copyWith(void Function(Input) updates) =>
- super.copyWith((message) => updates(message as Input));
- $pb.BuilderInfo get info_ => _i;
- @$core.pragma('dart2js:noInline')
- static Input create() => Input._();
- Input createEmptyInstance() => create();
- static $pb.PbList<Input> createRepeated() => $pb.PbList<Input>();
- @$core.pragma('dart2js:noInline')
- static Input getDefault() =>
- _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Input>(create);
- static Input _defaultInstance;
-
- @$pb.TagNumber(1)
- $core.String get path => $_getSZ(0);
- @$pb.TagNumber(1)
- set path($core.String v) {
- $_setString(0, v);
- }
-
- @$pb.TagNumber(1)
- $core.bool hasPath() => $_has(0);
- @$pb.TagNumber(1)
- void clearPath() => clearField(1);
-
- @$pb.TagNumber(2)
- $core.List<$core.int> get digest => $_getN(1);
- @$pb.TagNumber(2)
- set digest($core.List<$core.int> v) {
- $_setBytes(1, v);
- }
-
- @$pb.TagNumber(2)
- $core.bool hasDigest() => $_has(1);
- @$pb.TagNumber(2)
- void clearDigest() => clearField(2);
-}
-
-class WorkRequest extends $pb.GeneratedMessage {
- static final $pb.BuilderInfo _i = $pb.BuilderInfo('WorkRequest',
- package: const $pb.PackageName('blaze.worker'),
- createEmptyInstance: create)
- ..pPS(1, 'arguments')
- ..pc<Input>(2, 'inputs', $pb.PbFieldType.PM, subBuilder: Input.create)
- ..a<$core.int>(3, 'requestId', $pb.PbFieldType.O3)
- ..hasRequiredFields = false;
-
- WorkRequest._() : super();
- factory WorkRequest() => create();
- factory WorkRequest.fromBuffer($core.List<$core.int> i,
- [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
- create()..mergeFromBuffer(i, r);
- factory WorkRequest.fromJson($core.String i,
- [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
- create()..mergeFromJson(i, r);
- WorkRequest clone() => WorkRequest()..mergeFromMessage(this);
- WorkRequest copyWith(void Function(WorkRequest) updates) =>
- super.copyWith((message) => updates(message as WorkRequest));
- $pb.BuilderInfo get info_ => _i;
- @$core.pragma('dart2js:noInline')
- static WorkRequest create() => WorkRequest._();
- WorkRequest createEmptyInstance() => create();
- static $pb.PbList<WorkRequest> createRepeated() => $pb.PbList<WorkRequest>();
- @$core.pragma('dart2js:noInline')
- static WorkRequest getDefault() => _defaultInstance ??=
- $pb.GeneratedMessage.$_defaultFor<WorkRequest>(create);
- static WorkRequest _defaultInstance;
-
- @$pb.TagNumber(1)
- $core.List<$core.String> get arguments => $_getList(0);
-
- @$pb.TagNumber(2)
- $core.List<Input> get inputs => $_getList(1);
-
- @$pb.TagNumber(3)
- $core.int get requestId => $_getIZ(2);
- @$pb.TagNumber(3)
- set requestId($core.int v) {
- $_setSignedInt32(2, v);
- }
-
- @$pb.TagNumber(3)
- $core.bool hasRequestId() => $_has(2);
- @$pb.TagNumber(3)
- void clearRequestId() => clearField(3);
-}
-
-class WorkResponse extends $pb.GeneratedMessage {
- static final $pb.BuilderInfo _i = $pb.BuilderInfo('WorkResponse',
- package: const $pb.PackageName('blaze.worker'),
- createEmptyInstance: create)
- ..a<$core.int>(1, 'exitCode', $pb.PbFieldType.O3)
- ..aOS(2, 'output')
- ..a<$core.int>(3, 'requestId', $pb.PbFieldType.O3)
- ..hasRequiredFields = false;
-
- WorkResponse._() : super();
- factory WorkResponse() => create();
- factory WorkResponse.fromBuffer($core.List<$core.int> i,
- [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
- create()..mergeFromBuffer(i, r);
- factory WorkResponse.fromJson($core.String i,
- [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
- create()..mergeFromJson(i, r);
- WorkResponse clone() => WorkResponse()..mergeFromMessage(this);
- WorkResponse copyWith(void Function(WorkResponse) updates) =>
- super.copyWith((message) => updates(message as WorkResponse));
- $pb.BuilderInfo get info_ => _i;
- @$core.pragma('dart2js:noInline')
- static WorkResponse create() => WorkResponse._();
- WorkResponse createEmptyInstance() => create();
- static $pb.PbList<WorkResponse> createRepeated() =>
- $pb.PbList<WorkResponse>();
- @$core.pragma('dart2js:noInline')
- static WorkResponse getDefault() => _defaultInstance ??=
- $pb.GeneratedMessage.$_defaultFor<WorkResponse>(create);
- static WorkResponse _defaultInstance;
-
- @$pb.TagNumber(1)
- $core.int get exitCode => $_getIZ(0);
- @$pb.TagNumber(1)
- set exitCode($core.int v) {
- $_setSignedInt32(0, v);
- }
-
- @$pb.TagNumber(1)
- $core.bool hasExitCode() => $_has(0);
- @$pb.TagNumber(1)
- void clearExitCode() => clearField(1);
-
- @$pb.TagNumber(2)
- $core.String get output => $_getSZ(1);
- @$pb.TagNumber(2)
- set output($core.String v) {
- $_setString(1, v);
- }
-
- @$pb.TagNumber(2)
- $core.bool hasOutput() => $_has(1);
- @$pb.TagNumber(2)
- void clearOutput() => clearField(2);
-
- @$pb.TagNumber(3)
- $core.int get requestId => $_getIZ(2);
- @$pb.TagNumber(3)
- set requestId($core.int v) {
- $_setSignedInt32(2, v);
- }
-
- @$pb.TagNumber(3)
- $core.bool hasRequestId() => $_has(2);
- @$pb.TagNumber(3)
- void clearRequestId() => clearField(3);
-}
diff --git a/bazel_worker/lib/testing.dart b/bazel_worker/lib/testing.dart
deleted file mode 100644
index 037aa1e..0000000
--- a/bazel_worker/lib/testing.dart
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2016, 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:collection';
-import 'dart:io';
-import 'dart:typed_data';
-
-import 'package:bazel_worker/bazel_worker.dart';
-
-export 'src/async_message_grouper.dart';
-export 'src/sync_message_grouper.dart';
-export 'src/utils.dart' show protoToDelimitedBuffer;
-
-/// Interface for a mock [Stdin] object that allows you to add bytes manually.
-abstract class TestStdin implements Stdin {
- void addInputBytes(List<int> bytes);
-
- void close();
-}
-
-/// A [Stdin] mock object which only implements `readByteSync`.
-class TestStdinSync implements TestStdin {
- /// Pending bytes to be delivered synchronously.
- final Queue<int> pendingBytes = Queue<int>();
-
- /// Adds all the [bytes] to this stream.
- @override
- void addInputBytes(List<int> bytes) {
- pendingBytes.addAll(bytes);
- }
-
- /// Add a -1 to signal EOF.
- @override
- void close() {
- pendingBytes.add(-1);
- }
-
- @override
- int readByteSync() {
- return pendingBytes.removeFirst();
- }
-
- @override
- void noSuchMethod(Invocation invocation) {
- throw StateError('Unexpected invocation ${invocation.memberName}.');
- }
-}
-
-/// A mock [Stdin] object which only implements `listen`.
-///
-/// Note: You must call [close] in order for the loop to exit properly.
-class TestStdinAsync implements TestStdin {
- /// Controls the stream for async delivery of bytes.
- final StreamController<Uint8List> _controller = StreamController();
- StreamController<Uint8List> get controller => _controller;
-
- /// Adds all the [bytes] to this stream.
- @override
- void addInputBytes(List<int> bytes) {
- _controller.add(Uint8List.fromList(bytes));
- }
-
- /// Closes this stream. This is necessary for the [AsyncWorkerLoop] to exit.
- @override
- void close() {
- _controller.close();
- }
-
- @override
- StreamSubscription<Uint8List> listen(void Function(Uint8List bytes) onData,
- {Function onError, void Function() onDone, bool cancelOnError}) {
- return _controller.stream.listen(onData,
- onError: onError, onDone: onDone, cancelOnError: cancelOnError);
- }
-
- @override
- void noSuchMethod(Invocation invocation) {
- throw StateError('Unexpected invocation ${invocation.memberName}.');
- }
-}
-
-/// A [Stdout] mock object.
-class TestStdoutStream implements Stdout {
- final List<List<int>> writes = <List<int>>[];
-
- @override
- void add(List<int> bytes) {
- writes.add(bytes);
- }
-
- @override
- void noSuchMethod(Invocation invocation) {
- throw StateError('Unexpected invocation ${invocation.memberName}.');
- }
-}
-
-/// Interface for a [TestWorkerConnection] which records its responses
-abstract class TestWorkerConnection implements WorkerConnection {
- List<WorkResponse> get responses;
-}
-
-/// Interface for a [TestWorkerLoop] which allows you to enqueue responses.
-abstract class TestWorkerLoop implements WorkerLoop {
- void enqueueResponse(WorkResponse response);
-
- /// If set, this message will be printed during the call to `performRequest`.
- String get printMessage;
-}
-
-/// A [StdSyncWorkerConnection] which records its responses.
-class TestSyncWorkerConnection extends StdSyncWorkerConnection
- implements TestWorkerConnection {
- @override
- final List<WorkResponse> responses = <WorkResponse>[];
-
- TestSyncWorkerConnection(Stdin stdinStream, Stdout stdoutStream)
- : super(stdinStream: stdinStream, stdoutStream: stdoutStream);
-
- @override
- void writeResponse(WorkResponse response) {
- super.writeResponse(response);
- responses.add(response);
- }
-}
-
-/// A [SyncWorkerLoop] for testing.
-class TestSyncWorkerLoop extends SyncWorkerLoop implements TestWorkerLoop {
- final List<WorkRequest> requests = <WorkRequest>[];
- final Queue<WorkResponse> _responses = Queue<WorkResponse>();
-
- @override
- final String printMessage;
-
- TestSyncWorkerLoop(SyncWorkerConnection connection, {this.printMessage})
- : super(connection: connection);
-
- @override
- WorkResponse performRequest(WorkRequest request) {
- requests.add(request);
- if (printMessage != null) print(printMessage);
- return _responses.removeFirst();
- }
-
- /// Adds [response] to the queue. These will be returned from
- /// [performResponse] in the order they are added, otherwise it will throw
- /// if the queue is empty.
- @override
- void enqueueResponse(WorkResponse response) {
- _responses.addLast(response);
- }
-}
-
-/// A [StdAsyncWorkerConnection] which records its responses.
-class TestAsyncWorkerConnection extends StdAsyncWorkerConnection
- implements TestWorkerConnection {
- @override
- final List<WorkResponse> responses = <WorkResponse>[];
-
- TestAsyncWorkerConnection(
- Stream<List<int>> inputStream, StreamSink<List<int>> outputStream)
- : super(inputStream: inputStream, outputStream: outputStream);
-
- @override
- void writeResponse(WorkResponse response) {
- super.writeResponse(response);
- responses.add(response);
- }
-}
-
-/// A [AsyncWorkerLoop] for testing.
-class TestAsyncWorkerLoop extends AsyncWorkerLoop implements TestWorkerLoop {
- final List<WorkRequest> requests = <WorkRequest>[];
- final Queue<WorkResponse> _responses = Queue<WorkResponse>();
-
- @override
- final String printMessage;
-
- TestAsyncWorkerLoop(AsyncWorkerConnection connection, {this.printMessage})
- : super(connection: connection);
-
- @override
- Future<WorkResponse> performRequest(WorkRequest request) async {
- requests.add(request);
- if (printMessage != null) print(printMessage);
- return _responses.removeFirst();
- }
-
- /// Adds [response] to the queue. These will be returned from
- /// [performResponse] in the order they are added, otherwise it will throw
- /// if the queue is empty.
- @override
- void enqueueResponse(WorkResponse response) {
- _responses.addLast(response);
- }
-}
diff --git a/bazel_worker/pubspec.yaml b/bazel_worker/pubspec.yaml
deleted file mode 100644
index dbae4cd..0000000
--- a/bazel_worker/pubspec.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: bazel_worker
-version: 0.1.23+1
-
-description: Tools for creating a bazel persistent worker.
-homepage: https://github.com/dart-lang/bazel_worker
-
-environment:
- sdk: '>=2.3.0 <3.0.0'
-
-dependencies:
- async: '>1.9.0 <3.0.0'
- pedantic: ^1.8.0
- protobuf: '>=0.14.4 <2.0.0'
-
-dev_dependencies:
- test: ^1.2.0
diff --git a/bazel_worker/tool/travis.sh b/bazel_worker/tool/travis.sh
deleted file mode 100755
index bccd424..0000000
--- a/bazel_worker/tool/travis.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# Copyright (c) 2016, 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.
-
-# Fast fail the script on failures.
-set -e
-
-# Verify that the libraries are error free.
-dartanalyzer --fatal-infos --fatal-warnings \
- lib/bazel_worker.dart \
- lib/driver.dart \
- lib/testing.dart \
- test/test_all.dart
-
-# Run the tests.
-pub run test
-
-pushd e2e_test
-pub get
-dartanalyzer --fatal-infos --fatal-warnings test/e2e_test.dart
-pub run test
-popd
diff --git a/bazel_worker/tool/update_proto.sh b/bazel_worker/tool/update_proto.sh
deleted file mode 100755
index b224694..0000000
--- a/bazel_worker/tool/update_proto.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-set -e
-
-if [ -z "$1" ]; then
- echo "Expected exactly one argument which is the protoc_plugin version to use"
-else
- echo "Using protoc_plugin version $1"
- pub global activate protoc_plugin "$1"
-fi
-
-BAZEL_REPO=.dart_tool/bazel_worker/bazel.git/
-# Bash away old versions if they exist
-rm -rf "$BAZEL_REPO"
-git clone https://github.com/bazelbuild/bazel.git "$BAZEL_REPO"
-
-protoc --proto_path="${BAZEL_REPO}/src/main/protobuf" --dart_out=lib/src worker_protocol.proto
-dartfmt -w lib/src/worker_protocol.pb.dart
-
-# We only care about the *.pb.dart file, not the extra files
-rm lib/src/worker_protocol.pbenum.dart
-rm lib/src/worker_protocol.pbjson.dart
-rm lib/src/worker_protocol.pbserver.dart
-
-rm -rf "$BAZEL_REPO"
diff --git a/build/BUILD.gn b/build/BUILD.gn
deleted file mode 100644
index 1cb5195..0000000
--- a/build/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is generated by importer.py for build-1.2.2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build") {
- package_name = "build"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/convert",
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/glob",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/analyzer",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/async",
- "//third_party/dart-pkg/pub/path",
- ]
-}
diff --git a/build/CHANGELOG.md b/build/CHANGELOG.md
deleted file mode 100644
index 1926bf6..0000000
--- a/build/CHANGELOG.md
+++ /dev/null
@@ -1,471 +0,0 @@
-## 1.2.2
-
-### Updated docs for some minor behavior changes in build_resolvers 1.3.0
-
-- `Resolver.libraries` will now return any library that has been resolved with
- this resolver. This means calls to `libraryFor` or `isLibrary` on files not
- already resolved will make subsequent `libraries` streams return more
- libraries than previous calls did.
-- The same holds for `findLibraryByName` since it searches through the
- `libraries` stream. You may get a different result at different points in
- your build method if you resolve additional libraries.
-
-## 1.2.1
-
-- Allow analyzer `0.39.x`.
-
-## 1.2.0
-
-- Add the `void reportUnusedAssets(Iterable<AssetId> ids)` method to the
- `BuildStep` class.
- - **WARNING**: Using this introduces serious risk of non-hermetic builds.
- - Indicates to the build system that `ids` were read but their content has
- no impact on the outputs of the build.
- - Build system implementations can choose to support this feature or not,
- and it should be assumed to be a no-op by default.
-
-## 1.1.6
-
-- Allow analyzer version 0.38.0.
-
-## 1.1.5
-
-- Allow analyzer version 0.37.0.
-
-## 1.1.4
-
-- Internal cleanup: use "strict raw types".
-- Some return types for interfaces to implement changed from `Future<dynamic>`
- to `Future<void>`.
-
-## 1.1.3
-
-- Update the minimum sdk constraint to 2.1.0.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-
-## 1.1.2
-
-- Internal fixes: Remove default value for optional argument.
-
-## 1.1.1
-
-- Requires analyzer version `0.35.0`
- - `Resolver` implementations in other packages are now backed by an
- `AnalysisDriver`. There are behavior changes which may be breaking. The
- `LibraryElement` instances returned by the resolver will now:
- - Have non-working `context` fields.
- - Have no source offsets for annotations or their errors.
- - Have working `session` fields.
- - Have `Source` instances with different URIs than before.
-
-## 1.1.0
-
-- Add `Resolver.assetIdForElement` API. This allows finding the Dart source
- asset which contains the definition of an element found through the analyzer.
-- Include the AssetId hash code in the default digest implementation.
- - Any custom implementations of the `AssetReader.digest` method should do the
- same, and a comment has been added to that effect.
-
-## 1.0.2
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 1.0.1
-
-- Increased the upper bound for `package:analyzer` to `<0.34.0`.
-
-## 1.0.0
-
-### Breaking Changes
-
-- Changed the return type of `Builder.build` from `Future<dynamic>` to
- `FutureOr<void>`. This should not be breaking for most `Builder` authors, it
- is only breaking for build system implementations that run `Builder`s.
-
-## 0.12.8
-
-- Added the `T trackStage<T>(String label, T Function() action);` method to
- `BuildStep`. Actions that are tracked in this way will show up in the
- performance timeline at `/$perf`.
-
-## 0.12.7+4
-
-- `print` calls inside a Builder will now log at warning instead of info.
-
-## 0.12.7+3
-
-- Throw when attempting to use a `BuildStep` after it has been completed.
-
-## 0.12.7+2
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.12.7+1
-
-- `AssetId`s can no longer be constructed with paths that reach outside their
- package.
-
-## 0.12.7
-
-- Added `Resolvers.reset` method.
-
-## 0.12.6
-
-- Added `List<String> get pathSegments` to `AssetId`.
-- `log` will now always return a `Logger` instance.
-- Support `package:analyzer` `0.32.0`.
-
-## 0.12.5
-
-- Add exclude support to `FileDeletingBuilder`.
-
-## 0.12.4
-
-- Add `FileDeletingBuilder`.
-- Add `PostProcesBuilderFactory` typedef.
-
-## 0.12.3
-
-- Added an `isRoot` boolean to `BuilderOptions`, which allows builders to have
- different behavior for the root package, if desired.
-- Add `PostProcessBuilder`. This is only supported by `build_runner`.
-
-## 0.12.2
-
-- Include stack trace in log for exceptions throw by builders.
-
-## 0.12.1
-
-- Add `BuilderOptions.empty` and `BuilderOptions.overrideWith`.
-
-## 0.12.0+2
-
-- **Bug Fix** Correctly handle encoding `AssetId`s as `URI`s when they contain
- characters which are not valid for a path segment.
-
-## 0.12.0+1
-
-- Support the latest `analyzer` package.
-
-## 0.12.0
-
-### Breaking Changes
-
-- Added the `Future<Digest> digest(AssetId id)` method to the `AssetReader`
- interface. There is a default implementation which uses `readAsBytes` and
- `md5`.
-
-## 0.11.2
-
-- Bug Fix: `MultiplexingBuilder` now filters inputs rather than calling _every_
- builder on any input that matched _any_ builder.
-
-## 0.11.1
-
-- Add `BuilderOptions` and `BuilderFactory` interfaces. Along with
- `package:build_config` this will offer a consistent way to describe and create
- the Builder instances exposed by a package.
-
-## 0.11.0
-
-- **Breaking**: `AssetReader.findAssets` now returns a `Stream<AssetId>`
- instead of an `Iterable<AssetId>`. This also impacts `BuildStep` since that
- implements `AssetReader`.
-
-## 0.10.2+1
-
-- Fix an issue where multiple `ResourceManager`s would share `Resource`
- instances if running at the same time.
-
-## 0.10.2
-
-- Added the `MultiPackageAssetReader` interface which allows globbing within
- any package.
- - This is not exposed to typical users, only build system implementations
- need it. The `BuildStep` class does not implement this interface.
-- The docs for `AssetReader#findAssets` have changed such that it globs within
- the current package instead of the root package (typically defined as
- `buildStep.inputId.package`).
- - Before you could run builders only on the root package, but now that you
- can run them on any package the old functionality no longer makes sense.
-
-## 0.10.1
-
-- Remove restrictions around the root package when Builders are running. It is
- the responsibility of the build system to ensure that builders are only run on
- inputs that will produce outputs that can be written.
-- Added the `Resource` class, and `BuildStep#fetchResource` method.
-
-## 0.10.0+1
-
-- Bug Fix: Capture asynchronous errors during asset writing.
-
-## 0.10.0
-
-- **Breaking**: Removed deprecated method `BuildStep.hasInput` - all uses should
- be going through `BuildStep.canRead`.
-- **Breaking**: `Resolver` has asynchronous APIs for resolution and is retrieved
- synchronously from the `BuildStep`.
-- **Breaking**: Replaced `Resolver.getLibrary` with `libraryFor` and
- `getLibraryByName` with `findLibraryByName`.
-- Change `AssetReader.canRead` to always return a Future.
-
-## 0.9.3
-
-- Add support for resolving `asset:` URIs into AssetIds
-- Add `uri` property on AssetId
-
-## 0.9.1
-
-- Skip Builders which would produce no outputs.
-
-## 0.9.0
-
-- Deprecate `BuildStep.hasInput` in favor of `BuildStep.canRead`.
-- Rename `AssetReader.hasInput` as `canRead`. This is breaking for implementers
- of `AssetReader` and for any clients passing a `BuildStep` as an `AssetReader`
-- Make `canRead` return a `FutureOr` for more flexibility
-- Drop `ManagedBuildStep` class.
-- Drop `BuildStep.logger`. All logging should go through the top level `log`.
-- `BuildStep.writeAs*` methods now take a `FutureOr` for content. Builders which
- produce content asynchronously can now set up the write without waiting for it
- to resolve.
-- **Breaking** `declareOutputs` is replaced with `buildExtensions`. All `Builder`
- implementations must now have outputs that vary only based on the extensions
- of inputs, rather than based on any part of the `AssetId`.
-
-## 0.8.0
-
-- Add `AssetReader.findAssets` to allow listing assets by glob.
-
-## 0.7.3
-
-- Add `BuildStep.inputLibrary` as a convenience.
-- Fix a bug in `AssetId.resolve` to prepend `lib/` when resolving packages.
-
-## 0.7.2
-
-- Add an `AssetId.resolve` constructor to easily construct AssetIds from import
- uris.
-- Capture 'print' calls inside running builds and automatically turn them in to
- `log.info`. Depending on the environment a print can be hazardous so this
- makes all builders safe and consistent by default.
-
-## 0.7.1+1
-
-- Use comment syntax for generic method - not everyone is on an SDK version that
- supports the real syntax.
-
-## 0.7.1
-
-- Add a top-level `log` getter which is scoped to running builds and can be used
- anywhere within a build rather than passing around a logger. This replaces the
- `BuildStep.logger` field.
-- Deprecate `BuildStep.logger` - it is replaced by `log`
-- Deprecate `ManagedBuildStep`, all build runs should go through `runBuilders`.
-
-## 0.7.0
-
-A number of changes to the apis, primarily to support reading/writing as bytes,
-as this is going to inevitably be a required feature. This will hopefully be the
-last breaking change before the `1.0` release, but it is a fairly large one.
-
-### New Features
-
-- The `AssetWriter` class now has a
- `Future writeAsBytes(AssetId id, List<int> bytes)` method.
-- The `AssetReader` class now has a `Future<List<int>> readAsBytes(AssetId id)`
- method.
-- You no longer need to call `Resolver#release` on any resolvers you get from
- a `BuildStep` (in fact, the `Resolver` interface no longer has this method).
-- There is now a `BuildStep#resolver` getter, which resolves the primary input,
- and returns a `Future<Resolver>`. This replaces the `BuildStep#resolve`
- method.
-- `Resolver` has a new `isLibrary` method to check whether an asset is a Dart
- library source file before trying to resolve it's LibraryElement
-
-### Breaking Changes
-
-- The `Asset` class has been removed entirely.
-- The `AssetWriter#writeAsString` signature has changed to
- `Future writeAsString(AssetId id, String contents, {Encoding encoding})`.
-- The type of the `AssetWriterSpy#assetsWritten` getter has changed from an
- `Iterable<Asset>` to an `Iterable<AssetId>`.
-- `BuildStep#input` has been changed to `BuildStep#inputId`, and its type has
- changed from `Asset` to `AssetId`. This means you must now use
- `BuildStep#readAsString` or `BuildStep#readAsBytes` to read the primary input,
- instead of it already being read in for you.
-- `Resolver` no longer has a `release` method (they are released for you).
-- `BuildStep#resolve` no longer exists, and has been replaced with the
- `BuildStep#resolver` getter.
-- `Resolver.getLibrary` will now throw a `NonLibraryAssetException` instead of
- return null if it is asked to resolve an impossible library.
-
-**Note**: The changes to `AssetReader` and `AssetWriter` also affect `BuildStep`
-and other classes that implement those interfaces.
-
-## 0.6.3
-
-- Add hook for `build_barback` to write assets from a Future
-
-## 0.6.2
-
-- Remove unused dependencies
-
-## 0.6.1
-
-- `BuildStep` now implements `AssetReader` and `AssetWriter` so it's easier to
- share with other code paths using a more limited interface.
-
-## 0.6.0
-
-- **BREAKING** Move some classes and methods out of this package. If you are
- using `build`, `watch`, or `serve`, along with `PhaseGroup` and related
- classes add a dependency on `build_runner`. If you are using
- `BuilderTransformer` or `TansformerBuilder` add a dependency on
- `build_barback`.
-- **BREAKING** Resolvers is now an abstract class. If you were using the
- constructor `const Resolvers()` as a default instance import `build_barback`
- and used `const BarbackResolvers()` instead.
-
-## 0.5.0
-
-- **BREAKING** BuilderTransformer must be constructed with a single Builder. Use
- the MultiplexingBuilder to cover cases with a list of builders
-- When using a MultiplexingBuilder if multiple Builders have overlapping outputs
- the entire step will not run rather than running builders up to the point
- where there is an overlap
-
-## 0.4.1+3
-
-- With the default logger, print exceptions with a terse stack trace.
-- Provide a better error when an inputSet package cannot be found.
-- Fix `dev_dependencies` so tests run.
-
-## 0.4.1+2
-
-- Stop using removed argument `useSharedSources` when constructing Resolvers
-- Support code_transformers 0.5.x
-
-## 0.4.1+1
-
-- Support analyzer 0.29.x
-
-## 0.4.1
-
-- Support analyzer 0.28.x
-
-## 0.4.0
-
-- **BREAKING** BuilderTransformer must be constructed with a List<Builder>
- rather than inherit and override.
-- Simplifies Resolver interface so it is possible to add implementations which
- are less complex than the one from code_transformers.
-- Adds a Resolvers class and support for overriding the concrete Resolver that
- is used by build steps.
-- Updates some test expectations to match the new behavior of analyzer.
-
-## 0.3.0+6
-
-- Convert `packages` paths in the file watcher to their absolute paths. This
- fixes [#109](https://github.com/dart-lang/build/issues/109).
-
-## 0.3.0+5
-
-- Fix duplicate logs issue when running as a BuilderTransformer.
-
-- Support `crypto` 2.0.0.
-
-## 0.3.0+4
-
-- Add error and stack trace to log messages from the BuilderTransformer.
-
-## 0.3.0+3
-
-- Fixed BuilderTransformer so that logs are passed on to the TransformLogger.
-
-## 0.3.0+2
-
-- Enable serving files outside the server root by default (enables serving
- files from other packages).
-
-## 0.3.0+1
-
-- Fix an AssetGraph bug where generated nodes might be created as non-generated
- nodes if they are attempted to be read from previous build steps.
-
-## 0.3.0
-
-- **BREAKING** Renamed values of three enums to be lower-case:
- `BuildType`, `BuildStatus`, and `PackageDependencyType`.
-- Updated to crypto ^1.0.0.
-- Added option to resolve additional entry points in `buildStep.resolve`.
-- Added option to pass in a custom `Resolvers` instance.
-
-## 0.2.1
-
-- Added the `deleteFilesByDefault` option to all top level methods. This will
- skip the prompt to delete files, and instead act as if you responded `y`.
- - Also by default in a non-console environment the prompt no longer exists and
- it will instead just exit with an error.
-- Added support for multiple build scripts. Each script now has its own asset
- graph based on a hash of the script uri.
- - You need to be careful here, as you can get in an infinite loop if two
- separate build scripts keep triggering updates for each other.
- - There is no explicit link between multiple scripts, so they operate as if
- all changes from other scripts were user edits. This will usually just do
- the "right thing", but may result in undesired behavior in some
- circumstances.
-- Improved logging for non-posix consoles.
-
-## 0.2.0
-
-- Updated the top level classes to take a `PhaseGroup` instead of a
- `List<List<Phase>>`.
-- Added logic to handle nested package directories.
-- Basic windows support added, although it may still be unstable.
-- Significantly increased the resolving speed by using the same sources cache.
-- Added a basic README.
-- Moved the `.build` folder to `.dart_tool/build`. Other packages in the future
- may also use this folder.
-
-## 0.1.4
-
-- Added top level `serve` function.
- - Just like `watch`, but it provides a server which blocks on any ongoing
- builds before responding to requests.
-- Minor bug fixes.
-
-## 0.1.3
-
-- Builds are now fully incremental, even on startup.
- - Builds will be invalidated if the build script or any of its dependencies
- are updated since there is no way of knowing how that would affect things.
-- Added `lastModified` to `AssetReader` (only matters if you implement it).
-
-## 0.1.2
-
-- Exposed the top level `watch` function. This can be used to watch the file
- system and run incremental rebuilds on changes.
- - Initial build is still non-incremental.
-
-## 0.1.1
-
-- Exposed the top level `build` function. This can be used to run builds.
- - For this release all builds are non-incremental, and delete all previous
- build outputs when they start up.
- - Creates a `.build` directory which should be added to your `.gitignore`.
-- Added `resolve` method to `BuildStep` which can give you a `Resolver` for an
- `AssetId`.
- - This is experimental and may get moved out to a separate package.
- - Resolves the full dart sdk so this is slow, first call will take multiple
- seconds. Subsequent calls are much faster though.
- - Will end up marking all transitive deps as dependencies, so your files may
- end up being recompiled often when not entirely necessary (once we have
- incremental builds).
-- Added `listAssetIds` to `AssetReader` (only matters if you implement it).
-- Added `delete` to `AssetWriter` (also only matters if you implement it).
-
-## 0.1.0
-
-- Initial version
diff --git a/build/LICENSE b/build/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/build/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build/README.md b/build/README.md
deleted file mode 100644
index 48c3545..0000000
--- a/build/README.md
+++ /dev/null
@@ -1,157 +0,0 @@
-# [![Build Status](https://travis-ci.org/dart-lang/build.svg?branch=master)](https://travis-ci.org/dart-lang/build)
-
-# `build`
-
-Defines the basic pieces of how a build happens and how they interact.
-
-## [`Builder`][dartdoc:Builder]
-
-The business logic for code generation. Most consumers of the `build` package
-will create custom implementations of `Builder`.
-
-## [`BuildStep`][dartdoc:BuildStep]
-
-The way a `Builder` interacts with the outside world. Defines the unit of work
-and allows reading/writing files and resolving Dart source code.
-
-## [`Resolver`][dartdoc:Resolver] class
-
-An interface into the dart [analyzer][pub:analyzer] to allow resolution of code
-that needs static analysis and/or code generation.
-
-## Implementing your own Builders
-
-A `Builder` gets invoked one by one on it's inputs, and may read other files and
-output new files based on those inputs.
-
-The basic API looks like this:
-
-```dart
-abstract class Builder {
- /// You can only output files that are configured here by suffix substitution.
- /// You are not required to output all of these files, but no other builder
- /// may declare the same outputs.
- Map<String, List<String>> get buildExtensions;
-
- /// This is where you build and output files.
- FutureOr<void> build(BuildStep buildStep);
-}
-```
-
-Here is an implementation of a `Builder` which just copies files to other files
-with the same name, but an additional extension:
-
-```dart
-import 'package:build/build.dart';
-
-/// A really simple [Builder], it just makes copies of .txt files!
-class CopyBuilder implements Builder {
- @override
- final buildExtensions = const {
- '.txt': ['.txt.copy']
- };
-
- @override
- Future<void> build(BuildStep buildStep) async {
- // Each `buildStep` has a single input.
- var inputId = buildStep.inputId;
-
- // Create a new target `AssetId` based on the old one.
- var copy = inputId.addExtension('.copy');
- var contents = await buildStep.readAsString(inputId);
-
- // Write out the new asset.
- await buildStep.writeAsString(copy, contents);
- }
-}
-```
-
-It should be noted that you should _never_ touch the file system directly. Go
-through the `buildStep#readAsString` and `buildStep#writeAsString` methods in
-order to read and write assets. This is what enables the package to track all of
-your dependencies and do incremental rebuilds. It is also what enables your
-[`Builder`][dartdoc:Builder] to run on different environments.
-
-### Using the analyzer
-
-If you need to do analyzer resolution, you can use the `BuildStep#resolver`
-object. This makes sure that all `Builder`s in the system share the same
-analysis context, which greatly speeds up the overall system when multiple
-`Builder`s are doing resolution.
-
-Here is an example of a `Builder` which uses the `resolve` method:
-
-```dart
-import 'package:build/build.dart';
-
-class ResolvingCopyBuilder implements Builder {
- // Take a `.dart` file as input so that the Resolver has code to resolve
- @override
- final buildExtensions = const {
- '.dart': ['.dart.copy']
- };
-
- @override
- Future<void> build(BuildStep buildStep) async {
- // Get the `LibraryElement` for the primary input.
- var entryLib = await buildStep.inputLibrary;
- // Resolves all libraries reachable from the primary input.
- var resolver = buildStep.resolver;
- // Get a `LibraryElement` for another asset.
- var libFromAsset = await resolver.libraryFor(
- AssetId.resolve('some_import.dart', from: buildStep.inputId));
- // Or get a `LibraryElement` by name.
- var libByName = await resolver.findLibraryByName('my.library');
- }
-}
-```
-
-Once you have gotten a `LibraryElement` using one of the methods on `Resolver`,
-you are now just using the regular `analyzer` package to explore your app.
-
-### Sharing expensive objects across build steps
-
-The build package includes a `Resource` class, which can give you an instance
-of an expensive object that is guaranteed to be unique across builds, but may
-be re-used by multiple build steps within a single build (to the extent that
-the implementation allows). It also gives you a way of disposing of your
-resource at the end of its lifecycle.
-
-The `Resource<T>` constructor takes a single required argument which is a
-factory function that returns a `FutureOr<T>`. There is also a named argument
-`dispose` which is called at the end of life for the resource, with the
-instance that should be disposed. This returns a `FutureOr<dynamic>`.
-
-So a simple example `Resource` would look like this:
-
-```dart
-final resource = Resource(
- () => createMyExpensiveResource(),
- dispose: (instance) async {
- await instance.doSomeCleanup();
- });
-```
-
-You can get an instance of the underlying resource by using the
-`BuildStep#fetchResource` method, whose type signature looks like
-`Future<T> fetchResource<T>(Resource<T>)`.
-
-**Important Note**: It may be tempting to try and use a `Resource` instance to
-cache information from previous build steps (or even assets), but this should
-be avoided because it can break the soundness of the build, and may introduce
-subtle bugs for incremental builds (remember the whole build doesn't run every
-time!). The `build` package relies on the `BuildStep#canRead` and
-`BuildStep#readAs*` methods to track build step dependencies, so sidestepping
-those can and will break the dependency tracking, resulting in inconsistent and
-stale assets.
-
-## Features and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/build/issues
-
-[dartdoc:Builder]: https://pub.dev/documentation/build/latest/build/Builder-class.html
-[dartdoc:BuildStep]: https://pub.dev/documentation/build/latest/build/BuildStep-class.html
-[dartdoc:Resolver]: https://pub.dev/documentation/build/latest/build/Resolver-class.html
-[pub:analyzer]: https://pub.dev/packages/analyzer
diff --git a/build/lib/build.dart b/build/lib/build.dart
deleted file mode 100644
index b5f3574..0000000
--- a/build/lib/build.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/analyzer/resolver.dart';
-export 'src/asset/exceptions.dart';
-export 'src/asset/id.dart';
-export 'src/asset/reader.dart';
-export 'src/asset/writer.dart';
-export 'src/builder/build_step.dart' hide NoOpStageTracker;
-export 'src/builder/builder.dart';
-export 'src/builder/exceptions.dart';
-export 'src/builder/file_deleting_builder.dart' show FileDeletingBuilder;
-export 'src/builder/logging.dart' show log;
-export 'src/builder/multiplexing_builder.dart';
-export 'src/builder/post_process_build_step.dart' show PostProcessBuildStep;
-export 'src/builder/post_process_builder.dart'
- show PostProcessBuilder, PostProcessBuilderFactory;
-export 'src/generate/expected_outputs.dart';
-export 'src/generate/run_builder.dart';
-export 'src/generate/run_post_process_builder.dart' show runPostProcessBuilder;
-export 'src/resource/resource.dart';
diff --git a/build/lib/src/analyzer/resolver.dart b/build/lib/src/analyzer/resolver.dart
deleted file mode 100644
index be73cfc..0000000
--- a/build/lib/src/analyzer/resolver.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2016, 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 'package:analyzer/dart/element/element.dart';
-
-import '../asset/id.dart';
-import '../builder/build_step.dart';
-
-/// Standard interface for resolving Dart source code as part of a build.
-abstract class Resolver {
- /// Returns whether [assetId] represents an Dart library file.
- ///
- /// This will be `false` in the case where the file is not Dart source code,
- /// or is a `part of` file (not a standalone Dart library).
- Future<bool> isLibrary(AssetId assetId);
-
- /// All libraries recursively accessible from the entry point or subsequent
- /// calls to [libraryFor] and [isLibrary].
- ///
- /// **NOTE**: This includes all Dart SDK libraries as well.
- Stream<LibraryElement> get libraries;
-
- /// Returns a resolved library representing the file defined in [assetId].
- ///
- /// * Throws [NonLibraryAssetException] if [assetId] is not a Dart library.
- Future<LibraryElement> libraryFor(AssetId assetId);
-
- /// Returns the first resolved library identified by [libraryName].
- ///
- /// A library is resolved if it's recursively accessible from the entry point
- /// or subsequent calls to [libraryFor] and [isLibrary]. If no library can be
- /// found, returns `null`.
- ///
- /// **NOTE**: In general, its recommended to use [libraryFor] with an absolute
- /// asset id instead of a named identifier that has the possibility of not
- /// being unique.
- Future<LibraryElement> findLibraryByName(String libraryName);
-
- /// Returns the [AssetId] of the Dart library or part declaring [element].
- ///
- /// If [element] is defined in the SDK or in a summary throws
- /// `UnresolvableAssetException`, although a non-throwing return here does not
- /// guarantee that the asset is readable.
- ///
- /// The returned asset is not necessarily the asset that should be imported to
- /// use the element, it may be a part file instead of the library.
- Future<AssetId> assetIdForElement(Element element);
-}
-
-/// A resolver that should be manually released at the end of a build step.
-abstract class ReleasableResolver implements Resolver {
- /// Release this resolver so it can be updated by following build steps.
- void release();
-}
-
-/// A factory that returns a resolver for a given [BuildStep].
-abstract class Resolvers {
- const Resolvers();
-
- Future<ReleasableResolver> get(BuildStep buildStep);
-
- /// Reset the state of any caches within [Resolver] instances produced by
- /// this [Resolvers].
- ///
- /// In between calls to [reset] no Assets should change, so every call to
- /// `BuildStep.readAsString` for a given AssetId should return identical
- /// contents. Any time an Asset's contents may change [reset] must be called.
- void reset() {}
-}
-
-/// Thrown when attempting to read a non-Dart library in a [Resolver].
-class NonLibraryAssetException implements Exception {
- final AssetId assetId;
-
- const NonLibraryAssetException(this.assetId);
-
- @override
- String toString() => 'Asset [$assetId] is not a Dart library. '
- 'It may be a part file or a file without Dart source code.';
-}
diff --git a/build/lib/src/asset/exceptions.dart b/build/lib/src/asset/exceptions.dart
deleted file mode 100644
index 141c071..0000000
--- a/build/lib/src/asset/exceptions.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2016, 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 'id.dart';
-
-class AssetNotFoundException implements Exception {
- final AssetId assetId;
-
- AssetNotFoundException(this.assetId);
-
- @override
- String toString() => 'AssetNotFoundException: $assetId';
-}
-
-class PackageNotFoundException implements Exception {
- final String name;
-
- PackageNotFoundException(this.name);
-
- @override
- String toString() => 'PackageNotFoundException: $name';
-}
-
-class InvalidOutputException implements Exception {
- final AssetId assetId;
- final String message;
-
- InvalidOutputException(this.assetId, this.message);
-
- @override
- String toString() => 'InvalidOutputException: $assetId\n$message';
-}
-
-class InvalidInputException implements Exception {
- final AssetId assetId;
-
- InvalidInputException(this.assetId);
-
- @override
- String toString() => 'InvalidInputException: $assetId\n'
- 'For package dependencies, only files under `lib` may be used as inputs.';
-}
-
-class BuildStepCompletedException implements Exception {
- @override
- String toString() => 'BuildStepCompletedException: '
- 'Attempt to use a BuildStep after is has completed';
-}
-
-class UnresolvableAssetException implements Exception {
- final String description;
-
- const UnresolvableAssetException(this.description);
-
- @override
- String toString() => 'Unresolvable Asset from $description.';
-}
diff --git a/build/lib/src/asset/id.dart b/build/lib/src/asset/id.dart
deleted file mode 100644
index a743cf7..0000000
--- a/build/lib/src/asset/id.dart
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2016, 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:path/path.dart' as p;
-
-/// Identifies an asset within a package.
-class AssetId implements Comparable<AssetId> {
- /// The name of the package containing this asset.
- final String package;
-
- /// The path to the asset relative to the root directory of [package].
- ///
- /// Source (i.e. read from disk) and generated (i.e. the output of a
- /// `Builder`) assets all have paths. Even intermediate assets that are
- /// generated and then consumed by later transformations will still have a
- /// path used to identify it.
- ///
- /// Asset paths always use forward slashes as path separators, regardless of
- /// the host platform. Asset paths will always be within their package, that
- /// is they will never contain "../".
- final String path;
-
- /// Splits [path] into its components.
- List<String> get pathSegments => p.url.split(path);
-
- /// The file extension of the asset, if it has one, including the ".".
- String get extension => p.extension(path);
-
- /// Creates a new [AssetId] at [path] within [package].
- ///
- /// The [path] will be normalized: any backslashes will be replaced with
- /// forward slashes (regardless of host OS) and "." and ".." will be removed
- /// where possible.
- AssetId(this.package, String path) : path = _normalizePath(path);
-
- /// Creates a new [AssetId] from an [uri] String.
- ///
- /// This gracefully handles `package:` or `asset:` URIs.
- ///
- /// Resolve a `package:` URI when creating an [AssetId] from an `import` or
- /// `export` directive pointing to a package's _lib_ directory:
- /// ```dart
- /// AssetId assetOfDirective(UriReferencedElement element) {
- /// return new AssetId.resolve(element.uri);
- /// }
- /// ```
- ///
- /// When resolving a relative URI with no scheme, specifyg the origin asset
- /// ([from]) - otherwise an [ArgumentError] will be thrown.
- /// ```dart
- /// AssetId assetOfDirective(AssetId origin, UriReferencedElement element) {
- /// return new AssetId.resolve(element.uri, from: origin);
- /// }
- /// ```
- ///
- /// `asset:` uris have the format '$package/$path', including the top level
- /// directory.
- factory AssetId.resolve(String uri, {AssetId from}) {
- final parsedUri = Uri.parse(uri);
- if (parsedUri.hasScheme) {
- if (parsedUri.scheme == 'package') {
- return AssetId(parsedUri.pathSegments.first,
- p.url.join('lib', p.url.joinAll(parsedUri.pathSegments.skip(1))));
- } else if (parsedUri.scheme == 'asset') {
- return AssetId(parsedUri.pathSegments.first,
- p.url.joinAll(parsedUri.pathSegments.skip(1)));
- }
- throw UnsupportedError(
- 'Cannot resolve $uri; only "package" and "asset" schemes supported');
- }
- if (from == null) {
- throw ArgumentError.value(from, 'from',
- 'An AssetId "from" must be specified to resolve a relative URI');
- }
- return AssetId(p.url.normalize(from.package),
- p.url.join(p.url.dirname(from.path), uri));
- }
-
- /// Parses an [AssetId] string of the form "package|path/to/asset.txt".
- ///
- /// The [path] will be normalized: any backslashes will be replaced with
- /// forward slashes (regardless of host OS) and "." and ".." will be removed
- /// where possible.
- factory AssetId.parse(String description) {
- var parts = description.split('|');
- if (parts.length != 2) {
- throw FormatException('Could not parse "$description".');
- }
-
- if (parts[0].isEmpty) {
- throw FormatException(
- 'Cannot have empty package name in "$description".');
- }
-
- if (parts[1].isEmpty) {
- throw FormatException('Cannot have empty path in "$description".');
- }
-
- return AssetId(parts[0], parts[1]);
- }
-
- /// A `package:` URI suitable for use directly with other systems if this
- /// asset is under it's package's `lib/` directory, else an `asset:` URI
- /// suitable for use within build tools.
- Uri get uri => _uri ??= _constructUri(this);
- Uri _uri;
-
- /// Deserializes an [AssetId] from [data], which must be the result of
- /// calling [serialize] on an existing [AssetId].
- AssetId.deserialize(List<dynamic> data)
- : package = data[0] as String,
- path = data[1] as String;
-
- /// Returns `true` if [other] is an [AssetId] with the same package and path.
- @override
- bool operator ==(Object other) =>
- other is AssetId && package == other.package && path == other.path;
-
- @override
- int get hashCode => package.hashCode ^ path.hashCode;
-
- @override
- int compareTo(AssetId other) {
- var packageComp = package.compareTo(other.package);
- if (packageComp != 0) return packageComp;
- return path.compareTo(other.path);
- }
-
- /// Returns a new [AssetId] with the same [package] as this one and with the
- /// [path] extended to include [extension].
- AssetId addExtension(String extension) => AssetId(package, '$path$extension');
-
- /// Returns a new [AssetId] with the same [package] and [path] as this one
- /// but with file extension [newExtension].
- AssetId changeExtension(String newExtension) =>
- AssetId(package, p.withoutExtension(path) + newExtension);
-
- @override
- String toString() => '$package|$path';
-
- /// Serializes this [AssetId] to an object that can be sent across isolates
- /// and passed to [AssetId.deserialize].
- Object serialize() => [package, path];
-}
-
-String _normalizePath(String path) {
- if (p.isAbsolute(path)) {
- throw ArgumentError.value(path, 'Asset paths must be relative.');
- }
-
- // Normalize path separators so that they are always "/" in the AssetID.
- path = path.replaceAll(r'\', '/');
-
- // Collapse "." and "..".
- final collapsed = p.posix.normalize(path);
- if (collapsed.startsWith('../')) {
- throw ArgumentError.value(
- path, 'Asset paths may not reach outside the package.');
- }
- return collapsed;
-}
-
-Uri _constructUri(AssetId id) {
- final originalSegments = id.pathSegments;
- final isLib = originalSegments.first == 'lib';
- final scheme = isLib ? 'package' : 'asset';
- final pathSegments = isLib ? originalSegments.skip(1) : originalSegments;
- return Uri(scheme: scheme, pathSegments: [id.package]..addAll(pathSegments));
-}
diff --git a/build/lib/src/asset/reader.dart b/build/lib/src/asset/reader.dart
deleted file mode 100644
index fdee30b..0000000
--- a/build/lib/src/asset/reader.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:crypto/crypto.dart';
-import 'package:convert/convert.dart';
-import 'package:glob/glob.dart';
-
-import 'id.dart';
-
-/// Standard interface for reading an asset within in a package.
-///
-/// An [AssetReader] is required when calling the `runBuilder` method.
-abstract class AssetReader {
- /// Returns a [Future] that completes with the bytes of a binary asset.
- ///
- /// * Throws a `PackageNotFoundException` if `id.package` is not found.
- /// * Throws a `AssetNotFoundException` if `id.path` is not found.
- Future<List<int>> readAsBytes(AssetId id);
-
- /// Returns a [Future] that completes with the contents of a text asset.
- ///
- /// When decoding as text uses [encoding], or [utf8] is not specified.
- ///
- /// * Throws a `PackageNotFoundException` if `id.package` is not found.
- /// * Throws a `AssetNotFoundException` if `id.path` is not found.
- Future<String> readAsString(AssetId id, {Encoding encoding});
-
- /// Indicates whether asset at [id] is readable.
- Future<bool> canRead(AssetId id);
-
- /// Returns all readable assets matching [glob] under the current package.
- Stream<AssetId> findAssets(Glob glob);
-
- /// Returns a [Digest] representing a hash of the contents of [id].
- ///
- /// The digests should include the asset ID as well as the content of the
- /// file, as some build systems may rely on the digests for two files being
- /// different, even if their content is the same.
- ///
- /// This should be treated as a transparent [Digest] and the implementation
- /// may differ based on the current build system being used.
- Future<Digest> digest(AssetId id) async {
- var digestSink = AccumulatorSink<Digest>();
- md5.startChunkedConversion(digestSink)
- ..add(await readAsBytes(id))
- ..add(id.toString().codeUnits)
- ..close();
- return digestSink.events.first;
- }
-}
-
-/// The same as an `AssetReader`, except that `findAssets` takes an optional
-/// argument `package` which allows you to glob any package.
-///
-/// This should not be exposed to end users generally, but can be used by
-/// different build system implementations.
-abstract class MultiPackageAssetReader extends AssetReader {
- /// Returns all readable assets matching [glob] under [package].
- ///
- /// Some implementations may require the [package] argument, while others
- /// may have a sane default.
- @override
- Stream<AssetId> findAssets(Glob glob, {String package});
-}
diff --git a/build/lib/src/asset/writer.dart b/build/lib/src/asset/writer.dart
deleted file mode 100644
index 68ba81f..0000000
--- a/build/lib/src/asset/writer.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'id.dart';
-
-/// Standard interface for writing an asset into a package's outputs.
-abstract class AssetWriter {
- /// Writes [bytes] to a binary file located at [id].
- ///
- /// Returns a [Future] that completes after writing the asset out.
- ///
- /// * Throws a `PackageNotFoundException` if `id.package` is not found.
- /// * Throws an `InvalidOutputException` if the output was not valid.
- Future<void> writeAsBytes(AssetId id, List<int> bytes);
-
- /// Writes [contents] to a text file located at [id] with [encoding].
- ///
- /// Returns a [Future] that completes after writing the asset out.
- ///
- /// * Throws a `PackageNotFoundException` if `id.package` is not found.
- /// * Throws an `InvalidOutputException` if the output was not valid.
- Future<void> writeAsString(AssetId id, String contents,
- {Encoding encoding = utf8});
-}
-
-/// An [AssetWriter] which tracks all [assetsWritten] during its lifetime.
-class AssetWriterSpy implements AssetWriter {
- final AssetWriter _delegate;
- final _assetsWritten = Set<AssetId>();
-
- AssetWriterSpy(this._delegate);
-
- Iterable<AssetId> get assetsWritten => _assetsWritten;
-
- @override
- Future<void> writeAsBytes(AssetId id, List<int> bytes) {
- _assetsWritten.add(id);
- return _delegate.writeAsBytes(id, bytes);
- }
-
- @override
- Future<void> writeAsString(AssetId id, String contents,
- {Encoding encoding = utf8}) {
- _assetsWritten.add(id);
- return _delegate.writeAsString(id, contents, encoding: encoding);
- }
-}
diff --git a/build/lib/src/builder/build_step.dart b/build/lib/src/builder/build_step.dart
deleted file mode 100644
index fb7a159..0000000
--- a/build/lib/src/builder/build_step.dart
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-
-import 'package:analyzer/dart/element/element.dart';
-
-import '../analyzer/resolver.dart';
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../resource/resource.dart';
-
-/// A single step in a build process.
-///
-/// This represents a single [inputId], logic around resolving as a library,
-/// and the ability to read and write assets as allowed by the underlying build
-/// system.
-abstract class BuildStep implements AssetReader, AssetWriter {
- /// The primary for this build step.
- AssetId get inputId;
-
- /// Resolved library defined by [inputId].
- ///
- /// Throws [NonLibraryAssetException] if [inputId] is not a Dart library file.
- Future<LibraryElement> get inputLibrary;
-
- /// Gets an instance provided by [resource] which is guaranteed to be unique
- /// within a single build, and may be reused across build steps within a
- /// build if the implementation allows.
- ///
- /// It is also guaranteed that [resource] will be disposed before the next
- /// build starts (and the dispose callback will be invoked if provided).
- Future<T> fetchResource<T>(Resource<T> resource);
-
- /// Writes [bytes] to a binary file located at [id].
- ///
- /// Returns a [Future] that completes after writing the asset out.
- ///
- /// * Throws a `PackageNotFoundException` if `id.package` is not found.
- /// * Throws an `InvalidOutputException` if the output was not valid.
- ///
- /// **NOTE**: Most `Builder` implementations should not need to `await` this
- /// Future since the runner will be responsible for waiting until all outputs
- /// are written.
- @override
- Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes);
-
- /// Writes [contents] to a text file located at [id] with [encoding].
- ///
- /// Returns a [Future] that completes after writing the asset out.
- ///
- /// * Throws a `PackageNotFoundException` if `id.package` is not found.
- /// * Throws an `InvalidOutputException` if the output was not valid.
- ///
- /// **NOTE**: Most `Builder` implementations should not need to `await` this
- /// Future since the runner will be responsible for waiting until all outputs
- /// are written.
- @override
- Future<void> writeAsString(AssetId id, FutureOr<String> contents,
- {Encoding encoding = utf8});
-
- /// A [Resolver] for [inputId].
- Resolver get resolver;
-
- /// Tracks performance of [action] separately.
- ///
- /// If performance tracking is enabled, tracks [action] as separate stage
- /// identified by [label]. Otherwise just runs [action].
- ///
- /// You can specify [action] as [isExternal] (waiting for some external
- /// resource like network, process or file IO). In that case [action] will
- /// be tracked as single time slice from the beginning of the stage till
- /// completion of Future returned by [action].
- ///
- /// Otherwise all separate time slices of asynchronous execution will be
- /// tracked, but waiting for external resources will be a gap.
- ///
- /// Returns value returned by [action].
- /// [action] can be async function returning [Future].
- T trackStage<T>(String label, T Function() action, {bool isExternal = false});
-
- /// Indicates that [ids] were read but their content has no impact on the
- /// outputs of this step.
- ///
- /// **WARNING**: Using this introduces serious risk of non-hermetic builds.
- ///
- /// If these files change or become unreadable on the next build this build
- /// step may not run.
- ///
- /// **Note**: This is not guaranteed to have any effect and it should be
- /// assumed to be a no-op by default. Implementations must explicitly
- /// choose to support this feature.
- void reportUnusedAssets(Iterable<AssetId> ids);
-}
-
-abstract class StageTracker {
- T trackStage<T>(String label, T Function() action, {bool isExternal = false});
-}
-
-class NoOpStageTracker implements StageTracker {
- static const StageTracker instance = NoOpStageTracker._();
-
- @override
- T trackStage<T>(String label, T Function() action,
- {bool isExternal = false}) =>
- action();
-
- const NoOpStageTracker._();
-}
diff --git a/build/lib/src/builder/build_step_impl.dart b/build/lib/src/builder/build_step_impl.dart
deleted file mode 100644
index 65e0aaa..0000000
--- a/build/lib/src/builder/build_step_impl.dart
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:async/async.dart';
-import 'package:build/src/builder/build_step.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import '../analyzer/resolver.dart';
-import '../asset/exceptions.dart';
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../resource/resource.dart';
-import 'build_step.dart';
-import 'exceptions.dart';
-
-/// A single step in the build processes.
-///
-/// This represents a single input and its expected and real outputs. It also
-/// handles tracking of dependencies.
-class BuildStepImpl implements BuildStep {
- final Resolvers _resolvers;
- final StageTracker _stageTracker;
-
- /// The primary input id for this build step.
- @override
- final AssetId inputId;
-
- @override
- Future<LibraryElement> get inputLibrary async {
- if (_isComplete) throw BuildStepCompletedException();
- return resolver.libraryFor(inputId);
- }
-
- /// The list of all outputs which are expected/allowed to be output from this
- /// step.
- final Set<AssetId> _expectedOutputs;
-
- /// The result of any writes which are starting during this step.
- final _writeResults = <Future<Result<void>>>[];
-
- /// Used internally for reading files.
- final AssetReader _reader;
-
- /// Used internally for writing files.
- final AssetWriter _writer;
-
- /// The current root package, used for input/output validation.
- final String _rootPackage;
-
- final ResourceManager _resourceManager;
-
- bool _isComplete = false;
-
- final void Function(Iterable<AssetId>) _reportUnusedAssets;
-
- BuildStepImpl(this.inputId, Iterable<AssetId> expectedOutputs, this._reader,
- this._writer, this._rootPackage, this._resolvers, this._resourceManager,
- {StageTracker stageTracker,
- void Function(Iterable<AssetId>) reportUnusedAssets})
- : _expectedOutputs = expectedOutputs.toSet(),
- _stageTracker = stageTracker ?? NoOpStageTracker.instance,
- _reportUnusedAssets = reportUnusedAssets;
-
- @override
- Resolver get resolver {
- if (_isComplete) throw BuildStepCompletedException();
- return _DelayedResolver(_resolver ??= _resolvers.get(this));
- }
-
- Future<ReleasableResolver> _resolver;
-
- @override
- Future<bool> canRead(AssetId id) {
- if (_isComplete) throw BuildStepCompletedException();
- _checkInput(id);
- return _reader.canRead(id);
- }
-
- @override
- Future<T> fetchResource<T>(Resource<T> resource) {
- if (_isComplete) throw BuildStepCompletedException();
- return _resourceManager.fetch(resource);
- }
-
- @override
- Future<List<int>> readAsBytes(AssetId id) {
- if (_isComplete) throw BuildStepCompletedException();
- _checkInput(id);
- return _reader.readAsBytes(id);
- }
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) {
- if (_isComplete) throw BuildStepCompletedException();
- _checkInput(id);
- return _reader.readAsString(id, encoding: encoding);
- }
-
- @override
- Stream<AssetId> findAssets(Glob glob) {
- if (_isComplete) throw BuildStepCompletedException();
- if (_reader is MultiPackageAssetReader) {
- return (_reader as MultiPackageAssetReader)
- .findAssets(glob, package: inputId?.package ?? _rootPackage);
- } else {
- return _reader.findAssets(glob);
- }
- }
-
- @override
- Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes) {
- if (_isComplete) throw BuildStepCompletedException();
- _checkOutput(id);
- var done =
- _futureOrWrite(bytes, (List<int> b) => _writer.writeAsBytes(id, b));
- _writeResults.add(Result.capture(done));
- return done;
- }
-
- @override
- Future<void> writeAsString(AssetId id, FutureOr<String> content,
- {Encoding encoding = utf8}) {
- if (_isComplete) throw BuildStepCompletedException();
- _checkOutput(id);
- var done = _futureOrWrite(content,
- (String c) => _writer.writeAsString(id, c, encoding: encoding));
- _writeResults.add(Result.capture(done));
- return done;
- }
-
- @override
- Future<Digest> digest(AssetId id) {
- if (_isComplete) throw BuildStepCompletedException();
- _checkInput(id);
- return _reader.digest(id);
- }
-
- @override
- T trackStage<T>(String label, T Function() action,
- {bool isExternal = false}) =>
- _stageTracker.trackStage(label, action, isExternal: isExternal);
-
- Future<void> _futureOrWrite<T>(
- FutureOr<T> content, Future<void> write(T content)) =>
- (content is Future<T>) ? content.then(write) : write(content as T);
-
- /// Waits for work to finish and cleans up resources.
- ///
- /// This method should be called after a build has completed. After the
- /// returned [Future] completes then all outputs have been written and the
- /// [Resolver] for this build step - if any - has been released.
- Future<void> complete() async {
- _isComplete = true;
- await Future.wait(_writeResults.map(Result.release));
- (await _resolver)?.release();
- }
-
- /// Checks that [id] is a valid input, and throws an [InvalidInputException]
- /// if its not.
- void _checkInput(AssetId id) {
- if (id.package != _rootPackage && !id.path.startsWith('lib/')) {
- throw InvalidInputException(id);
- }
- }
-
- /// Checks that [id] is an expected output, and throws an
- /// [InvalidOutputException] or [UnexpectedOutputException] if it's not.
- void _checkOutput(AssetId id) {
- if (!_expectedOutputs.contains(id)) {
- throw UnexpectedOutputException(id, expected: _expectedOutputs);
- }
- }
-
- @override
- void reportUnusedAssets(Iterable<AssetId> assets) {
- if (_reportUnusedAssets != null) _reportUnusedAssets(assets);
- }
-}
-
-class _DelayedResolver implements Resolver {
- final Future<Resolver> _delegate;
-
- _DelayedResolver(this._delegate);
-
- @override
- Future<bool> isLibrary(AssetId assetId) async =>
- (await _delegate).isLibrary(assetId);
-
- @override
- Stream<LibraryElement> get libraries {
- var completer = StreamCompleter<LibraryElement>();
- _delegate.then((r) => completer.setSourceStream(r.libraries));
- return completer.stream;
- }
-
- @override
- Future<LibraryElement> libraryFor(AssetId assetId) async =>
- (await _delegate).libraryFor(assetId);
-
- @override
- Future<LibraryElement> findLibraryByName(String libraryName) async =>
- (await _delegate).findLibraryByName(libraryName);
-
- @override
- Future<AssetId> assetIdForElement(Element element) async =>
- (await _delegate).assetIdForElement(element);
-}
diff --git a/build/lib/src/builder/builder.dart b/build/lib/src/builder/builder.dart
deleted file mode 100644
index 1c97f40..0000000
--- a/build/lib/src/builder/builder.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2017, 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_step.dart';
-
-/// The basic builder class, used to build new files from existing ones.
-abstract class Builder {
- /// Generates the outputs for a given [BuildStep].
- FutureOr<void> build(BuildStep buildStep);
-
- /// Mapping from input file extension to output file extensions.
- ///
- /// All input sources matching any key in this map will be passed as build
- /// step to this builder. Only files with the same basename and an extension
- /// from the values in this map are expected as outputs.
- ///
- /// - If an empty key exists, all inputs are considered matching.
- /// - A builder must always return the same configuration. Typically this will
- /// be `const` but may vary based on build arguments.
- /// - Most builders will use a single input extension and one or more output
- /// extensions.
- Map<String, List<String>> get buildExtensions;
-}
-
-class BuilderOptions {
- /// A configuration with no options set.
- static const empty = BuilderOptions({});
-
- /// A configuration with [isRoot] set to `true`, and no options set.
- static const forRoot = BuilderOptions({}, isRoot: true);
-
- /// The configuration to apply to a given usage of a [Builder].
- ///
- /// A `Map` parsed from json or yaml. The value types will be `String`, `num`,
- /// `bool` or `List` or `Map` of these types.
- final Map<String, dynamic> config;
-
- /// Whether or not this builder is running on the root package.
- final bool isRoot;
-
- const BuilderOptions(this.config, {bool isRoot}) : isRoot = isRoot ?? false;
-
- /// Returns a new set of options with keys from [other] overriding options in
- /// this instance.
- ///
- /// Config values are overridden at a per-key granularity. There is no value
- /// level merging. [other] may be null, in which case this instance is
- /// returned directly.
- ///
- /// The `isRoot` value will also be overridden to value from [other].
- BuilderOptions overrideWith(BuilderOptions other) {
- if (other == null) return this;
- return BuilderOptions({}..addAll(config)..addAll(other.config),
- isRoot: other.isRoot);
- }
-}
-
-/// Creates a [Builder] honoring the configuation in [options].
-typedef BuilderFactory = Builder Function(BuilderOptions options);
diff --git a/build/lib/src/builder/exceptions.dart b/build/lib/src/builder/exceptions.dart
deleted file mode 100644
index 8458b05..0000000
--- a/build/lib/src/builder/exceptions.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, 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 '../asset/id.dart';
-
-class UnexpectedOutputException implements Exception {
- final AssetId assetId;
- final Iterable<AssetId> expected;
-
- UnexpectedOutputException(this.assetId, {this.expected});
-
- @override
- String toString() => 'UnexpectedOutputException: $assetId'
- '${expected == null ? '' : '\nExpected only: $expected'}';
-}
diff --git a/build/lib/src/builder/file_deleting_builder.dart b/build/lib/src/builder/file_deleting_builder.dart
deleted file mode 100644
index 4621039..0000000
--- a/build/lib/src/builder/file_deleting_builder.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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 'package:glob/glob.dart';
-
-import 'post_process_build_step.dart';
-import 'post_process_builder.dart';
-
-/// A [PostProcessBuilder] which can be configured to consume any input
-/// extensions and always deletes it primary input.
-class FileDeletingBuilder implements PostProcessBuilder {
- @override
- final List<String> inputExtensions;
-
- final bool isEnabled;
- final List<Glob> exclude;
-
- const FileDeletingBuilder(this.inputExtensions, {this.isEnabled = true})
- : exclude = const [];
-
- FileDeletingBuilder.withExcludes(
- this.inputExtensions, Iterable<String> exclude,
- {this.isEnabled = true})
- : exclude = exclude?.map((s) => Glob(s))?.toList() ?? const [];
-
- @override
- FutureOr<Null> build(PostProcessBuildStep buildStep) {
- if (!isEnabled) return null;
- if (exclude.any((g) => g.matches(buildStep.inputId.path))) return null;
- buildStep.deletePrimaryInput();
- return null;
- }
-}
diff --git a/build/lib/src/builder/logging.dart b/build/lib/src/builder/logging.dart
deleted file mode 100644
index a00e67e..0000000
--- a/build/lib/src/builder/logging.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'dart:async';
-
-import 'package:logging/logging.dart';
-
-const Symbol logKey = #buildLog;
-
-final _default = Logger('build.fallback');
-
-/// The log instance for the currently running BuildStep.
-///
-/// Will be `null` when not running within a build.
-Logger get log => Zone.current[logKey] as Logger ?? _default;
-
-/// Runs [fn] in an error handling [Zone].
-///
-/// Any calls to [print] will be logged with `log.warning`, and any errors will
-/// be logged with `log.severe`.
-///
-/// Completes with the first error or result of `fn`, whichever comes first.
-Future<T> scopeLogAsync<T>(Future<T> fn(), Logger log) {
- var done = Completer<T>();
- runZoned(fn,
- zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- log.warning(message);
- }),
- zoneValues: {logKey: log},
- onError: (Object e, StackTrace s) {
- log.severe('', e, s);
- if (done.isCompleted) return;
- done.completeError(e, s);
- }).then((result) {
- if (done.isCompleted) return;
- done.complete(result);
- });
- return done.future;
-}
diff --git a/build/lib/src/builder/multiplexing_builder.dart b/build/lib/src/builder/multiplexing_builder.dart
deleted file mode 100644
index e91ee15..0000000
--- a/build/lib/src/builder/multiplexing_builder.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2017, 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_step.dart';
-import 'builder.dart';
-
-/// A [Builder] that runs multiple delegate builders asynchronously.
-///
-/// **Note**: All builders are ran without ordering guarantees. Thus, none of
-/// the builders can use the outputs of other builders in this group. All
-/// builders must also have distinct outputs.
-class MultiplexingBuilder implements Builder {
- final Iterable<Builder> _builders;
-
- MultiplexingBuilder(this._builders);
-
- @override
- FutureOr<void> build(BuildStep buildStep) {
- return Future.wait(_builders
- .where((builder) =>
- builder.buildExtensions.keys.any(buildStep.inputId.path.endsWith))
- .map((builder) => builder.build(buildStep))
- .whereType<Future<void>>());
- }
-
- /// Merges output extensions from all builders.
- ///
- /// If multiple builders declare the same output it will appear in this List
- /// more than once. This should be considered an error.
- @override
- Map<String, List<String>> get buildExtensions =>
- _mergeMaps(_builders.map((b) => b.buildExtensions));
-
- @override
- String toString() => '$_builders';
-}
-
-Map<String, List<String>> _mergeMaps(Iterable<Map<String, List<String>>> maps) {
- var result = <String, List<String>>{};
- for (var map in maps) {
- for (var key in map.keys) {
- result.putIfAbsent(key, () => []);
- result[key].addAll(map[key]);
- }
- }
- return result;
-}
diff --git a/build/lib/src/builder/post_process_build_step.dart b/build/lib/src/builder/post_process_build_step.dart
deleted file mode 100644
index 5fef55f..0000000
--- a/build/lib/src/builder/post_process_build_step.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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:convert';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:crypto/src/digest.dart';
-
-// This is not exported to hack around a package-private constructor.
-PostProcessBuildStep postProcessBuildStep(
- AssetId inputId,
- AssetReader reader,
- AssetWriter writer,
- void Function(AssetId) addAsset,
- void Function(AssetId) deleteAsset) =>
- PostProcessBuildStep._(inputId, reader, writer, addAsset, deleteAsset);
-
-/// A simplified [BuildStep] which can only read its primary input, and can't
-/// get a [Resolver] or any [Resource]s, at least for now.
-class PostProcessBuildStep {
- final AssetId inputId;
-
- final AssetReader _reader;
- final AssetWriter _writer;
- final void Function(AssetId) _addAsset;
- final void Function(AssetId) _deleteAsset;
-
- /// The result of any writes which are starting during this step.
- final _writeResults = <Future<Result<void>>>[];
-
- PostProcessBuildStep._(this.inputId, this._reader, this._writer,
- this._addAsset, this._deleteAsset);
-
- Future<Digest> digest(AssetId id) => inputId == id
- ? _reader.digest(id)
- : Future.error(InvalidInputException(id));
-
- Future<List<int>> readInputAsBytes() => _reader.readAsBytes(inputId);
-
- Future<String> readInputAsString({Encoding encoding = utf8}) =>
- _reader.readAsString(inputId, encoding: encoding);
-
- Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes) {
- _addAsset(id);
- var done =
- _futureOrWrite(bytes, (List<int> b) => _writer.writeAsBytes(id, b));
- _writeResults.add(Result.capture(done));
- return done;
- }
-
- Future<void> writeAsString(AssetId id, FutureOr<String> content,
- {Encoding encoding = utf8}) {
- _addAsset(id);
- var done = _futureOrWrite(content,
- (String c) => _writer.writeAsString(id, c, encoding: encoding));
- _writeResults.add(Result.capture(done));
- return done;
- }
-
- /// Marks an asset for deletion in the post process step.
- void deletePrimaryInput() {
- _deleteAsset(inputId);
- }
-
- /// Waits for work to finish and cleans up resources.
- ///
- /// This method should be called after a build has completed. After the
- /// returned [Future] completes then all outputs have been written.
- Future<void> complete() async {
- await Future.wait(_writeResults.map(Result.release));
- }
-}
-
-Future<void> _futureOrWrite<T>(
- FutureOr<T> content, Future<void> write(T content)) =>
- (content is Future<T>) ? content.then(write) : write(content as T);
diff --git a/build/lib/src/builder/post_process_builder.dart b/build/lib/src/builder/post_process_builder.dart
deleted file mode 100644
index 074f1d1..0000000
--- a/build/lib/src/builder/post_process_builder.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 'builder.dart';
-import 'post_process_build_step.dart';
-
-/// A builder which runes in a special phase at the end of the build.
-///
-/// They are different from a normal [Builder] in several ways:
-///
-/// - They don't have to declare output extensions, and can output any file as
-/// long as it doesn't conflict with an existing one.
-/// - They can only read their primary input.
-/// - They will not cause optional actions to run - they will only run on assets
-/// that were built as a part of the normal build.
-/// - They all run in a single phase, and thus can not see the outputs of any
-/// other [PostProcessBuilder]s.
-/// - Because they run in a separate phase, after other builders, none of thier
-/// outputs can be consumed by [Builder]s.
-///
-/// Because of these restrictions, these builders should never be used to output
-/// Dart files, or any other file which would should be processed by normal
-/// [Builder]s.
-abstract class PostProcessBuilder {
- /// The extensions this builder expects for its inputs.
- Iterable<String> get inputExtensions;
-
- /// Generates the outputs and deletes for [buildStep].
- FutureOr<void> build(PostProcessBuildStep buildStep);
-}
-
-typedef PostProcessBuilderFactory = PostProcessBuilder Function(BuilderOptions);
diff --git a/build/lib/src/generate/expected_outputs.dart b/build/lib/src/generate/expected_outputs.dart
deleted file mode 100644
index 9d3425a..0000000
--- a/build/lib/src/generate/expected_outputs.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, 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 '../asset/id.dart';
-import '../builder/builder.dart';
-
-/// Collects the expected AssetIds created by [builder] when given [input] based
-/// on the extension configuration.
-Iterable<AssetId> expectedOutputs(Builder builder, AssetId input) {
- var matchingExtensions =
- builder.buildExtensions.keys.where((e) => input.path.endsWith(e));
- return matchingExtensions
- .expand((e) => _replaceExtensions(input, e, builder.buildExtensions[e]));
-}
-
-Iterable<AssetId> _replaceExtensions(
- AssetId assetId, String oldExtension, List<String> newExtensions) =>
- newExtensions.map((n) => _replaceExtension(assetId, oldExtension, n));
-
-AssetId _replaceExtension(
- AssetId assetId, String oldExtension, String newExtension) {
- var path = assetId.path;
- assert(path.endsWith(oldExtension));
- return AssetId(
- assetId.package,
- path.replaceRange(
- path.length - oldExtension.length, path.length, newExtension));
-}
diff --git a/build/lib/src/generate/run_builder.dart b/build/lib/src/generate/run_builder.dart
deleted file mode 100644
index fbceb53..0000000
--- a/build/lib/src/generate/run_builder.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2017, 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 'package:logging/logging.dart';
-
-import '../analyzer/resolver.dart';
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../builder/build_step.dart';
-import '../builder/build_step_impl.dart';
-import '../builder/builder.dart';
-import '../builder/logging.dart';
-import '../resource/resource.dart';
-import 'expected_outputs.dart';
-
-/// Run [builder] with each asset in [inputs] as the primary input.
-///
-/// Builds for all inputs are run asynchronously and ordering is not guaranteed.
-/// The [log] instance inside the builds will be scoped to [logger] which is
-/// defaulted to a [Logger] name 'runBuilder'.
-///
-/// If a [resourceManager] is provided it will be used and it will not be
-/// automatically disposed of (its up to the caller to dispose of it later). If
-/// one is not provided then one will be created and disposed at the end of
-/// this function call.
-///
-/// If [reportUnusedAssetsForInput] is provided then all calls to
-/// `BuildStep.reportUnusedAssets` in [builder] will be forwarded to this
-/// function with the associated primary input.
-Future<void> runBuilder(Builder builder, Iterable<AssetId> inputs,
- AssetReader reader, AssetWriter writer, Resolvers resolvers,
- {Logger logger,
- ResourceManager resourceManager,
- String rootPackage,
- StageTracker stageTracker = NoOpStageTracker.instance,
- void Function(AssetId input, Iterable<AssetId> assets)
- reportUnusedAssetsForInput}) async {
- var shouldDisposeResourceManager = resourceManager == null;
- resourceManager ??= ResourceManager();
- logger ??= Logger('runBuilder');
- //TODO(nbosch) check overlapping outputs?
- Future<void> buildForInput(AssetId input) async {
- var outputs = expectedOutputs(builder, input);
- if (outputs.isEmpty) return;
- var buildStep = BuildStepImpl(input, outputs, reader, writer,
- rootPackage ?? input.package, resolvers, resourceManager,
- stageTracker: stageTracker,
- reportUnusedAssets: reportUnusedAssetsForInput == null
- ? null
- : (assets) => reportUnusedAssetsForInput(input, assets));
- try {
- await builder.build(buildStep);
- } finally {
- await buildStep.complete();
- }
- }
-
- await scopeLogAsync(() => Future.wait(inputs.map(buildForInput)), logger);
-
- if (shouldDisposeResourceManager) {
- await resourceManager.disposeAll();
- await resourceManager.beforeExit();
- }
-}
diff --git a/build/lib/src/generate/run_post_process_builder.dart b/build/lib/src/generate/run_post_process_builder.dart
deleted file mode 100644
index a4945fb..0000000
--- a/build/lib/src/generate/run_post_process_builder.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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 'package:logging/logging.dart';
-import 'package:meta/meta.dart';
-
-import '../asset/id.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../builder/logging.dart';
-import '../builder/post_process_build_step.dart';
-import '../builder/post_process_builder.dart';
-
-/// Run [builder] with [inputId] as the primary input.
-///
-/// [addAsset] should update the build systems knowledge of what assets exist.
-/// If an asset should not be written this function should throw.
-/// [deleteAsset] should remove the asset from the build system, it will not be
-/// deleted on disk since the `writer` has no mechanism for delete.
-Future<void> runPostProcessBuilder(PostProcessBuilder builder, AssetId inputId,
- AssetReader reader, AssetWriter writer, Logger logger,
- {@required void Function(AssetId) addAsset,
- @required void Function(AssetId) deleteAsset}) async {
- await scopeLogAsync(() async {
- var buildStep =
- postProcessBuildStep(inputId, reader, writer, addAsset, deleteAsset);
- try {
- await builder.build(buildStep);
- } finally {
- await buildStep.complete();
- }
- }, logger);
-}
diff --git a/build/lib/src/resource/resource.dart b/build/lib/src/resource/resource.dart
deleted file mode 100644
index 8e786de..0000000
--- a/build/lib/src/resource/resource.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2017, 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';
-
-typedef CreateInstance<T> = FutureOr<T> Function();
-typedef DisposeInstance<T> = FutureOr<void> Function(T instance);
-typedef BeforeExit = FutureOr<void> Function();
-
-/// A [Resource] encapsulates the logic for creating and disposing of some
-/// expensive object which has a lifecycle.
-///
-/// Actual [Resource]s should be retrieved using `BuildStep#fetchResource`.
-///
-/// Build system implementations should be the only users that directly
-/// instantiate a [ResourceManager] since they can handle the lifecycle
-/// guarantees in a sane way.
-class Resource<T> {
- /// Factory method which creates an instance of this resource.
- final CreateInstance<T> _create;
-
- /// Optional method which is given an existing instance that is ready to be
- /// disposed.
- final DisposeInstance<T> _userDispose;
-
- /// Optional method which is called before the process is going to exit.
- ///
- /// This allows resources to do any final cleanup, and is not given an
- /// instance.
- final BeforeExit _userBeforeExit;
-
- /// A Future instance of this resource if one has ever been requested.
- final _instanceByManager = <ResourceManager, Future<T>>{};
-
- Resource(this._create, {DisposeInstance<T> dispose, BeforeExit beforeExit})
- : _userDispose = dispose,
- _userBeforeExit = beforeExit;
-
- /// Fetches an actual instance of this resource for [manager].
- Future<T> _fetch(ResourceManager manager) =>
- _instanceByManager.putIfAbsent(manager, () async => await _create());
-
- /// Disposes the actual instance of this resource for [manager] if present.
- Future<void> _dispose(ResourceManager manager) {
- if (!_instanceByManager.containsKey(manager)) return Future.value(null);
- var oldInstance = _fetch(manager);
- _instanceByManager.remove(manager);
- if (_userDispose != null) {
- return oldInstance.then(_userDispose);
- } else {
- return Future.value(null);
- }
- }
-}
-
-/// Manages fetching and disposing of a group of [Resource]s.
-///
-/// This is an internal only API which should only be used by build system
-/// implementations and not general end users. Instead end users should use
-/// the `buildStep#fetchResource` method to get [Resource]s.
-class ResourceManager {
- final _resources = Set<Resource<void>>();
-
- /// The [Resource]s that we need to call `beforeExit` on.
- ///
- /// We have to hang on to these forever, but they should be small in number,
- /// and we don't hold on to the actual created instances, just the [Resource]
- /// instances.
- final _resourcesWithBeforeExit = Set<Resource<void>>();
-
- /// Fetches an instance of [resource].
- Future<T> fetch<T>(Resource<T> resource) async {
- if (resource._userBeforeExit != null) {
- _resourcesWithBeforeExit.add(resource);
- }
- _resources.add(resource);
- return resource._fetch(this);
- }
-
- /// Disposes of all [Resource]s fetched since the last call to [disposeAll].
- Future<Null> disposeAll() {
- var done = Future.wait(_resources.map((r) => r._dispose(this)));
- _resources.clear();
- return done.then((_) => null);
- }
-
- /// Invokes the `beforeExit` callbacks of all [Resource]s that had one.
- Future<Null> beforeExit() async {
- await Future.wait(_resourcesWithBeforeExit.map((r) async {
- if (r._userBeforeExit != null) return r._userBeforeExit();
- }));
- _resourcesWithBeforeExit.clear();
- }
-}
diff --git a/build/mono_pkg.yaml b/build/mono_pkg.yaml
deleted file mode 100644
index dc1b387..0000000
--- a/build/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.3.0
- - unit_test:
- - command: pub run build_runner test
- os:
- - linux
- - windows
-
-cache:
- directories:
- - .dart_tool/build
diff --git a/build/pubspec.yaml b/build/pubspec.yaml
deleted file mode 100644
index dbbe0c0..0000000
--- a/build/pubspec.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: build
-version: 1.2.2
-description: A build system for Dart.
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/build/tree/master/build
-
-environment:
- sdk: ">=2.3.0 <3.0.0"
-
-dependencies:
- analyzer: '>=0.35.0 <0.40.0'
- async: ">=1.13.3 <3.0.0"
- convert: ^2.0.0
- crypto: ">=0.9.2 <3.0.0"
- logging: ^0.11.2
- meta: ^1.1.0
- path: ^1.1.0
- glob: ^1.1.0
-
-dev_dependencies:
- build_resolvers: ^1.0.0
- build_runner: ^1.0.0
- build_test: ^0.10.0
- build_vm_compilers: ">=0.1.0 <2.0.0"
- pedantic: ^1.0.0
- test: ^1.2.0
diff --git a/build_config/BUILD.gn b/build_config/BUILD.gn
deleted file mode 100644
index 2b434b9..0000000
--- a/build_config/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# This file is generated by importer.py for build_config-0.4.2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_config") {
- package_name = "build_config"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/yaml",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/json_annotation",
- "//third_party/dart-pkg/pub/pubspec_parse",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/checked_yaml",
- ]
-}
diff --git a/build_config/CHANGELOG.md b/build_config/CHANGELOG.md
deleted file mode 100644
index 80d5976..0000000
--- a/build_config/CHANGELOG.md
+++ /dev/null
@@ -1,174 +0,0 @@
-## 0.4.2
-
-- Add support for an `auto_apply_builders` option to the `target` config.
- - Defaults to `true` (the previous behavior), setting it to `false`
- means all builders have to be explicitly enabled.
-
-## 0.4.1+1
-
-- Support the latest release of `package:json_annotation`.
-- Increased the lower bound for the Dart SDK to `>=2.3.0`.
-
-## 0.4.1
-
-- Added optional `configYamlPath` parameter to `BuildConfig.parse`. When
- provided, errors reported when parsing build configuration will include
- the file path.
-
-## 0.4.0
-
-- Breaking for build systems - change type of `BuilderOptions` fields to
- `Map<String, dynamic>` to drop dependency on `build`. Does not impact packages
- only depending on `build.yaml` parsing.
-- Breaking for build systems - versioning scheme is changing to match
- `package:build`. Changes which are breaking to _users_ - those with
- `build.yaml` files will be indicated with a breaking major version bump.
- Changed which are breaking to build system _implementors_ - those who use the
- Dart API for this package, will be indicated with a minor version bump.
-
-## 0.3.2
-
-- Add an explicit error when `buildExtensions` is configured to overwrite it's
- input.
-- Add an explicit error when an `InputSet` has an empty or null value in a glob
- list.
-- Increase lower bound SDK constraint to 2.0.0.
-- Normalize builder keys with the legacy `|` separator to use `:` instead.
-
-## 0.3.1+4
-
-- Support the latest `package:json_annotation`.
-
-## 0.3.1+3
-
-- Support `package:build` version `1.x.x`.
-
-## 0.3.1+2
-
-- Support `package:json_annotation` v1.
-
-## 0.3.1+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.3.1
-
-- Improve validation and errors when parsing `build.yaml`.
-- Add `BuildConfig.globalOptions` support.
-
-## 0.3.0
-
-- Parsing of `build.yaml` files is now done with the `json_serializable` package
- and is Dart 2 compatible.
-
- - The error reporting will be a bit different, but generally should be better,
- and will include the yaml spans of the problem sections.
-
-### Breaking Changes
-
-There are no changes to the `build.yaml` format, the following changes only
-affect the imperative apis of this package.
-
-- The Constructors for most of the build config classes other than `BuildConfig`
- itself now have to be ran inside a build config zone, which can be done using
- the `runInBuildConfigZone` function. This gives the context about what package
- is currently being parsed, as well as what the default dependencies should be
- for targets.
-- Many constructor signatures have changed, for the most part removing the
- `package` parameter (it is now read off the zone).
-
-## 0.2.6+2
-
-- Restore error for missing default target.
-
-## 0.2.6+1
-
-- Restore error for missing build extensions.
-
-## 0.2.6
-
-- The `target` and `build_extensions` keys for builder definitions are now
- optional and should be omitted in most cases since they are currently unused.
-- Support options based on mode, add `devOptions` and `releaseOptions` on
- `TargetBuilderConfig`.
-- Support applying default options based on builder definitions, add `option`,
- `devOptions`, and `releaseOptions` to `TargetBuilderConfigDefaults`.
-- Ensure that `defaults` and `generateFor` fields are never null.
-- Add `InputSet.anything` to name the input sets that don't filter out any
- assets.
-
-## 0.2.5
-
-- Added `post_process_builders` section to `build.yaml`. See README.md for more
- information.-dev
-- Adds support for `$default` as a _dependency_, i.e.:
-
-```yaml
-targets:
- $default:
- ...
- foo:
- dependencies:
- - $default
-```
-
-## 0.2.4
-
-- Add support for `runs_before` in `BuilderDefinition`.
-
-## 0.2.3
-
-- Expose key normalization methods publicly, these include:
- - `normalizeBuilderKeyUsage`
- - `normalizeTargetKeyUsage`
-
-## 0.2.2+1
-
-- Expand support for `package:build` to include version `0.12.0`.
-
-## 0.2.2
-
-- **Bug fix**: Empty build.yaml files no longer fail to parse.
-- Allow `$default` as a target name to get he package name automatically filled
- in.
-
-## 0.2.1
-
-- Change the default for `BuilderDefinition.buildTo` to `BuildTo.cache`.
- Builders which want to operate on the source tree will need to explicitly opt
- in. Allow this regardless of the value of `autoApply` and the build system
- will need to filter out the builders that can't run.
-- By default including any configuration for a Builder within a BuildTarget will
- enabled that builder.
-
-## 0.2.0
-
-- Add `build_to` option to Builder configuration.
-- Add `BuildConfig.fromBuildConfigDir` for cases where the package name and
- dependencies are already known.
-- Add `TargetBuilderConfig` class to configure builders applied to specific
- targets.
-- Add `TargetBuilderConfigDefaults` class for Builder authors to provide default
- configuration.
-- Add `InputSet` and change `sources` and `generate_for` to use it.
-- Remove `BuildTarget.isDefault` and related config parsing. The default will be
- determined by the target which matches the package name.
-- Normalize Target and Builder names so they are scoped to the package they are
- defined in.
-
-### Breaking
-
-- Remove `BuildConfigSet` class. This was unused.
-- Hide `Pubspec` class. Construct `BuildConfig` instances with a package path
- rather than an already created `Pubspec` instance.
-
-## 0.1.1
-
-- Add `auto_apply` option to Builder configuration.
-- Add `required_inputs` option to Builder configuration.
-- Add `is_optional` option to Builder configuration.
-
-## 0.1.0
-
-- Initial release - pulled from `package:dazel`. Updated to support
- `build_extensions` instead of `input_extension` and `output_extensions`.
diff --git a/build_config/LICENSE b/build_config/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/build_config/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_config/README.md b/build_config/README.md
deleted file mode 100644
index e759cf4..0000000
--- a/build_config/README.md
+++ /dev/null
@@ -1,239 +0,0 @@
-# Customizing builds
-
-Customizing the build behavior of a package is done by creating a `build.yaml`
-file, which describes your configuration.
-
-The full format is described in the
-[docs/build_yaml_format.md](https://github.com/dart-lang/build/blob/master/docs/build_yaml_format.md)
-file, while this documentation is more focused on specific usage scenarios of
-the file.
-
-## Dividing a package into Build targets
-
-When a `Builder` should be applied to a subset of files in a package the package
-can be broken up into multiple 'targets'. Targets are configured in the
-`targets` section of the `build.yaml`. The key for each target makes up the name
-for that target. Targets can be referred to in
-`'$definingPackageName:$targetname'`. When the target name matches the package
-name it can also be referred to as just the package name. One target in every
-package _must_ use the package name so that consumers will use it by default.
-In the `build.yaml` file this target can be defined with the key `$default` or
-with the name of the package.
-
-Each target may also contain the following keys:
-
-- **sources**: List of Strings or Map, Optional. The set of files within the
- package which make up this target. Files are specified using glob syntax. If a
- List of Strings is used they are considered the 'include' globs. If a Map is
- used can only have the keys `include` and `exclude`. Any file which matches
- any glob in `include` and no globs in `exclude` is considered a source of the
- target. When `include` is omitted every file is considered a match.
-- **dependencies**: List of Strings, Optional. The targets that this target
- depends on. Strings in the format `'$packageName:$targetName'` to depend on a
- target within a package or `$packageName` to depend on a package's default
- target. By default this is all of the package names this package depends on
- (from the `pubspec.yaml`).
-- **builders**: Map, Optional. See "configuring builders" below.
-
-## Configuring `Builder`s applied to your package
-Each target can specify a `builders` key which configures the builders which are
-applied to that target. The value is a Map from builder to configuration for
-that builder. The key is in the format `'$packageName:$builderName'`. The
-configuration may have the following keys:
-
-- **enabled**: Boolean, Optional: Whether to apply the builder to this target.
- Omit this key if you want the default behavior based on the builder's
- `auto_apply` configuration. Builders which are manually applied
- (`auto_apply: none`) are only ever used when there is a target specifying the
- builder with `enabled: True`.
-- **generate_for**: List of String or Map, Optional:. The subset of files within
- the target's `sources` which should have this Builder applied. See `sources`
- configuration above for how to configure this.
-- **options**: Map, Optional: A free-form map which will be passed to the
- `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
- on the particular builder. Values in this map will override the default
- provided by builder authors. Values may also be overridden based on the build
- mode with `dev_options` or `release_options`.
-- **dev_options**: Map, Optional: A free-form map which will be passed to the
- `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
- on the particular builder. The values in this map override Builder defaults or
- non mode-specific options per-key when the build is done in dev mode.
-- **release_options**: Map, Optional: A free-form map which will be passed to
- the `Builder` as a `BuilderOptions` when it is constructed. Usage varies
- depending on the particular builder. The values in this map override Builder
- defaults or non mode-specific options when the build is done in release mode.
-
-## Configuring `Builder`s globally
-Target level builder options can be overridden globally across all packages with
-the `global_options` section. These options are applied _after_ all Builder
-defaults and target level configuration, and _before_ `--define` command line
-arguments.
-
-- **options**: Map, Optional: A free-form map which will be passed to the
- `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
- on the particular builder. Values in this map will override the default
- provided by builder authors or at the target level. Values may also be
- overridden based on the build mode with `dev_options` or `release_options`.
-- **dev_options**: Map, Optional: A free-form map which will be passed to the
- `Builder` as a `BuilderOptions` when it is constructed. Usage varies depending
- on the particular builder. The values in this map override all other values
- per-key when the build is done in dev mode.
-- **release_options**: Map, Optional: A free-form map which will be passed to
- the `Builder` as a `BuilderOptions` when it is constructed. Usage varies
- depending on the particular builder. The values in this map override all other
- values per-key when the build is done in release mode.
-
-## Defining `Builder`s to apply to dependents
-
-If users of your package need to apply some code generation to their package,
-then you can define `Builder`s and have those applied to packages with a
-dependency on yours.
-
-The key for a Builder will be normalized so that consumers of the builder can
-refer to it in `'$definingPackageName:$builderName'` format. If the builder name
-matches the package name it can also be referred to with just the package name.
-
-Exposed `Builder`s are configured in the `builders` section of the `build.yaml`.
-This is a map of builder names to configuration. Each builder config may contain
-the following keys:
-
-- **import**: Required. The import uri that should be used to import the library
- containing the `Builder` class. This should always be a `package:` uri.
-- **builder_factories**: A `List<String>` which contains the names of the
- top-level methods in the imported library which are a function fitting the
- typedef `Builder factoryName(BuilderOptions options)`.
-- **build_extensions**: Required. A map from input extension to the list of
- output extensions that may be created for that input. This must match the
- merged `buildExtensions` maps from each `Builder` in `builder_factories`.
-- **auto_apply**: Optional. The packages which should have this builder
- automatically to applied. Defaults to `'none'` The possibilities are:
- - `"none"`: Never apply this Builder unless it is manually configured
- - `"dependents"`: Apply this Builder to the package with a direct dependency
- on the package exposing the builder.
- - `"all_packages"`: Apply this Builder to all packages in the transitive
- dependency graph.
- - `"root_package"`: Apply this Builder only to the top-level package.
-- **required_inputs**: Optional, see [adjusting builder ordering][]
-- **runs_before**: Optional, see [adjusting builder ordering][]
-- **applies_builders**: Optional, list of Builder keys. Specifies that other
- builders should be run on any target which will run this Builder.
-- **is_optional**: Optional, boolean. Specifies whether a Builder can be run
- lazily, such that it won't execute until one of it's outputs is requested by a
- later Builder. This option should be rare. Defaults to `False`.
-- **build_to**: Optional. The location that generated assets should be output
- to. The possibilities are:
- - `"source"`: Outputs go to the source tree next to their primary inputs.
- - `"cache"`: Outputs go to a hidden build cache and won't be published.
- The default is "cache". If a Builder specifies that it outputs to "source" it
- will never run on any package other than the root - but does not necessarily
- need to use the "root_package" value for "auto_apply". If it would otherwise
- run on a non-root package it will be filtered out.
-- **defaults**: Optional: Default values to apply when a user does not specify
- the corresponding key in their `builders` section. May contain the following
- keys:
- - **generate_for**: A list of globs that this Builder should run on as a
- subset of the corresponding target, or a map with `include` and `exclude`
- lists of globs.
- - **options**: Arbitrary yaml map, provided as the `config` map in
- `BuilderOptions` to the `BuilderFactory` for this builder. Individual keys
- will be overridden by configuration provided in either `dev_options` or
- `release_options` based on the build mode, and then overridden by any user
- specified configuration.
- - **dev_options**: Arbitrary yaml map. Values will replace the defaults from
- `options` when the build is done in dev mode (the default mode).
- - **release_options**: Arbitrary yaml map. Values will replace the defaults
- from `options` when the build is done in release mode (with `--release`).
-
-Example `builders` config:
-
-```yaml
-builders:
- my_builder:
- import: "package:my_package/builder.dart"
- builder_factories: ["myBuilder"]
- build_extensions: {".dart": [".my_package.dart"]}
- auto_apply: dependents
- defaults:
- release_options:
- some_key: "Some value the users will want in release mode"
-```
-
-## Defining `PostProcessBuilder`s
-
-`PostProcessBuilder`s are configured similarly to normal `Builder`s, but they
-have some different/missing options.
-
-These builders can not be auto-applied on their own, and must always build to
-cache because their outputs are not declared ahead of time. To apply them a
-user will need to explicitly enable them on a target, or a `Builder` definition
-can add them to `apply_builders`.
-
-Exposed `PostProcessBuilder`s are configured in the `post_process_builders`
-section of the `build.yaml`. This is a map of builder names to configuration.
-Each post process builder config may contain the following keys:
-
-- **import**: Required. The import uri that should be used to import the library
- containing the `Builder` class. This should always be a `package:` uri.
-- **builder_factory**: A `String` which contains the name of the top-level
- method in the imported library which is a function fitting the
- typedef `PostProcessBuilder factoryName(BuilderOptions options)`.
-- **input_extensions**: Required. A list of input extensions that will be
- processed. This must match the `inputExtensions` from the `PostProcessBuilder`
- returned by the `builder_factory`.
-- **defaults**: Optional: Default values to apply when a user does not specify
- the corresponding key in their `builders` section. May contain the following
- keys:
- - **generate_for**: A list of globs that this Builder should run on as a
- subset of the corresponding target, or a map with `include` and `exclude`
- lists of globs.
-
-Example config with a normal `builder` which auto-applies a
-`post_process_builder`:
-
-```yaml
-builders:
- # The regular builder config, creates `.tar.gz` files.
- regular_builder:
- import: "package:my_package/builder.dart"
- builder_factories: ["myBuilder"]
- build_extensions: {".dart": [".tar.gz"]}
- auto_apply: dependents
- apply_builders: [":archive_extract_builder"]
-post_process_builders:
- # The post process builder config, extracts `.tar.gz` files.
- extract_archive_builder:
- import: "package:my_package/extract_archive_builder.dart"
- builder_factory: "myExtractArchiveBuilder"
- input_extensions: [".tar.gz"]
-```
-
-[adjusting builder ordering]: #adjusting-builder-ordering
-
-### Adjusting Builder Ordering
-
-Both `required_inputs` and `runs_before` can be used to tweak the order that
-Builders run in on a given target. These work by indicating a given builder is a
-_dependency_ of another. The resulting dependency graph must not have cycles and
-these options should be used rarely.
-
-- **required_inputs**: Optional, list of extensions, defaults to empty list. If
- a Builder must see every input with one or more file extensions they can be
- specified here and it will be guaranteed to run after any Builder which might
- produce an output of that type. For instance a compiler must run after any
- Builder which can produce `.dart` outputs or those libraries can't be
- compiled. A Builder may not specify that it requires an output that it also
- produces since this would be a self-cycle.
-- **runs_before**: Optional, list of Builder keys. If a Builder is producing
- outputs which are intended to be inputs to other Builders they may be
- specified here. This guarantees that the specified Builders will be ordered
- later than this one. This will not cause Builders to be applied if they would
- not otherwise run, it only affects ordering.
-
-# Publishing `build.yaml` files
-
-`build.yaml` configuration should be published to pub with the package and
-checked in to source control. Whenever a package is published with a
-`build.yaml` it should mark a `dependency` on `build_config` to ensure that
-the package consuming the config has a compatible version. Breaking version
-changes which do not impact the configuration file format will be clearly marked
-in the changelog.
diff --git a/build_config/build.yaml b/build_config/build.yaml
deleted file mode 100644
index 2f30635..0000000
--- a/build_config/build.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-targets:
- $default:
- builders:
- json_serializable:
- options:
- any_map: true
- checked: true
diff --git a/build_config/lib/build_config.dart b/build_config/lib/build_config.dart
deleted file mode 100644
index c2a6553..0000000
--- a/build_config/lib/build_config.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/build_config.dart' show BuildConfig;
-export 'src/build_target.dart'
- show BuildTarget, TargetBuilderConfig, GlobalBuilderConfig;
-export 'src/builder_definition.dart'
- show
- BuilderDefinition,
- AutoApply,
- BuildTo,
- PostProcessBuilderDefinition,
- TargetBuilderConfigDefaults;
-export 'src/common.dart' show runInBuildConfigZone;
-export 'src/input_set.dart' show InputSet;
-export 'src/key_normalization.dart'
- show normalizeBuilderKeyUsage, normalizeTargetKeyUsage;
diff --git a/build_config/lib/src/build_config.dart b/build_config/lib/src/build_config.dart
deleted file mode 100644
index ac3f903..0000000
--- a/build_config/lib/src/build_config.dart
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2017, 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 'package:checked_yaml/checked_yaml.dart';
-import 'package:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:pubspec_parse/pubspec_parse.dart';
-
-import 'build_target.dart';
-import 'builder_definition.dart';
-import 'common.dart';
-import 'expandos.dart';
-import 'input_set.dart';
-import 'key_normalization.dart';
-
-part 'build_config.g.dart';
-
-/// The parsed values from a `build.yaml` file.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class BuildConfig {
- /// Returns a parsed [BuildConfig] file in [path], if one exist, otherwise a
- /// default config.
- ///
- /// [path] must be a directory which contains a `pubspec.yaml` file and
- /// optionally a `build.yaml`.
- static Future<BuildConfig> fromPackageDir(String path) async {
- final pubspec = await _fromPackageDir(path);
- return fromBuildConfigDir(pubspec.name, pubspec.dependencies.keys, path);
- }
-
- /// Returns a parsed [BuildConfig] file in [path], if one exists, otherwise a
- /// default config.
- ///
- /// [path] should the path to a directory which may contain a `build.yaml`.
- static Future<BuildConfig> fromBuildConfigDir(
- String packageName, Iterable<String> dependencies, String path) async {
- final configPath = p.join(path, 'build.yaml');
- final file = File(configPath);
- if (await file.exists()) {
- return BuildConfig.parse(
- packageName,
- dependencies,
- await file.readAsString(),
- configYamlPath: file.path,
- );
- } else {
- return BuildConfig.useDefault(packageName, dependencies);
- }
- }
-
- @JsonKey(ignore: true)
- final String packageName;
-
- /// All the `builders` defined in a `build.yaml` file.
- @JsonKey(name: 'builders')
- final Map<String, BuilderDefinition> builderDefinitions;
-
- /// All the `post_process_builders` defined in a `build.yaml` file.
- @JsonKey(name: 'post_process_builders')
- final Map<String, PostProcessBuilderDefinition> postProcessBuilderDefinitions;
-
- /// All the `targets` defined in a `build.yaml` file.
- @JsonKey(name: 'targets', fromJson: _buildTargetsFromJson)
- final Map<String, BuildTarget> buildTargets;
-
- @JsonKey(name: 'global_options')
- final Map<String, GlobalBuilderConfig> globalOptions;
-
- /// The default config if you have no `build.yaml` file.
- factory BuildConfig.useDefault(
- String packageName, Iterable<String> dependencies) {
- return runInBuildConfigZone(() {
- final key = '$packageName:$packageName';
- final target = BuildTarget(
- dependencies: dependencies
- .map((dep) => normalizeTargetKeyUsage(dep, packageName))
- .toList(),
- sources: InputSet.anything,
- );
- return BuildConfig(
- packageName: packageName,
- buildTargets: {key: target},
- globalOptions: {},
- );
- }, packageName, dependencies.toList());
- }
-
- /// Create a [BuildConfig] by parsing [configYaml].
- ///
- /// If [configYamlPath] is passed, it's used as the URL from which
- /// [configYaml] for error reporting.
- factory BuildConfig.parse(
- String packageName,
- Iterable<String> dependencies,
- String configYaml, {
- String configYamlPath,
- }) {
- try {
- return checkedYamlDecode(
- configYaml,
- (map) =>
- BuildConfig.fromMap(packageName, dependencies, map ?? const {}),
- allowNull: true,
- sourceUrl: configYamlPath,
- );
- } on ParsedYamlException catch (e) {
- throw ArgumentError(e.formattedMessage);
- }
- }
-
- /// Create a [BuildConfig] read a map which was already parsed.
- factory BuildConfig.fromMap(
- String packageName, Iterable<String> dependencies, Map config) {
- return runInBuildConfigZone(() => BuildConfig._fromJson(config),
- packageName, dependencies.toList());
- }
-
- BuildConfig({
- String packageName,
- @required Map<String, BuildTarget> buildTargets,
- Map<String, GlobalBuilderConfig> globalOptions,
- Map<String, BuilderDefinition> builderDefinitions,
- Map<String, PostProcessBuilderDefinition> postProcessBuilderDefinitions =
- const {},
- }) : buildTargets = buildTargets ??
- {
- _defaultTarget(packageName ?? currentPackage): BuildTarget(
- dependencies: currentPackageDefaultDependencies,
- )
- },
- globalOptions = (globalOptions ?? const {}).map((key, config) =>
- MapEntry(normalizeBuilderKeyUsage(key, currentPackage), config)),
- builderDefinitions = _normalizeBuilderDefinitions(
- builderDefinitions ?? const {}, packageName ?? currentPackage),
- postProcessBuilderDefinitions = _normalizeBuilderDefinitions(
- postProcessBuilderDefinitions ?? const {},
- packageName ?? currentPackage),
- packageName = packageName ?? currentPackage {
- // Set up the expandos for all our build targets and definitions so they
- // can know which package and builder key they refer to.
- this.buildTargets.forEach((key, target) {
- packageExpando[target] = this.packageName;
- builderKeyExpando[target] = key;
- });
- this.builderDefinitions.forEach((key, definition) {
- packageExpando[definition] = this.packageName;
- builderKeyExpando[definition] = key;
- });
- this.postProcessBuilderDefinitions.forEach((key, definition) {
- packageExpando[definition] = this.packageName;
- builderKeyExpando[definition] = key;
- });
- }
-
- factory BuildConfig._fromJson(Map json) => _$BuildConfigFromJson(json);
-}
-
-String _defaultTarget(String package) => '$package:$package';
-
-Map<String, T> _normalizeBuilderDefinitions<T>(
- Map<String, T> builderDefinitions, String packageName) =>
- builderDefinitions.map((key, definition) =>
- MapEntry(normalizeBuilderKeyDefinition(key, packageName), definition));
-
-Map<String, BuildTarget> _buildTargetsFromJson(Map json) {
- if (json == null) {
- return null;
- }
- var targets = json.map((key, target) => MapEntry(
- normalizeTargetKeyDefinition(key as String, currentPackage),
- BuildTarget.fromJson(target as Map)));
-
- if (!targets.containsKey(_defaultTarget(currentPackage))) {
- throw ArgumentError('Must specify a target with the name '
- '`$currentPackage` or `\$default`.');
- }
-
- return targets;
-}
-
-Future<Pubspec> _fromPackageDir(String path) async {
- final pubspec = p.join(path, 'pubspec.yaml');
- final file = File(pubspec);
- if (await file.exists()) {
- return Pubspec.parse(await file.readAsString());
- }
- throw FileSystemException('No file found', p.absolute(pubspec));
-}
diff --git a/build_config/lib/src/build_config.g.dart b/build_config/lib/src/build_config.g.dart
deleted file mode 100644
index dbbe12b..0000000
--- a/build_config/lib/src/build_config.g.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'build_config.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuildConfig _$BuildConfigFromJson(Map json) {
- return $checkedNew('BuildConfig', json, () {
- $checkKeys(json, allowedKeys: const [
- 'builders',
- 'post_process_builders',
- 'targets',
- 'global_options'
- ]);
- final val = BuildConfig(
- buildTargets: $checkedConvert(
- json, 'targets', (v) => _buildTargetsFromJson(v as Map)),
- globalOptions: $checkedConvert(
- json,
- 'global_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String,
- e == null ? null : GlobalBuilderConfig.fromJson(e as Map)),
- )),
- builderDefinitions: $checkedConvert(
- json,
- 'builders',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String,
- e == null ? null : BuilderDefinition.fromJson(e as Map)),
- )),
- postProcessBuilderDefinitions: $checkedConvert(
- json,
- 'post_process_builders',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(
- k as String,
- e == null
- ? null
- : PostProcessBuilderDefinition.fromJson(e as Map)),
- )),
- );
- return val;
- }, fieldKeyMap: const {
- 'buildTargets': 'targets',
- 'globalOptions': 'global_options',
- 'builderDefinitions': 'builders',
- 'postProcessBuilderDefinitions': 'post_process_builders'
- });
-}
diff --git a/build_config/lib/src/build_target.dart b/build_config/lib/src/build_target.dart
deleted file mode 100644
index 740a048..0000000
--- a/build_config/lib/src/build_target.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-// 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:json_annotation/json_annotation.dart';
-
-import 'builder_definition.dart';
-import 'common.dart';
-import 'expandos.dart';
-import 'input_set.dart';
-import 'key_normalization.dart';
-
-part 'build_target.g.dart';
-
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class BuildTarget {
- @JsonKey(name: 'auto_apply_builders')
- final bool autoApplyBuilders;
-
- /// A map from builder key to the configuration used for this target.
- ///
- /// Builder keys are in the format `"$package|$builder"`. This does not
- /// represent the full set of builders that are applied to the target, only
- /// those which have configuration customized against the default.
- final Map<String, TargetBuilderConfig> builders;
-
- final List<String> dependencies;
-
- final InputSet sources;
-
- /// A unique key for this target in `'$package:$target'` format.
- String get key => builderKeyExpando[this];
-
- String get package => packageExpando[this];
-
- BuildTarget({
- bool autoApplyBuilders,
- InputSet sources,
- Iterable<String> dependencies,
- Map<String, TargetBuilderConfig> builders,
- }) : autoApplyBuilders = autoApplyBuilders ?? true,
- dependencies = (dependencies ?? currentPackageDefaultDependencies)
- .map((d) => normalizeTargetKeyUsage(d, currentPackage))
- .toList(),
- builders = (builders ?? const {}).map((key, config) =>
- MapEntry(normalizeBuilderKeyUsage(key, currentPackage), config)),
- sources = sources ?? InputSet.anything;
-
- factory BuildTarget.fromJson(Map json) => _$BuildTargetFromJson(json);
-
- @override
- String toString() => {
- 'package': package,
- 'sources': sources,
- 'dependencies': dependencies,
- 'builders': builders,
- 'autoApplyBuilders': autoApplyBuilders,
- }.toString();
-}
-
-/// The configuration a particular [BuildTarget] applies to a Builder.
-///
-/// Build targets may have builders applied automatically based on
-/// [BuilderDefinition.autoApply] and may override with more specific
-/// configuration.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class TargetBuilderConfig {
- /// Overrides the setting of whether the Builder would run on this target.
- ///
- /// Builders may run on this target by default based on the `apply_to`
- /// argument, set to `false` to disable a Builder which would otherwise run.
- ///
- /// By default including a config for a Builder enables that builder.
- @JsonKey(name: 'enabled')
- final bool isEnabled;
-
- /// Sources to use as inputs for this Builder in glob format.
- ///
- /// This is always a subset of the `include` argument in the containing
- /// [BuildTarget]. May be `null` in which cases it will be all the sources in
- /// the target.
- @JsonKey(name: 'generate_for')
- final InputSet generateFor;
-
- /// The options to pass to the `BuilderFactory` when constructing this
- /// builder.
- ///
- /// The `options` key in the configuration.
- ///
- /// Individual keys may be overridden by either [devOptions] or
- /// [releaseOptions].
- final Map<String, dynamic> options;
-
- /// Overrides for [options] in dev mode.
- @JsonKey(name: 'dev_options')
- final Map<String, dynamic> devOptions;
-
- /// Overrides for [options] in release mode.
- @JsonKey(name: 'release_options')
- final Map<String, dynamic> releaseOptions;
-
- TargetBuilderConfig({
- bool isEnabled,
- this.generateFor,
- Map<String, dynamic> options,
- Map<String, dynamic> devOptions,
- Map<String, dynamic> releaseOptions,
- }) : isEnabled = isEnabled ?? true,
- options = options ?? const {},
- devOptions = devOptions ?? const {},
- releaseOptions = releaseOptions ?? const {};
-
- factory TargetBuilderConfig.fromJson(Map json) =>
- _$TargetBuilderConfigFromJson(json);
-
- @override
- String toString() => {
- 'isEnabled': isEnabled,
- 'generateFor': generateFor,
- 'options': options,
- 'devOptions': devOptions,
- 'releaseOptions': releaseOptions,
- }.toString();
-}
-
-/// The configuration for a Builder applied globally.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class GlobalBuilderConfig {
- /// The options to pass to the `BuilderFactory` when constructing this
- /// builder.
- ///
- /// The `options` key in the configuration.
- ///
- /// Individual keys may be overridden by either [devOptions] or
- /// [releaseOptions].
- final Map<String, dynamic> options;
-
- /// Overrides for [options] in dev mode.
- @JsonKey(name: 'dev_options')
- final Map<String, dynamic> devOptions;
-
- /// Overrides for [options] in release mode.
- @JsonKey(name: 'release_options')
- final Map<String, dynamic> releaseOptions;
-
- GlobalBuilderConfig({
- Map<String, dynamic> options,
- Map<String, dynamic> devOptions,
- Map<String, dynamic> releaseOptions,
- }) : options = options ?? const {},
- devOptions = devOptions ?? const {},
- releaseOptions = releaseOptions ?? const {};
-
- factory GlobalBuilderConfig.fromJson(Map json) =>
- _$GlobalBuilderConfigFromJson(json);
-
- @override
- String toString() => {
- 'options': options,
- 'devOptions': devOptions,
- 'releaseOptions': releaseOptions,
- }.toString();
-}
diff --git a/build_config/lib/src/build_target.g.dart b/build_config/lib/src/build_target.g.dart
deleted file mode 100644
index 44143e2..0000000
--- a/build_config/lib/src/build_target.g.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'build_target.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuildTarget _$BuildTargetFromJson(Map json) {
- return $checkedNew('BuildTarget', json, () {
- $checkKeys(json, allowedKeys: const [
- 'auto_apply_builders',
- 'builders',
- 'dependencies',
- 'sources'
- ]);
- final val = BuildTarget(
- autoApplyBuilders:
- $checkedConvert(json, 'auto_apply_builders', (v) => v as bool),
- sources: $checkedConvert(
- json, 'sources', (v) => v == null ? null : InputSet.fromJson(v)),
- dependencies: $checkedConvert(
- json, 'dependencies', (v) => (v as List)?.map((e) => e as String)),
- builders: $checkedConvert(
- json,
- 'builders',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String,
- e == null ? null : TargetBuilderConfig.fromJson(e as Map)),
- )),
- );
- return val;
- }, fieldKeyMap: const {'autoApplyBuilders': 'auto_apply_builders'});
-}
-
-TargetBuilderConfig _$TargetBuilderConfigFromJson(Map json) {
- return $checkedNew('TargetBuilderConfig', json, () {
- $checkKeys(json, allowedKeys: const [
- 'enabled',
- 'generate_for',
- 'options',
- 'dev_options',
- 'release_options'
- ]);
- final val = TargetBuilderConfig(
- isEnabled: $checkedConvert(json, 'enabled', (v) => v as bool),
- generateFor: $checkedConvert(
- json, 'generate_for', (v) => v == null ? null : InputSet.fromJson(v)),
- options: $checkedConvert(
- json,
- 'options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- devOptions: $checkedConvert(
- json,
- 'dev_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- releaseOptions: $checkedConvert(
- json,
- 'release_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- );
- return val;
- }, fieldKeyMap: const {
- 'isEnabled': 'enabled',
- 'generateFor': 'generate_for',
- 'devOptions': 'dev_options',
- 'releaseOptions': 'release_options'
- });
-}
-
-GlobalBuilderConfig _$GlobalBuilderConfigFromJson(Map json) {
- return $checkedNew('GlobalBuilderConfig', json, () {
- $checkKeys(json,
- allowedKeys: const ['options', 'dev_options', 'release_options']);
- final val = GlobalBuilderConfig(
- options: $checkedConvert(
- json,
- 'options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- devOptions: $checkedConvert(
- json,
- 'dev_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- releaseOptions: $checkedConvert(
- json,
- 'release_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- );
- return val;
- }, fieldKeyMap: const {
- 'devOptions': 'dev_options',
- 'releaseOptions': 'release_options'
- });
-}
diff --git a/build_config/lib/src/builder_definition.dart b/build_config/lib/src/builder_definition.dart
deleted file mode 100644
index 0abdfc1..0000000
--- a/build_config/lib/src/builder_definition.dart
+++ /dev/null
@@ -1,251 +0,0 @@
-// 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:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-
-import 'build_target.dart';
-import 'common.dart';
-import 'expandos.dart';
-import 'input_set.dart';
-import 'key_normalization.dart';
-
-part 'builder_definition.g.dart';
-
-enum AutoApply {
- none,
- dependents,
- @JsonValue('all_packages')
- allPackages,
- @JsonValue('root_package')
- rootPackage
-}
-
-enum BuildTo {
- /// Generated files are written to the source directory next to their primary
- /// inputs.
- source,
-
- /// Generated files are written to the hidden 'generated' directory.
- cache
-}
-
-/// Definition of a builder parsed from the `builders` section of `build.yaml`.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class BuilderDefinition {
- /// The package which provides this Builder.
- String get package => packageExpando[this];
-
- /// A unique key for this Builder in `'$package:$builder'` format.
- String get key => builderKeyExpando[this];
-
- /// The names of the top-level methods in [import] from args -> Builder.
- @JsonKey(
- name: 'builder_factories',
- nullable: false,
- required: true,
- disallowNullValue: true)
- final List<String> builderFactories;
-
- /// The import to be used to load `clazz`.
- @JsonKey(nullable: false, required: true, disallowNullValue: true)
- final String import;
-
- /// A map from input extension to the output extensions created for matching
- /// inputs.
- @JsonKey(
- name: 'build_extensions',
- nullable: false,
- required: true,
- disallowNullValue: true)
- final Map<String, List<String>> buildExtensions;
-
- /// The name of the dart_library target that contains `import`.
- ///
- /// May be null or unreliable and should not be used.
- @deprecated
- final String target;
-
- /// Which packages should have this builder applied automatically.
- @JsonKey(name: 'auto_apply')
- final AutoApply autoApply;
-
- /// A list of file extensions which are required to run this builder.
- ///
- /// No builder which outputs any extension in this list is allowed to run
- /// after this builder.
- @JsonKey(name: 'required_inputs')
- final List<String> requiredInputs;
-
- /// Builder keys in `$package:$builder` format which should only be run after
- /// this Builder.
- @JsonKey(name: 'runs_before')
- final List<String> runsBefore;
-
- /// Builder keys in `$package:$builder` format which should be run on any
- /// target which also runs this Builder.
- @JsonKey(name: 'applies_builders')
- final List<String> appliesBuilders;
-
- /// Whether this Builder should be deferred until it's output is requested.
- ///
- /// Optional builders are lazy and will not run unless some later builder
- /// requests one of it's possible outputs through either `readAs*` or
- /// `canRead`.
- @JsonKey(name: 'is_optional')
- final bool isOptional;
-
- /// Where the outputs of this builder should be written.
- @JsonKey(name: 'build_to')
- final BuildTo buildTo;
-
- final TargetBuilderConfigDefaults defaults;
-
- BuilderDefinition({
- @required this.builderFactories,
- @required this.buildExtensions,
- @required this.import,
- String target,
- AutoApply autoApply,
- Iterable<String> requiredInputs,
- Iterable<String> runsBefore,
- Iterable<String> appliesBuilders,
- bool isOptional,
- BuildTo buildTo,
- TargetBuilderConfigDefaults defaults,
- }) :
- // ignore: deprecated_member_use
- target = target != null
- ? normalizeTargetKeyUsage(target, currentPackage)
- : null,
- autoApply = autoApply ?? AutoApply.none,
- requiredInputs = requiredInputs?.toList() ?? const [],
- runsBefore = runsBefore
- ?.map((builder) =>
- normalizeBuilderKeyUsage(builder, currentPackage))
- ?.toList() ??
- const [],
- appliesBuilders = appliesBuilders
- ?.map((builder) =>
- normalizeBuilderKeyUsage(builder, currentPackage))
- ?.toList() ??
- const [],
- isOptional = isOptional ?? false,
- buildTo = buildTo ?? BuildTo.cache,
- defaults = defaults ?? const TargetBuilderConfigDefaults() {
- if (builderFactories.isEmpty) {
- throw ArgumentError.value(builderFactories, 'builderFactories',
- 'Must have at least one value.');
- }
- if (buildExtensions.entries.any((e) => e.value.contains(e.key))) {
- throw ArgumentError.value(
- buildExtensions,
- 'buildExtensions',
- 'May not overwrite an input, '
- 'the output extensions must not contain the input extension');
- }
- }
-
- factory BuilderDefinition.fromJson(Map json) =>
- _$BuilderDefinitionFromJson(json);
-
- @override
- String toString() => {
- 'autoApply': autoApply,
- 'import': import,
- 'builderFactories': builderFactories,
- 'buildExtensions': buildExtensions,
- 'requiredInputs': requiredInputs,
- 'runsBefore': runsBefore,
- 'isOptional': isOptional,
- 'buildTo': buildTo,
- 'defaults': defaults,
- }.toString();
-}
-
-/// The definition of a `PostProcessBuilder` in the `post_process_builders`
-/// section of a `build.yaml`.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class PostProcessBuilderDefinition {
- /// The package which provides this Builder.
- String get package => packageExpando[this];
-
- /// A unique key for this Builder in `'$package:$builder'` format.
- String get key => builderKeyExpando[this];
-
- /// The name of the top-level method in [import] from
- /// Map<String, dynamic> -> Builder.
- @JsonKey(
- name: 'builder_factory',
- nullable: false,
- required: true,
- disallowNullValue: true)
- final String builderFactory;
-
- /// The import to be used to load `clazz`.
- @JsonKey(nullable: false, required: true, disallowNullValue: true)
- final String import;
-
- /// A list of input extensions for this builder.
- ///
- /// May be null or unreliable and should not be used.
- @deprecated
- @JsonKey(name: 'input_extensions')
- final Iterable<String> inputExtensions;
-
- /// The name of the dart_library target that contains `import`.
- ///
- /// May be null or unreliable and should not be used.
- @deprecated
- final String target;
-
- final TargetBuilderConfigDefaults defaults;
-
- PostProcessBuilderDefinition({
- @required this.builderFactory,
- @required this.import,
- this.inputExtensions,
- this.target,
- TargetBuilderConfigDefaults defaults,
- }) : defaults = defaults ?? const TargetBuilderConfigDefaults();
-
- factory PostProcessBuilderDefinition.fromJson(Map json) =>
- _$PostProcessBuilderDefinitionFromJson(json);
-
- @override
- String toString() => {
- 'import': import,
- 'builderFactory': builderFactory,
- 'defaults': defaults,
- }.toString();
-}
-
-/// Default values that builder authors can specify when users don't fill in the
-/// corresponding key for [TargetBuilderConfig].
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class TargetBuilderConfigDefaults {
- @JsonKey(name: 'generate_for')
- final InputSet generateFor;
-
- final Map<String, dynamic> options;
-
- @JsonKey(name: 'dev_options')
- final Map<String, dynamic> devOptions;
-
- @JsonKey(name: 'release_options')
- final Map<String, dynamic> releaseOptions;
-
- const TargetBuilderConfigDefaults({
- InputSet generateFor,
- Map<String, dynamic> options,
- Map<String, dynamic> devOptions,
- Map<String, dynamic> releaseOptions,
- }) : generateFor = generateFor ?? InputSet.anything,
- options = options ?? const {},
- devOptions = devOptions ?? const {},
- releaseOptions = releaseOptions ?? const {};
-
- factory TargetBuilderConfigDefaults.fromJson(Map json) =>
- _$TargetBuilderConfigDefaultsFromJson(json);
-}
diff --git a/build_config/lib/src/builder_definition.g.dart b/build_config/lib/src/builder_definition.g.dart
deleted file mode 100644
index 550710f..0000000
--- a/build_config/lib/src/builder_definition.g.dart
+++ /dev/null
@@ -1,191 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'builder_definition.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuilderDefinition _$BuilderDefinitionFromJson(Map json) {
- return $checkedNew('BuilderDefinition', json, () {
- $checkKeys(json, allowedKeys: const [
- 'builder_factories',
- 'import',
- 'build_extensions',
- 'target',
- 'auto_apply',
- 'required_inputs',
- 'runs_before',
- 'applies_builders',
- 'is_optional',
- 'build_to',
- 'defaults'
- ], requiredKeys: const [
- 'builder_factories',
- 'import',
- 'build_extensions'
- ], disallowNullValues: const [
- 'builder_factories',
- 'import',
- 'build_extensions'
- ]);
- final val = BuilderDefinition(
- builderFactories: $checkedConvert(json, 'builder_factories',
- (v) => (v as List).map((e) => e as String).toList()),
- buildExtensions: $checkedConvert(
- json,
- 'build_extensions',
- (v) => (v as Map).map(
- (k, e) => MapEntry(
- k as String, (e as List).map((e) => e as String).toList()),
- )),
- import: $checkedConvert(json, 'import', (v) => v as String),
- target: $checkedConvert(json, 'target', (v) => v as String),
- autoApply: $checkedConvert(json, 'auto_apply',
- (v) => _$enumDecodeNullable(_$AutoApplyEnumMap, v)),
- requiredInputs: $checkedConvert(
- json, 'required_inputs', (v) => (v as List)?.map((e) => e as String)),
- runsBefore: $checkedConvert(
- json, 'runs_before', (v) => (v as List)?.map((e) => e as String)),
- appliesBuilders: $checkedConvert(json, 'applies_builders',
- (v) => (v as List)?.map((e) => e as String)),
- isOptional: $checkedConvert(json, 'is_optional', (v) => v as bool),
- buildTo: $checkedConvert(
- json, 'build_to', (v) => _$enumDecodeNullable(_$BuildToEnumMap, v)),
- defaults: $checkedConvert(
- json,
- 'defaults',
- (v) => v == null
- ? null
- : TargetBuilderConfigDefaults.fromJson(v as Map)),
- );
- return val;
- }, fieldKeyMap: const {
- 'builderFactories': 'builder_factories',
- 'buildExtensions': 'build_extensions',
- 'autoApply': 'auto_apply',
- 'requiredInputs': 'required_inputs',
- 'runsBefore': 'runs_before',
- 'appliesBuilders': 'applies_builders',
- 'isOptional': 'is_optional',
- 'buildTo': 'build_to'
- });
-}
-
-T _$enumDecode<T>(
- Map<T, dynamic> enumValues,
- dynamic source, {
- T unknownValue,
-}) {
- if (source == null) {
- throw ArgumentError('A value must be provided. Supported values: '
- '${enumValues.values.join(', ')}');
- }
-
- final value = enumValues.entries
- .singleWhere((e) => e.value == source, orElse: () => null)
- ?.key;
-
- if (value == null && unknownValue == null) {
- throw ArgumentError('`$source` is not one of the supported values: '
- '${enumValues.values.join(', ')}');
- }
- return value ?? unknownValue;
-}
-
-T _$enumDecodeNullable<T>(
- Map<T, dynamic> enumValues,
- dynamic source, {
- T unknownValue,
-}) {
- if (source == null) {
- return null;
- }
- return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
-}
-
-const _$AutoApplyEnumMap = {
- AutoApply.none: 'none',
- AutoApply.dependents: 'dependents',
- AutoApply.allPackages: 'all_packages',
- AutoApply.rootPackage: 'root_package',
-};
-
-const _$BuildToEnumMap = {
- BuildTo.source: 'source',
- BuildTo.cache: 'cache',
-};
-
-PostProcessBuilderDefinition _$PostProcessBuilderDefinitionFromJson(Map json) {
- return $checkedNew('PostProcessBuilderDefinition', json, () {
- $checkKeys(json, allowedKeys: const [
- 'builder_factory',
- 'import',
- 'input_extensions',
- 'target',
- 'defaults'
- ], requiredKeys: const [
- 'builder_factory',
- 'import'
- ], disallowNullValues: const [
- 'builder_factory',
- 'import'
- ]);
- final val = PostProcessBuilderDefinition(
- builderFactory:
- $checkedConvert(json, 'builder_factory', (v) => v as String),
- import: $checkedConvert(json, 'import', (v) => v as String),
- inputExtensions: $checkedConvert(json, 'input_extensions',
- (v) => (v as List)?.map((e) => e as String)),
- target: $checkedConvert(json, 'target', (v) => v as String),
- defaults: $checkedConvert(
- json,
- 'defaults',
- (v) => v == null
- ? null
- : TargetBuilderConfigDefaults.fromJson(v as Map)),
- );
- return val;
- }, fieldKeyMap: const {
- 'builderFactory': 'builder_factory',
- 'inputExtensions': 'input_extensions'
- });
-}
-
-TargetBuilderConfigDefaults _$TargetBuilderConfigDefaultsFromJson(Map json) {
- return $checkedNew('TargetBuilderConfigDefaults', json, () {
- $checkKeys(json, allowedKeys: const [
- 'generate_for',
- 'options',
- 'dev_options',
- 'release_options'
- ]);
- final val = TargetBuilderConfigDefaults(
- generateFor: $checkedConvert(
- json, 'generate_for', (v) => v == null ? null : InputSet.fromJson(v)),
- options: $checkedConvert(
- json,
- 'options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- devOptions: $checkedConvert(
- json,
- 'dev_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- releaseOptions: $checkedConvert(
- json,
- 'release_options',
- (v) => (v as Map)?.map(
- (k, e) => MapEntry(k as String, e),
- )),
- );
- return val;
- }, fieldKeyMap: const {
- 'generateFor': 'generate_for',
- 'devOptions': 'dev_options',
- 'releaseOptions': 'release_options'
- });
-}
diff --git a/build_config/lib/src/common.dart b/build_config/lib/src/common.dart
deleted file mode 100644
index ad77ebd..0000000
--- a/build_config/lib/src/common.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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';
-
-final _defaultDependenciesZoneKey = Symbol('buildConfigDefaultDependencies');
-final _packageZoneKey = Symbol('buildConfigPackage');
-
-T runInBuildConfigZone<T>(
- T Function() fn, String package, List<String> defaultDependencies) =>
- runZoned(fn, zoneValues: {
- _packageZoneKey: package,
- _defaultDependenciesZoneKey: defaultDependencies,
- });
-
-String get currentPackage {
- var package = Zone.current[_packageZoneKey] as String;
- if (package == null) {
- throw StateError(
- 'Must be running inside a build config zone, which can be done using '
- 'the `runInBuildConfigZone` function.');
- }
- return package;
-}
-
-List<String> get currentPackageDefaultDependencies {
- var defaultDependencies =
- Zone.current[_defaultDependenciesZoneKey] as List<String>;
- if (defaultDependencies == null) {
- throw StateError(
- 'Must be running inside a build config zone, which can be done using '
- 'the `runInBuildConfigZone` function.');
- }
- return defaultDependencies;
-}
diff --git a/build_config/lib/src/expandos.dart b/build_config/lib/src/expandos.dart
deleted file mode 100644
index 2cc9e01..0000000
--- a/build_config/lib/src/expandos.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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.
-
-final builderKeyExpando = Expando<String>();
-
-final packageExpando = Expando<String>();
diff --git a/build_config/lib/src/input_set.dart b/build_config/lib/src/input_set.dart
deleted file mode 100644
index e077b3b..0000000
--- a/build_config/lib/src/input_set.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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:json_annotation/json_annotation.dart';
-
-part 'input_set.g.dart';
-
-/// A filter on files inputs or sources.
-///
-/// Takes a list of strings in glob format for [include] and [exclude]. Matches
-/// the `glob()` function in skylark.
-@JsonSerializable(createToJson: false, disallowUnrecognizedKeys: true)
-class InputSet {
- static const anything = InputSet();
-
- /// The globs to include in the set.
- ///
- /// May be null or empty which means every possible path (like `'**'`).
- final List<String> include;
-
- /// The globs as a subset of [include] to remove from the set.
- ///
- /// May be null or empty which means every path in [include].
- final List<String> exclude;
-
- const InputSet({this.include, this.exclude});
-
- factory InputSet.fromJson(dynamic json) {
- if (json is List) {
- json = {'include': json};
- } else if (json is! Map) {
- throw ArgumentError.value(json, 'sources',
- 'Expected a Map or a List but got a ${json.runtimeType}');
- }
- final parsed = _$InputSetFromJson(json as Map);
- if (parsed.include != null &&
- parsed.include.any((s) => s == null || s.isEmpty)) {
- throw ArgumentError.value(
- parsed.include, 'include', 'Include globs must not be empty');
- }
- if (parsed.exclude != null &&
- parsed.exclude.any((s) => s == null || s.isEmpty)) {
- throw ArgumentError.value(
- parsed.exclude, 'exclude', 'Exclude globs must not be empty');
- }
- return parsed;
- }
-
- @override
- String toString() {
- final result = StringBuffer();
- if (include == null || include.isEmpty) {
- result.write('any path');
- } else {
- result.write('paths matching $include');
- }
- if (exclude != null && exclude.isNotEmpty) {
- result.write(' except $exclude');
- }
- return '$result';
- }
-}
diff --git a/build_config/lib/src/input_set.g.dart b/build_config/lib/src/input_set.g.dart
deleted file mode 100644
index 6733313..0000000
--- a/build_config/lib/src/input_set.g.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'input_set.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-InputSet _$InputSetFromJson(Map json) {
- return $checkedNew('InputSet', json, () {
- $checkKeys(json, allowedKeys: const ['include', 'exclude']);
- final val = InputSet(
- include: $checkedConvert(json, 'include',
- (v) => (v as List)?.map((e) => e as String)?.toList()),
- exclude: $checkedConvert(json, 'exclude',
- (v) => (v as List)?.map((e) => e as String)?.toList()),
- );
- return val;
- });
-}
diff --git a/build_config/lib/src/key_normalization.dart b/build_config/lib/src/key_normalization.dart
deleted file mode 100644
index 62b5eae..0000000
--- a/build_config/lib/src/key_normalization.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2017, 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.
-
-const _defaultTargetNamePlaceholder = r'$default';
-
-/// Returns the normalized [builderKey] definition when used from [packageName].
-///
-/// Example normalizations:
-///
-/// - "some_builder" => "$packageName:some_builder"
-/// - ":some_builder" => "$packageName:some_builder"
-/// - "some_package:some_builder" => "some_package:some_builder"
-///
-/// If the legacy separator `|` is used it will be transformed to `:`
-String normalizeBuilderKeyDefinition(String builderKey, String packageName) =>
- _normalizeDefinition(
- builderKey.contains('|')
- ? builderKey.replaceFirst('|', ':')
- : builderKey,
- packageName);
-
-/// Returns the normalized [builderKey] usage when used from [packageName].
-///
-/// Example normalizations:
-///
-/// - "some_package" => "some_package:some_package"
-/// - ":some_builder" => "$packageName:some_builder"
-/// - "some_package:some_builder" => "some_package:some_builder"
-///
-/// If the legacy separator `|` is used it will be transformed to `:`
-String normalizeBuilderKeyUsage(String builderKey, String packageName) =>
- _normalizeUsage(
- builderKey.contains('|')
- ? builderKey.replaceFirst('|', ':')
- : builderKey,
- packageName);
-
-/// Returns the normalized [targetKey] definition when used from [packageName].
-///
-/// Example normalizations:
-///
-/// - "$default" => "$packageName:$packageName"
-/// - "some_target" => "$packageName:some_target"
-/// - ":some_target" => "$packageName:some_target"
-/// - "some_package:some_target" => "some_package|some_target"
-String normalizeTargetKeyDefinition(String targetKey, String packageName) =>
- targetKey == _defaultTargetNamePlaceholder
- ? '$packageName:$packageName'
- : _normalizeDefinition(targetKey, packageName);
-
-/// Returns the normalized [targetKey] usage when used from [packageName].
-///
-/// Example normalizations:
-///
-/// - "$default" => "$packageName:$packageName"
-/// - ":$default" => "$packageName:$packageName"
-/// - "$default:$default" => "$packageName:$packageName"
-/// - "some_package" => "some_package:some_package"
-/// - ":some_target" => "$packageName:some_target"
-/// - "some_package:some_target" => "some_package:some_target"
-String normalizeTargetKeyUsage(String targetKey, String packageName) {
- switch (targetKey) {
- case _defaultTargetNamePlaceholder:
- case ':$_defaultTargetNamePlaceholder':
- case '$_defaultTargetNamePlaceholder:$_defaultTargetNamePlaceholder':
- return '$packageName:$packageName';
- default:
- return _normalizeUsage(targetKey, packageName);
- }
-}
-
-/// Gives a full unique key for [name] used from [packageName].
-///
-/// If [name] omits the separator we assume it's referring to a target or
-/// builder named after a package (which is not this package). If [name] starts
-/// with the separator we assume it's referring to a target within the package
-/// it's used from.
-///
-/// For example: If I depend on `angular` from `my_package` it is treated as a
-/// dependency on the globally unique `angular:angular`.
-String _normalizeUsage(String name, String packageName) {
- if (name.startsWith(':')) return '$packageName$name';
- if (!name.contains(':')) return '$name:$name';
- return name;
-}
-
-/// Gives a full unique key for [name] definied within [packageName].
-///
-/// The result is always '$packageName$separator$name since at definition the
-/// key must be referring to something within [packageName].
-///
-/// For example: If I expose a builder `my_builder` within `my_package` it is
-/// turned into the globally unique `my_package|my_builder`.
-String _normalizeDefinition(String name, String packageName) {
- if (name.startsWith(':')) return '$packageName$name';
- if (!name.contains(':')) return '$packageName:$name';
- return name;
-}
diff --git a/build_config/mono_pkg.yaml b/build_config/mono_pkg.yaml
deleted file mode 100644
index e317dee..0000000
--- a/build_config/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.6.0
- - unit_test:
- - command: pub run test
- os:
- - linux
- - windows
-
-cache:
- directories:
- - .dart_tool/build
diff --git a/build_config/pubspec.yaml b/build_config/pubspec.yaml
deleted file mode 100644
index 12a59db..0000000
--- a/build_config/pubspec.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: build_config
-version: 0.4.2
-description: Support for parsing `build.yaml` configuration.
-homepage: https://github.com/dart-lang/build/tree/master/build_config
-
-environment:
- sdk: '>=2.6.0 <3.0.0'
-
-dependencies:
- checked_yaml: ^1.0.0
- json_annotation: '>=1.0.0 <4.0.0'
- meta: ^1.1.0
- path: ^1.4.0
- pubspec_parse: ^0.1.5
- yaml: ^2.1.11
-
-dev_dependencies:
- build_runner: ^1.0.0
- json_serializable: ^3.0.0
- term_glyph: ^1.0.0
- test: ^1.6.0
diff --git a/build_modules/BUILD.gn b/build_modules/BUILD.gn
deleted file mode 100644
index cee16c9..0000000
--- a/build_modules/BUILD.gn
+++ /dev/null
@@ -1,31 +0,0 @@
-# This file is generated by importer.py for build_modules-2.8.0
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_modules") {
- package_name = "build_modules"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/pedantic",
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/glob",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/collection",
- "//third_party/dart-pkg/pub/graphs",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/scratch_space",
- "//third_party/dart-pkg/pub/analyzer",
- "//third_party/dart-pkg/pub/async",
- "//third_party/dart-pkg/pub/build_config",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/bazel_worker",
- "//third_party/dart-pkg/pub/json_annotation",
- ]
-}
diff --git a/build_modules/CHANGELOG.md b/build_modules/CHANGELOG.md
deleted file mode 100644
index 92c2fbe..0000000
--- a/build_modules/CHANGELOG.md
+++ /dev/null
@@ -1,346 +0,0 @@
-## 2.8.0
-
-- Add the ability to pass a list of experiments to enable to the KernelBuilder.
-
-## 2.7.0
-
-- Add support for an environment variable `BUILD_DART2JS_VM_ARGS` which can
- be used to supply Dart vm arguments for the dart2js processes.
-
-## 2.6.3
-
-- Keep cached deserialized module instances in more cases. This may improve
- performance of incremental builds in watch mode.
-- **Deprecated**: The package specific unsupported module whitelist option
- provided by `computeTransitiveDependencies`. The only known uses are being
- removed.
-- Allow analyzer version `0.39.x`.
-
-## 2.6.2
-
-Republish of `2.6.0` with the proper min sdk contraint.
-
-## 2.6.1
-
-### Bug fix for issue #2464
-
-Ignore the `trackUnusedInputs` option that was added in `2.6.0`.
-
-This option will be respected again in the next release which will have the
-proper minimum sdk constraint.
-
-## 2.6.0
-
-Add support for dependency pruning to the `KernelBuilder`. This should greatly
-improve the invalidation semantics for builds, meaning that less code will be
-recompiled for each edit you make.
-
-This is not enabled by default but can be enabled by passing
-`trackUnusedInputs: true` to the `KernelBuilder` constructor.
-
-## 2.5.0
-
-- Add an option to skip the unsupported module check for modules in specified
- packages.
-
-## 2.4.3
-
-- Allow analyzer version 0.38.0.
-
-## 2.4.2
-
-- Support the latest release of `package:json_annotation`.
-
-## 2.4.1
-
-- Require non-empty output from kernel build steps.
-
-## 2.4.0
-
-- Allow overriding the target name passed to the kernel worker.
-
-## 2.3.1
-
-- Allow analyzer version 0.37.0.
-
-## 2.3.0
-
-- Add a `hasMain` boolean to the `ModuleLibrary` class.
- - This is now used instead of `isEntrypoint` for determining whether or not
- to copy module files for application discovery.
-- Fix `computeTransitiveDeps` to do error checking for the root module as well
- as transitive modules.
-
-## 2.2.0
-
-- Make the `librariesPath` in the `KernelBuilder` configurable.
-- Fixed bug where the configured dart SDK was ignored.
-
-## 2.1.3
-
-- Skip compiling modules with kernel when the primary source isn't the primary
- input (only shows up in non-lazy builds - essentially just tests).
-
-## 2.1.2
-
-- Output additional `.module` files for all entrypoints to ease discovery of
- modules for compilers.
-
-## 2.1.1
-
-- Allow `build_config` `0.4.x`.
-
-## 2.1.0
-
-- Make using the incremental compiler in the `KernelBuilder` configurable.
-
-## 2.0.0
-
-### Breaking Changes
-
-- Remove the `merge` method from `Module` and replace with a static
- `Module.merge`. Module instances are now immutable.
-- Remove `jsId`, and `jsSourceMapId` from `Module`.
-- `DartPlatform` no longer has hard coded platforms, and its constructor is now
- public. Anybody is now free to create their own `platform`.
-- Removed the platform specific builder factories from the `builders.dart` file.
- - Packages that want to target compilation for a platform should create their
- own builder factories.
-- Removed completely the analyzer based builders - `UnlinkedSummaryBuilder` and
- `LinkedSummaryBuilder`.
- - All backends should now be using the `KernelBuilder` instead.
-- Removed the default module builders for each supported platform. These
- must now be created by the packages that want to add compilation targeting a
- specific platform.
- - This will help reduce asset graph bloat caused by platforms that you weren't
- actually targeting.
-
-### Improvements
-
-- Update the kernel worker to pass input digests, along with
- `--reuse-compiler-result` and `--use-incremental-compiler`.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-
-## 1.0.11
-
-- Allow build_config 0.4.x.
-
-## 1.0.10
-
-- Fix a performance issue in the kernel_builder, especially for larger projects.
-
-## 1.0.9
-
-- Allow configuring the platform SDK directory in the `KernelBuilder` builder.
-
-## 1.0.8
-
-- Don't follow `dart.library.isolate` conditional imports for the DDC
- platform.
-
-## 1.0.7+2
-
-- Update `dart2js` snapshot arguments for upcoming SDK.
-
-## 1.0.7+1
-
-- Fix broken release by updating `dart2js` worker and restricting sdk version.
-
-## 1.0.7
-
-- Explicitly skip dart-ext uris during module creation.
- - Filed Issue #2047 to track real support for native extensions.
-- Run workers with mode `detachedWithStdio` if no terminal is connected.
-
-## 1.0.6
-
-- Improved the time tracking for kernel and analyzer actions by not reporting
- time spent waiting for a worker to be available.
-
-## 1.0.5
-
-- Increased the upper bound for `package:analyzer` to `<0.36.0`.
-
-## 1.0.4
-
-- Update to `package:graphs` version `0.2.0`.
-- Use `dartdevc --kernel` instead of `dartdevk`.
-
-## 1.0.3
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 1.0.2
-
-- Support the latest `package:json_annotation`.
-
-## 1.0.1
-
-- Increased the upper bound for `package:analyzer` to '<0.34.0'.
-
-## 1.0.0
-
-### Breaking Changes
-
-- The `Module` constructor has an additional required parameter `isSupported`,
- which indicates if a module is supported on that module's platform.
-
-## 0.4.0
-
-### Improvements
-
-- Modules are now platform specific, and config specific imports using
- `dart.library.*` constants are supported.
-
-### Breaking Configuration Changes
-
-- Module granularity now has to be configured per platform, so instead of
- configuring it using the `build_modules|modules` builder, you now need to
- configure the builder for each specific platform:
-
-```yaml
-targets:
- $default:
- build_modules|dartdevc:
- options:
- strategy: fine
-```
-
- The supported platforms are currently `dart2js`, `dartdevc`, `flutter`, and
- `vm`.
-
-### Breaking API Changes
-
-- Output extensions of builders have changed to include the platform being built
- for.
- - All the top level file extension getters are now methods that take a
- platform and return the extension for that platform.
-- Most builders are no longer applied by default, you must manually apply them
- using applies_builders in your builder.
-- Most builder constructors now require a `platform` argument.
-
-## 0.3.2
-
-- Module strategies are now respected for all packages instead of just the root
- package.
-- Can now mix and match fine and coarse strategies at will, even within package
- cycles (although this may cause larger modules).
-- Removed analyzer dependency.
-
-## 0.3.1+1
-
-- Support `package:json_annotation` v1.
-
-## 0.3.1
-
-- Change the default module strategy for the root package to `coarse`.
-
-## 0.3.0
-
-### Improvements
-
-- Updated dart2js support so that it can do multiple builds concurrently and
- will restart workers periodically to mitigate the effects of
- dart-lang/sdk#33708.
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-### Breaking Changes
-
-- Removed the `kernelSummaryExtension`, and renamed the `KernelSummaryBuilder`
- to `KernelBuilder`. The new builder can be used to create summaries or full
- kernel files, and requires users to give it a custom sdk.
-- Changed `metaModuleCleanBuilder` to read `.module.library` files which are
- produced by the `moduleLibrayBuilder`. Clients using the automatically
- generated build script will get this automatically. Clients which have
- manually written build scripts will need to add it.
-
-## 0.2.3
-
-- Update to the latest `package:scratch_space` and don't manually clear it out
- between builds. This provides significant speed improvements for large
- projects.
-
-## 0.2.2+6
-
-- Support the latest `package:build_config`.
-
-## 0.2.2+5
-
-- Updated the missing modules message to highlight that the error is likely due
- to a missing dependency.
-
-## 0.2.2+4
-
-- Support `package:analyzer` `0.32.0`.
-
-## 0.2.2+3
-
-- Fix a race condition where we could fail to find the modules for some
- dependencies.
-
-## 0.2.2+2
-
-- Fix an issue where modules were unnecessarily being built with DDC.
- [#1375](https://github.com/dart-lang/build/issues/1375).
-
-## 0.2.2+1
-
-- Fix an issue with new files causing subsequent build failures
- [#1358](https://github.com/dart-lang/build/issues/1358).
-- Expose `MetaModuleCleanBuilder` and `metaModuleCleanExtension` publicly for
- usage in tests and manual build scripts.
-
-## 0.2.2
-
-- Clean up `.module` and summary files from the output and server.
-- Add new `ModuleBuilder` strategies. By default the `coarse` strategy is used
- for all non-root packages and will create a minimum number of modules. This
- strategy can not be overridden. However, for the root package, the `fine`
- strategy will be used which creates a module for each strongly
- connected component. You can override this behavior by providing `coarse`
- to the `strategy` option.
-
- Example configuration:
-
- ```yaml
- targets:
- $default:
- builders:
- build_modules|modules:
- options:
- strategy: coarse
- ```
-
-## 0.2.1
-
-- Give a guaranteed reverse dependency order for
- `Module.computeTransitiveDependencies`
-
-## 0.2.0+2
-
-- Fix use of `whereType` in `MissingModulesException`,
- https://github.com/dart-lang/build/issues/1123.
-
-## 0.2.0+1
-
-- Fix null pointer error in `MissingModulesException`,
- https://github.com/dart-lang/build/issues/1092.
-
-## 0.2.0
-
-- `computeTransitiveDependencies` now throws a `MissingModulesException` instead
- of logging a warning if it discovers a missing module.
-
-## 0.1.0+2
-
-- Fix a bug with the dart2js workers where the worker could hang if you try to
- re-use it after calling `terminateWorkers`. This only really surfaces in test
- environments.
-
-## 0.1.0+1
-
-- Fix a bug with imports to libraries that have names starting with `dart.`
-
-## 0.1.0
-
-- Split from `build_web_compilers`.
diff --git a/build_modules/LICENSE b/build_modules/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/build_modules/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_modules/README.md b/build_modules/README.md
deleted file mode 100644
index 4ce5c7d..0000000
--- a/build_modules/README.md
+++ /dev/null
@@ -1,102 +0,0 @@
-<p align="center">
- Module builders for modular compilation pipelines.
- <br>
- <a href="https://travis-ci.org/dart-lang/build">
- <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
- </a>
- <a href="https://github.com/dart-lang/build/labels/package%3A%20build_modules">
- <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_modules.svg" alt="Issues related to build_modules" />
- </a>
- <a href="https://pub.dev/packages/build_modules">
- <img src="https://img.shields.io/pub/v/build_modules.svg" alt="Pub Package Version" />
- </a>
- <a href="https://pub.dev/documentation/build_modules/latest/">
- <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
- </a>
- <a href="https://gitter.im/dart-lang/build">
- <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
- </a>
-</p>
-
-This package provides generic module builders which can be used to create custom
-compilation pipelines. It is used by [`build_web_compilers`][] and
-[`build_vm_compilers`][] package which provides standard builders for the web
-and vm platforms.
-
-## Usage
-
-There should be no need to import this package directly unless you are
-developing a custom compiler pipeline. See documentation in
-[`build_web_compilers`][] and [`build_vm_compilers`][] for more details on
-building your Dart code.
-
-[`build_web_compilers`]: https://pub.dev/packages/build_web_compilers
-[`build_vm_compilers`]: https://pub.dev/packages/build_vm_compilers
-
-## Module creation
-
-The overall process for emitting modules follows these steps:
-
-1. Emit a `.module.library` asset for every `.dart` library containing a
- description of the directives (imports, exports, and parts), a list of the
- `dart:` imports used, and a determination of whether the library is an
- "entrypoint". Entrypoint libraries are either those which are likely to be
- directly imported (they are under `lib/` but not `lib/src/`) or which have a
- `main`. Only the libraries that can be imported (they aren't part files) will
- have an output. This step is mainly separated out for better invalidation
- behavior since the output will change less frequently than the code. The
- outputs from this step are non differentiated by platform.
-2. Emit package level `.meta_module` assets. This is an aggregation of the
- `.module.library` information with a first run at creating a module
- structure. The output depends on the algorithm, described below. The outputs
- from this step are specific to a platform and will indicate which libraries
- contain unsupported `dart:` imports for a platform. Conditional imports will
- also be resolved to a concrete dependency based on the platform. In this step
- the dependencies of modules references the imported library, which may not
- match the primary source of the module containing that library.
-3. Emit package level `.meta_module.clean` assets. This step performs an extra
- run of the strongly connected components algorithm so that any libraries
- which are in an import cycle are grouped into a single module. This is done
- as a separate step so that it can be sure it may read all the `.meta_module`
- results across packages in a dependency cycle so that it may resolve import
- cycles across packages. As modules are merged due to import cycles the new
- module becomes the union of their sources and dependencies. Dependencies are
- resolved to the "primary source" of the module containing the imported
- library.
-4. Emit `.module` assets which contain a filtered view of the package level
- meta-module specific to a single module. These are emitted for the "primary
- source" of each module, as well as each library which is an entrypoint.
-
-## Module algorithms
-
-### Fine
-
-The fine-grained module algorithm is straightforward - any dart library which
-_can_ be it's own module, _is_ it's own module. Libraries are only grouped into
-a module when there is an import cycle between them.
-
-The `.meta_module` step filters unsupported libraries and does no clustering.
-Import cycles are resolved by the `.meta_module.clean` step.
-
-### Coarse
-
-The coarse-grained module algorithm attempts to cluster libraries into larger
-modules without bringing in more code than may be imported by downstream code.
-It assumes that libraries under `lib/src/` won't be imported directly outside of
-the package. Assuming that external packages only import the libraries outside
-of `lib/src/` then no code outside of the transitive imports will be brought in
-due to module clustering.
-
-The `.meta_module` step performs strongly connected components and libraries
-which are in an import cycle are grouped into modules since they can't be
-ordered otherwise. Within each top level directory under the package (`lib/`,
-`test/`, etc) the libraries are further bundled into modules where possible.
-Each "entrypoint" library is always kept in it's own modules (other than in the
-case of import cycles). Non entrypoint libraries are grouped where possible
-based on the entrypoints that transitively import them. Any non-entrypoint which
-is only transitively imported by a single entrypoint is merged into the module
-for that entrypoint. Any non-entrypoints which are imported by the same set of
-entrypoints are merged into their own module. The "primary source" for any
-module is always the lowest alpha-sorted source, regardless of whether it is an
-entrypoint. As libraries are merged the module becomes the union of their
-sources and dependencies.
diff --git a/build_modules/build.yaml b/build_modules/build.yaml
deleted file mode 100644
index a73fedf..0000000
--- a/build_modules/build.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-builders:
- module_library:
- import: "package:build_modules/builders.dart"
- builder_factories:
- - moduleLibraryBuilder
- build_extensions:
- .dart:
- - .module.library
- auto_apply: all_packages
- is_optional: True
- required_inputs: [".dart"]
- applies_builders: ["|module_cleanup"]
-post_process_builders:
- module_cleanup:
- import: "package:build_modules/builders.dart"
- builder_factory: "moduleCleanup"
diff --git a/build_modules/dart_test.yaml b/build_modules/dart_test.yaml
deleted file mode 100644
index 56f2311..0000000
--- a/build_modules/dart_test.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-tags:
- presubmit-only:
- skip: "Should only be run during presubmit"
- presets: {presubmit: {skip: false}}
diff --git a/build_modules/lib/build_modules.dart b/build_modules/lib/build_modules.dart
deleted file mode 100644
index 216b65d..0000000
--- a/build_modules/lib/build_modules.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/errors.dart' show MissingModulesException, UnsupportedModules;
-export 'src/kernel_builder.dart'
- show KernelBuilder, multiRootScheme, reportUnusedKernelInputs;
-export 'src/meta_module_builder.dart'
- show MetaModuleBuilder, metaModuleExtension;
-export 'src/meta_module_clean_builder.dart'
- show MetaModuleCleanBuilder, metaModuleCleanExtension;
-export 'src/module_builder.dart' show ModuleBuilder, moduleExtension;
-export 'src/module_library_builder.dart'
- show ModuleLibraryBuilder, moduleLibraryExtension;
-export 'src/modules.dart';
-export 'src/platform.dart' show DartPlatform;
-export 'src/scratch_space.dart' show scratchSpace, scratchSpaceResource;
-export 'src/workers.dart' show dart2JsWorkerResource, dartdevkDriverResource;
diff --git a/build_modules/lib/builders.dart b/build_modules/lib/builders.dart
deleted file mode 100644
index 4366a82..0000000
--- a/build_modules/lib/builders.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2017, 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:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:build_modules/src/module_cleanup.dart';
-import 'package:build_modules/src/module_library_builder.dart';
-
-Builder moduleLibraryBuilder(_) => const ModuleLibraryBuilder();
-
-PostProcessBuilder moduleCleanup(_) => const ModuleCleanup();
diff --git a/build_modules/lib/src/common.dart b/build_modules/lib/src/common.dart
deleted file mode 100644
index e7b7197..0000000
--- a/build_modules/lib/src/common.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import 'kernel_builder.dart';
-
-final defaultAnalysisOptionsId =
- AssetId('build_modules', 'lib/src/analysis_options.default.yaml');
-
-String defaultAnalysisOptionsArg(ScratchSpace scratchSpace) =>
- '--options=${scratchSpace.fileFor(defaultAnalysisOptionsId).path}';
-
-// TODO: better solution for a .packages file, today we just create a new one
-// for every kernel build action.
-Future<File> createPackagesFile(Iterable<AssetId> allAssets) async {
- var allPackages = allAssets.map((id) => id.package).toSet();
- var packagesFileDir =
- await Directory.systemTemp.createTemp('kernel_builder_');
- var packagesFile = File(p.join(packagesFileDir.path, '.packages'));
- await packagesFile.create();
- await packagesFile.writeAsString(allPackages
- .map((pkg) => '$pkg:$multiRootScheme:///packages/$pkg')
- .join('\r\n'));
- return packagesFile;
-}
-
-enum ModuleStrategy { fine, coarse }
-
-ModuleStrategy moduleStrategy(BuilderOptions options) {
- var config = options.config['strategy'] as String ?? 'coarse';
- switch (config) {
- case 'coarse':
- return ModuleStrategy.coarse;
- case 'fine':
- return ModuleStrategy.fine;
- default:
- throw ArgumentError('Unexpected ModuleBuilder strategy: $config');
- }
-}
-
-/// Validates that [config] only has the top level keys [supportedOptions].
-///
-/// Throws an [ArgumentError] if not.
-void validateOptions(Map<String, dynamic> config, List<String> supportedOptions,
- String builderKey) {
- var unsupportedOptions =
- config.keys.where((o) => !supportedOptions.contains(o));
- if (unsupportedOptions.isNotEmpty) {
- throw ArgumentError.value(unsupportedOptions.join(', '), builderKey,
- 'only $supportedOptions are supported options, but got');
- }
-}
diff --git a/build_modules/lib/src/errors.dart b/build_modules/lib/src/errors.dart
deleted file mode 100644
index d3dfbf1..0000000
--- a/build_modules/lib/src/errors.dart
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2017, 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';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-
-import 'module_library.dart';
-import 'module_library_builder.dart';
-import 'modules.dart';
-
-/// An [Exception] that is thrown when a worker returns an error.
-abstract class _WorkerException implements Exception {
- final AssetId failedAsset;
-
- final String error;
-
- /// A message to prepend to [toString] output.
- String get message;
-
- _WorkerException(this.failedAsset, this.error);
-
- @override
- String toString() => '$message:$failedAsset\n\nResponse:$error\n';
-}
-
-/// An [Exception] that is thrown when the analyzer fails to create a summary.
-class AnalyzerSummaryException extends _WorkerException {
- @override
- final String message = 'Error creating summary for module';
-
- AnalyzerSummaryException(AssetId summaryId, String error)
- : super(summaryId, error);
-}
-
-/// An [Exception] that is thrown when the common frontend fails to create a
-/// kernel summary.
-class KernelException extends _WorkerException {
- @override
- final String message = 'Error creating kernel summary for module';
-
- KernelException(AssetId summaryId, String error) : super(summaryId, error);
-}
-
-/// An [Exception] that is thrown when there are some missing modules.
-class MissingModulesException implements Exception {
- final String message;
-
- @override
- String toString() => message;
-
- MissingModulesException._(this.message);
-
- static Future<MissingModulesException> create(Set<AssetId> missingSources,
- Iterable<Module> transitiveModules, AssetReader reader) async {
- var buffer = StringBuffer('''
-Unable to find modules for some sources, this is usually the result of either a
-bad import, a missing dependency in a package (or possibly a dev_dependency
-needs to move to a real dependency), or a build failure (if importing a
-generated file).
-
-Please check the following imports:\n
-''');
-
- var checkedSourceDependencies = <AssetId, Set<AssetId>>{};
- for (var module in transitiveModules) {
- var missingIds = module.directDependencies.intersection(missingSources);
- for (var missingId in missingIds) {
- var checkedAlready =
- checkedSourceDependencies.putIfAbsent(missingId, () => <AssetId>{});
- for (var sourceId in module.sources) {
- if (checkedAlready.contains(sourceId)) {
- continue;
- }
- checkedAlready.add(sourceId);
- var message =
- await _missingImportMessage(sourceId, missingId, reader);
- if (message != null) buffer.writeln(message);
- }
- }
- }
-
- return MissingModulesException._(buffer.toString());
- }
-}
-
-/// Checks if [sourceId] directly imports [missingId], and returns an error
-/// message if so.
-Future<String> _missingImportMessage(
- AssetId sourceId, AssetId missingId, AssetReader reader) async {
- var contents = await reader.readAsString(sourceId);
- // ignore: deprecated_member_use
- var parsed = parseDirectives(contents, suppressErrors: true);
- var import =
- parsed.directives.whereType<UriBasedDirective>().firstWhere((directive) {
- var uriString = directive.uri.stringValue;
- if (uriString.startsWith('dart:')) return false;
- var id = AssetId.resolve(uriString, from: sourceId);
- return id == missingId;
- }, orElse: () => null);
- if (import == null) return null;
- var lineInfo = parsed.lineInfo.getLocation(import.offset);
- return '`$import` from $sourceId at $lineInfo';
-}
-
-/// An [Exception] that is thrown when there are some unsupported modules.
-class UnsupportedModules implements Exception {
- final Set<Module> unsupportedModules;
-
- UnsupportedModules(this.unsupportedModules);
-
- Stream<ModuleLibrary> exactLibraries(AssetReader reader) async* {
- for (var module in unsupportedModules) {
- for (var source in module.sources) {
- var libraryId = source.changeExtension(moduleLibraryExtension);
- ModuleLibrary library;
- if (await reader.canRead(libraryId)) {
- library = ModuleLibrary.deserialize(
- libraryId, await reader.readAsString(libraryId));
- } else {
- // A missing .module.library file indicates a part file, which can't
- // have import statements, so we just skip them.
- continue;
- }
- if (library.sdkDeps
- .any((lib) => !module.platform.supportsLibrary(lib))) {
- yield library;
- }
- }
- }
- }
-
- @override
- String toString() =>
- 'Some modules contained libraries that were incompatible '
- 'with the current platform.';
-}
diff --git a/build_modules/lib/src/kernel_builder.dart b/build_modules/lib/src/kernel_builder.dart
deleted file mode 100644
index 24e2abf..0000000
--- a/build_modules/lib/src/kernel_builder.dart
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:graphs/graphs.dart' show crawlAsync;
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import 'common.dart';
-import 'errors.dart';
-import 'module_builder.dart';
-import 'module_cache.dart';
-import 'modules.dart';
-import 'platform.dart';
-import 'scratch_space.dart';
-import 'workers.dart';
-
-const multiRootScheme = 'org-dartlang-app';
-
-/// A builder which can output kernel files for a given sdk.
-///
-/// This creates kernel files based on [moduleExtension] files, which are what
-/// determine the module structure of an application.
-class KernelBuilder implements Builder {
- @override
- final Map<String, List<String>> buildExtensions;
-
- final bool useIncrementalCompiler;
-
- final bool trackUnusedInputs;
-
- final String outputExtension;
-
- final DartPlatform platform;
-
- /// Whether this should create summary kernel files or full kernel files.
- ///
- /// Summary files only contain the "outline" of the module - you can think of
- /// this as everything but the method bodies.
- final bool summaryOnly;
-
- /// The sdk kernel file for the current platform.
- final String sdkKernelPath;
-
- /// The root directory of the platform's dart SDK.
- ///
- /// If not provided, defaults to the directory of
- /// [Platform.resolvedExecutable].
- ///
- /// On flutter this is the path to the root of the flutter_patched_sdk
- /// directory, which contains the platform kernel files.
- final String platformSdk;
-
- /// The absolute path to the libraries file for the current platform.
- ///
- /// If not provided, defaults to "lib/libraries.json" in the sdk directory.
- final String librariesPath;
-
- /// The `--target` argument passed to the kernel worker.
- ///
- /// Optional. When omitted the [platform] name is used.
- final String kernelTargetName;
-
- /// Experiments to pass to kernel (as --enable-experiment=<experiment> args).
- final Iterable<String> experiments;
-
- KernelBuilder(
- {@required this.platform,
- @required this.summaryOnly,
- @required this.sdkKernelPath,
- @required this.outputExtension,
- String librariesPath,
- bool useIncrementalCompiler,
- bool trackUnusedInputs,
- String platformSdk,
- String kernelTargetName,
- Iterable<String> experiments})
- : platformSdk = platformSdk ?? sdkDir,
- kernelTargetName = kernelTargetName ?? platform.name,
- librariesPath = librariesPath ??
- p.join(platformSdk ?? sdkDir, 'lib', 'libraries.json'),
- useIncrementalCompiler = useIncrementalCompiler ?? false,
- trackUnusedInputs = trackUnusedInputs ?? false,
- buildExtensions = {
- moduleExtension(platform): [outputExtension]
- },
- experiments = experiments ?? [];
-
- @override
- Future build(BuildStep buildStep) async {
- var module = Module.fromJson(
- json.decode(await buildStep.readAsString(buildStep.inputId))
- as Map<String, dynamic>);
- // Entrypoints always have a `.module` file for ease of looking them up,
- // but they might not be the primary source.
- if (module.primarySource.changeExtension(moduleExtension(platform)) !=
- buildStep.inputId) {
- return;
- }
-
- try {
- await _createKernel(
- module: module,
- buildStep: buildStep,
- summaryOnly: summaryOnly,
- outputExtension: outputExtension,
- targetName: kernelTargetName,
- dartSdkDir: platformSdk,
- sdkKernelPath: sdkKernelPath,
- librariesPath: librariesPath,
- useIncrementalCompiler: useIncrementalCompiler,
- trackUnusedInputs: trackUnusedInputs,
- experiments: experiments);
- } on MissingModulesException catch (e) {
- log.severe(e.toString());
- } on KernelException catch (e, s) {
- log.severe(
- 'Error creating '
- '${module.primarySource.changeExtension(outputExtension)}',
- e,
- s);
- }
- }
-}
-
-/// Creates a kernel file for [module].
-Future<void> _createKernel(
- {@required Module module,
- @required BuildStep buildStep,
- @required bool summaryOnly,
- @required String outputExtension,
- @required String targetName,
- @required String dartSdkDir,
- @required String sdkKernelPath,
- @required String librariesPath,
- @required bool useIncrementalCompiler,
- @required bool trackUnusedInputs,
- @required Iterable<String> experiments}) async {
- var request = WorkRequest();
- var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
- var outputId = module.primarySource.changeExtension(outputExtension);
- var outputFile = scratchSpace.fileFor(outputId);
-
- File packagesFile;
- var kernelDeps = <AssetId>[];
-
- // Maps the inputs paths we provide to the kernel worker to asset ids,
- // if `trackUnusedInputs` is `true`.
- Map<String, AssetId> kernelInputPathToId;
- // If `trackUnusedInputs` is `true`, this is the file we will use to
- // communicate the used inputs with the kernel worker.
- File usedInputsFile;
-
- await buildStep.trackStage('CollectDeps', () async {
- var sourceDeps = <AssetId>[];
-
- await _findModuleDeps(
- module, kernelDeps, sourceDeps, buildStep, outputExtension);
-
- var allAssetIds = <AssetId>{
- ...module.sources,
- ...kernelDeps,
- ...sourceDeps,
- };
- await scratchSpace.ensureAssets(allAssetIds, buildStep);
-
- packagesFile = await createPackagesFile(allAssetIds);
- if (trackUnusedInputs) {
- usedInputsFile = await File(p.join(
- (await Directory.systemTemp.createTemp('kernel_builder_')).path,
- 'used_inputs.txt'))
- .create();
- kernelInputPathToId = {};
- }
-
- await _addRequestArguments(
- request,
- module,
- kernelDeps,
- targetName,
- dartSdkDir,
- sdkKernelPath,
- librariesPath,
- outputFile,
- packagesFile,
- summaryOnly,
- useIncrementalCompiler,
- buildStep,
- experiments,
- usedInputsFile: usedInputsFile,
- kernelInputPathToId: kernelInputPathToId);
- });
-
- // We need to make sure and clean up the temp dir, even if we fail to compile.
- try {
- var frontendWorker = await buildStep.fetchResource(frontendDriverResource);
- var response = await frontendWorker.doWork(request,
- trackWork: (response) => buildStep
- .trackStage('Kernel Generate', () => response, isExternal: true));
- if (response.exitCode != EXIT_CODE_OK || !await outputFile.exists()) {
- throw KernelException(
- outputId, '${request.arguments.join(' ')}\n${response.output}');
- }
-
- if (response.output?.isEmpty == false) {
- log.info(response.output);
- }
-
- // Copy the output back using the buildStep.
- await scratchSpace.copyOutput(outputId, buildStep, requireContent: true);
-
- // Note that we only want to do this on success, we can't trust the unused
- // inputs if there is a failure.
- if (usedInputsFile != null) {
- await reportUnusedKernelInputs(
- usedInputsFile, kernelDeps, kernelInputPathToId, buildStep);
- }
- } finally {
- await packagesFile.parent.delete(recursive: true);
- await usedInputsFile?.parent?.delete(recursive: true);
- }
-}
-
-/// Reports any unused kernel inputs based on the [usedInputsFile] we get
-/// back from the kernel/ddk workers.
-///
-/// This file logs paths as they were given in the original [WorkRequest],
-/// so [inputPathToId] is used to map those paths back to the kernel asset ids.
-///
-/// This function will not report any unused dependencies if:
-///
-/// - It isn't able to match all reported used dependencies to an asset id (it
-/// would be unsafe to do so in that case).
-/// - No used dependencies are reported (it is assumed something went wrong
-/// or there were zero deps to begin with).
-Future<void> reportUnusedKernelInputs(
- File usedInputsFile,
- Iterable<AssetId> transitiveKernelDeps,
- Map<String, AssetId> inputPathToId,
- BuildStep buildStep) async {
- var usedPaths = await usedInputsFile.readAsLines();
- if (usedPaths.isEmpty || usedPaths.first == '') return;
-
- String firstMissingInputPath;
- var usedIds = usedPaths.map((usedPath) {
- var id = inputPathToId[usedPath];
- if (id == null) firstMissingInputPath ??= usedPath;
- return id;
- }).toSet();
-
- if (firstMissingInputPath != null) {
- log.warning('Error reporting unused kernel deps, unable to map path: '
- '`$firstMissingInputPath` back to an asset id.\n\nPlease file an issue '
- 'at https://github.com/dart-lang/build/issues/new.');
- return;
- }
-
- buildStep.reportUnusedAssets(
- transitiveKernelDeps.where((id) => !usedIds.contains(id)));
-}
-
-/// Finds the transitive dependencies of [root] and categorizes them as
-/// [kernelDeps] or [sourceDeps].
-///
-/// A module will have it's kernel file in [kernelDeps] if it and all of it's
-/// transitive dependencies have readable kernel files. If any module has no
-/// readable kernel file then it, and all of it's dependents will be categorized
-/// as [sourceDeps] which will have all of their [Module.sources].
-Future<void> _findModuleDeps(
- Module root,
- List<AssetId> kernelDeps,
- List<AssetId> sourceDeps,
- BuildStep buildStep,
- String outputExtension) async {
- final resolvedModules = await _resolveTransitiveModules(root, buildStep);
-
- final sourceOnly = await _parentsOfMissingKernelFiles(
- resolvedModules, buildStep, outputExtension);
-
- for (final module in resolvedModules) {
- if (sourceOnly.contains(module.primarySource)) {
- sourceDeps.addAll(module.sources);
- } else {
- kernelDeps.add(module.primarySource.changeExtension(outputExtension));
- }
- }
-}
-
-/// The transitive dependencies of [root], not including [root] itself.
-Future<List<Module>> _resolveTransitiveModules(
- Module root, BuildStep buildStep) async {
- var missing = <AssetId>{};
- var modules = await crawlAsync<AssetId, Module>(
- [root.primarySource],
- (id) => buildStep.fetchResource(moduleCache).then((c) async {
- var moduleId =
- id.changeExtension(moduleExtension(root.platform));
- var module = await c.find(moduleId, buildStep);
- if (module == null) {
- missing.add(moduleId);
- } else if (module.isMissing) {
- missing.add(module.primarySource);
- }
- return module;
- }),
- (id, module) => module.directDependencies)
- .skip(1) // Skip the root.
- .toList();
-
- if (missing.isNotEmpty) {
- throw await MissingModulesException.create(
- missing, [...modules, root], buildStep);
- }
-
- return modules;
-}
-
-/// Finds the primary source of all transitive parents of any module which does
-/// not have a readable kernel file.
-///
-/// Inverts the direction of the graph and then crawls to all reachables nodes
-/// from the modules which do not have a readable kernel file
-Future<Set<AssetId>> _parentsOfMissingKernelFiles(
- List<Module> modules, BuildStep buildStep, String outputExtension) async {
- final sourceOnly = <AssetId>{};
- final parents = <AssetId, Set<AssetId>>{};
- for (final module in modules) {
- for (final dep in module.directDependencies) {
- parents.putIfAbsent(dep, () => <AssetId>{}).add(module.primarySource);
- }
- if (!await buildStep
- .canRead(module.primarySource.changeExtension(outputExtension))) {
- sourceOnly.add(module.primarySource);
- }
- }
- final toCrawl = Queue.of(sourceOnly);
- while (toCrawl.isNotEmpty) {
- final current = toCrawl.removeFirst();
- if (!parents.containsKey(current)) continue;
- for (final next in parents[current]) {
- if (!sourceOnly.add(next)) {
- toCrawl.add(next);
- }
- }
- }
- return sourceOnly;
-}
-
-/// Fills in all the required arguments for [request] in order to compile the
-/// kernel file for [module].
-Future<void> _addRequestArguments(
- WorkRequest request,
- Module module,
- Iterable<AssetId> transitiveKernelDeps,
- String targetName,
- String sdkDir,
- String sdkKernelPath,
- String librariesPath,
- File outputFile,
- File packagesFile,
- bool summaryOnly,
- bool useIncrementalCompiler,
- AssetReader reader,
- Iterable<String> experiments, {
- File usedInputsFile,
- Map<String, AssetId> kernelInputPathToId,
-}) async {
- // Add all kernel outlines as summary inputs, with digests.
- var inputs = await Future.wait(transitiveKernelDeps.map((id) async {
- var relativePath = p.url.relative(scratchSpace.fileFor(id).uri.path,
- from: scratchSpace.tempDir.uri.path);
- var path = '$multiRootScheme:///$relativePath';
- if (kernelInputPathToId != null) {
- kernelInputPathToId[path] = id;
- }
- return Input()
- ..path = path
- ..digest = (await reader.digest(id)).bytes;
- }));
- request.arguments.addAll([
- '--dart-sdk-summary=${Uri.file(p.join(sdkDir, sdkKernelPath))}',
- '--output=${outputFile.path}',
- '--packages-file=${packagesFile.uri}',
- '--multi-root-scheme=$multiRootScheme',
- '--exclude-non-sources',
- summaryOnly ? '--summary-only' : '--no-summary-only',
- '--target=$targetName',
- '--libraries-file=${p.toUri(librariesPath)}',
- if (useIncrementalCompiler) ...[
- '--reuse-compiler-result',
- '--use-incremental-compiler',
- ],
- if (usedInputsFile != null)
- '--used-inputs=${usedInputsFile.uri.toFilePath()}',
- for (var input in inputs)
- '--input-${summaryOnly ? 'summary' : 'linked'}=${input.path}',
- for (var experiment in experiments) '--enable-experiment=$experiment',
- for (var source in module.sources) _sourceArg(source),
- ]);
-
- request.inputs.addAll([
- ...inputs,
- Input()
- ..path = '${Uri.file(p.join(sdkDir, sdkKernelPath))}'
- // Sdk updates fully invalidate the build anyways.
- ..digest = md5.convert(utf8.encode(targetName)).bytes,
- ]);
-}
-
-String _sourceArg(AssetId id) {
- var uri = id.path.startsWith('lib')
- ? canonicalUriFor(id)
- : '$multiRootScheme:///${id.path}';
- return '--source=$uri';
-}
diff --git a/build_modules/lib/src/meta_module.dart b/build_modules/lib/src/meta_module.dart
deleted file mode 100644
index 476cace..0000000
--- a/build_modules/lib/src/meta_module.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:graphs/graphs.dart';
-import 'package:path/path.dart' as p;
-import 'package:json_annotation/json_annotation.dart';
-
-import 'common.dart';
-import 'module_library.dart';
-import 'modules.dart';
-import 'platform.dart';
-
-part 'meta_module.g.dart';
-
-/// Returns the top level directory in [path].
-///
-/// Throws an [ArgumentError] if [path] is just a filename with no directory.
-String _topLevelDir(String path) {
- var parts = p.url.split(p.url.normalize(path));
- String error;
- if (parts.length == 1) {
- error = 'The path `$path` does not contain a directory.';
- } else if (parts.first == '..') {
- error = 'The path `$path` reaches outside the root directory.';
- }
- if (error != null) {
- throw ArgumentError(
- 'Cannot compute top level dir for path `$path`. $error');
- }
- return parts.first;
-}
-
-/// Creates a module containing [componentLibraries].
-Module _moduleForComponent(
- List<ModuleLibrary> componentLibraries, DartPlatform platform) {
- // Name components based on first alphabetically sorted node, preferring
- // public srcs (not under lib/src).
- var sources = componentLibraries.map((n) => n.id).toSet();
- var nonSrcIds = sources.where((id) => !id.path.startsWith('lib/src/'));
- var primaryId =
- nonSrcIds.isNotEmpty ? nonSrcIds.reduce(_min) : sources.reduce(_min);
- // Expand to include all the part files of each node, these aren't
- // included as individual `_AssetNodes`s in `connectedComponents`.
- sources.addAll(componentLibraries.expand((n) => n.parts));
- var directDependencies = <AssetId>{}
- ..addAll(componentLibraries.expand((n) => n.depsForPlatform(platform)))
- ..removeAll(sources);
- var isSupported = componentLibraries
- .expand((l) => l.sdkDeps)
- .every(platform.supportsLibrary);
- return Module(primaryId, sources, directDependencies, platform, isSupported);
-}
-
-/// Gets the local (same top level dir of the same package) transitive deps of
-/// [module] using [assetsToModules].
-Set<AssetId> _localTransitiveDeps(
- Module module, Map<AssetId, Module> assetsToModules) {
- var localTransitiveDeps = <AssetId>{};
- var nextIds = module.directDependencies;
- var seenIds = <AssetId>{};
- while (nextIds.isNotEmpty) {
- var ids = nextIds;
- seenIds.addAll(ids);
- nextIds = <AssetId>{};
- for (var id in ids) {
- var module = assetsToModules[id];
- if (module == null) continue; // Skip non-local modules
- if (localTransitiveDeps.add(module.primarySource)) {
- nextIds.addAll(module.directDependencies.difference(seenIds));
- }
- }
- }
- return localTransitiveDeps;
-}
-
-/// Creates a map of modules to the entrypoint modules that transitively
-/// depend on those modules.
-Map<AssetId, Set<AssetId>> _findReverseEntrypointDeps(
- Iterable<Module> entrypointModules, Iterable<Module> modules) {
- var reverseDeps = <AssetId, Set<AssetId>>{};
- var assetsToModules = <AssetId, Module>{};
- for (var module in modules) {
- for (var assetId in module.sources) {
- assetsToModules[assetId] = module;
- }
- }
- for (var module in entrypointModules) {
- for (var moduleDep in _localTransitiveDeps(module, assetsToModules)) {
- reverseDeps
- .putIfAbsent(moduleDep, () => <AssetId>{})
- .add(module.primarySource);
- }
- }
- return reverseDeps;
-}
-
-/// Merges [modules] into a minimum set of [Module]s using the
-/// following rules:
-///
-/// * If it is an entrypoint module do not merge it.
-/// * If it is not depended on my any entrypoint do not merge it.
-/// * If it is depended on by no entrypoint merge it into the entrypoint
-/// modules
-/// * Else merge it into with others that are depended on by the same set of
-/// entrypoints
-List<Module> _mergeModules(Iterable<Module> modules, Set<AssetId> entrypoints) {
- var entrypointModules =
- modules.where((m) => m.sources.any(entrypoints.contains)).toList();
-
- // Groups of modules that can be merged into an existing entrypoint module.
- var entrypointModuleGroups = {
- for (var m in entrypointModules) m.primarySource: [m],
- };
-
- // Maps modules to entrypoint modules that transitively depend on them.
- var modulesToEntryPoints =
- _findReverseEntrypointDeps(entrypointModules, modules);
-
- // Modules which are not depended on by any entrypoint
- var standaloneModules = <Module>[];
-
- // Modules which are merged with others.
- var mergedModules = <String, List<Module>>{};
-
- for (var module in modules) {
- // Skip entrypoint modules.
- if (entrypointModuleGroups.containsKey(module.primarySource)) continue;
-
- // The entry points that transitively import this module.
- var entrypointIds = modulesToEntryPoints[module.primarySource];
-
- // If no entrypoint imports the module, just leave it alone.
- if (entrypointIds == null || entrypointIds.isEmpty) {
- standaloneModules.add(module);
- continue;
- }
-
- // If there are multiple entry points for a given resource we must create
- // a new shared module. Use `$` to signal that it is a shared module.
- if (entrypointIds.length > 1) {
- var mId = (entrypointIds.toList()..sort()).map((m) => m.path).join('\$');
- mergedModules.putIfAbsent(mId, () => []).add(module);
- } else {
- entrypointModuleGroups[entrypointIds.single].add(module);
- }
- }
-
- return mergedModules.values
- .map(Module.merge)
- .map(_withConsistentPrimarySource)
- .followedBy(entrypointModuleGroups.values.map(Module.merge))
- .followedBy(standaloneModules)
- .toList();
-}
-
-Module _withConsistentPrimarySource(Module m) => Module(m.sources.reduce(_min),
- m.sources, m.directDependencies, m.platform, m.isSupported);
-
-T _min<T extends Comparable<T>>(T a, T b) => a.compareTo(b) < 0 ? a : b;
-
-/// Compute modules for the internal strongly connected components of
-/// [libraries].
-///
-/// This should only be called with [libraries] all in the same package and top
-/// level directory within the package.
-///
-/// A dependency is considered "internal" if it is within [libraries]. Any
-/// "external" deps are ignored during this computation since we are only
-/// considering the strongly connected components within [libraries], but they
-/// will be maintained as a dependency of the module to be used at a later step.
-///
-/// Part files are also tracked but ignored during computation of strongly
-/// connected components, as they must always be a part of the containing
-/// library's module.
-List<Module> _computeModules(
- Map<AssetId, ModuleLibrary> libraries, DartPlatform platform) {
- assert(() {
- var dir = _topLevelDir(libraries.values.first.id.path);
- return libraries.values.every((l) => _topLevelDir(l.id.path) == dir);
- }());
-
- final connectedComponents = stronglyConnectedComponents<ModuleLibrary>(
- libraries.values,
- (n) => n
- .depsForPlatform(platform)
- // Only "internal" dependencies
- .where(libraries.containsKey)
- .map((dep) => libraries[dep]),
- equals: (a, b) => a.id == b.id,
- hashCode: (l) => l.id.hashCode);
-
- final entryIds =
- libraries.values.where((l) => l.isEntryPoint).map((l) => l.id).toSet();
- return _mergeModules(
- connectedComponents.map((c) => _moduleForComponent(c, platform)),
- entryIds);
-}
-
-@JsonSerializable()
-class MetaModule {
- @JsonKey(name: 'm', nullable: false)
- final List<Module> modules;
-
- MetaModule(List<Module> modules) : modules = List.unmodifiable(modules);
-
- /// Generated factory constructor.
- factory MetaModule.fromJson(Map<String, dynamic> json) =>
- _$MetaModuleFromJson(json);
-
- Map<String, dynamic> toJson() => _$MetaModuleToJson(this);
-
- static Future<MetaModule> forLibraries(
- AssetReader reader,
- List<AssetId> libraryIds,
- ModuleStrategy strategy,
- DartPlatform platform) async {
- var libraries = <ModuleLibrary>[];
- for (var id in libraryIds) {
- libraries.add(ModuleLibrary.deserialize(
- id.changeExtension('').changeExtension('.dart'),
- await reader.readAsString(id)));
- }
- switch (strategy) {
- case ModuleStrategy.fine:
- return _fineModulesForLibraries(reader, libraries, platform);
- case ModuleStrategy.coarse:
- return _coarseModulesForLibraries(reader, libraries, platform);
- }
- throw StateError('Unrecognized module strategy $strategy');
- }
-}
-
-MetaModule _coarseModulesForLibraries(
- AssetReader reader, List<ModuleLibrary> libraries, DartPlatform platform) {
- var librariesByDirectory = <String, Map<AssetId, ModuleLibrary>>{};
- for (var library in libraries) {
- final dir = _topLevelDir(library.id.path);
- if (!librariesByDirectory.containsKey(dir)) {
- librariesByDirectory[dir] = <AssetId, ModuleLibrary>{};
- }
- librariesByDirectory[dir][library.id] = library;
- }
- final modules = librariesByDirectory.values
- .expand((libs) => _computeModules(libs, platform))
- .toList();
- _sortModules(modules);
- return MetaModule(modules);
-}
-
-MetaModule _fineModulesForLibraries(
- AssetReader reader, List<ModuleLibrary> libraries, DartPlatform platform) {
- var modules = libraries
- .map((library) => Module(
- library.id,
- library.parts.followedBy([library.id]),
- library.depsForPlatform(platform),
- platform,
- library.sdkDeps.every(platform.supportsLibrary)))
- .toList();
- _sortModules(modules);
- return MetaModule(modules);
-}
-
-/// Sorts [modules] in place so we get deterministic output.
-void _sortModules(List<Module> modules) {
- modules.sort((a, b) => a.primarySource.compareTo(b.primarySource));
-}
diff --git a/build_modules/lib/src/meta_module.g.dart b/build_modules/lib/src/meta_module.g.dart
deleted file mode 100644
index 908194a..0000000
--- a/build_modules/lib/src/meta_module.g.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'meta_module.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-MetaModule _$MetaModuleFromJson(Map<String, dynamic> json) {
- return MetaModule(
- (json['m'] as List)
- .map((e) => Module.fromJson(e as Map<String, dynamic>))
- .toList(),
- );
-}
-
-Map<String, dynamic> _$MetaModuleToJson(MetaModule instance) =>
- <String, dynamic>{
- 'm': instance.modules,
- };
diff --git a/build_modules/lib/src/meta_module_builder.dart b/build_modules/lib/src/meta_module_builder.dart
deleted file mode 100644
index bc92e96..0000000
--- a/build_modules/lib/src/meta_module_builder.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-import 'common.dart';
-import 'meta_module.dart';
-import 'module_cache.dart';
-import 'module_library_builder.dart';
-import 'platform.dart';
-
-/// The extension for serialized meta module assets for a specific platform.
-String metaModuleExtension(DartPlatform platform) =>
- '.${platform.name}.meta_module.raw';
-
-/// Creates `.meta_module` file for any Dart library.
-///
-/// This file contains information about the full computed
-/// module structure for the package.
-class MetaModuleBuilder implements Builder {
- @override
- final Map<String, List<String>> buildExtensions;
-
- final ModuleStrategy strategy;
-
- final DartPlatform _platform;
-
- MetaModuleBuilder(this._platform, {ModuleStrategy strategy})
- : strategy = strategy ?? ModuleStrategy.coarse,
- buildExtensions = {
- r'$lib$': [metaModuleExtension(_platform)]
- };
-
- factory MetaModuleBuilder.forOptions(
- DartPlatform platform, BuilderOptions options) =>
- MetaModuleBuilder(platform, strategy: moduleStrategy(options));
-
- @override
- Future build(BuildStep buildStep) async {
- if (buildStep.inputId.package == r'$sdk') return;
-
- var libraryAssets =
- await buildStep.findAssets(Glob('**$moduleLibraryExtension')).toList();
-
- var metaModule = await MetaModule.forLibraries(
- buildStep, libraryAssets, strategy, _platform);
- var id = AssetId(
- buildStep.inputId.package, 'lib/${metaModuleExtension(_platform)}');
- var metaModules = await buildStep.fetchResource(metaModuleCache);
- await metaModules.write(id, buildStep, metaModule);
- }
-}
diff --git a/build_modules/lib/src/meta_module_clean_builder.dart b/build_modules/lib/src/meta_module_clean_builder.dart
deleted file mode 100644
index fb05802..0000000
--- a/build_modules/lib/src/meta_module_clean_builder.dart
+++ /dev/null
@@ -1,167 +0,0 @@
-// 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:collection';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:graphs/graphs.dart';
-
-import 'meta_module.dart';
-import 'meta_module_builder.dart';
-import 'module_cache.dart';
-import 'modules.dart';
-import 'platform.dart';
-
-/// The extension for serialized clean meta module assets.
-///
-/// Clean in this context means all dependencies are primary sources.
-/// Furthermore cyclic modules are merged into a single module.
-String metaModuleCleanExtension(DartPlatform platform) =>
- '.${platform.name}.meta_module.clean';
-
-/// Creates `.meta_module.clean` file for any Dart library.
-///
-/// This file contains information about the full computed
-/// module structure for the package where each module's dependencies
-/// are only primary sources.
-///
-/// Note if the raw meta module file can't be found for any of the
-/// module's transitive dependencies there will be no output.
-class MetaModuleCleanBuilder implements Builder {
- @override
- final Map<String, List<String>> buildExtensions;
-
- final DartPlatform _platform;
-
- MetaModuleCleanBuilder(this._platform)
- : buildExtensions = {
- metaModuleExtension(_platform): [metaModuleCleanExtension(_platform)]
- };
-
- @override
- Future build(BuildStep buildStep) async {
- var assetToModule = (await buildStep.fetchResource(_assetToModule))
- .putIfAbsent(_platform, () => {});
- var assetToPrimary = (await buildStep.fetchResource(_assetToPrimary))
- .putIfAbsent(_platform, () => {});
- var modules = await _transitiveModules(
- buildStep, buildStep.inputId, assetToModule, assetToPrimary, _platform);
- var connectedComponents = stronglyConnectedComponents<Module>(
- modules,
- (m) => m.directDependencies.map((d) =>
- assetToModule[d] ??
- Module(d, [d], [], _platform, false, isMissing: true)),
- equals: (a, b) => a.primarySource == b.primarySource,
- hashCode: (m) => m.primarySource.hashCode);
- Module merge(List<Module> c) =>
- _mergeComponent(c, assetToPrimary, _platform);
- bool primarySourceInPackage(Module m) =>
- m.primarySource.package == buildStep.inputId.package;
- // Ensure deterministic output by sorting the modules.
- var cleanModules = SplayTreeSet<Module>(
- (a, b) => a.primarySource.compareTo(b.primarySource))
- ..addAll(connectedComponents.map(merge).where(primarySourceInPackage));
- await buildStep.writeAsString(
- AssetId(buildStep.inputId.package,
- 'lib/${metaModuleCleanExtension(_platform)}'),
- jsonEncode(MetaModule(cleanModules.toList())));
- }
-}
-
-/// Map of [AssetId] to corresponding non clean containing [Module] per
-/// [DartPlatform].
-final _assetToModule = Resource<Map<DartPlatform, Map<AssetId, Module>>>(
- () => {},
- dispose: (map) => map.clear());
-
-/// Map of [AssetId] to corresponding primary [AssetId] within the same
-/// clean [Module] per platform.
-final _assetToPrimary = Resource<Map<DartPlatform, Map<AssetId, AssetId>>>(
- () => {},
- dispose: (map) => map.clear());
-
-/// Returns a set of all modules transitively reachable from the provided meta
-/// module asset.
-Future<Set<Module>> _transitiveModules(
- BuildStep buildStep,
- AssetId metaAsset,
- Map<AssetId, Module> assetToModule,
- Map<AssetId, AssetId> assetToPrimary,
- DartPlatform platform) async {
- var dependentModules = <Module>{};
- // Ensures we only process a meta file once.
- var seenMetas = <AssetId>{}..add(metaAsset);
- var metaModules = await buildStep.fetchResource(metaModuleCache);
- var meta = await metaModules.find(buildStep.inputId, buildStep);
- var nextModules = List.of(meta.modules);
- while (nextModules.isNotEmpty) {
- var module = nextModules.removeLast();
- dependentModules.add(module);
- for (var source in module.sources) {
- assetToModule[source] = module;
- // The asset to primary map will be updated when the merged modules are
- // created. This is why we can't use the assetToModule map.
- assetToPrimary[source] = module.primarySource;
- }
- for (var dep in module.directDependencies) {
- var depMetaAsset =
- AssetId(dep.package, 'lib/${metaModuleExtension(platform)}');
- // The testing package is an odd package used by package:frontend_end
- // which doesn't really exist.
- // https://github.com/dart-lang/sdk/issues/32952
- if (seenMetas.contains(depMetaAsset) || dep.package == 'testing') {
- continue;
- }
- seenMetas.add(depMetaAsset);
- if (!await buildStep.canRead(depMetaAsset)) {
- log.warning('Unable to read module information for '
- 'package:${depMetaAsset.package}, make sure you have a dependency '
- 'on it in your pubspec.');
- continue;
- }
- var depMeta = await metaModules.find(depMetaAsset, buildStep);
- nextModules.addAll(depMeta.modules);
- }
- }
- return dependentModules;
-}
-
-/// Merges the modules in a strongly connected component.
-///
-/// Note this will clean the module dependencies as the merge happens.
-/// The result will be that all dependencies are primary sources.
-Module _mergeComponent(List<Module> connectedComponent,
- Map<AssetId, AssetId> assetToPrimary, DartPlatform platform) {
- var sources = <AssetId>{};
- var deps = <AssetId>{};
- // Sort the modules to deterministicly select the primary source.
- var components =
- SplayTreeSet<Module>((a, b) => a.primarySource.compareTo(b.primarySource))
- ..addAll(connectedComponent);
- var primarySource = components.first.primarySource;
- var isSupported = true;
- for (var module in connectedComponent) {
- sources.addAll(module.sources);
- isSupported = isSupported && module.isSupported;
- for (var dep in module.directDependencies) {
- var primaryDep = assetToPrimary[dep];
- if (primaryDep == null) continue;
- // This dep is now merged into sources so skip it.
- if (!components
- .map((c) => c.sources)
- .any((s) => s.contains(primaryDep))) {
- deps.add(primaryDep);
- }
- }
- }
- // Update map so that sources now point to the merged module.
- var mergedModule =
- Module(primarySource, sources, deps, platform, isSupported);
- for (var source in mergedModule.sources) {
- assetToPrimary[source] = mergedModule.primarySource;
- }
- return mergedModule;
-}
diff --git a/build_modules/lib/src/module_builder.dart b/build_modules/lib/src/module_builder.dart
deleted file mode 100644
index ee8dcb9..0000000
--- a/build_modules/lib/src/module_builder.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart';
-
-import 'meta_module_clean_builder.dart';
-import 'module_cache.dart';
-import 'module_library.dart';
-import 'module_library_builder.dart' show moduleLibraryExtension;
-import 'modules.dart';
-import 'platform.dart';
-
-/// The extension for serialized module assets.
-String moduleExtension(DartPlatform platform) => '.${platform.name}.module';
-
-/// Creates `.module` files for any `.dart` file that is the primary dart
-/// source of a [Module].
-class ModuleBuilder implements Builder {
- final DartPlatform _platform;
-
- ModuleBuilder(this._platform)
- : buildExtensions = {
- '.dart': [moduleExtension(_platform)]
- };
-
- @override
- final Map<String, List<String>> buildExtensions;
-
- @override
- Future build(BuildStep buildStep) async {
- final cleanMetaModules = await buildStep.fetchResource(metaModuleCache);
- final metaModule = await cleanMetaModules.find(
- AssetId(buildStep.inputId.package,
- 'lib/${metaModuleCleanExtension(_platform)}'),
- buildStep);
- var outputModule = metaModule.modules.firstWhere(
- (m) => m.primarySource == buildStep.inputId,
- orElse: () => null);
- if (outputModule == null) {
- final serializedLibrary = await buildStep.readAsString(
- buildStep.inputId.changeExtension(moduleLibraryExtension));
- final libraryModule =
- ModuleLibrary.deserialize(buildStep.inputId, serializedLibrary);
- if (libraryModule.hasMain) {
- outputModule = metaModule.modules
- .firstWhere((m) => m.sources.contains(buildStep.inputId));
- }
- }
- if (outputModule == null) return;
- final modules = await buildStep.fetchResource(moduleCache);
- await modules.write(
- buildStep.inputId.changeExtension(moduleExtension(_platform)),
- buildStep,
- outputModule);
- }
-}
diff --git a/build_modules/lib/src/module_cache.dart b/build_modules/lib/src/module_cache.dart
deleted file mode 100644
index 5a91108..0000000
--- a/build_modules/lib/src/module_cache.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2019, 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:convert';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-
-import 'meta_module.dart';
-import 'modules.dart';
-
-Map<String, dynamic> _deserialize(List<int> bytes) =>
- jsonDecode(utf8.decode(bytes)) as Map<String, dynamic>;
-
-List<int> _serialize(Map<String, dynamic> data) =>
- utf8.encode(jsonEncode(data));
-
-final metaModuleCache = DecodingCache.resource(
- (m) => MetaModule.fromJson(_deserialize(m)), (m) => _serialize(m.toJson()));
-
-final moduleCache = DecodingCache.resource(
- (m) => Module.fromJson(_deserialize(m)), (m) => _serialize(m.toJson()));
-
-/// A cache of objects decoded from written assets suitable for use as a
-/// [Resource].
-///
-/// Instances that are decoded will be cached throughout the duration of a build
-/// and invalidated between builds. Instances that are shared through the cache
-/// should be treated as immutable to avoid leaking any information which was
-/// not loaded from the underlying asset.
-class DecodingCache<T> {
- /// Create a [Resource] which can decoded instances of [T] serialized via json
- /// to assets.
- static Resource<DecodingCache<T>> resource<T>(
- T Function(List<int>) fromBytes, List<int> Function(T) toBytes) =>
- Resource<DecodingCache<T>>(() => DecodingCache._(fromBytes, toBytes),
- dispose: (c) => c._dispose());
-
- final _cached = <AssetId, _Entry<T>>{};
-
- final T Function(List<int>) _fromBytes;
- final List<int> Function(T) _toBytes;
-
- DecodingCache._(this._fromBytes, this._toBytes);
-
- void _dispose() {
- _cached.removeWhere((_, entry) => entry.digest == null);
- for (var entry in _cached.values) {
- entry.needsCheck = true;
- }
- }
-
- /// Find and deserialize a [T] stored in [id].
- ///
- /// If the asset at [id] is unreadable the returned future will resolve to
- /// `null`. If the instance is cached it will not be decoded again, but the
- /// content dependencies will be tracked through [reader].
- Future<T> find(AssetId id, AssetReader reader) async {
- if (!await reader.canRead(id)) return null;
- _Entry<T> entry;
- if (!_cached.containsKey(id)) {
- entry = _cached[id] = _Entry()
- ..needsCheck = false
- ..value = Result.capture(reader.readAsBytes(id).then(_fromBytes))
- ..digest = Result.capture(reader.digest(id));
- } else {
- entry = _cached[id];
- if (entry.needsCheck) {
- await (entry.onGoingCheck ??= () async {
- var previousDigest = await Result.release(entry.digest);
- entry.digest = Result.capture(reader.digest(id));
- if (await Result.release(entry.digest) != previousDigest) {
- entry.value =
- Result.capture(reader.readAsBytes(id).then(_fromBytes));
- }
- entry
- ..needsCheck = false
- ..onGoingCheck = null;
- }());
- }
- }
- return Result.release(entry.value);
- }
-
- /// Serialized and write a [T] to [id].
- ///
- /// The instance will be cached so that later calls to [find] may return the
- /// instances without deserializing it.
- Future<void> write(AssetId id, AssetWriter writer, T instance) async {
- await writer.writeAsBytes(id, _toBytes(instance));
- _cached[id] = _Entry()
- ..needsCheck = false
- ..value = Result.capture(Future.value(instance));
- }
-}
-
-class _Entry<T> {
- bool needsCheck = false;
- Future<Result<T>> value;
- Future<Result<Digest>> digest;
- Future<void> onGoingCheck;
-}
diff --git a/build_modules/lib/src/module_cleanup.dart b/build_modules/lib/src/module_cleanup.dart
deleted file mode 100644
index ff1af73..0000000
--- a/build_modules/lib/src/module_cleanup.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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:build/build.dart';
-
-import 'module_library_builder.dart';
-
-class ModuleCleanup implements PostProcessBuilder {
- const ModuleCleanup();
-
- @override
- void build(PostProcessBuildStep buildStep) {
- buildStep.deletePrimaryInput();
- }
-
- @override
- final inputExtensions = const [
- moduleLibraryExtension,
- '.meta_module.raw',
- '.meta_module.clean',
- '.module',
- ];
-}
diff --git a/build_modules/lib/src/module_library.dart b/build_modules/lib/src/module_library.dart
deleted file mode 100644
index c00c93a..0000000
--- a/build_modules/lib/src/module_library.dart
+++ /dev/null
@@ -1,224 +0,0 @@
-// 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:convert';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-import 'package:meta/meta.dart';
-
-import 'platform.dart';
-
-/// A Dart library within a module.
-///
-/// Modules can be computed based on library dependencies (imports and exports)
-/// and parts.
-class ModuleLibrary {
- /// The AssetId of the original Dart source file.
- final AssetId id;
-
- /// Whether this library can be imported.
- ///
- /// This will be false if the source file is a "part of", or imports code that
- /// can't be used outside the SDK.
- final bool isImportable;
-
- /// Whether this library is an entrypoint.
- ///
- /// True if the library is in `lib/` but not `lib/src`, or if it is outside of
- /// `lib/` and contains a `main` method. Always false if this is not an
- /// importable library.
- final bool isEntryPoint;
-
- /// Deps that are imported with a conditional import.
- ///
- /// Keys are the stringified ast node for the conditional, and the default
- /// import is under the magic `$default` key.
- final List<Map<String, AssetId>> conditionalDeps;
-
- /// The IDs of libraries that are imported or exported by this library.
- ///
- /// Null if this is not an importable library.
- final Set<AssetId> _deps;
-
- /// The "part" files for this library.
- ///
- /// Null if this is not an importable library.
- final Set<AssetId> parts;
-
- /// The `dart:` libraries that this library directly depends on.
- final Set<String> sdkDeps;
-
- /// Whether this library has a `main` function.
- final bool hasMain;
-
- ModuleLibrary._(this.id,
- {@required this.isEntryPoint,
- @required Set<AssetId> deps,
- @required this.parts,
- @required this.conditionalDeps,
- @required this.sdkDeps,
- @required this.hasMain})
- : _deps = deps,
- isImportable = true;
-
- ModuleLibrary._nonImportable(this.id)
- : isImportable = false,
- isEntryPoint = false,
- _deps = null,
- parts = null,
- conditionalDeps = null,
- sdkDeps = null,
- hasMain = false;
-
- factory ModuleLibrary._fromCompilationUnit(
- AssetId id, bool isEntryPoint, CompilationUnit parsed) {
- var deps = <AssetId>{};
- var parts = <AssetId>{};
- var sdkDeps = <String>{};
- var conditionalDeps = <Map<String, AssetId>>[];
- for (var directive in parsed.directives) {
- if (directive is! UriBasedDirective) continue;
- var path = (directive as UriBasedDirective).uri.stringValue;
- var uri = Uri.parse(path);
- if (uri.isScheme('dart-ext')) {
- // TODO: What should we do for native extensions?
- continue;
- }
- if (uri.scheme == 'dart') {
- sdkDeps.add(uri.path);
- continue;
- }
- var linkedId = AssetId.resolve(path, from: id);
- if (linkedId == null) continue;
- if (directive is PartDirective) {
- parts.add(linkedId);
- continue;
- }
-
- List<Configuration> conditionalDirectiveConfigurations;
-
- if (directive is ImportDirective && directive.configurations.isNotEmpty) {
- conditionalDirectiveConfigurations = directive.configurations;
- } else if (directive is ExportDirective &&
- directive.configurations.isNotEmpty) {
- conditionalDirectiveConfigurations = directive.configurations;
- }
- if (conditionalDirectiveConfigurations != null) {
- var conditions = <String, AssetId>{r'$default': linkedId};
- for (var condition in conditionalDirectiveConfigurations) {
- if (Uri.parse(condition.uri.stringValue).scheme == 'dart') {
- throw ArgumentError('Unsupported conditional import of '
- '`${condition.uri.stringValue}` found in $id.');
- }
- conditions[condition.name.toSource()] =
- AssetId.resolve(condition.uri.stringValue, from: id);
- }
- conditionalDeps.add(conditions);
- } else {
- deps.add(linkedId);
- }
- }
- return ModuleLibrary._(id,
- isEntryPoint: isEntryPoint,
- deps: deps,
- parts: parts,
- sdkDeps: sdkDeps,
- conditionalDeps: conditionalDeps,
- hasMain: _hasMainMethod(parsed));
- }
-
- /// Parse the directives from [source] and compute the library information.
- static ModuleLibrary fromSource(AssetId id, String source) {
- final isLibDir = id.path.startsWith('lib/');
- // ignore: deprecated_member_use
- final parsed = parseCompilationUnit(source,
- name: id.path, suppressErrors: true, parseFunctionBodies: false);
- // Packages within the SDK but published might have libraries that can't be
- // used outside the SDK.
- if (parsed.directives.any((d) =>
- d is UriBasedDirective &&
- d.uri.stringValue.startsWith('dart:_') &&
- id.package != 'dart_internal')) {
- return ModuleLibrary._nonImportable(id);
- }
- if (_isPart(parsed)) {
- return ModuleLibrary._nonImportable(id);
- }
-
- final isEntryPoint =
- (isLibDir && !id.path.startsWith('lib/src/')) || _hasMainMethod(parsed);
- return ModuleLibrary._fromCompilationUnit(id, isEntryPoint, parsed);
- }
-
- /// Parses the output of [serialize] back into a [ModuleLibrary].
- ///
- /// Importable libraries can be round tripped to a String. Non-importable
- /// libraries should not be printed or parsed.
- factory ModuleLibrary.deserialize(AssetId id, String encoded) {
- var json = jsonDecode(encoded);
-
- return ModuleLibrary._(id,
- isEntryPoint: json['isEntrypoint'] as bool,
- deps: _deserializeAssetIds(json['deps'] as Iterable),
- parts: _deserializeAssetIds(json['parts'] as Iterable),
- sdkDeps: Set.of((json['sdkDeps'] as Iterable).cast<String>()),
- conditionalDeps:
- (json['conditionalDeps'] as Iterable).map((conditions) {
- return Map.of((conditions as Map<String, dynamic>)
- .map((k, v) => MapEntry(k, AssetId.parse(v as String))));
- }).toList(),
- hasMain: json['hasMain'] as bool);
- }
-
- String serialize() => jsonEncode({
- 'isEntrypoint': isEntryPoint,
- 'deps': _deps.map((id) => id.toString()).toList(),
- 'parts': parts.map((id) => id.toString()).toList(),
- 'conditionalDeps': conditionalDeps
- .map((conditions) =>
- conditions.map((k, v) => MapEntry(k, v.toString())))
- .toList(),
- 'sdkDeps': sdkDeps.toList(),
- 'hasMain': hasMain,
- });
-
- List<AssetId> depsForPlatform(DartPlatform platform) {
- return _deps.followedBy(conditionalDeps.map((conditions) {
- var selectedImport = conditions[r'$default'];
- assert(selectedImport != null);
- for (var condition in conditions.keys) {
- if (condition == r'$default') continue;
- if (!condition.startsWith('dart.library.')) {
- throw UnsupportedError(
- '$condition not supported for config specific imports. Only the '
- 'dart.library.<name> constants are supported.');
- }
- var library = condition.substring('dart.library.'.length);
- if (platform.supportsLibrary(library)) {
- selectedImport = conditions[condition];
- break;
- }
- }
- return selectedImport;
- })).toList();
- }
-}
-
-Set<AssetId> _deserializeAssetIds(Iterable serlialized) =>
- Set.from(serlialized.map((decoded) => AssetId.parse(decoded as String)));
-
-bool _isPart(CompilationUnit dart) =>
- dart.directives.any((directive) => directive is PartOfDirective);
-
-/// Allows two or fewer arguments to `main` so that entrypoints intended for
-/// use with `spawnUri` get counted.
-//
-// TODO: This misses the case where a Dart file doesn't contain main(),
-// but has a part that does, or it exports a `main` from another library.
-bool _hasMainMethod(CompilationUnit dart) => dart.declarations.any((node) =>
- node is FunctionDeclaration &&
- node.name.name == 'main' &&
- node.functionExpression.parameters.parameters.length <= 2);
diff --git a/build_modules/lib/src/module_library_builder.dart b/build_modules/lib/src/module_library_builder.dart
deleted file mode 100644
index e5defec..0000000
--- a/build_modules/lib/src/module_library_builder.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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 'package:build/build.dart';
-
-import 'module_library.dart';
-
-const moduleLibraryExtension = '.module.library';
-
-/// Creates `.module.library` assets listing the dependencies and parts for a
-/// Dart library, as well as whether it is an entrypoint.
-///
-///
-/// The output format is determined by [ModuleLibrary.serialize] and can be
-/// restored by [ModuleLibrary.deserialize].
-///
-/// Non-importable Dart source files will not get a `.module.library` asset
-/// output. See [ModuleLibrary.isImportable].
-class ModuleLibraryBuilder implements Builder {
- const ModuleLibraryBuilder();
-
- @override
- final buildExtensions = const {
- '.dart': [moduleLibraryExtension]
- };
-
- @override
- Future build(BuildStep buildStep) async {
- final library = ModuleLibrary.fromSource(
- buildStep.inputId, await buildStep.readAsString(buildStep.inputId));
- if (!library.isImportable) return;
- await buildStep.writeAsString(
- buildStep.inputId.changeExtension(moduleLibraryExtension),
- library.serialize());
- }
-}
diff --git a/build_modules/lib/src/modules.dart b/build_modules/lib/src/modules.dart
deleted file mode 100644
index 8f3e3b0..0000000
--- a/build_modules/lib/src/modules.dart
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-
-import 'package:build/build.dart';
-import 'package:collection/collection.dart' show UnmodifiableSetView;
-import 'package:graphs/graphs.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-import 'errors.dart';
-import 'module_builder.dart';
-import 'module_cache.dart';
-import 'platform.dart';
-
-part 'modules.g.dart';
-
-/// A collection of Dart libraries in a strongly connected component of the
-/// import graph.
-///
-/// Modules track their sources and the other modules they depend on.
-/// modules they depend on.
-/// Modules can span pub package boundaries when there are import cycles across
-/// packages.
-@JsonSerializable()
-@_AssetIdConverter()
-@_DartPlatformConverter()
-class Module {
- /// Merge the sources and dependencies from [modules] into a single module.
- ///
- /// All modules must have the same [platform].
- /// [primarySource] will be the earliest value from the combined [sources] if
- /// they were sorted.
- /// [isMissing] will be true if any input module is missing.
- /// [isSupported] will be true if all input modules are supported.
- /// [directDependencies] will be merged for all modules, but if any module
- /// depended on a source from any other they will be filtered out.
- static Module merge(List<Module> modules) {
- assert(modules.isNotEmpty);
- if (modules.length == 1) return modules.single;
- assert(modules.every((m) => m.platform == modules.first.platform));
-
- final allSources = HashSet.of(modules.expand((m) => m.sources));
- final allDependencies =
- HashSet.of(modules.expand((m) => m.directDependencies))
- ..removeAll(allSources);
- final primarySource =
- allSources.reduce((a, b) => a.compareTo(b) < 0 ? a : b);
- final isMissing = modules.any((m) => m.isMissing);
- final isSupported = modules.every((m) => m.isSupported);
- return Module(primarySource, allSources, allDependencies,
- modules.first.platform, isSupported,
- isMissing: isMissing);
- }
-
- /// The library which will be used to reference any library in [sources].
- ///
- /// The assets which are built once per module, such as DDC compiled output or
- /// Analyzer summaries, will be named after the primary source and will
- /// encompass everything in [sources].
- @JsonKey(name: 'p', nullable: false)
- final AssetId primarySource;
-
- /// The libraries in the strongly connected import cycle with [primarySource].
- ///
- /// In most cases without cyclic imports this will contain only the primary
- /// source. For libraries with an import cycle all of the libraries in the
- /// cycle will be contained in `sources`. For example:
- ///
- /// ```dart
- /// library foo;
- ///
- /// import 'bar.dart';
- /// ```
- ///
- /// ```dart
- /// library bar;
- ///
- /// import 'foo.dart';
- /// ```
- ///
- /// Libraries `foo` and `bar` form an import cycle so they would be grouped in
- /// the same module. Every Dart library will only be contained in a single
- /// [Module].
- @JsonKey(name: 's', nullable: false, toJson: _toJsonAssetIds)
- final Set<AssetId> sources;
-
- /// The [primarySource]s of the [Module]s which contain any library imported
- /// from any of the [sources] in this module.
- @JsonKey(name: 'd', nullable: false, toJson: _toJsonAssetIds)
- final Set<AssetId> directDependencies;
-
- /// Missing modules are created if a module depends on another non-existent
- /// module.
- ///
- /// We want to report these errors lazily to allow for builds to succeed if it
- /// won't actually impact any apps negatively.
- @JsonKey(name: 'm', nullable: true, defaultValue: false)
- final bool isMissing;
-
- /// Whether or not this module is supported for [platform].
- ///
- /// Note that this only indicates support for the [sources] within this
- /// module, and not its transitive (or direct) dependencies.
- ///
- /// Compilers can use this to either silently skip compilation of this module
- /// or throw early errors or warnings.
- ///
- /// Modules are allowed to exist even if they aren't supported, which can help
- /// with discovering root causes of incompatibility.
- @JsonKey(name: 'is', nullable: false)
- final bool isSupported;
-
- @JsonKey(name: 'pf', nullable: false)
- final DartPlatform platform;
-
- Module(this.primarySource, Iterable<AssetId> sources,
- Iterable<AssetId> directDependencies, this.platform, this.isSupported,
- {bool isMissing})
- : sources = UnmodifiableSetView(HashSet.of(sources)),
- directDependencies =
- UnmodifiableSetView(HashSet.of(directDependencies)),
- isMissing = isMissing ?? false;
-
- /// Generated factory constructor.
- factory Module.fromJson(Map<String, dynamic> json) => _$ModuleFromJson(json);
-
- Map<String, dynamic> toJson() => _$ModuleToJson(this);
-
- /// Returns all [Module]s in the transitive dependencies of this module in
- /// reverse dependency order.
- ///
- /// Throws a [MissingModulesException] if there are any missing modules. This
- /// typically means that somebody is trying to import a non-existing file.
- ///
- /// If [throwIfUnsupported] is `true`, then an [UnsupportedModules]
- /// will be thrown if there are any modules that are not supported.
- Future<List<Module>> computeTransitiveDependencies(BuildStep buildStep,
- {bool throwIfUnsupported = false,
- @deprecated Set<String> skipPlatformCheckPackages = const {}}) async {
- throwIfUnsupported ??= false;
- skipPlatformCheckPackages ??= const {};
- final modules = await buildStep.fetchResource(moduleCache);
- var transitiveDeps = <AssetId, Module>{};
- var modulesToCrawl = {primarySource};
- var missingModuleSources = <AssetId>{};
- var unsupportedModules = <Module>{};
-
- while (modulesToCrawl.isNotEmpty) {
- var next = modulesToCrawl.last;
- modulesToCrawl.remove(next);
- if (transitiveDeps.containsKey(next)) continue;
- var nextModuleId = next.changeExtension(moduleExtension(platform));
- var module = await modules.find(nextModuleId, buildStep);
- if (module == null || module.isMissing) {
- missingModuleSources.add(next);
- continue;
- }
- if (throwIfUnsupported &&
- !module.isSupported &&
- !skipPlatformCheckPackages.contains(module.primarySource.package)) {
- unsupportedModules.add(module);
- }
- // Don't include the root module in the transitive deps.
- if (next != primarySource) transitiveDeps[next] = module;
- modulesToCrawl.addAll(module.directDependencies);
- }
-
- if (missingModuleSources.isNotEmpty) {
- throw await MissingModulesException.create(missingModuleSources,
- transitiveDeps.values.toList()..add(this), buildStep);
- }
- if (throwIfUnsupported && unsupportedModules.isNotEmpty) {
- throw UnsupportedModules(unsupportedModules);
- }
- var orderedModules = stronglyConnectedComponents<Module>(
- transitiveDeps.values,
- (m) => m.directDependencies.map((s) => transitiveDeps[s]),
- equals: (a, b) => a.primarySource == b.primarySource,
- hashCode: (m) => m.primarySource.hashCode);
- return orderedModules.map((c) => c.single).toList();
- }
-}
-
-class _AssetIdConverter implements JsonConverter<AssetId, List> {
- const _AssetIdConverter();
-
- @override
- AssetId fromJson(List json) => AssetId.deserialize(json);
-
- @override
- List toJson(AssetId object) => object.serialize() as List;
-}
-
-class _DartPlatformConverter implements JsonConverter<DartPlatform, String> {
- const _DartPlatformConverter();
-
- @override
- DartPlatform fromJson(String json) => DartPlatform.byName(json);
-
- @override
- String toJson(DartPlatform object) => object.name;
-}
-
-/// Ensure sets of asset IDs are sorted before writing them for a consistent
-/// output.
-List<List> _toJsonAssetIds(Set<AssetId> ids) =>
- (ids.toList()..sort()).map((i) => i.serialize() as List).toList();
diff --git a/build_modules/lib/src/modules.g.dart b/build_modules/lib/src/modules.g.dart
deleted file mode 100644
index 1e7a80d..0000000
--- a/build_modules/lib/src/modules.g.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'modules.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-Module _$ModuleFromJson(Map<String, dynamic> json) {
- return Module(
- const _AssetIdConverter().fromJson(json['p'] as List),
- (json['s'] as List)
- .map((e) => const _AssetIdConverter().fromJson(e as List)),
- (json['d'] as List)
- .map((e) => const _AssetIdConverter().fromJson(e as List)),
- const _DartPlatformConverter().fromJson(json['pf'] as String),
- json['is'] as bool,
- isMissing: json['m'] as bool ?? false,
- );
-}
-
-Map<String, dynamic> _$ModuleToJson(Module instance) => <String, dynamic>{
- 'p': const _AssetIdConverter().toJson(instance.primarySource),
- 's': _toJsonAssetIds(instance.sources),
- 'd': _toJsonAssetIds(instance.directDependencies),
- 'm': instance.isMissing,
- 'is': instance.isSupported,
- 'pf': const _DartPlatformConverter().toJson(instance.platform),
- };
diff --git a/build_modules/lib/src/platform.dart b/build_modules/lib/src/platform.dart
deleted file mode 100644
index c74e47a..0000000
--- a/build_modules/lib/src/platform.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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.
-
-/// A supported "platform" for compilation of Dart libraries.
-///
-/// Each "platform" has its own compilation pipeline and builders, and could
-/// differ from other platforms in many ways:
-///
-/// - The core libs that are supported
-/// - The implementations of the core libs
-/// - The compilation steps that are required (frontends or backends could be
-/// different).
-///
-/// Typically these should correspond to `libraries.json` files in the SDK.
-///
-/// New platforms should be created with [register], and can later be
-/// fetched by name using the [DartPlatform.byName] static method.
-class DartPlatform {
- /// A list of all registered platforms by name, populated by
- /// [register].
- static final _platformsByName = <String, DartPlatform>{};
-
- final List<String> _supportedLibraries;
-
- final String name;
-
- /// Returns a [DartPlatform] instance by name.
- ///
- /// Throws an [UnrecognizedDartPlatform] if [name] has not been
- /// registered with [DartPlatform.register].
- static DartPlatform byName(String name) =>
- _platformsByName[name] ?? (throw UnrecognizedDartPlatform(name));
-
- /// Registers a new [DartPlatform].
- ///
- /// Throws a [DartPlatformAlreadyRegistered] if [name] has already
- /// been registered by somebody else.
- static DartPlatform register(String name, List<String> supportedLibraries) {
- if (_platformsByName.containsKey(name)) {
- throw DartPlatformAlreadyRegistered(name);
- }
-
- return _platformsByName[name] =
- DartPlatform._(name, List.unmodifiable(supportedLibraries));
- }
-
- const DartPlatform._(this.name, this._supportedLibraries);
-
- /// Returns whether or not [library] is supported on this platform.
- ///
- /// The [library] is path portion of a `dart:` import (should not include the
- /// scheme).
- bool supportsLibrary(String library) => _supportedLibraries.contains(library);
-
- @override
- int get hashCode => name.hashCode;
-
- @override
- bool operator ==(other) => other is DartPlatform && other.name == name;
-}
-
-class DartPlatformAlreadyRegistered implements Exception {
- final String name;
-
- const DartPlatformAlreadyRegistered(this.name);
-
- @override
- String toString() => 'The platform `$name`, has already been registered.';
-}
-
-class UnrecognizedDartPlatform implements Exception {
- final String name;
-
- const UnrecognizedDartPlatform(this.name);
-
- @override
- String toString() => 'Unrecognized platform `$name`, it must be registered '
- 'first using `DartPlatform.register`';
-}
diff --git a/build_modules/lib/src/scratch_space.dart b/build_modules/lib/src/scratch_space.dart
deleted file mode 100644
index 6149341..0000000
--- a/build_modules/lib/src/scratch_space.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2017, 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:math' as math;
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:scratch_space/scratch_space.dart';
-
-import 'workers.dart';
-
-final _logger = Logger('BuildModules');
-
-/// A shared [ScratchSpace] for ddc and analyzer workers that persists
-/// throughout builds.
-final scratchSpace = ScratchSpace();
-
-/// A shared [Resource] for a [ScratchSpace], which cleans up the contents of
-/// the [ScratchSpace] in dispose, but doesn't delete it entirely.
-final scratchSpaceResource = Resource<ScratchSpace>(() {
- if (!scratchSpace.exists) {
- scratchSpace.tempDir.createSync(recursive: true);
- scratchSpace.exists = true;
- }
- return scratchSpace;
-}, beforeExit: () async {
- // The workers are running inside the scratch space, so wait for them to
- // shut down before deleting it.
- await dartdevkWorkersAreDone;
- await frontendWorkersAreDone;
- await dart2jsWorkersAreDone;
- // Attempt to clean up the scratch space. Even after waiting for the workers
- // to shut down we might get file system exceptions on windows for an
- // arbitrary amount of time, so do retries with an exponential backoff.
- var numTries = 0;
- while (true) {
- numTries++;
- if (numTries > 3) {
- _logger
- .warning('Failed to clean up temp dir ${scratchSpace.tempDir.path}.');
- return;
- }
- try {
- // TODO(https://github.com/dart-lang/build/issues/656): The scratch
- // space throws on `delete` if it thinks it was already deleted.
- // Manually clean up in this case.
- if (scratchSpace.exists) {
- await scratchSpace.delete();
- } else {
- await scratchSpace.tempDir.delete(recursive: true);
- }
- return;
- } on FileSystemException {
- var delayMs = math.pow(10, numTries).floor();
- _logger.info('Failed to delete temp dir ${scratchSpace.tempDir.path}, '
- 'retrying in ${delayMs}ms');
- await Future.delayed(Duration(milliseconds: delayMs));
- }
- }
-});
diff --git a/build_modules/lib/src/workers.dart b/build_modules/lib/src/workers.dart
deleted file mode 100644
index c7fc0b2..0000000
--- a/build_modules/lib/src/workers.dart
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math' show min;
-
-import 'package:bazel_worker/driver.dart';
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
-
-import 'scratch_space.dart';
-
-final sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-// If no terminal is attached, prevent a new one from launching.
-final _processMode = stdin.hasTerminal
- ? ProcessStartMode.normal
- : ProcessStartMode.detachedWithStdio;
-
-/// Completes once the dartdevk workers have been shut down.
-Future<void> get dartdevkWorkersAreDone =>
- _dartdevkWorkersAreDoneCompleter?.future ?? Future.value();
-Completer<void> _dartdevkWorkersAreDoneCompleter;
-
-/// Completes once the dart2js workers have been shut down.
-Future<void> get dart2jsWorkersAreDone =>
- _dart2jsWorkersAreDoneCompleter?.future ?? Future.value();
-Completer<void> _dart2jsWorkersAreDoneCompleter;
-
-/// Completes once the common frontend workers have been shut down.
-Future<void> get frontendWorkersAreDone =>
- _frontendWorkersAreDoneCompleter?.future ?? Future.value();
-Completer<void> _frontendWorkersAreDoneCompleter;
-
-final int _defaultMaxWorkers = min((Platform.numberOfProcessors / 2).ceil(), 4);
-
-const _maxWorkersEnvVar = 'BUILD_MAX_WORKERS_PER_TASK';
-
-final int _maxWorkersPerTask = () {
- var toParse =
- Platform.environment[_maxWorkersEnvVar] ?? '$_defaultMaxWorkers';
- var parsed = int.tryParse(toParse);
- if (parsed == null) {
- log.warning('Invalid value for $_maxWorkersEnvVar environment variable, '
- 'expected an int but got `$toParse`. Falling back to default value '
- 'of $_defaultMaxWorkers.');
- return _defaultMaxWorkers;
- }
- return parsed;
-}();
-
-/// Manages a shared set of persistent dartdevk workers.
-BazelWorkerDriver get _dartdevkDriver {
- _dartdevkWorkersAreDoneCompleter ??= Completer<void>();
- return __dartdevkDriver ??= BazelWorkerDriver(
- () => Process.start(
- p.join(sdkDir, 'bin', 'dart'),
- [
- p.join(sdkDir, 'bin', 'snapshots', 'dartdevc.dart.snapshot'),
- '--kernel',
- '--persistent_worker'
- ],
- mode: _processMode,
- workingDirectory: scratchSpace.tempDir.path),
- maxWorkers: _maxWorkersPerTask);
-}
-
-BazelWorkerDriver __dartdevkDriver;
-
-/// Resource for fetching the current [BazelWorkerDriver] for dartdevk.
-final dartdevkDriverResource =
- Resource<BazelWorkerDriver>(() => _dartdevkDriver, beforeExit: () async {
- await _dartdevkDriver?.terminateWorkers();
- _dartdevkWorkersAreDoneCompleter.complete();
- _dartdevkWorkersAreDoneCompleter = null;
- __dartdevkDriver = null;
-});
-
-/// Manages a shared set of persistent common frontend workers.
-BazelWorkerDriver get _frontendDriver {
- _frontendWorkersAreDoneCompleter ??= Completer<void>();
- return __frontendDriver ??= BazelWorkerDriver(
- () => Process.start(
- p.join(sdkDir, 'bin', 'dart'),
- [
- p.join(sdkDir, 'bin', 'snapshots', 'kernel_worker.dart.snapshot'),
- '--persistent_worker'
- ],
- mode: _processMode,
- workingDirectory: scratchSpace.tempDir.path),
- maxWorkers: _maxWorkersPerTask);
-}
-
-BazelWorkerDriver __frontendDriver;
-
-/// Resource for fetching the current [BazelWorkerDriver] for common frontend.
-final frontendDriverResource =
- Resource<BazelWorkerDriver>(() => _frontendDriver, beforeExit: () async {
- await _frontendDriver?.terminateWorkers();
- _frontendWorkersAreDoneCompleter.complete();
- _frontendWorkersAreDoneCompleter = null;
- __frontendDriver = null;
-});
-
-const _dart2jsVmArgsEnvVar = 'BUILD_DART2JS_VM_ARGS';
-final _dart2jsVmArgs = () {
- var env = Platform.environment[_dart2jsVmArgsEnvVar];
- return env?.split(' ') ?? <String>[];
-}();
-
-/// Manages a shared set of persistent dart2js workers.
-Dart2JsBatchWorkerPool get _dart2jsWorkerPool {
- _dart2jsWorkersAreDoneCompleter ??= Completer<void>();
- var librariesSpec = p.joinAll([sdkDir, 'lib', 'libraries.json']);
- return __dart2jsWorkerPool ??= Dart2JsBatchWorkerPool(() => Process.start(
- p.join(sdkDir, 'bin', 'dart'),
- [
- ..._dart2jsVmArgs,
- p.join(sdkDir, 'bin', 'snapshots', 'dart2js.dart.snapshot'),
- '--libraries-spec=$librariesSpec',
- '--batch',
- ],
- mode: _processMode,
- workingDirectory: scratchSpace.tempDir.path));
-}
-
-Dart2JsBatchWorkerPool __dart2jsWorkerPool;
-
-/// Resource for fetching the current [Dart2JsBatchWorkerPool] for dart2js.
-final dart2JsWorkerResource = Resource<Dart2JsBatchWorkerPool>(
- () => _dart2jsWorkerPool, beforeExit: () async {
- await _dart2jsWorkerPool.terminateWorkers();
- _dart2jsWorkersAreDoneCompleter.complete();
- _dart2jsWorkersAreDoneCompleter = null;
-});
-
-/// Manages a pool of persistent [_Dart2JsWorker]s running in batch mode and
-/// schedules jobs among them.
-class Dart2JsBatchWorkerPool {
- final Future<Process> Function() _spawnWorker;
-
- final _workQueue = Queue<_Dart2JsJob>();
-
- bool _queueIsActive = false;
-
- final _availableWorkers = Queue<_Dart2JsWorker>();
-
- final _allWorkers = <_Dart2JsWorker>[];
-
- Dart2JsBatchWorkerPool(this._spawnWorker);
-
- Future<Dart2JsResult> compile(List<String> args) async {
- var job = _Dart2JsJob(args);
- _workQueue.add(job);
- if (!_queueIsActive) _startWorkQueue();
- return job.result;
- }
-
- void _startWorkQueue() {
- assert(!_queueIsActive);
- _queueIsActive = true;
- () async {
- while (_workQueue.isNotEmpty) {
- _Dart2JsWorker worker;
- if (_availableWorkers.isEmpty &&
- _allWorkers.length < _maxWorkersPerTask) {
- worker = _Dart2JsWorker(_spawnWorker);
- _allWorkers.add(worker);
- }
-
- _Dart2JsWorker nextWorker() => _availableWorkers.isNotEmpty
- ? _availableWorkers.removeFirst()
- : null;
-
- worker ??= nextWorker();
- while (worker == null) {
- // TODO: something smarter here? in practice this seems to work
- // reasonably well though and simplifies things a lot ¯\_(ツ)_/¯.
- await Future.delayed(Duration(seconds: 1));
- worker = nextWorker();
- }
- unawaited(worker
- .doJob(_workQueue.removeFirst())
- .whenComplete(() => _availableWorkers.add(worker)));
- }
- _queueIsActive = false;
- }();
- }
-
- Future<void> terminateWorkers() async {
- var allWorkers = _allWorkers.toList();
- _allWorkers.clear();
- _availableWorkers.clear();
- await Future.wait(allWorkers.map((w) => w.terminate()));
- }
-}
-
-/// A single dart2js worker process running in batch mode.
-///
-/// This may actually spawn multiple processes over time, if a running worker
-/// dies or it decides that it should be restarted for some reason.
-class _Dart2JsWorker {
- final Future<Process> Function() _spawnWorker;
-
- int _jobsSinceLastRestartCount = 0;
- static const int _jobsBeforeRestartMax = 5;
- static const int _retryCountMax = 2;
-
- Stream<String> __workerStderrLines;
- Stream<String> get _workerStderrLines {
- assert(__worker != null);
- return __workerStderrLines ??= __worker.stderr
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .asBroadcastStream();
- }
-
- Stream<String> __workerStdoutLines;
- Stream<String> get _workerStdoutLines {
- assert(__worker != null);
- return __workerStdoutLines ??= __worker.stdout
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .asBroadcastStream();
- }
-
- Process __worker;
- Future<Process> _spawningWorker;
- Future<Process> get _worker {
- if (__worker != null) return Future.value(__worker);
- return _spawningWorker ??= () async {
- if (__worker == null) {
- _jobsSinceLastRestartCount = 0;
- __worker ??= await _spawnWorker();
- _spawningWorker = null;
- // exitCode can be null: https://github.com/dart-lang/sdk/issues/35874
- unawaited(__worker.exitCode?.then((_) {
- __worker = null;
- __workerStdoutLines = null;
- __workerStderrLines = null;
- _currentJobResult
- ?.completeError('Dart2js exited with an unknown error');
- }));
- }
- return __worker;
- }();
- }
-
- Completer<Dart2JsResult> _currentJobResult;
-
- _Dart2JsWorker(this._spawnWorker);
-
- /// Performs [job], gracefully handling worker failures by retrying
- /// [_retryCountMax] times and restarting the worker between jobs based on
- /// [_jobsBeforeRestartMax] to limit memory consumption.
- ///
- /// Only one job may be performed at a time.
- Future<void> doJob(_Dart2JsJob job) async {
- assert(_currentJobResult == null);
- var tryCount = 0;
- var succeeded = false;
- while (tryCount < _retryCountMax && !succeeded) {
- tryCount++;
- _jobsSinceLastRestartCount++;
- var worker = await _worker;
- var output = StringBuffer();
- _currentJobResult = Completer<Dart2JsResult>();
- var sawError = false;
- var stderrListener = _workerStderrLines.listen((line) {
- if (line == '>>> EOF STDERR') {
- _currentJobResult?.complete(
- Dart2JsResult(!sawError, 'Dart2Js finished with:\n\n$output'));
- }
- if (!line.startsWith('>>> ')) {
- output.writeln(line);
- }
- });
- var stdoutListener = _workerStdoutLines.listen((line) {
- if (line.contains('>>> TEST FAIL')) {
- sawError = true;
- }
- if (!line.startsWith('>>> ')) {
- output.writeln(line);
- }
- });
-
- log.info('Running dart2js with ${job.args.join(' ')}\n');
- worker.stdin.writeln(job.args.join(' '));
-
- Dart2JsResult result;
- try {
- result = await _currentJobResult.future;
- job.resultCompleter.complete(result);
- succeeded = true;
- } catch (e) {
- log.warning('Dart2Js failure: $e');
- succeeded = false;
- if (tryCount >= _retryCountMax) {
- job.resultCompleter.complete(_currentJobResult.future);
- }
- } finally {
- _currentJobResult = null;
- // TODO: Remove this hack once dart-lang/sdk#33708 is resolved.
- if (_jobsSinceLastRestartCount >= _jobsBeforeRestartMax) {
- await terminate();
- }
- await stderrListener.cancel();
- await stdoutListener.cancel();
- }
- }
- }
-
- Future<void> terminate() async {
- var worker = __worker ?? await _spawningWorker;
- __worker = null;
- __workerStdoutLines = null;
- __workerStderrLines = null;
- if (worker != null) {
- worker.kill();
- await worker.stdin.close();
- }
- await worker?.exitCode;
- }
-}
-
-/// A single dart2js job, consisting of [args] and a [result].
-class _Dart2JsJob {
- final List<String> args;
-
- final resultCompleter = Completer<Dart2JsResult>();
- Future<Dart2JsResult> get result => resultCompleter.future;
-
- _Dart2JsJob(this.args);
-}
-
-/// The result of a [_Dart2JsJob]
-class Dart2JsResult {
- final bool succeeded;
- final String output;
-
- Dart2JsResult(this.succeeded, this.output);
-}
diff --git a/build_modules/mono_pkg.yaml b/build_modules/mono_pkg.yaml
deleted file mode 100644
index 3d1ec9e..0000000
--- a/build_modules/mono_pkg.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.5.0
- - unit_test:
- # Run the script directly - running from snapshot has issues for packages
- # that are depended on by build_runner itself.
- - command: dart $(pub run build_runner generate-build-script) test --delete-conflicting-outputs -- -P presubmit
- os:
- - linux
- - windows
-
-cache:
- directories:
- - .dart_tool/build
diff --git a/build_modules/pubspec.yaml b/build_modules/pubspec.yaml
deleted file mode 100644
index 4161b17..0000000
--- a/build_modules/pubspec.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: build_modules
-version: 2.8.0
-description: Builders for Dart modules
-homepage: https://github.com/dart-lang/build/tree/master/build_modules
-
-environment:
- sdk: ">=2.5.0 <3.0.0"
-
-dependencies:
- analyzer: ">0.35.0 <0.40.0"
- async: ^2.0.0
- bazel_worker: ^0.1.20
- build: ">=1.2.0 <2.0.0"
- build_config: ">=0.3.0 <0.5.0"
- collection: ^1.0.0
- crypto: ^2.0.0
- glob: ^1.0.0
- graphs: ^0.2.0
- json_annotation: ">=1.2.0 <4.0.0"
- logging: ^0.11.2
- meta: ^1.1.0
- path: ^1.4.2
- pedantic: ^1.0.0
- scratch_space: ^0.0.4
-
-dev_dependencies:
- build_runner: ^1.0.0
- build_test: ^0.10.9
- build_vm_compilers: ^1.0.0
- test: ^1.6.0
- a:
- path: test/fixtures/a
- b:
- path: test/fixtures/b
-
-dependency_overrides:
- build_vm_compilers:
- path: ../build_vm_compilers
diff --git a/build_resolvers/BUILD.gn b/build_resolvers/BUILD.gn
deleted file mode 100644
index 5abdb1a..0000000
--- a/build_resolvers/BUILD.gn
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is generated by importer.py for build_resolvers-1.3.3
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_resolvers") {
- package_name = "build_resolvers"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/graphs",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/analyzer",
- "//third_party/dart-pkg/pub/yaml",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/package_resolver",
- "//third_party/dart-pkg/pub/path",
- ]
-}
diff --git a/build_resolvers/CHANGELOG.md b/build_resolvers/CHANGELOG.md
deleted file mode 100644
index cc491dc..0000000
--- a/build_resolvers/CHANGELOG.md
+++ /dev/null
@@ -1,190 +0,0 @@
-## 1.3.3
-
-- Fix an issue where non-existing Dart assets weren't visible to the analyzer, even
- when they are created later.
-
-## 1.3.2
-
-- Improve detection of the flutter SDK for older flutter versions.
-
-## 1.3.1
-
-- Add an exception on trying to resolve an `AssetId` that is not a Dart
- library with `libraryFor` to fit the contract expressed by the doc comment on
- `Resolver`.
-
-## 1.3.0
-
-### New feature
-
-You can now resolve additional libraries other than those imported by the
-primary entrypoint.
-
- - This is supported through the `isLibrary` and `libraryFor` methods on
- `Resolver`, which will now resolve the provided asset if it is not already
- resolved.
- - **Note**: Doing this may affect the result of subsequent calls to
- `resolver.libraries` and `resolver.findLibraryByName` if new libraries are
- discovered.
-
-**Note**: If using `build_runner` then this will also require you to upgrade
-to version `4.2.0` of `build_runner_core` .
-
-### Other
-
-- Changed a `hide` declaration to a `show` declaration to support a
-`package:analyzer` change.
-
-## 1.2.2
-
-- Update to `package:analyzer` version `0.39.0`.
-
-## 1.2.1
-
-Check the build_resolvers version as a part of sdk summary invalidation.
-
-## 1.2.0
-
-Add flutters embedded sdk to the summary if available. This has the effect of
-making `dart:ui` and any future libraries available if using the flutter sdk
-instead of the dart sdk.
-
-## 1.1.1
-
-### Bug Fix
-
-Check the analyzer path before reading cached summaries in addition to the
-SDK version.
-
-## 1.1.0
-
-### Bug Fix: #38499
-
-Update the `AnalysisResolvers` class to no longer use the SDK summary that is
-shipped with the SDK by default. This is not guaranteed compatible with
-analyzer versions shipped on pub and should not be used by any non-sdk code.
-
-In order to fix this the `AnalysisResolvers` class now takes an optional method
-that returns the path to an arbitrary SDK summary. By default it will lazily
-generate a summary under `.dart_tool/build_resolvers` which is invalidated
-based on the `Platform.version` from `dart:io`.
-
-## 1.0.8
-
-- Allow `build` version 1.2.x.
-
-## 1.0.7
-
-- Allow analyzer version 0.38.0.
-
-## 1.0.6
-
-- Allow analyzer version 0.37.0.
-
-## 1.0.5
-
-- Fix a race condition where some assets may be resolved with missing
- dependencies. This was likely to have only manifested in tests using
- `resolveSource`.
-
-## 1.0.4
-
-- Increase lower bound sdk constraint to 2.1.0.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-
-## 1.0.3
-
-- Fixes a bug where transitive `dart-ext:` imports would cause the resolver
- to fail. These uris will now be ignored.
-
-## 1.0.2
-
-- Ensure that `BuildAssetUriResolver.restoreAbsolute` never returns null.
- - Fixes a crash when a resolver is requested but not all transitive sources
- are available yet.
-
-## 1.0.1
-
-- Fix a bug causing crashes on windows.
-
-## 1.0.0
-
-- Migrate to `AnalysisDriver`. There are behavior changes which may be breaking.
- The `LibraryElement` instances returned by the resolver will now:
- - Have non-working `context` fields.
- - Have no source offsets for annotations or their errors.
- - Have working `session` fields.
- - Have `Source` instances with different URIs than before.
- - Not include missing libraries in the `importedLibraries` getter. You can
- instead use the `imports` getter to see all the imports.
-
-## 0.2.3
-
-- Update to `build` `1.1.0` and add `assetIdForElement`.
-
-## 0.2.2+7
-
-- Updated _AssetUriResolver to prepare for a future release of the analyzer.
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.2.2+6
-
-- Increased the upper bound for `package:analyzer` to `<0.34.0`.
-
-## 0.2.2+5
-
-- Increased the upper bound for the `build` to `<1.1.0`.
-
-## 0.2.2+4
-
-- Removed dependency on cli_util.
-- Increased the upper bound for the `build` to `<0.12.9`.
-
-## 0.2.2+3
-
-- Don't log a severe message when a URI cannot be resolved. Just return `null`.
-
-## 0.2.2+2
-
-- Use sdk summaries for the analysis context, which makes getting the initial
- resolver faster (reapplied).
-
-## 0.2.2+1
-
-- Restore `new` keyword for a working release on Dart 1 VM.
-
-## 0.2.2
-
-- Use sdk summaries for the analysis context, which makes getting the initial
- resolver faster.
-- Release broken on Dart 1 VM.
-
-## 0.2.1+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.2.1
-
-- Allow passing in custom `AnalysisOptions`.
-
-## 0.2.0+2
-
-- Support `package:analyzer` `0.32.0`.
-
-## 0.2.0+1
-
-- Switch to `firstWhere(orElse)` for compatibility with the SDK dev.45
-
-## 0.2.0
-
-- Removed locking between uses of the Resolver and added a mandatory `reset`
- call to indicate that a complete build is finished.
-
-## 0.1.1
-
-- Support the latest `analyzer` package.
-
-## 0.1.0
-
-- Initial release as a migration from `code_transformers` with a near-identical
- implementation.
diff --git a/build_resolvers/LICENSE b/build_resolvers/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/build_resolvers/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_resolvers/README.md b/build_resolvers/README.md
deleted file mode 100644
index 9aa64bf..0000000
--- a/build_resolvers/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Provides an in-memory `Resolvers` implementation for use with `package:build`.
-
-This implementation does a monolithic analysis from source, with fine grained
-invalidation, which works well when it can be shared across multiple build steps
-in the same process. It is not however suitable for use in more general build
-systems, which should build up their analysis context using analyzer summaries.
diff --git a/build_resolvers/lib/build_resolvers.dart b/build_resolvers/lib/build_resolvers.dart
deleted file mode 100644
index 9a72353..0000000
--- a/build_resolvers/lib/build_resolvers.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-export 'src/resolver.dart' show AnalyzerResolvers;
diff --git a/build_resolvers/lib/src/analysis_driver.dart b/build_resolvers/lib/src/analysis_driver.dart
deleted file mode 100644
index acfbd8d..0000000
--- a/build_resolvers/lib/src/analysis_driver.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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:analyzer/src/dart/analysis/byte_store.dart'
- show MemoryByteStore;
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart'
- show PerformanceLog;
-import 'package:analyzer/src/generated/engine.dart'
- show AnalysisOptionsImpl, AnalysisOptions;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
-
-import 'build_asset_uri_resolver.dart';
-
-/// Builds an [AnalysisDriver] backed by a summary SDK and package summary
-/// files.
-///
-/// Any code which is not covered by the summaries must be resolvable through
-/// [buildAssetUriResolver].
-AnalysisDriver analysisDriver(BuildAssetUriResolver buildAssetUriResolver,
- AnalysisOptions analysisOptions, String sdkSummaryPath) {
- var sdk = SummaryBasedDartSdk(sdkSummaryPath, true);
- var sdkResolver = DartUriResolver(sdk);
-
- var resolvers = [sdkResolver, buildAssetUriResolver];
- var sourceFactory = SourceFactory(resolvers);
-
- var dataStore = SummaryDataStore([sdkSummaryPath]);
-
- var logger = PerformanceLog(null);
- var scheduler = AnalysisDriverScheduler(logger);
- var driver = AnalysisDriver(
- scheduler,
- logger,
- buildAssetUriResolver.resourceProvider,
- MemoryByteStore(),
- FileContentOverlay(),
- null,
- sourceFactory,
- (analysisOptions as AnalysisOptionsImpl) ?? AnalysisOptionsImpl(),
- externalSummaries: dataStore,
- );
-
- scheduler.start();
- return driver;
-}
diff --git a/build_resolvers/lib/src/build_asset_uri_resolver.dart b/build_resolvers/lib/src/build_asset_uri_resolver.dart
deleted file mode 100644
index 35b34a5..0000000
--- a/build_resolvers/lib/src/build_asset_uri_resolver.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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:collection';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart' show parseDirectives;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:build/build.dart' show AssetId, BuildStep;
-import 'package:crypto/crypto.dart';
-import 'package:graphs/graphs.dart';
-import 'package:path/path.dart' as p;
-
-const _ignoredSchemes = ['dart', 'dart-ext'];
-
-class BuildAssetUriResolver extends UriResolver {
- /// A cache of the directives for each Dart library.
- ///
- /// This is stored across builds and is only invalidated if we read a file and
- /// see that it's content is different from what it was last time it was read.
- final _cachedAssetDependencies = <AssetId, Set<AssetId>>{};
-
- /// A cache of the digest for each Dart asset.
- ///
- /// This is stored across builds and used to invalidate the values in
- /// [_cachedAssetDependencies] only when the actual content of the library
- /// changed.
- final _cachedAssetDigests = <AssetId, Digest>{};
-
- final resourceProvider = MemoryResourceProvider(context: p.posix);
-
- /// The assets which are known to be readable at some point during the current
- /// build.
- ///
- /// When actions can run out of order an asset can move from being readable
- /// (in the later phase) to being unreadable (in the earlier phase which ran
- /// later). If this happens we don't want to hide the asset from the analyzer.
- final globallySeenAssets = HashSet<AssetId>();
-
- /// The assets which have been resolved from a [BuildStep], either as an
- /// input, subsequent calls to a resolver, or a transitive import thereof.
- final _buildStepAssets = <BuildStep, HashSet<AssetId>>{};
-
- /// Crawl the transitive imports from [entryPoints] and ensure that the
- /// content of each asset is updated in [resourceProvider] and [driver].
- Future<void> performResolve(BuildStep buildStep, List<AssetId> entryPoints,
- AnalysisDriver driver) async {
- final seenInBuildStep =
- _buildStepAssets.putIfAbsent(buildStep, () => HashSet());
- bool notCrawled(AssetId asset) => !seenInBuildStep.contains(asset);
-
- final changedPaths = await crawlAsync<AssetId, _AssetState>(
- entryPoints.where(notCrawled), (id) async {
- final path = assetPath(id);
- if (!await buildStep.canRead(id)) {
- if (globallySeenAssets.contains(id)) {
- // ignore from this graph, some later build step may still be using it
- // so it shouldn't be removed from [resourceProvider], but we also
- // don't care about it's transitive imports.
- return null;
- }
- _cachedAssetDependencies.remove(id);
- _cachedAssetDigests.remove(id);
- if (resourceProvider.getFile(path).exists) {
- resourceProvider.deleteFile(path);
- }
- return _AssetState.removed(path);
- }
- globallySeenAssets.add(id);
- seenInBuildStep.add(id);
- final digest = await buildStep.digest(id);
- if (_cachedAssetDigests[id] == digest) {
- return _AssetState.unchanged(path, _cachedAssetDependencies[id]);
- } else {
- final isChange = _cachedAssetDigests.containsKey(id);
- final content = await buildStep.readAsString(id);
- _cachedAssetDigests[id] = digest;
- final dependencies =
- _cachedAssetDependencies[id] = _parseDirectives(content, id);
- if (isChange) {
- resourceProvider.updateFile(path, content);
- return _AssetState.changed(path, dependencies);
- } else {
- resourceProvider.newFile(path, content);
- return _AssetState.newAsset(path, dependencies);
- }
- }
- }, (id, state) => state.directives.where(notCrawled))
- .where((state) => state.isAssetUpdate)
- .map((state) => state.path)
- .toList();
- changedPaths.forEach(driver.changeFile);
- }
-
- /// Attempts to parse [uri] into an [AssetId].
- ///
- /// Handles 'package:' or 'asset:' URIs, as well as 'file:' URIs that have the
- /// same pattern used by [assetPath].
- ///
- /// Returns null if the Uri cannot be parsed.
- AssetId parseAsset(Uri uri) {
- if (_ignoredSchemes.any(uri.isScheme)) return null;
- if (uri.isScheme('package') || uri.isScheme('asset')) {
- return AssetId.resolve('$uri');
- }
- if (uri.isScheme('file')) {
- final parts = p.split(uri.path);
- return AssetId(parts[1], p.posix.joinAll(parts.skip(2)));
- }
- return null;
- }
-
- /// Attempts to parse [uri] into an [AssetId] and returns it if it is cached.
- ///
- /// Handles 'package:' or 'asset:' URIs, as well as 'file:' URIs that have the
- /// same pattern used by [assetPath].
- ///
- /// Returns null if the Uri cannot be parsed or is not cached.
- AssetId lookupCachedAsset(Uri uri) {
- final assetId = parseAsset(uri);
- if (assetId == null || !_cachedAssetDigests.containsKey(assetId)) {
- return null;
- }
-
- return assetId;
- }
-
- void notifyComplete(BuildStep step) {
- _buildStepAssets.remove(step);
- }
-
- /// Clear cached information specific to an individual build.
- void reset() {
- assert(_buildStepAssets.isEmpty,
- 'Reset was called before all build steps completed');
- globallySeenAssets.clear();
- }
-
- @override
- Source resolveAbsolute(Uri uri, [Uri actualUri]) {
- final assetId = parseAsset(uri);
- if (assetId == null) return null;
-
- return resourceProvider
- .getFile(assetPath(assetId))
- .createSource(assetId.uri);
- }
-
- @override
- Uri restoreAbsolute(Source source) =>
- lookupCachedAsset(source.uri)?.uri ?? source.uri;
-}
-
-String assetPath(AssetId assetId) =>
- p.posix.join('/${assetId.package}', assetId.path);
-
-/// Returns all the directives from a Dart library that can be resolved to an
-/// [AssetId].
-Set<AssetId> _parseDirectives(String content, AssetId from) =>
- // ignore: deprecated_member_use
- HashSet.of(parseDirectives(content, suppressErrors: true)
- .directives
- .whereType<UriBasedDirective>()
- .where((directive) {
- var uri = Uri.parse(directive.uri.stringValue);
- return !_ignoredSchemes.any(uri.isScheme);
- })
- .map((d) => AssetId.resolve(d.uri.stringValue, from: from))
- .where((id) => id != null));
-
-class _AssetState {
- final String path;
- final bool isAssetUpdate;
- final Iterable<AssetId> directives;
-
- _AssetState.removed(this.path)
- : isAssetUpdate = false,
- directives = const [];
- _AssetState.changed(this.path, this.directives) : isAssetUpdate = true;
- _AssetState.unchanged(this.path, this.directives) : isAssetUpdate = false;
- _AssetState.newAsset(this.path, this.directives) : isAssetUpdate = true;
-}
diff --git a/build_resolvers/lib/src/human_readable_duration.dart b/build_resolvers/lib/src/human_readable_duration.dart
deleted file mode 100644
index 736e915..0000000
--- a/build_resolvers/lib/src/human_readable_duration.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019, 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.
-
-/// Returns a human readable string for a duration.
-///
-/// Handles durations that span up to hours - this will not be a good fit for
-/// durations that are longer than days.
-///
-/// Always attempts 2 'levels' of precision. Will show hours/minutes,
-/// minutes/seconds, seconds/tenths of a second, or milliseconds depending on
-/// the largest level that needs to be displayed.
-///
-// TODO: This is copied from `package:build_runner_core`, at some point we
-// may want to move this to a shared dependency.
-String humanReadable(Duration duration) {
- if (duration < const Duration(seconds: 1)) {
- return '${duration.inMilliseconds}ms';
- }
- if (duration < const Duration(minutes: 1)) {
- return '${(duration.inMilliseconds / 1000.0).toStringAsFixed(1)}s';
- }
- if (duration < const Duration(hours: 1)) {
- final minutes = duration.inMinutes;
- final remaining = duration - Duration(minutes: minutes);
- return '${minutes}m ${remaining.inSeconds}s';
- }
- final hours = duration.inHours;
- final remaining = duration - Duration(hours: hours);
- return '${hours}h ${remaining.inMinutes}m';
-}
diff --git a/build_resolvers/lib/src/resolver.dart b/build_resolvers/lib/src/resolver.dart
deleted file mode 100644
index 35c255a..0000000
--- a/build_resolvers/lib/src/resolver.dart
+++ /dev/null
@@ -1,335 +0,0 @@
-// 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:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:analyzer/src/summary/summary_file_builder.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/file_system.dart' hide File;
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
-import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/generated/engine.dart'
- show AnalysisOptions, AnalysisOptionsImpl;
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:package_resolver/package_resolver.dart';
-import 'package:path/path.dart' as p;
-import 'package:yaml/yaml.dart';
-
-import 'analysis_driver.dart';
-import 'build_asset_uri_resolver.dart';
-import 'human_readable_duration.dart';
-
-final _logger = Logger('build_resolvers');
-
-/// Implements [Resolver.libraries] and [Resolver.findLibraryByName] by crawling
-/// down from entrypoints.
-class PerActionResolver implements ReleasableResolver {
- final AnalyzerResolver _delegate;
- final BuildStep _step;
-
- final Set<AssetId> _entryPoints;
-
- PerActionResolver(this._delegate, this._step, Iterable<AssetId> entryPoints)
- : _entryPoints = entryPoints.toSet();
-
- @override
- Stream<LibraryElement> get libraries async* {
- final seen = <LibraryElement>{};
- final toVisit = Queue<LibraryElement>();
-
- // keep a copy of entry points in case [_resolveIfNecessary] is called
- // before this stream is done.
- final entryPoints = _entryPoints.toList();
- for (final entryPoint in entryPoints) {
- if (!await _delegate.isLibrary(entryPoint)) continue;
- final library = await _delegate.libraryFor(entryPoint);
- toVisit.add(library);
- seen.add(library);
- }
- while (toVisit.isNotEmpty) {
- final current = toVisit.removeFirst();
- // TODO - avoid crawling or returning libraries which are not visible via
- // `BuildStep.canRead`. They'd still be reachable by crawling the element
- // model manually.
- yield current;
- final toCrawl = current.importedLibraries
- .followedBy(current.exportedLibraries)
- .where((l) => !seen.contains(l))
- .toSet();
- toVisit.addAll(toCrawl);
- seen.addAll(toCrawl);
- }
- }
-
- @override
- Future<LibraryElement> findLibraryByName(String libraryName) async =>
- libraries.firstWhere((l) => l.name == libraryName, orElse: () => null);
-
- @override
- Future<bool> isLibrary(AssetId assetId) async {
- await _resolveIfNecesssary(assetId);
- return _delegate.isLibrary(assetId);
- }
-
- @override
- Future<LibraryElement> libraryFor(AssetId assetId) async {
- await _resolveIfNecesssary(assetId);
- return _delegate.libraryFor(assetId);
- }
-
- Future<void> _resolveIfNecesssary(AssetId id) async {
- if (!_entryPoints.contains(id)) {
- _entryPoints.add(id);
-
- // the resolver will only visit assets that haven't been resolved in this
- // step yet
- await _delegate._uriResolver
- .performResolve(_step, [id], _delegate._driver);
- }
- }
-
- @override
- void release() {
- _delegate._uriResolver.notifyComplete(_step);
- _delegate.release();
- }
-
- @override
- Future<AssetId> assetIdForElement(Element element) =>
- _delegate.assetIdForElement(element);
-}
-
-class AnalyzerResolver implements ReleasableResolver {
- final BuildAssetUriResolver _uriResolver;
- final AnalysisDriver _driver;
-
- AnalyzerResolver(this._driver, this._uriResolver);
-
- @override
- Future<bool> isLibrary(AssetId assetId) async {
- var source = _driver.sourceFactory.forUri2(assetId.uri);
- return source != null &&
- (await _driver.getSourceKind(assetPath(assetId))) == SourceKind.LIBRARY;
- }
-
- @override
- Future<LibraryElement> libraryFor(AssetId assetId) async {
- var path = assetPath(assetId);
- var uri = assetId.uri;
- var source = _driver.sourceFactory.forUri2(uri);
- if (source == null) throw ArgumentError('missing source for $uri');
- var kind = await _driver.getSourceKind(path);
- if (kind != SourceKind.LIBRARY) throw NonLibraryAssetException(assetId);
- return _driver.getLibraryByUri(assetId.uri.toString());
- }
-
- @override
- // Do nothing
- void release() {}
-
- @override
- Stream<LibraryElement> get libraries {
- // We don't know what libraries to expose without leaking libraries written
- // by later phases.
- throw UnimplementedError();
- }
-
- @override
- Future<LibraryElement> findLibraryByName(String libraryName) {
- // We don't know what libraries to expose without leaking libraries written
- // by later phases.
- throw UnimplementedError();
- }
-
- @override
- Future<AssetId> assetIdForElement(Element element) async {
- final uri = element.source.uri;
- if (!uri.isScheme('package') && !uri.isScheme('asset')) {
- throw UnresolvableAssetException(
- '${element.name} in ${element.source.uri}');
- }
- return AssetId.resolve('${element.source.uri}');
- }
-}
-
-class AnalyzerResolvers implements Resolvers {
- /// Nullable, the default analysis options are used if not provided.
- final AnalysisOptions _analysisOptions;
-
- /// A function that returns the path to the SDK summary when invoked.
- ///
- /// Defaults to [_defaultSdkSummaryGenerator].
- final Future<String> Function() _sdkSummaryGenerator;
-
- // Lazy, all access must be preceded by a call to `_ensureInitialized`.
- AnalyzerResolver _resolver;
- BuildAssetUriResolver _uriResolver;
-
- /// Nullable, should not be accessed outside of [_ensureInitialized].
- Future<void> _initialized;
-
- AnalyzerResolvers(
- [this._analysisOptions, Future<String> Function() sdkSummaryGenerator])
- : _sdkSummaryGenerator =
- sdkSummaryGenerator ?? _defaultSdkSummaryGenerator;
-
- /// Create a Resolvers backed by an `AnalysisContext` using options
- /// [_analysisOptions].
- Future<void> _ensureInitialized() {
- return _initialized ??= () async {
- _uriResolver = BuildAssetUriResolver();
- var driver = analysisDriver(
- _uriResolver, _analysisOptions, await _sdkSummaryGenerator());
- _resolver = AnalyzerResolver(driver, _uriResolver);
- }();
- }
-
- @override
- Future<ReleasableResolver> get(BuildStep buildStep) async {
- await _ensureInitialized();
-
- await _uriResolver.performResolve(
- buildStep, [buildStep.inputId], _resolver._driver);
- return PerActionResolver(_resolver, buildStep, [buildStep.inputId]);
- }
-
- /// Must be called between each build.
- @override
- void reset() {
- _uriResolver?.reset();
- }
-}
-
-/// Lazily creates a summary of the users SDK and caches it under
-/// `.dart_tool/build_resolvers`.
-///
-/// This is only intended for use in typical dart packages, which must
-/// have an already existing `.dart_tool` directory (this is how we
-/// validate we are running under a typical dart package and not a custom
-/// environment).
-Future<String> _defaultSdkSummaryGenerator() async {
- var dartToolPath = '.dart_tool';
- if (!await Directory(dartToolPath).exists()) {
- throw StateError(
- 'The default analyzer resolver can only be used when the current '
- 'working directory is a standard pub package.');
- }
-
- var cacheDir = p.join(dartToolPath, 'build_resolvers');
- var summaryPath = p.join(cacheDir, 'sdk.sum');
- var depsFile = File('$summaryPath.deps');
- var summaryFile = File(summaryPath);
-
- var currentDeps = {
- 'sdk': Platform.version,
- for (var package in _packageDepsToCheck)
- package: await PackageResolver.current.packagePath(package),
- };
-
- // Invalidate existing summary/version/analyzer files if present.
- if (await depsFile.exists()) {
- if (!await _checkDeps(depsFile, currentDeps)) {
- await depsFile.delete();
- if (await summaryFile.exists()) await summaryFile.delete();
- }
- } else if (await summaryFile.exists()) {
- // Fallback for cases where we could not do a proper version check.
- await summaryFile.delete();
- }
-
- // Generate the summary and version files if necessary.
- if (!await summaryFile.exists()) {
- var watch = Stopwatch()..start();
- _logger.info('Generating SDK summary...');
- await summaryFile.create(recursive: true);
- await summaryFile.writeAsBytes(_buildSdkSummary());
-
- await _createDepsFile(depsFile, currentDeps);
- watch.stop();
- _logger.info('Generating SDK summary completed, took '
- '${humanReadable(watch.elapsed)}\n');
- }
-
- return p.absolute(summaryPath);
-}
-
-final _packageDepsToCheck = ['analyzer', 'build_resolvers'];
-
-Future<bool> _checkDeps(
- File versionsFile, Map<String, Object> currentDeps) async {
- var previous =
- jsonDecode(await versionsFile.readAsString()) as Map<String, Object>;
-
- if (previous.keys.length != currentDeps.keys.length) return false;
-
- for (var entry in previous.entries) {
- if (entry.value != currentDeps[entry.key]) return false;
- }
-
- return true;
-}
-
-Future<void> _createDepsFile(
- File depsFile, Map<String, Object> currentDeps) async {
- await depsFile.create(recursive: true);
- await depsFile.writeAsString(jsonEncode(currentDeps));
-}
-
-List<int> _buildSdkSummary() {
- var resourceProvider = PhysicalResourceProvider.INSTANCE;
- var dartSdkFolder = resourceProvider.getFolder(_runningDartSdkPath);
- var sdk = FolderBasedDartSdk(resourceProvider, dartSdkFolder)
- ..useSummary = false
- ..analysisOptions = AnalysisOptionsImpl();
-
- if (isFlutter) {
- _addFlutterLibraries(sdk, resourceProvider);
- }
-
- var sdkSources = {
- for (var library in sdk.sdkLibraries) sdk.mapDartUri(library.shortName),
- };
-
- return SummaryBuilder(sdkSources, sdk.context).build();
-}
-
-/// Loads the flutter engine _embedder.yaml file and adds any new libraries to
-/// [sdk].
-void _addFlutterLibraries(
- AbstractDartSdk sdk, ResourceProvider resourceProvider) {
- var embedderYamlFile =
- resourceProvider.getFile(p.join(_dartUiPath, '_embedder.yaml'));
- if (!embedderYamlFile.exists) {
- throw StateError('Unable to find flutter libraries, please run '
- '`flutter precache` and try again.');
- }
-
- var embedderYaml = loadYaml(embedderYamlFile.readAsStringSync()) as YamlMap;
- var flutterSdk = EmbedderSdk(resourceProvider,
- {resourceProvider.getFolder(_dartUiPath): embedderYaml});
-
- for (var library in flutterSdk.sdkLibraries) {
- if (sdk.libraryMap.getLibrary(library.shortName) != null) continue;
- sdk.libraryMap.setLibrary(library.shortName, library as SdkLibraryImpl);
- }
-}
-
-/// Path to the running dart's SDK root.
-final _runningDartSdkPath = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-/// Path where the dart:ui package will be found, if executing via the dart
-/// binary provided by the Flutter SDK.
-final _dartUiPath =
- p.normalize(p.join(_runningDartSdkPath, '..', 'pkg', 'sky_engine', 'lib'));
-
-/// `true` if the currently running dart was provided by the Flutter SDK.
-final isFlutter =
- Platform.version.contains('flutter') || Directory(_dartUiPath).existsSync();
diff --git a/build_resolvers/mono_pkg.yaml b/build_resolvers/mono_pkg.yaml
deleted file mode 100644
index 3e88b03..0000000
--- a/build_resolvers/mono_pkg.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.3.0
- - unit_test:
- - group:
- - command: pub run build_runner test
- - command: test/flutter_test.sh
- os:
- - linux
- - windows
-
-cache:
- directories:
- - .dart_tool/build
diff --git a/build_resolvers/pubspec.yaml b/build_resolvers/pubspec.yaml
deleted file mode 100644
index a129cfb..0000000
--- a/build_resolvers/pubspec.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: build_resolvers
-version: 1.3.3
-description: Resolve Dart code in a Builder
-homepage: https://github.com/dart-lang/build/tree/master/build_resolvers
-
-environment:
- sdk: ">=2.3.0 <3.0.0"
-
-dependencies:
- analyzer: ^0.39.0
- build: ">=1.1.0 <1.3.0"
- crypto: ^2.0.0
- graphs: ^0.2.0
- logging: ^0.11.2
- package_resolver: ^1.0.0
- path: ^1.1.0
- yaml: ^2.0.0
-
-dev_dependencies:
- test: ^1.0.0
- build_test: ^0.10.1
- build_runner: ^1.0.0
- build_vm_compilers: ">=0.1.0 <2.0.0"
- build_modules: any
-
-dependency_overrides:
- build_vm_compilers:
- path: ../build_vm_compilers
- build_modules:
- path: ../build_modules
diff --git a/build_runner/BUILD.gn b/build_runner/BUILD.gn
deleted file mode 100644
index 6a8d0eb..0000000
--- a/build_runner/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# This file is generated by importer.py for build_runner-1.7.4
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_runner") {
- package_name = "build_runner"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/shelf_web_socket",
- "//third_party/dart-pkg/pub/code_builder",
- "//third_party/dart-pkg/pub/watcher",
- "//third_party/dart-pkg/pub/pubspec_parse",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/io",
- "//third_party/dart-pkg/pub/build_config",
- "//third_party/dart-pkg/pub/pub_semver",
- "//third_party/dart-pkg/pub/graphs",
- "//third_party/dart-pkg/pub/web_socket_channel",
- "//third_party/dart-pkg/pub/yaml",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/dart_style",
- "//third_party/dart-pkg/pub/build_runner_core",
- "//third_party/dart-pkg/pub/stack_trace",
- "//third_party/dart-pkg/pub/pedantic",
- "//third_party/dart-pkg/pub/build_daemon",
- "//third_party/dart-pkg/pub/shelf",
- "//third_party/dart-pkg/pub/glob",
- "//third_party/dart-pkg/pub/args",
- "//third_party/dart-pkg/pub/http_multi_server",
- "//third_party/dart-pkg/pub/collection",
- "//third_party/dart-pkg/pub/js",
- "//third_party/dart-pkg/pub/mime",
- "//third_party/dart-pkg/pub/timing",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/pool",
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/stream_transform",
- "//third_party/dart-pkg/pub/build_resolvers",
- "//third_party/dart-pkg/pub/async",
- ]
-}
diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md
deleted file mode 100644
index 684e5b2..0000000
--- a/build_runner/CHANGELOG.md
+++ /dev/null
@@ -1,962 +0,0 @@
-## 1.7.4
-
-- Give a warning instead of a stack trace when using a build config override
- file for a package that does not exist.
-- Allow the latest build_config version.
-
-## 1.7.3
-
-- Improve the error message when a `--hostname` argument is invalid.
-- Require SDK version `2.6.0` to enable extension methods.
-- Allow the latest `stream_transform`.
-
-## 1.7.2
-
-- Enable the native windows directory watcher by default.
- - Added a --use-polling-watcher option which overrides this to use a polling
- watcher again.
- - Increased the lower bound for the SDK to a version which contains various
- fixes for the native windows directory watcher.
-- Give a more consistent ordering for Builders when their ordering is allowed to
- be arbitrary.
-- Handle more `--help` invocations without generating the build script.
-
-## 1.7.1
-
-- Allow `build` version 1.2.x.
-
-## 1.7.0
-
-### New Feature: Build Filters
-
-Build filters allow you to choose explicitly which files to build instead of
-building entire directories.
-
-A build filter is a combination of a package and a path, with glob syntax
-supported for each.
-
-Whenever a build filter is provided, only required outputs matching one of the
-build filters will be built, in addition to the inputs to those outputs.
-
-### Command Line Usage
-
-Build filters are supplied using the new `--build-filter` option, which accepts
-relative paths under the package as well as `package:` uris.
-
-Glob syntax is allowed in both package names and paths.
-
-**Example**: The following would build and serve the JS output for an
-application, as well as copy over the required SDK resources for that app:
-
-```
-pub run build_runner serve \
- --build-filter="web/main.dart.js" \
- --build-filter="package:build_web_compilers/**/*.js"
-```
-
-### Build Daemon Usage
-
-The build daemon now accepts build filters when registering a build target. If
-no filters are supplied these default filters are used, which is designed to
-match the previous behavior as closely as possible:
-
-- `<target-dir>/**`
-- `package:*/**`
-
-**Note**: There is one small difference compared to the previous behavior,
-which is that build to source outputs from other top level directories in the
-root package will no longer be built when they would have before. This should
-have no meaningful impact other than being more efficient.
-
-### Common Use Cases
-
-**Note**: For all the listed use cases it is up to the user or tool the user is
-using to request all the required files for the desired task. This package only
-provides the core building blocks for these use cases.
-
-#### Testing
-
-If you have a large number of tests but only want to run a single one you can
-now build just that test instead of all tests under the `test` directory.
-
-This can greatly speed up iteration times in packages with lots of tests.
-
-**Example**: This will build a single web test and run it:
-
-```
-pub run build_runner test \
- --build-filter="test/my_test.dart.browser_test.dart.js" \
- --build-filter="package:build_web_compilers/**/*.js" \
- -- -p chrome test/my_test.dart
-```
-
-**Note**: If your test requires any other generated files (css, etc) you will
-need to add additional filters.
-
-#### Applications
-
-This feature works as expected with the `--output <dir>` and the `serve`
-command. This means you can create an output directory for a single
-application in your package instead of all applications under the same
-directory.
-
-The serve command also uses the build filters to restrict what files are
-available, which means it ensures if something works in serve mode it will
-also work when you create an output directory.
-
-## 1.6.9
-
-- Fix bugs in snapshot invalidation logic that prevented invalidation when
- core packages changed and always created a new snapshot on the second build.
-
-## 1.6.8
-
-- Improve the manual change detector to do a file system scan on demand instead
- of using a file watcher.
-
-## 1.6.7
-
-- Set the `charset` to `utf-8` for Dart content returned by the `AssetHandler`.
-
-## 1.6.6
-
-- Added watch event debouncing to the `daemon` command to line up with the
- `watch` command. This makes things work more nicely with swap files as well
- as "save all" type scenarios (you will only get a single build most times).
-
-## 1.6.5
-
-- Require `package:build_config` `">=0.4.1 <0.4.2"`. Use new API that improves
- error information when a build configuration file is malformed.
-
-## 1.6.4
-
-- Fix an issue where warning logs on startup were accidentally upgraded to
- severe logs in the daemon mode.
-
-## 1.6.3
-
-- Preemptively re-snapshot when the `build_runner` or `build_daemon` packages
- are updated.
-
-## 1.6.2
-
-- Support the latest `build_daemon` version.
-- Expose `assetServerPort` as a top level helper method.
-
-## 1.6.1
-
-- Update the `test` command to wait to exit until the inner test process exits.
-
-## 1.6.0
-
-- Depend on the latest `build_daemon` and provide a shutdown notification on
- build script updates.
-
-## 1.5.2
-
-- Use a polling directory watcher by default on windows again.
-
-## 1.5.1
-
-- Fix an issue where exit codes were not set correctly when running the
- generated build script directly.
-
-## 1.5.0
-
-- Update to the latest `build_daemon`.
-
-## 1.4.0
-
-- Add a `run` command to execute VM entrypoints with generated sources.
-
-## 1.3.5
-
-- Use the latest `build_daemon`.
-
-## 1.3.4
-
-- Use the latest `build_config`.
-
-## 1.3.3
-
-- Use `HttpMultiServer.loopback` for the daemon asset server.
-
-## 1.3.2
-
-- Fix an error where daemon mode would claim support for prompts when it can't
- actually support them and would hang instead.
-- Improve logging when the daemon fails to start up, previously no logs would
- be shown.
-
-## 1.3.1
-
-- Remove usage of set literals to fix errors on older sdks that don't support
- them.
-
-## 1.3.0
-
-- Fix an issue where we might re-use stale build snapshots, which could only be
- resolved by deleting the `.dart_tool` dir (or doing a `clean`).
-- Depend on the latest `build_runner_core` and `build_daemon` releases.
-
-## 1.2.8
-
-- Fix issue where daemon command wouldn't properly shutdown.
-- Allow running when the root package, or a path dependency, is named `test`.
-
-## 1.2.7
-
-- Fix issue where daemon command would occasionally color a log.
-
-## 1.2.6
-
-- Prevent terminals being launched when running the daemon command on Windows.
-- No longer assumeTty when logging through the daemon command.
-- Update `build_daemon` to version `0.4.0`.
-- Update `build_runner_core` to version `2.0.3`.
-- Ensure the daemon command always exits.
-
-## 1.2.5
-
-- Fix a bug with the build daemon where the output options were ignored.
-
-## 1.2.4
-
-- Update `build_resolvers` to version `1.0.0`.
-
-## 1.2.3
-
-- Fix a bug where changing between `--live-reload` and `--hot-reload` might not
- work due to the etags for the injected JS not changing when they should.
-
-## 1.2.2
-
-- Change the format of Build Daemon messages.
-- Build Daemon asset server now properly waits for build results.
-- Build Daemon now properly signals the start of a build.
-- Fix path issues with Daemon command under Windows.
-
-## 1.2.1
-
-- Update `package:build_runner_core` to version `2.0.1`.
-
-## 1.2.0
-
-- Support building through `package:build_daemon`.
-- Update `package:build_runner_core` to version `2.0.0`.
-
-## 1.1.3
-
-- Update to `package:graphs` version `0.2.0`.
-- Fix an issue where when running from source in watch mode the script would
- delete itself when it shouldn't.
-- Add digest string to the asset graph visualization.
-- Added a filter box to the asset graph visualization.
-- Allow `build` version `1.1.x`.
-
-## 1.1.2
-
-- Improve error message when the generated build script cannot be parsed or
- compiled and exit with code `78` to indicate that there is a problem with
- configuration in the project or a dependency's `build.yaml`.
-
-## 1.1.1
-
-### Bug Fixes
-
-- Handle re-snapshotting the build script on SDK updates.
-- Suppress header for the `Bootstrap` logger.
-
-## 1.1.0
-
-### New Features
-
-- The build script will now be ran from snapshot, which improves startup times.
-- The build script will automatically re-run itself when the build script is
- changed, instead of requiring the user to re-run it manually.
-
-## 1.0.0
-
-### Breaking Changes
-
-- Massive cleanup of the public api. The only thing exported from this package
- is now the `run` method. The goal is to reduce the surface area in order to
- stabilize this package, since it is directly depended on by all users.
- - Removed all exports from build_runner_core, if you are creating a custom
- build script you will need to import build_runner_core directly and add a
- dependency on it.
- - Stopped exporting the `build` and `watch` functions directly, as well as the
- `ServeHandler`.
- - If this has broken your use case please file an issue on the package and
- request that we export the api you were using previously. These will be
- considered on an individual basis but the bar for additional exports will be
- high.
-- Removed support for the --[no-]assume-tty command line argument as it is no
- longer needed.
-
-## 0.10.3
-
-- Improve performance tracking and visualization using the `timing` package.
-- Handle bad asset graph in the `clean` command.
-
-## 0.10.2
-
-- Added `--hot-reload` cli option and appropriate functionality.
- See [hot-module-reloading](../docs/hot_module_reloading.md) for more info.
-- Removed dependency on cli_util.
-
-## 0.10.1+1
-
-- Added better error handling when a socket is already in use in `serve` mode.
-
-## 0.10.1
-
-- Added `--live-reload` cli option and appropriate functionality
-- Migrated glob tracking to a specialized node type to fix dart-lang/build#1702.
-
-## 0.10.0
-
-### Breaking Changes
-
-- Implementations of `BuildEnvironment` must now implement the `finalizeBuild`
- method. There is a default implementation if you extend `BuildEnvironment`
- that is a no-op.
- - This method is invoked at the end of the build that allows you to do
- arbitrary additional work, such as creating merged output directories.
-- The `assumeTty` argument on `IOEnvironment` has moved to a named argument
- since `null` is an accepted value.
-- The `outputMap` field on `BuildOptions` has moved to the `IOEnvironment`
- class.
-
-### New Features/Updates
-
-- Added a `outputSymlinksOnly` option to `IOEnvironment` constructor, that
- causes the merged output directories to contain only symlinks, which is much
- faster than copying files.
-- Added the `FinalizedAssetView` class which provides a list of all available
- assets to the `BuildEnvironment` during the build finalization phase.
- - `outputMap` has moved from `BuildOptions` to this constructor, as a named
- argument.
-- The `OverridableEnvironment` now supports overriding the new `finalizeBuild`
- api.
-- The number of concurrent actions per phase is now limited (currently to 16),
- which should help with memory and cpu usage for large builds.
-
-## 0.9.2
-
-- Changed the default file caching logic to use an LRU cache.
-
-## 0.9.1+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.9.1
-
-- The hash dir for the asset graph under `.dart_tool/build` is now based on a
- relative path to the build script instead of the absolute path.
- - This enables `.dart_tool/build` directories to be reused across different
- computers and directories for the same project.
-
-## 0.9.0
-
-### New Features
-
-- Added the `--log-performance <dir>` option which will dump performance
- information to `<dir>` after each build.
-- The `BuildPerformance` class is now serializable, it has a `fromJson`
- constructor and a `toJson` instance method.
-- Added support for `global_options` in `build.yaml` of the root package.
-- Allow overriding the default `Resolvers` implementation.
-- Allows building with symlinked files. Note that changes to the linked files
- will not trigger rebuilds in watch or serve mode.
-
-### Breaking changes
-
-- `BuildPhasePerformance.action` has been replaced with
- `BuildPhasePerformance.builderKeys`.
-- `BuilderActionPerformance.builder` has been replaced with
- `BuilderActionPerformance.builderKey`.
-- `BuildResult` no longer has an `exception` or `stackTrace` field.
-- The 'test' command through `run` will no longer set an exit code. All manual
- build scripts which call `run` should use the `Future<int>` return to set the
- exit code for the process.
-- Dropped `failOnSevere` arguments and `--fail-on-severe` flag. Severe logs are
- always considered failing.
-- Severe level logs now go to `stdout` along with other logs rather than
- `stderr`. Uncaught exceptions from the `build_runner` system itself still go
- to `stderr`.
-
-## Other
-
-- Updated to the latest camel case constants from the sdk.
-- Minimum sdk version is now `>=2.0.0-dev.61`.
-
-## 0.8.10
-
-- All builders with `build_to: source` will now be ran regardless of which
- directory is currently being built, see
- https://github.com/dart-lang/build/issues/1454 for context.
-- `build` will now throw instead of returning a failed build result if nothing
- was built.
-- Improve error message when a dependency has a bad `build.yaml` with a missing
- dependency.
-- Sources that are not a part of a `target` will no longer appear in the asset
- graph, so they will not be readable or globbable.
-- Updated the generated build script to not rely on json encode/decode for the
- builder options object. Instead it now directly inlines a map literal.
-
-## 0.8.9
-
-- Added support for building only specified top level directories.
- - The `build`, `watch` commands support positional arguments which are the
- directories to build. For example, `pub run build_runner build web` will
- only build the `web` directory.
- - The `serve` command treats positional args as it did before, except it will
- only build the directories you ask it to serve.
- - The `test` command will automatically only build the `test` directory.
- - If using the `-o` option, with the `<dir-to-build>:<output-dir>` syntax,
- then the `<dir-to-build>` will be added to the list of directories to build.
- - If additional directories are supplied with positional arguments, then
- those will also be built.
-- Update to latest analyzer and build packages.
-- Updated the `serve` logic to only serve files which were part of the actual
- build, and not stale assets. This brings the semantics exactly in line with
- what would be copied to the `-o` output directory.
-
-## 0.8.8
-
-- Improve search behavior on the `/$graph` page. Users can now query for
- paths and `AssetID` values – `pkg_name|lib/pkg_name.dart`.
-- Commands that don't support trailing args will now appropriately fail with a
- usage exception.
-- Fix a bug where some rebuilds would not happen after adding a new file that
- has outputs which were missing during the previous build.
-- Fix a bug where failing actions which are no longer required can still cause
- the overall build to fail.
-
-## 0.8.7
-
-- Improve error handling on the `/$graph` page.
-- Support the latest `package:builde`
-
-## 0.8.6
-
-- Forward default options for `PostProcessBuilder`s in the generated build
- script.
-- If a build appears to be not making progress (no actions completed for 15
- seconds), then a warning will now be logged with the pending actions.
-- Now fail when a build is requested which does not build anything.
-- Clean up some error messages.
-
-## 0.8.5
-
-- Add log message for merged output errors.
-
-## 0.8.4
-
-- Log the number of completed actions on successful builds.
-- Support the new `isRoot` field for `BuilderOptions` so that builders can
- do different things for the root package.
-- Deprecated `PostProcessBuilder` and `PostProcessBuildStep`. These should be
- imported from `package:build` instead.
-
-## 0.8.3
-
-- Clean and summarize stack traces printed with `--verbose`.
-- Added a `clean` command which deletes generated to source files and the entire
- build cache directory.
-- Bug Fix: Use the same order to compute the digest of input files to a build
- step when writing it as when comparing it. Previously builds would not be
- pruned as efficiently as they can be because the inputs erroneously looked
- different.
-
-## 0.8.2+2
-
-- The `.packages` file is now always created in the root of the output directory
- instead of under each top level directory.
-
-## 0.8.2+1
-
-- Bug Fix: Correctly parse Window's paths with new `--output` semantics.
-
-## 0.8.2
-
-- Allow passing multiple `--output` options. Each option will be split on
- `:`. The first value will be the root input directory, the second value will
- be the output directory. If no delimeter is provided, all resources
- will be copied to the output directory.
-- Allow deleting files in the post process build step.
-- Bug Fix: Correctly include the default whitelist when multiple targets
- without include are provided.
-- Allow logging from within a build factory.
-- Allow serving assets from successful build steps if the overall build fails.
-- Add a `--release` flag to choose the options from `release_options` in
- `build.yaml`. This should replace the need to use `--config` pointing to a
- release version of `build.yaml`.
-
-## 0.8.1
-
-- Improved the layout of `/$perf`, especially after browser window resize.
-- `pub run build_runner` exits with a error when invoked with an unsupported
- command.
-- Bug Fix: Update outputs in merged directory for sources which are not used
- during the build. For example if `web/index.html` is not read to produce any
- generated outputs changes to this file will now get picked up during `pub run
- build_runner watch --output build`.
-- Don't allow a thrown exception from a Builder to take down the entire build
- process - instead record it as a failed action. The overall build will still
- be marked as a failure, but it won't crash the process.
-
-## 0.8.0
-
-### New Features
-
-- Added the new `PostProcessBuilder` class. These are not supported in bazel,
- and are different than a normal `Builder` in some fundamental ways:
- - They don't have to declare output extensions, and can output any file as
- long as it doesn't conflict with an existing one. This is only checked at
- build time.
- - They can only read their primary input.
- - They will not cause optional actions to run - they will only run on assets
- that were built as a part of the normal build.
- - They can not be optional themselves, and can only output to cache.
- - Because they all run in a single phase, after other builders, none of their
- outputs can be used as inputs to any actions.
-- Added `applyPostProccess` method which takes `PostProcessBuilderFactory`s
- instead of `BuilderFactory`s.
-
-### Breaking Changes
-
-- `BuilderApplication` now has a `builderActionFactories` getter instead of a
- `builderFactories` getter.
-- The default constructor for `BuilderApplication` has been replaced with
- `BuilderApplication.forBuilder` and
- `BuilderApplication.forPostProcessBuilder`.
-
-## 0.7.14
-
-- Warn when using `--define` or `build.yaml` configuration for invalid builders.
-
-## 0.7.13+1
-
-- Fix a concurrent modification error when using `listAssets` when an asset
- could be written.
-
-## 0.7.13
-
-- Fix a bug where a chain of `Builder`s would fail to run on some outputs from
- previous steps when the generated asset did not match the target's `sources`.
-- Added support for serving on IPv4 loopback when the server hostname is
- 'localhost' (the default).
-- Added support for serving on any connection (both IPv4 and IPv6) when the
- hostname is 'any'.
-- Improved stdout output.
-
-## 0.7.12
-
-- Added the `--log-requests` flag to the `serve` command, which will log all
- requests to the server.
-- Build actions using `findAssets` will be more smartly invalidated.
-- Added a warning if using `serve` mode but no directories were found to serve.
-- The `--output` option now only outputs files that were required for the latest
- build. Previously when switching js compilers you could end up with ddc
- modules in your dart2js output, even though they weren't required. See
- https://github.com/dart-lang/build/issues/1033.
-- The experimental `create_merged_dir` binary is now removed, it can't be easily
- supported any more and has been replaced by the `--output` option.
-- Builders which write to `source` are no longer guaranteed to run before
- builders which write to `cache`.
-- Honors `runs_before` configuration from Builder definitions.
-- Honors `applies_builders` configuration from Builder definitions.
-
-## 0.7.11+1
-
-- Switch to use a `PollingDirectoryWatcher` on windows, which should fix file
- watching with the `--output` option. Follow along at
- https://github.com/dart-lang/watcher/issues/52 for more details.
-
-## 0.7.11
-
-- Performance tracking is now disabled by default, and you must pass the
- `--track-performance` flag to enable it.
-- The heartbeat logger will now log the current number of completed versus
- scheduled actions, and it will log once a second instead of every 5 seconds.
-- Builds will now be invalidated when the dart SDK is updated.
-- Fixed the error message when missing a build_test dependency but trying to run
- the `test` command.
-- The build script will now exit on changes to `build.yaml` files.
-
-## 0.7.10+1
-
-- Fix bug where relative imports in a dependencies build.yaml would break
- all downstream users, https://github.com/dart-lang/build/issues/995.
-
-## 0.7.10
-
-### New Features
-
-- Added a basic performance visualization. When running with `serve` you can
- now navigate to `/$perf` and get a timeline of all actions. If you are
- experiencing slow builds (especially incremental ones), you can save the
- html of that page and attach it to bug reports!
-
-### Bug Fixes
-
-- When using `--output` we will only clean up files we know we previously output
- to the specified directory. This should allow running long lived processes
- such as servers in that directory (as long as they don't hold open file
- handles).
-
-## 0.7.9+2
-
-- Fixed a bug with build to source and watch mode that would result in an
- infinite build loop, [#962](https://github.com/dart-lang/build/issues/962).
-
-## 0.7.9+1
-
-- Support the latest `analyzer` package.
-
-## 0.7.9
-
-### New Features
-
-- Added command line args to override config for builders globally. The format
- is `--define "<builder_key>=<option>=<value>"`. As an example, enabling the
- dart2js compiler for the `build_web_compilers|entrypoint` builder would look
- like this: `--define "build_web_compilers|entrypoint=compiler=dart2js"`.
-
-### Bug Fixes
-
-- Fixed an issue with mixed mode builds, see
- https://github.com/dart-lang/build/issues/924.
-- Fixed some issues with exit codes and --fail-on-severe, although there are
- still some outstanding problems. See
- https://github.com/dart-lang/build/issues/910 for status updates.
-- Fixed an issue where the process would hang on exceptions, see
- https://github.com/dart-lang/build/issues/883.
-- Fixed an issue with etags not getting updated for source files that weren't
- inputs to any build actions, https://github.com/dart-lang/build/issues/894.
-- Fixed an issue with hidden .DS_Store files on mac in the generated directory,
- https://github.com/dart-lang/build/issues/902.
-- Fixed test output so it will use the compact reporter,
- https://github.com/dart-lang/build/issues/821.
-
-## 0.7.8
-
-- Add `--config` option to use a different `build.yaml` at build time.
-
-## 0.7.7+1
-
-- Avoid watching hosted dependencies for file changes.
-
-## 0.7.7
-
-- The top level `run` method now returns an `int` which represents an `exitCode`
- for the command that was executed.
- - For now we still set the exitCode manually as well but this will likely
- change in the next breaking release. In manual scripts you should `await`
- the call to `run` and assign that to `exitCode` to be future-proofed.
-
-## 0.7.6
-
-- Update to package:build version `0.12.0`.
-- Removed the `DigestAssetReader` interface, the `digest` method has now moved
- to the core `AssetReader` interface. We are treating this as a non-breaking
- change because there are no known users of this interface.
-
-## 0.7.5+1
-
-- Bug fix for using the `--output` flag when you have no `test` directory.
-
-## 0.7.5
-
-- Add more human friendly duration printing.
-- Added the `--output <dir>` (or `-o`) argument which will create a merged
- output directory after each build.
-- Added the `--verbose` (or `-v`) flag which enables verbose logging.
- - Disables stack trace folding and terse stack traces.
- - Disables the overwriting of previous info logs.
- - Sets the default log level to `Level.ALL`.
-- Added `pubspec.yaml` and `pubspec.lock` to the whitelist for the root package
- sources.
-
-## 0.7.4
-
-- Allows using files in any build targets in the root package as sources if they
- fall outside the hardcoded whitelist.
-- Changes to the root `.packages` file during watch mode will now cause the
- build script to exit and prompt the user to restart the build.
-
-## 0.7.3
-
-- Added the flag `--low-resources-mode`, which defaults to `false`.
-
-## 0.7.2
-
-- Added the flag `--fail-on-severe`, which defaults to `false`. In a future
- version this will default to `true`, which means that logging a message via
- `log.severe` will fail the build instead of just printing to the terminal.
- This would match the current behavior in `bazel_codegen`.
-- Added the `test` command to the `build_runner` binary.
-
-## 0.7.1+1
-
-- **BUG FIX**: Running the `build_runner` binary without arguments no longer
- causes a crash saying `Could not find an option named "assume-tty".`.
-
-## 0.7.1
-
-- Run Builders which write to the source tree before those which write to the
- build cache.
-
-## 0.7.0
-
-### New Features
-
-- Added `toRoot` Package filter.
-- Actions are now invalidated at a fine grained level when `BuilderOptions`
- change.
-- Added magic placeholder files in all packages, which can be used when your
- builder doesn't have a clear primary input file.
- - For non-root packages the placeholder exists at `lib/$lib$`, you should
- declare your `buildExtensions` like this `{r'$lib$': 'my_output_file.txt'}`,
- which would result in an output file at `lib/my_output_file.txt` in the
- package.
- - For the root package there are also placeholders at `web/$web$` and
- `test/$test$` which should cover most use cases. Please file an issue if you
- need additional placeholders.
- - Note that these placeholders are not real assets and attempting to read them
- will result in an `AssetNotFoundException`.
-
-### Breaking Changes
-
-- Removed `BuildAction`. Changed `build` and `watch` to take a
- `List<BuilderApplication>`. See `apply` and `applyToRoot` to set these up.
-- Changed `apply` to take a single String argument - a Builder key from
- `package:build_config` rather than a separate package and builder name.
-- Changed the default value of `hideOutput` from `false` to `true` for `apply`.
- With `applyToRoot` the value remains `false`.
-- There is now a whitelist of top level directories that will be used as a part
- of the build, and other files will be ignored. For now those directories
- include 'benchmark', 'bin', 'example', 'lib', 'test', 'tool', and 'web'.
- - If this breaks your workflow please file an issue and we can look at either
- adding additional directories or making the list configurable per project.
-- Remove `PackageGraph.orderedPackages` and `PackageGraph.dependentsOf`.
-- Remove `writeToCache` argument of `build` and `watch`. Each `apply` call
- should specify `hideOutput` to keep this behavior.
-- Removed `PackageBuilder` and `PackageBuildActions` classes. Use the new
- magic placeholder files instead (see new features section for this release).
-
-The following changes are technically breaking but should not impact most
-clients:
-
-- Upgrade to `build_barback` v0.5.0 which uses strong mode analysis and no
- longer analyzes method bodies.
-- Removed `dependencyType`, `version`, `includes`, and `excludes` from
- `PackageNode`.
-- Removed `PackageNode.noPubspec` constructor.
-- Removed `InputSet`.
-- PackageGraph instances enforce that the `root` node is the only node with
- `isRoot == true`.
-
-## 0.6.1
-
-### New Features
-
-- Add an `enableLowResourcesMode` option to `build` and `watch`, which will
- consume less memory at the cost of slower builds. This is intended for use in
- resource constrained environments such as Travis.
-- Add `createBuildActions`. After finding a list of Builders to run, and defining
- which packages need them applied, use this tool to apply them in the correct
- order across the package graph.
-
-### Deprecations
-
-- Deprecate `PackageGraph.orderedPackages` and `PackageGraph.dependentsOf`.
-
-### Internal Improvements
-
-- Outputs will no longer be rebuilt unless their inputs actually changed,
- previously if any transtive dependency changed they would be invalidated.
-- Switched to using semantic analyzer summaries, this combined with the better
- input validation means that, ddc/summary builds are much faster on non-api
- affecting edits (dependent modules will no longer be rebuilt).
-- Build script invalidation is now much faster, which speeds up all builds.
-
-### Bug Fixes
-
-- The build actions are now checked against the previous builds actions, and if
- they do not match then a full build is performed. Previously the behavior in
- this case was undefined.
-- Fixed an issue where once an edge between an output and an input was created
- it was never removed, causing extra builds to happen that weren't necessary.
-- Build actions are now checked for overlapping outputs in non-checked mode,
- previously this was only an assert.
-- Fixed an issue where nodes could get in an inconsistent state for short
- periods of time, leading to various errors.
-- Fixed an issue on windows where incremental builds didn't work.
-
-## 0.6.0+1
-
-### Internal Improvements
-
-- Now using `package:pool` to limit the number of open file handles.
-
-### Bug fixes
-
-- Fixed an issue where the asset graph could get in an invalid state if you
- aren't setting `writeToCache: true`.
-
-## 0.6.0
-
-### New features
-
-- Added `orderedPackages` and `dependentsOf` utilities to `PackageGraph`.
-- Added the `noPubspec` constructor to `PackageNode`.
-- Added the `PackageBuilder` and `PackageBuildAction` classes. These builders
- only run once per package, and have no primary input. Outputs must be well
- known ahead of time and are declared with the `Iterable<String> get outputs`
- field, which returns relative paths under the current package.
-- Added the `isOptional` field to `BuildAction`. Setting this to `true` means
- that the action will not run unless some other non-optional action tries to
- read one of the outputs of the action.
-- **Breaking**: `PackageNode.location` has become `PackageNode.path`, and is
- now a `String` (absolute path) instead of a `Uri`; this prevents needing
- conversions to/from `Uri` across the package.
-- **Breaking**: `RunnerAssetReader` interface requires you to implement
- `MultiPackageAssetReader` and `DigestAssetReader`. This means the
- `packageName` named argument has changed to `package`, and you have to add the
- `Future<Digest> digest(AssetId id)` method. While technically breaking most
- users do not rely on this interface explicitly.
- - You also no longer have to implement the
- `Future<DateTime> lastModified(AssetId id)` method, as it has been replaced
- with the `DigestAssetReader` interface.
-- **Breaking**: `ServeHandler.handle` has been replaced with
- `Handler ServeHandler.handleFor(String rootDir)`. This allows you to create
- separate handlers per directory you want to serve, which maintains pub serve
- conventions and allows interoperation with `pub run test --pub-serve=$PORT`.
-
-### Bug fixes
-
-- **Breaking**: All `AssetReader#findAssets` implementations now return a
- `Stream<AssetId>` to match the latest `build` package. This should not affect
- most users unless you are extending the built in `AssetReader`s or using them
- in a custom way.
-- Fixed an issue where `findAssets` could return declared outputs from previous
- phases that did not actually output the asset.
-- Fixed two issues with `writeToCache`:
- - Over-declared outputs will no longer attempt to build on each startup.
- - Unrecognized files in the cache dir will no longer be treated as inputs.
-- Asset invalidation has changed from using last modified timestamps to content
- hashes. This is generally much more reliable, and unblocks other desired
- features.
-
-### Internal changes
-
-- Added `PackageGraphWatcher` and `PackageNodeWatcher` as a wrapper API,
- including an `AssetChange` class that is now consistently used across the
- package.
-
-## 0.5.0
-
-- **Breaking**: Removed `buildType` field from `BuildResult`.
-- **Breaking**: `watch` now returns a `ServeHandler` instead of a
- `Stream<BuildResult>`. Use `ServeHandler.buildResults` to get back to the
- original stream.
-- **Breaking**: `serve` has been removed. Instead use `watch` and use the
- resulting `ServeHandler.handle` method along with a server created in the
- client script to start a server.
-- Prevent reads into `.dart_tool` for more hermetic builds.
-- Bug Fix: Rebuild entire asset graph if the build script changes.
-- Add `writeToCache` argument to `build` and `watch` which separates generated
- files from the source directory and allows running builders against other
- packages.
-- Allow the latest version of `package:shelf`.
-
-## 0.4.0+3
-
-- Bug fix: Don't try to delete files generated for other packages.
-
-## 0.4.0+2
-
-- Bug fix: Don't crash after a Builder reads a file from another package.
-
-## 0.4.0+1
-
-- Depend on `build` 0.10.x and `build_barback` 0.4.x
-
-## 0.4.0
-
-- **Breaking**: The `PhaseGroup` class has been replaced with a
- `List<BuildAction>` in `build`, `watch`, and `serve`. The `PhaseGroup` and
- `Phase` classes are removed.
- If your current build has multiple actions in a single phase which are
- depending on *not* seeing the outputs from other actions in the phase you will
- need to instead set up the `InputSet`s so that the outputs are filtered out.
-- **Breaking**: The `resolvers` argument has been removed from `build`, `watch`,
- and `serve`.
-- Allow `package:build` v0.10.x
-
-## 0.3.4+1
-
-- Support the latest release of `build_barback`.
-
-## 0.3.4
-
-- Support the latest release of `analyzer`.
-
-## 0.3.2
-
-- Support for build 0.9.0
-
-## 0.3.1+1
-
-- Bug Fix: Update AssetGraph version so builds can be run without manually
- deleting old build directory.
-- Bug Fix: Check for unreadable assets in an async method rather than throw
- synchronously
-
-## 0.3.1
-
-- Internal refactoring of RunnerAssetReader.
-- Support for build 0.8.0
-- Add findAssets on AssetReader implementations
-- Limit Asset reads to those which were available at the start of the phase.
- This might cause some reads which uses to succeed to fail.
-
-## 0.3.0
-
-### Bug Fixes
-
-- Fixed a race condition bug [175](https://github.com/dart-lang/build/issues/175)
- that could cause invalid output errors.
-
-### Breaking Changes
-
-- `RunnerAssetWriter` now requires an additional field, `onDelete` which is a
- callback that must be called synchronously within `delete`.
-
-## 0.2.0
-
-Add support for the new bytes apis in `build`.
-
-### New Features
-
-- `FileBasedAssetReader` and `FileBasedAssetWriter` now support reading/writing
- as bytes.
-
-### Breaking Changes
-
-- Removed the `AssetCache`, `CachedAssetReader`, and `CachedAssetWriter`. These
- may come back at a later time if deemed necessary, but for now they just
- complicate things unnecessarily without proven benefits.
-- `BuildResult#outputs` now has a type of `List<AssetId>` instead of
- `List<Asset>`, since the `Asset` class no longer exists. Additionally this was
- wasting memory by keeping all output contents around when it's not generally
- a very useful thing outside of tests (which retain this information in other
- ways).
-
-## 0.0.1
-
-- Initial separate release - split off from `build` package.
diff --git a/build_runner/LICENSE b/build_runner/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/build_runner/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_runner/README.md b/build_runner/README.md
deleted file mode 100644
index 8845b2f..0000000
--- a/build_runner/README.md
+++ /dev/null
@@ -1,256 +0,0 @@
-<p align="center">
- Standalone generator and watcher for Dart using <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
- <br>
- <a href="https://travis-ci.org/dart-lang/build">
- <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
- </a>
- <a href="https://github.com/dart-lang/build/labels/package%3A%20build_runner">
- <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_runner.svg" alt="Issues related to build_runner" />
- </a>
- <a href="https://pub.dev/packages/build_runner">
- <img src="https://img.shields.io/pub/v/build_runner.svg" alt="Pub Package Version" />
- </a>
- <a href="https://pub.dev/documentation/build_runner/latest">
- <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
- </a>
- <a href="https://gitter.im/dart-lang/build">
- <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
- </a>
-</p>
-
-The `build_runner` package provides a concrete way of generating files using
-Dart code, outside of tools like `pub`. Unlike `pub serve/build`, files are
-always generated directly on disk, and rebuilds are _incremental_ - inspired by
-tools such as [Bazel][].
-
-> **NOTE**: Are you a user of this package? You may be interested in
-> simplified user-facing documentation, such as our
-> [getting started guide][getting-started-link].
-
-[getting-started-link]: https://goo.gl/b9o2j6
-
-* [Installation](#installation)
-* [Usage](#usage)
- * [Built-in commands](#built-in-commands)
- * [Inputs](#inputs)
- * [Outputs](#outputs)
- * [Source control](#source-control)
- * [Publishing packages](#publishing-packages)
-* [Contributing](#contributing)
- * [Testing](#testing)
-
-## Installation
-
-This package is intended to support development of Dart projects with
-[`package:build`][]. In general, put it under [dev_dependencies][], in your
-[`pubspec.yaml`][pubspec].
-
-```yaml
-dev_dependencies:
- build_runner:
-```
-
-## Usage
-
-When the packages providing `Builder`s are configured with a `build.yaml` file
-they are designed to be consumed using an generated build script. Most builders
-should need little or no configuration, see the documentation provided with the
-Builder to decide whether the build needs to be customized. If it does you may
-also provide a `build.yaml` with the configuration. See the
-`package:build_config` README for more information on this file.
-
-To have web code compiled to js add a `dev_dependency` on `build_web_compilers`.
-
-### Built-in Commands
-
-The `build_runner` package exposes a binary by the same name, which can be
-invoked using `pub run build_runner <command>`.
-
-The available commands are `build`, `watch`, `serve`, and `test`.
-
-- `build`: Runs a single build and exits.
-- `watch`: Runs a persistent build server that watches the files system for
- edits and does rebuilds as necessary.
-- `serve`: Same as `watch`, but runs a development server as well.
- - By default this serves the `web` and `test` directories, on port `8080` and
- `8081` respectively. See below for how to configure this.
-- `test`: Runs a single build, creates a merged output directory, and then runs
- `pub run test --precompiled <merged-output-dir>`. See below for instructions
- on passing custom args to the test command.
-
-#### Command Line Options
-
-All the above commands support the following arguments:
-
-- `--help`: Print usage information for the command.
-- `--assume-tty`: Enables colors and interactive input when the script does not
- appear to be running directly in a terminal, for instance when it is a
- subprocess.
-- `--delete-conflicting-outputs`: Assume conflicting outputs in the users
- package are from previous builds, and skip the user prompt that would usually
- be provided.
-- `--[no-]fail-on-severe`: Whether to consider the build a failure on an error
- logged. By default this is false.
-
-Some commands also have additional options:
-
-##### serve
-
-- `--hostname`: The host to run the server on.
-- `--live-reload`: Enables automatic page reloading on rebuilds.
- Can't be used together with `--hot-reload`.
-- `--hot-reload`: Enables automatic reloading of changed modules on rebuilds.
- See [hot-module-reloading](../docs/hot_module_reloading.md) for more info.
- Can't be used together with `--live-reload`.
-
-Trailing args of the form `<directory>:<port>` are supported to customize what
-directories are served, and on what ports.
-
-For example to serve the `example` and `web` directories on ports 8000 and 8001
-you would do `pub run build_runner serve example:8000 web:8001`.
-
-##### test
-
-The test command will forward any arguments after an empty `--` arg to the
-`pub run test` command.
-
-For example if you wanted to pass `-p chrome` you would do
-`pub run build_runner test -- -p chrome`.
-
-### Inputs
-
-Valid inputs follow the general dart package rules. You can read any files under
-the top level `lib` folder any package dependency, and you can read all files
-from the current package.
-
-In general it is best to be as specific as possible with your `InputSet`s,
-because all matching files will be checked against a `Builder`'s
-[`buildExtensions`][build_extensions] - see [outputs](#outputs) for more
-information.
-
-### Outputs
-
-* You may output files anywhere in the current package.
-
-> **NOTE**: When a `BuilderApplication` specifies `hideOutput: true` it may
-> output under the `lib` folder of _any_ package you depend on.
-
-* Builders are not allowed to overwrite existing files, only create new ones.
-* Outputs from previous builds will not be treated as inputs to later ones.
-* You may use a previous `BuilderApplications`'s outputs as an input to a later
- action.
-
-### Source control
-
-This package creates a top level `.dart_tool` folder in your package, which
-should not be submitted to your source control repository. You can see [our own
-`.gitignore`](https://github.com/dart-lang/build/blob/master/.gitignore) as an
-example.
-
-```git
-# Files generated by dart tools
-.dart_tool
-```
-
-When it comes to _generated_ files it is generally best to not submit them to
-source control, but a specific `Builder` may provide a recommendation otherwise.
-
-It should be noted that if you do submit generated files to your repo then when
-you change branches or merge in changes you may get a warning on your next build
-about declared outputs that already exist. This will be followed up with a
-prompt to delete those files. You can type `l` to list the files, and then type
-`y` to delete them if everything looks correct. If you think something is wrong
-you can type `n` to abandon the build without taking any action.
-
-### Publishing packages
-
-In general generated files **should** be published with your package, but this
-may not always be the case. Some `Builder`s may provide a recommendation for
-this as well.
-
-
-## Legacy Usage
-
-If the generated script does not do everything you need it's possible to
-manually write one. With this approach every package which *uses* a
-[`Builder`][builder] must have it's own script, they cannot be reused
-from other packages. A package which defines a [`Builder`][builder] may have an
-example you can reference, but a unique script must be written for the consuming
-packages as well. You can reference the generated script at
-`.dart_tool/build/entrypoint/build.dart` for an example.
-
-Your script should use one of the following functions defined by this library:
-
-- [**`run`**][run_fn]: Use the same argument parsing as the generated approach.
-- [**`build`**][build_fn]: Run a single build and exit.
-- [**`watch`**][watch_fn]: Continuously run builds as you edit files.
-
-### Configuring
-
-[`run`][run_fn], [`build`][build_fn], and [`watch`][watch_fn] have a required
-argument which is a `List<BuilderApplication>`. These correspond to the
-`BuilderDefinition` class from `package:build_config`. See `apply` and
-`applyToRoot` to create instances of this class. These will be translated into
-actions by crawling through dependencies. The order of this list is important.
-Each Builder may read the generated outputs of any Builder that ran on a package
-earlier in the dependency graph, but for the package it is running on it may
-only read the generated outputs from Builders earlier in the list of
-`BuilderApplication`s.
-
-**NOTE**: Any time you change your build script (or any of its dependencies),
-the next build will be a full rebuild. This is because the system has no way
-of knowing how that change may have affected the outputs.
-
-## Contributing
-
-We welcome a diverse set of contributions, including, but not limited to:
-
-* [Filing bugs and feature requests][file_an_issue]
-* [Send a pull request][pull_request]
-* Or, create something awesome using this API and share with us and others!
-
-For the stability of the API and existing users, consider opening an issue
-first before implementing a large new feature or breaking an API. For smaller
-changes (like documentation, minor bug fixes), just send a pull request.
-
-### Testing
-
-All pull requests are validated against [travis][travis], and must pass. The
-`build_runner` package lives in a mono repository with other `build` packages,
-and _all_ of the following checks must pass for _each_ package.
-
-Ensure code passes all our [analyzer checks][analysis_options]:
-
-```sh
-$ dartanalyzer .
-```
-
-Ensure all code is formatted with the latest [dev-channel SDK][dev_sdk].
-
-```sh
-$ dartfmt -w .
-```
-
-Run all of our unit tests:
-
-```sh
-$ pub run test
-```
-
-[Bazel]: https://bazel.build/
-[`package:build`]: https://pub.dev/packages/build
-[analysis_options]: https://github.com/dart-lang/build/blob/master/analysis_options.yaml
-
-[builder]: https://pub.dev/documentation/build/latest/build/Builder-class.html
-[run_fn]: https://pub.dev/documentation/build_runner/latest/build_runner/run.html
-[build_fn]: https://pub.dev/documentation/build_runner/latest/build_runner/build.html
-[watch_fn]: https://pub.dev/documentation/build_runner/latest/build_runner/watch.html
-[builder_application]: https://pub.dev/documentation/build_runner/latest/build_runner/BuilderApplication-class.html
-[build_extensions]: https://pub.dev/documentation/build/latest/build/Builder/buildExtensions.html
-
-[travis]: https://travis-ci.org/
-[dev_sdk]: https://dart.dev/get-dart
-[dev_dependencies]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[pubspec]: https://dart.dev/tools/pub/pubspec
-[file_an_issue]: https://github.com/dart-lang/build/issues/new
-[pull_request]: https://github.com/dart-lang/build/pulls
diff --git a/build_runner/bin/build_runner.dart b/build_runner/bin/build_runner.dart
deleted file mode 100644
index e790a51..0000000
--- a/build_runner/bin/build_runner.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2017, 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 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:io/ansi.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-
-import 'package:build_runner/src/build_script_generate/bootstrap.dart';
-import 'package:build_runner/src/entrypoint/runner.dart';
-import 'package:build_runner/src/logging/std_io_logging.dart';
-
-import 'src/commands/clean.dart';
-import 'src/commands/generate_build_script.dart';
-
-Future<void> main(List<String> args) async {
- // Use the actual command runner to parse the args and immediately print the
- // usage information if there is no command provided or the help command was
- // explicitly invoked.
- var commandRunner = BuildCommandRunner([]);
- var localCommands = [CleanCommand(), GenerateBuildScript()];
- var localCommandNames = localCommands.map((c) => c.name).toSet();
- localCommands.forEach(commandRunner.addCommand);
-
- ArgResults parsedArgs;
- try {
- parsedArgs = commandRunner.parse(args);
- } on UsageException catch (e) {
- print(red.wrap(e.message));
- print('');
- print(e.usage);
- exitCode = ExitCode.usage.code;
- return;
- }
-
- var commandName = parsedArgs.command?.name;
-
- if (parsedArgs.rest.isNotEmpty) {
- print(
- yellow.wrap('Could not find a command named "${parsedArgs.rest[0]}".'));
- print('');
- print(commandRunner.usageWithoutDescription);
- exitCode = ExitCode.usage.code;
- return;
- }
-
- if (commandName == 'help' ||
- parsedArgs.wasParsed('help') ||
- (parsedArgs.command?.wasParsed('help') ?? false)) {
- await commandRunner.runCommand(parsedArgs);
- return;
- }
-
- if (commandName == null) {
- commandRunner.printUsage();
- exitCode = ExitCode.usage.code;
- return;
- }
-
- StreamSubscription logListener;
- if (commandName == 'daemon') {
- // Simple logs only in daemon mode. These get converted into info or
- // severe logs by the client.
- logListener = Logger.root.onRecord.listen((record) {
- if (record.level >= Level.SEVERE) {
- var buffer = StringBuffer(record.message);
- if (record.error != null) buffer.writeln(record.error);
- if (record.stackTrace != null) buffer.writeln(record.stackTrace);
- stderr.writeln(buffer);
- } else {
- stdout.writeln(record.message);
- }
- });
- } else {
- logListener = Logger.root.onRecord.listen(stdIOLogListener());
- }
- if (localCommandNames.contains(commandName)) {
- exitCode = await commandRunner.runCommand(parsedArgs);
- } else {
- while ((exitCode = await generateAndRun(args)) == ExitCode.tempFail.code) {}
- }
- await logListener?.cancel();
-}
diff --git a/build_runner/bin/graph_inspector.dart b/build_runner/bin/graph_inspector.dart
deleted file mode 100644
index 21e6ea0..0000000
--- a/build_runner/bin/graph_inspector.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright (c) 2017, 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 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-
-AssetGraph assetGraph;
-PackageGraph packageGraph;
-
-final logger = Logger('graph_inspector');
-
-Future<void> main(List<String> args) async {
- final logSubscription =
- Logger.root.onRecord.listen((record) => print(record.message));
- logger.warning(
- 'Warning: this tool is unsupported and usage may change at any time, '
- 'use at your own risk.');
-
- final argParser = ArgParser()
- ..addOption('graph-file',
- abbr: 'g', help: 'Specify the asset_graph.json file to inspect.')
- ..addOption('build-script',
- abbr: 'b',
- help: 'Specify the build script to find the asset graph for.',
- defaultsTo: '.dart_tool/build/entrypoint/build.dart');
-
- final results = argParser.parse(args);
-
- if (results.wasParsed('graph-file') && results.wasParsed('build-script')) {
- throw ArgumentError(
- 'Expected exactly one of `--graph-file` or `--build-script`.');
- }
-
- var assetGraphFile = File(_findAssetGraph(results));
- if (!assetGraphFile.existsSync()) {
- throw ArgumentError('Unable to find AssetGraph.');
- }
- stdout.writeln('Loading asset graph at ${assetGraphFile.path}...');
-
- assetGraph = AssetGraph.deserialize(assetGraphFile.readAsBytesSync());
- packageGraph = PackageGraph.forThisPackage();
-
- var commandRunner = CommandRunner<bool>(
- '', 'A tool for inspecting the AssetGraph for your build')
- ..addCommand(InspectNodeCommand())
- ..addCommand(GraphCommand())
- ..addCommand(QuitCommand());
-
- stdout.writeln('Ready, please type in a command:');
-
- var shouldExit = false;
- while (!shouldExit) {
- stdout
- ..writeln('')
- ..write('> ');
- var nextCommand = stdin.readLineSync();
- stdout.writeln('');
- try {
- shouldExit = await commandRunner.run(nextCommand.split(' '));
- } on UsageException {
- stdout.writeln('Unrecognized option');
- await commandRunner.run(['help']);
- }
- }
- await logSubscription.cancel();
-}
-
-String _findAssetGraph(ArgResults results) {
- if (results.wasParsed('graph-file')) return results['graph-file'] as String;
- final scriptPath = results['build-script'] as String;
- final scriptFile = File(scriptPath);
- if (!scriptFile.existsSync()) {
- throw ArgumentError(
- 'Expected a build script at $scriptPath but didn\'t find one.');
- }
- return assetGraphPathFor(p.url.joinAll(p.split(scriptPath)));
-}
-
-class InspectNodeCommand extends Command<bool> {
- @override
- String get name => 'inspect';
-
- @override
- String get description =>
- 'Lists all the information about an asset using a relative or package: uri';
-
- @override
- String get invocation => '${super.invocation} <dart-uri>';
-
- InspectNodeCommand() {
- argParser.addFlag('verbose', abbr: 'v');
- }
-
- @override
- bool run() {
- var stringUris = argResults.rest;
- if (stringUris.isEmpty) {
- stderr.writeln('Expected at least one uri for a node to inspect.');
- }
- for (var stringUri in stringUris) {
- var id = _idFromString(stringUri);
- if (id == null) {
- continue;
- }
- var node = assetGraph.get(id);
- if (node == null) {
- stderr.writeln('Unable to find an asset node for $stringUri.');
- continue;
- }
-
- var description = StringBuffer()
- ..writeln('Asset: $stringUri')
- ..writeln(' type: ${node.runtimeType}');
-
- if (node is GeneratedAssetNode) {
- description
- ..writeln(' state: ${node.state}')
- ..writeln(' wasOutput: ${node.wasOutput}')
- ..writeln(' phase: ${node.phaseNumber}')
- ..writeln(' isFailure: ${node.isFailure}');
- }
-
- void _printAsset(AssetId asset) =>
- _listAsset(asset, description, indentation: ' ');
-
- if (argResults['verbose'] == true) {
- description.writeln(' primary outputs:');
- node.primaryOutputs.forEach(_printAsset);
-
- description.writeln(' secondary outputs:');
- node.outputs.difference(node.primaryOutputs).forEach(_printAsset);
-
- if (node is NodeWithInputs) {
- description.writeln(' inputs:');
- assetGraph.allNodes
- .where((n) => n.outputs.contains(node.id))
- .map((n) => n.id)
- .forEach(_printAsset);
- }
- }
-
- stdout.write(description);
- }
- return false;
- }
-}
-
-class GraphCommand extends Command<bool> {
- @override
- String get name => 'graph';
-
- @override
- String get description => 'Lists all the nodes in the graph.';
-
- @override
- String get invocation => '${super.invocation} <dart-uri>';
-
- GraphCommand() {
- argParser
- ..addFlag('generated',
- abbr: 'g', help: 'Show only generated assets.', defaultsTo: false)
- ..addFlag('original',
- abbr: 'o',
- help: 'Show only original source assets.',
- defaultsTo: false)
- ..addOption('package',
- abbr: 'p', help: 'Filters nodes to a certain package')
- ..addOption('pattern', abbr: 'm', help: 'glob pattern for path matching');
- }
-
- @override
- bool run() {
- var showGenerated = argResults['generated'] as bool;
- var showSources = argResults['original'] as bool;
- Iterable<AssetId> assets;
- if (showGenerated) {
- assets = assetGraph.outputs;
- } else if (showSources) {
- assets = assetGraph.sources;
- } else {
- assets = assetGraph.allNodes.map((n) => n.id);
- }
-
- var package = argResults['package'] as String;
- if (package != null) {
- assets = assets.where((id) => id.package == package);
- }
-
- var pattern = argResults['pattern'] as String;
- if (pattern != null) {
- var glob = Glob(pattern);
- assets = assets.where((id) => glob.matches(id.path));
- }
-
- for (var id in assets) {
- _listAsset(id, stdout, indentation: ' ');
- }
- return false;
- }
-}
-
-class QuitCommand extends Command<bool> {
- @override
- String get name => 'quit';
-
- @override
- String get description => 'Exit the inspector';
-
- @override
- bool run() => true;
-}
-
-AssetId _idFromString(String stringUri) {
- var uri = Uri.parse(stringUri);
- if (uri.scheme == 'package') {
- return AssetId(uri.pathSegments.first,
- p.url.join('lib', p.url.joinAll(uri.pathSegments.skip(1))));
- } else if (!uri.isAbsolute && (uri.scheme == '' || uri.scheme == 'file')) {
- return AssetId(packageGraph.root.name, uri.path);
- } else {
- stderr.writeln('Unrecognized uri $uri, must be a package: uri or a '
- 'relative path.');
- return null;
- }
-}
-
-void _listAsset(AssetId output, StringSink buffer,
- {String indentation = ' '}) {
- var outputUri = output.uri;
- if (outputUri.scheme == 'package') {
- buffer.writeln('$indentation${output.uri}');
- } else {
- buffer.writeln('$indentation${output.path}');
- }
-}
diff --git a/build_runner/bin/src/commands/clean.dart b/build_runner/bin/src/commands/clean.dart
deleted file mode 100644
index 70b0113..0000000
--- a/build_runner/bin/src/commands/clean.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2019, 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 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-
-import 'package:build_runner/src/build_script_generate/build_script_generate.dart';
-import 'package:build_runner/src/entrypoint/base_command.dart' show lineLength;
-import 'package:build_runner/src/entrypoint/clean.dart' show cleanFor;
-
-class CleanCommand extends Command<int> {
- @override
- final argParser = ArgParser(usageLineLength: lineLength);
-
- @override
- String get name => 'clean';
- final logger = Logger('clean');
-
- @override
- String get description =>
- 'Cleans up output from previous builds. Does not clean up --output '
- 'directories.';
-
- @override
- Future<int> run() async {
- await cleanFor(assetGraphPathFor(scriptLocation), logger);
- return 0;
- }
-}
diff --git a/build_runner/bin/src/commands/generate_build_script.dart b/build_runner/bin/src/commands/generate_build_script.dart
deleted file mode 100644
index 002abc8..0000000
--- a/build_runner/bin/src/commands/generate_build_script.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2019, 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 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import 'package:build_runner/src/build_script_generate/build_script_generate.dart';
-import 'package:build_runner/src/entrypoint/base_command.dart' show lineLength;
-
-class GenerateBuildScript extends Command<int> {
- @override
- final argParser = ArgParser(usageLineLength: lineLength);
-
- @override
- String get description =>
- 'Generate a script to run builds and print the file path '
- 'with no other logging. Useful for wrapping builds with other tools.';
-
- @override
- String get name => 'generate-build-script';
-
- @override
- bool get hidden => true;
-
- @override
- Future<int> run() async {
- Logger.root.clearListeners();
- var buildScript = await generateBuildScript();
- File(scriptLocation)
- ..createSync(recursive: true)
- ..writeAsStringSync(buildScript);
- print(p.absolute(scriptLocation));
- return 0;
- }
-}
diff --git a/build_runner/build.yaml b/build_runner/build.yaml
deleted file mode 100644
index d1e3e0f..0000000
--- a/build_runner/build.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-targets:
- $default:
- builders:
- build_web_compilers:entrypoint:
- options:
- compiler: dart2js
- dart2js_args:
- - -O4
- generate_for:
- - web/graph_viz_main.dart
- - web/hot_reload_client.dart
- build_runner:client_js_copy_builder:
- enabled: true
-builders:
- client_js_copy_builder:
- import: "tool/builders.dart"
- builder_factories:
- - copyCompiledJs
- build_extensions:
- web/graph_viz_main.dart.js:
- - lib/src/server/graph_viz_main.dart.js
- web/hot_reload_client.dart.js:
- - lib/src/server/build_updates_client/hot_reload_client.dart.js
- auto_apply: none
- build_to: source
diff --git a/build_runner/dart_test.yaml b/build_runner/dart_test.yaml
deleted file mode 100644
index 112148b..0000000
--- a/build_runner/dart_test.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-tags:
- integration:
- timeout: 16x
diff --git a/build_runner/lib/build_runner.dart b/build_runner/lib/build_runner.dart
deleted file mode 100644
index e4ce00d..0000000
--- a/build_runner/lib/build_runner.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) 2016, 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.
-
-export 'src/daemon/constants.dart' show assetServerPort;
-export 'src/entrypoint/run.dart' show run;
diff --git a/build_runner/lib/build_script_generate.dart b/build_runner/lib/build_script_generate.dart
deleted file mode 100644
index ee76280..0000000
--- a/build_runner/lib/build_script_generate.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.
-
-export 'src/build_script_generate/build_script_generate.dart'
- show generateBuildScript, scriptLocation;
diff --git a/build_runner/lib/src/build_script_generate/bootstrap.dart b/build_runner/lib/src/build_script_generate/bootstrap.dart
deleted file mode 100644
index 3426822..0000000
--- a/build_runner/lib/src/build_script_generate/bootstrap.dart
+++ /dev/null
@@ -1,210 +0,0 @@
-// 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:convert';
-import 'dart:io';
-import 'dart:isolate';
-
-import 'package:build_runner/src/build_script_generate/build_script_generate.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-import 'package:stack_trace/stack_trace.dart';
-
-final _logger = Logger('Bootstrap');
-
-/// Generates the build script, snapshots it if needed, and runs it.
-///
-/// Will retry once on [IsolateSpawnException]s to handle SDK updates.
-///
-/// Returns the exit code from running the build script.
-///
-/// If an exit code of 75 is returned, this function should be re-ran.
-Future<int> generateAndRun(List<String> args, {Logger logger}) async {
- logger ??= _logger;
- ReceivePort exitPort;
- ReceivePort errorPort;
- ReceivePort messagePort;
- StreamSubscription errorListener;
- int scriptExitCode;
-
- var tryCount = 0;
- var succeeded = false;
- while (tryCount < 2 && !succeeded) {
- tryCount++;
- exitPort?.close();
- errorPort?.close();
- messagePort?.close();
- await errorListener?.cancel();
-
- try {
- var buildScript = File(scriptLocation);
- var oldContents = '';
- if (buildScript.existsSync()) {
- oldContents = buildScript.readAsStringSync();
- }
- var newContents = await generateBuildScript();
- // Only trigger a build script update if necessary.
- if (newContents != oldContents) {
- buildScript
- ..createSync(recursive: true)
- ..writeAsStringSync(newContents);
- }
- } on CannotBuildException {
- return ExitCode.config.code;
- }
-
- scriptExitCode = await _createSnapshotIfNeeded(logger);
- if (scriptExitCode != 0) return scriptExitCode;
-
- exitPort = ReceivePort();
- errorPort = ReceivePort();
- messagePort = ReceivePort();
- errorListener = errorPort.listen((e) {
- final error = e[0];
- final trace = e[1] as String;
- stderr
- ..writeln('\n\nYou have hit a bug in build_runner')
- ..writeln('Please file an issue with reproduction steps at '
- 'https://github.com/dart-lang/build/issues\n\n')
- ..writeln(error)
- ..writeln(Trace.parse(trace).terse);
- if (scriptExitCode == 0) scriptExitCode = 1;
- });
- try {
- await Isolate.spawnUri(Uri.file(p.absolute(scriptSnapshotLocation)), args,
- messagePort.sendPort,
- errorsAreFatal: true,
- onExit: exitPort.sendPort,
- onError: errorPort.sendPort);
- succeeded = true;
- } on IsolateSpawnException catch (e) {
- if (tryCount > 1) {
- logger.severe(
- 'Failed to spawn build script after retry. '
- 'This is likely due to a misconfigured builder definition. '
- 'See the generated script at $scriptLocation to find errors.',
- e);
- messagePort.sendPort.send(ExitCode.config.code);
- exitPort.sendPort.send(null);
- } else {
- logger.warning(
- 'Error spawning build script isolate, this is likely due to a Dart '
- 'SDK update. Deleting snapshot and retrying...');
- }
- await File(scriptSnapshotLocation).delete();
- }
- }
-
- StreamSubscription exitCodeListener;
- exitCodeListener = messagePort.listen((isolateExitCode) {
- if (isolateExitCode is int) {
- scriptExitCode = isolateExitCode;
- } else {
- throw StateError(
- 'Bad response from isolate, expected an exit code but got '
- '$isolateExitCode');
- }
- exitCodeListener.cancel();
- exitCodeListener = null;
- });
- await exitPort.first;
- await errorListener.cancel();
- await exitCodeListener?.cancel();
-
- return scriptExitCode;
-}
-
-/// Creates a script snapshot for the build script in necessary.
-///
-/// A snapshot is generated if:
-///
-/// - It doesn't exist currently
-/// - Either build_runner or build_daemon point at a different location than
-/// they used to, see https://github.com/dart-lang/build/issues/1929.
-///
-/// Returns zero for success or a number for failure which should be set to the
-/// exit code.
-Future<int> _createSnapshotIfNeeded(Logger logger) async {
- var assetGraphFile = File(assetGraphPathFor(scriptSnapshotLocation));
- var snapshotFile = File(scriptSnapshotLocation);
-
- if (await snapshotFile.exists()) {
- // If we failed to serialize an asset graph for the snapshot, then we don't
- // want to re-use it because we can't check if it is up to date.
- if (!await assetGraphFile.exists()) {
- await snapshotFile.delete();
- logger.warning('Deleted previous snapshot due to missing asset graph.');
- } else if (!await _checkImportantPackageDeps()) {
- await snapshotFile.delete();
- logger.warning('Deleted previous snapshot due to core package update');
- }
- }
-
- String stderr;
- if (!await snapshotFile.exists()) {
- var mode = stdin.hasTerminal
- ? ProcessStartMode.normal
- : ProcessStartMode.detachedWithStdio;
- await logTimedAsync(logger, 'Creating build script snapshot...', () async {
- var snapshot = await Process.start(Platform.executable,
- ['--snapshot=$scriptSnapshotLocation', scriptLocation],
- mode: mode);
- stderr = (await snapshot.stderr
- .transform(utf8.decoder)
- .transform(LineSplitter())
- .toList())
- .join('');
- });
- if (!await snapshotFile.exists()) {
- logger.severe('Failed to snapshot build script $scriptLocation.\n'
- 'This is likely caused by a misconfigured builder definition.');
- if (stderr.isNotEmpty) {
- logger.severe(stderr);
- }
- return ExitCode.config.code;
- }
- // Create _previousLocationsFile.
- await _checkImportantPackageDeps();
- }
- return 0;
-}
-
-const _importantPackages = [
- 'build_daemon',
- 'build_runner',
-];
-final _previousLocationsFile = File(
- p.url.join(p.url.dirname(scriptSnapshotLocation), '.packageLocations'));
-
-/// Returns whether the [_importantPackages] are all pointing at same locations
-/// from the previous run.
-///
-/// Also updates the [_previousLocationsFile] with the new locations if not.
-///
-/// This is used to detect potential changes to the user facing api and
-/// pre-emptively resolve them by resnapshotting, see
-/// https://github.com/dart-lang/build/issues/1929.
-Future<bool> _checkImportantPackageDeps() async {
- var currentLocations = await Future.wait(_importantPackages.map((pkg) =>
- Isolate.resolvePackageUri(
- Uri(scheme: 'package', path: '$pkg/fake.dart'))));
- var currentLocationsContent = currentLocations.join('\n');
-
- if (!_previousLocationsFile.existsSync()) {
- _logger.fine('Core package locations file does not exist');
- _previousLocationsFile.writeAsStringSync(currentLocationsContent);
- return false;
- }
-
- if (currentLocationsContent != _previousLocationsFile.readAsStringSync()) {
- _logger.fine('Core packages locations have changed');
- _previousLocationsFile.writeAsStringSync(currentLocationsContent);
- return false;
- }
-
- return true;
-}
diff --git a/build_runner/lib/src/build_script_generate/build_script_generate.dart b/build_runner/lib/src/build_script_generate/build_script_generate.dart
deleted file mode 100644
index b06e2ba..0000000
--- a/build_runner/lib/src/build_script_generate/build_script_generate.dart
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart' show BuilderOptions;
-import 'package:build_config/build_config.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-import 'package:graphs/graphs.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../package_graph/build_config_overrides.dart';
-import 'builder_ordering.dart';
-
-const scriptLocation = '$entryPointDir/build.dart';
-const scriptSnapshotLocation = '$scriptLocation.snapshot';
-
-final _log = Logger('Entrypoint');
-
-Future<String> generateBuildScript() =>
- logTimedAsync(_log, 'Generating build script', _generateBuildScript);
-
-Future<String> _generateBuildScript() async {
- final builders = await _findBuilderApplications();
- final library = Library((b) => b.body.addAll([
- literalList(
- builders,
- refer('BuilderApplication',
- 'package:build_runner_core/build_runner_core.dart'))
- .assignFinal('_builders')
- .statement,
- _main()
- ]));
- final emitter = DartEmitter(Allocator.simplePrefixing());
- try {
- return DartFormatter().format('''
- // ignore_for_file: directives_ordering
-
- ${library.accept(emitter)}''');
- } on FormatterException {
- _log.severe('Generated build script could not be parsed.\n'
- 'This is likely caused by a misconfigured builder definition.');
- throw CannotBuildException();
- }
-}
-
-/// Finds expressions to create all the `BuilderApplication` instances that
-/// should be applied packages in the build.
-///
-/// Adds `apply` expressions based on the BuildefDefinitions from any package
-/// which has a `build.yaml`.
-Future<Iterable<Expression>> _findBuilderApplications() async {
- final builderApplications = <Expression>[];
- final packageGraph = PackageGraph.forThisPackage();
- final orderedPackages = stronglyConnectedComponents<PackageNode>(
- [packageGraph.root],
- (node) => node.dependencies,
- equals: (a, b) => a.name == b.name,
- hashCode: (n) => n.name.hashCode,
- ).expand((c) => c);
- final buildConfigOverrides =
- await findBuildConfigOverrides(packageGraph, null);
- Future<BuildConfig> _packageBuildConfig(PackageNode package) async {
- if (buildConfigOverrides.containsKey(package.name)) {
- return buildConfigOverrides[package.name];
- }
- try {
- return await BuildConfig.fromBuildConfigDir(
- package.name, package.dependencies.map((n) => n.name), package.path);
- } on ArgumentError catch (_) {
- // During the build an error will be logged.
- return BuildConfig.useDefault(
- package.name, package.dependencies.map((n) => n.name));
- }
- }
-
- bool _isValidDefinition(dynamic definition) {
- // Filter out builderDefinitions with relative imports that aren't
- // from the root package, because they will never work.
- if (definition.import.startsWith('package:') as bool) return true;
- return definition.package == packageGraph.root.name;
- }
-
- final orderedConfigs =
- await Future.wait(orderedPackages.map(_packageBuildConfig));
- final builderDefinitions = orderedConfigs
- .expand((c) => c.builderDefinitions.values)
- .where(_isValidDefinition);
-
- final orderedBuilders = findBuilderOrder(builderDefinitions).toList();
- builderApplications.addAll(orderedBuilders.map(_applyBuilder));
-
- final postProcessBuilderDefinitions = orderedConfigs
- .expand((c) => c.postProcessBuilderDefinitions.values)
- .where(_isValidDefinition);
- builderApplications
- .addAll(postProcessBuilderDefinitions.map(_applyPostProcessBuilder));
-
- return builderApplications;
-}
-
-/// A method forwarding to `run`.
-Method _main() => Method((b) => b
- ..name = 'main'
- ..returns = refer('void')
- ..modifier = MethodModifier.async
- ..requiredParameters.add(Parameter((b) => b
- ..name = 'args'
- ..type = TypeReference((b) => b
- ..symbol = 'List'
- ..types.add(refer('String')))))
- ..optionalParameters.add(Parameter((b) => b
- ..name = 'sendPort'
- ..type = refer('SendPort', 'dart:isolate')))
- ..body = Block.of([
- refer('run', 'package:build_runner/build_runner.dart')
- .call([refer('args'), refer('_builders')])
- .awaited
- .assignVar('result')
- .statement,
- refer('sendPort')
- .nullSafeProperty('send')
- .call([refer('result')]).statement,
- refer('exitCode', 'dart:io').assign(refer('result')).statement,
- ]));
-
-/// An expression calling `apply` with appropriate setup for a Builder.
-Expression _applyBuilder(BuilderDefinition definition) {
- final namedArgs = <String, Expression>{};
- if (definition.isOptional) {
- namedArgs['isOptional'] = literalTrue;
- }
- if (definition.buildTo == BuildTo.cache) {
- namedArgs['hideOutput'] = literalTrue;
- } else {
- namedArgs['hideOutput'] = literalFalse;
- }
- if (!identical(definition.defaults?.generateFor, InputSet.anything)) {
- final inputSetArgs = <String, Expression>{};
- if (definition.defaults.generateFor.include != null) {
- inputSetArgs['include'] =
- literalConstList(definition.defaults.generateFor.include);
- }
- if (definition.defaults.generateFor.exclude != null) {
- inputSetArgs['exclude'] =
- literalConstList(definition.defaults.generateFor.exclude);
- }
- namedArgs['defaultGenerateFor'] =
- refer('InputSet', 'package:build_config/build_config.dart')
- .constInstance([], inputSetArgs);
- }
- if (definition.defaults?.options?.isNotEmpty ?? false) {
- namedArgs['defaultOptions'] =
- _constructBuilderOptions(definition.defaults.options);
- }
- if (definition.defaults?.devOptions?.isNotEmpty ?? false) {
- namedArgs['defaultDevOptions'] =
- _constructBuilderOptions(definition.defaults.devOptions);
- }
- if (definition.defaults?.releaseOptions?.isNotEmpty ?? false) {
- namedArgs['defaultReleaseOptions'] =
- _constructBuilderOptions(definition.defaults.releaseOptions);
- }
- if (definition.appliesBuilders.isNotEmpty) {
- namedArgs['appliesBuilders'] = literalList(definition.appliesBuilders);
- }
- var import = _buildScriptImport(definition.import);
- return refer('apply', 'package:build_runner_core/build_runner_core.dart')
- .call([
- literalString(definition.key),
- literalList(
- definition.builderFactories.map((f) => refer(f, import)).toList()),
- _findToExpression(definition),
- ], namedArgs);
-}
-
-/// An expression calling `applyPostProcess` with appropriate setup for a
-/// PostProcessBuilder.
-Expression _applyPostProcessBuilder(PostProcessBuilderDefinition definition) {
- final namedArgs = <String, Expression>{};
- if (definition.defaults?.generateFor != null) {
- final inputSetArgs = <String, Expression>{};
- if (definition.defaults.generateFor.include != null) {
- inputSetArgs['include'] =
- literalConstList(definition.defaults.generateFor.include);
- }
- if (definition.defaults.generateFor.exclude != null) {
- inputSetArgs['exclude'] =
- literalConstList(definition.defaults.generateFor.exclude);
- }
- if (definition.defaults?.options?.isNotEmpty ?? false) {
- namedArgs['defaultOptions'] =
- _constructBuilderOptions(definition.defaults.options);
- }
- if (definition.defaults?.devOptions?.isNotEmpty ?? false) {
- namedArgs['defaultDevOptions'] =
- _constructBuilderOptions(definition.defaults.devOptions);
- }
- if (definition.defaults?.releaseOptions?.isNotEmpty ?? false) {
- namedArgs['defaultReleaseOptions'] =
- _constructBuilderOptions(definition.defaults.releaseOptions);
- }
- namedArgs['defaultGenerateFor'] =
- refer('InputSet', 'package:build_config/build_config.dart')
- .constInstance([], inputSetArgs);
- }
- var import = _buildScriptImport(definition.import);
- return refer('applyPostProcess',
- 'package:build_runner_core/build_runner_core.dart')
- .call([
- literalString(definition.key),
- refer(definition.builderFactory, import),
- ], namedArgs);
-}
-
-/// Returns the actual import to put in the generated script based on an import
-/// found in the build.yaml.
-String _buildScriptImport(String import) {
- if (import.startsWith('package:')) {
- return import;
- } else if (import.startsWith('../') || import.startsWith('/')) {
- _log.warning('The `../` import syntax in build.yaml is now deprecated, '
- 'instead do a normal relative import as if it was from the root of '
- 'the package. Found `$import` in your `build.yaml` file.');
- return import;
- } else {
- return p.url.relative(import, from: p.url.dirname(scriptLocation));
- }
-}
-
-Expression _findToExpression(BuilderDefinition definition) {
- switch (definition.autoApply) {
- case AutoApply.none:
- return refer('toNoneByDefault',
- 'package:build_runner_core/build_runner_core.dart')
- .call([]);
- case AutoApply.dependents:
- return refer('toDependentsOf',
- 'package:build_runner_core/build_runner_core.dart')
- .call([literalString(definition.package)]);
- case AutoApply.allPackages:
- return refer('toAllPackages',
- 'package:build_runner_core/build_runner_core.dart')
- .call([]);
- case AutoApply.rootPackage:
- return refer('toRoot', 'package:build_runner_core/build_runner_core.dart')
- .call([]);
- }
- throw ArgumentError('Unhandled AutoApply type: ${definition.autoApply}');
-}
-
-/// An expression creating a [BuilderOptions] from a json string.
-Expression _constructBuilderOptions(Map<String, dynamic> options) =>
- refer('BuilderOptions', 'package:build/build.dart')
- .newInstance([literalMap(options)]);
diff --git a/build_runner/lib/src/build_script_generate/builder_ordering.dart b/build_runner/lib/src/build_script_generate/builder_ordering.dart
deleted file mode 100644
index c681697..0000000
--- a/build_runner/lib/src/build_script_generate/builder_ordering.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2017, 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:build_config/build_config.dart';
-import 'package:graphs/graphs.dart';
-
-/// Put [builders] into an order such that any builder which specifies
-/// [BuilderDefinition.requiredInputs] will come after any builder which
-/// produces a desired output.
-///
-/// Builders will be ordered such that their `required_inputs` and `runs_before`
-/// constraints are met, but the rest of the ordering is arbitrary.
-Iterable<BuilderDefinition> findBuilderOrder(
- Iterable<BuilderDefinition> builders) {
- final consistentOrderBuilders = builders.toList()
- ..sort((a, b) => a.key.compareTo(b.key));
- Iterable<BuilderDefinition> dependencies(BuilderDefinition parent) =>
- consistentOrderBuilders.where((child) =>
- _hasInputDependency(parent, child) || _mustRunBefore(parent, child));
- var components = stronglyConnectedComponents<BuilderDefinition>(
- consistentOrderBuilders,
- dependencies,
- equals: (a, b) => a.key == b.key,
- hashCode: (b) => b.key.hashCode,
- );
- return components.map((component) {
- if (component.length > 1) {
- throw ArgumentError('Required input cycle for ${component.toList()}');
- }
- return component.single;
- }).toList();
-}
-
-/// Whether [parent] has a `required_input` that wants to read outputs produced
-/// by [child].
-bool _hasInputDependency(BuilderDefinition parent, BuilderDefinition child) {
- final childOutputs = child.buildExtensions.values.expand((v) => v).toSet();
- return parent.requiredInputs
- .any((input) => childOutputs.any((output) => output.endsWith(input)));
-}
-
-/// Whether [child] specifies that it wants to run before [parent].
-bool _mustRunBefore(BuilderDefinition parent, BuilderDefinition child) =>
- child.runsBefore.contains(parent.key);
diff --git a/build_runner/lib/src/daemon/asset_server.dart b/build_runner/lib/src/daemon/asset_server.dart
deleted file mode 100644
index 524a7d6..0000000
--- a/build_runner/lib/src/daemon/asset_server.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2019, 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 'package:http_multi_server/http_multi_server.dart';
-import 'package:shelf/shelf.dart';
-import 'package:shelf/shelf_io.dart' as shelf_io;
-
-import '../server/server.dart';
-import 'daemon_builder.dart';
-
-class AssetServer {
- final HttpServer _server;
-
- AssetServer._(this._server);
-
- int get port => _server.port;
-
- Future<void> stop() => _server.close(force: true);
-
- static Future<AssetServer> run(
- BuildRunnerDaemonBuilder builder,
- String rootPackage,
- ) async {
- var server = await HttpMultiServer.loopback(0);
- var cascade = Cascade().add((_) async {
- await builder.building;
- return Response.notFound('');
- }).add(AssetHandler(builder.reader, rootPackage).handle);
- shelf_io.serveRequests(server, cascade.handler);
- return AssetServer._(server);
- }
-}
diff --git a/build_runner/lib/src/daemon/change_providers.dart b/build_runner/lib/src/daemon/change_providers.dart
deleted file mode 100644
index 8d52c0a..0000000
--- a/build_runner/lib/src/daemon/change_providers.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, 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:build_daemon/change_provider.dart';
-import 'package:build_runner_core/src/generate/build_definition.dart';
-import 'package:watcher/src/watch_event.dart';
-
-/// Continually updates the [changes] stream as watch events are seen on the
-/// input stream.
-///
-/// The [collectChanges] method is a no-op for this implementation.
-class AutoChangeProvider implements ChangeProvider {
- @override
- final Stream<List<WatchEvent>> changes;
-
- AutoChangeProvider(this.changes);
-
- @override
- Future<List<WatchEvent>> collectChanges() async => [];
-}
-
-/// Computes changes with a file scan when requested by a call to
-/// [collectChanges].
-class ManualChangeProvider implements ChangeProvider {
- final AssetTracker _assetTracker;
-
- ManualChangeProvider(this._assetTracker);
-
- @override
- Future<List<WatchEvent>> collectChanges() async {
- var updates = await _assetTracker.collectChanges();
- return List.of(updates.entries
- .map((entry) => WatchEvent(entry.value, '${entry.key}')));
- }
-
- @override
- Stream<List<WatchEvent>> get changes => Stream.empty();
-}
diff --git a/build_runner/lib/src/daemon/constants.dart b/build_runner/lib/src/daemon/constants.dart
deleted file mode 100644
index 956fcea..0000000
--- a/build_runner/lib/src/daemon/constants.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2019, 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:io';
-
-import 'package:build_daemon/constants.dart';
-import 'package:path/path.dart' as p;
-
-String assetServerPortFilePath(String workingDirectory) =>
- p.join(daemonWorkspace(workingDirectory), '.asset_server_port');
-
-/// Returns the port of the daemon asset server.
-int assetServerPort(String workingDirectory) {
- var portFile = File(assetServerPortFilePath(workingDirectory));
- if (!portFile.existsSync()) {
- throw Exception('Unable to read daemon asset port file.');
- }
- return int.parse(portFile.readAsStringSync());
-}
diff --git a/build_runner/lib/src/daemon/daemon_builder.dart b/build_runner/lib/src/daemon/daemon_builder.dart
deleted file mode 100644
index b9104af..0000000
--- a/build_runner/lib/src/daemon/daemon_builder.dart
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright (c) 2019, 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 'package:build/build.dart';
-import 'package:build_daemon/change_provider.dart';
-import 'package:build_daemon/constants.dart';
-import 'package:build_daemon/daemon_builder.dart';
-import 'package:build_daemon/data/build_status.dart';
-import 'package:build_daemon/data/build_target.dart' hide OutputLocation;
-import 'package:build_daemon/data/server_log.dart';
-import 'package:build_runner/src/entrypoint/options.dart';
-import 'package:build_runner/src/package_graph/build_config_overrides.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:build_runner/src/watcher/change_filter.dart';
-import 'package:build_runner/src/watcher/collect_changes.dart';
-import 'package:build_runner/src/watcher/delete_writer.dart';
-import 'package:build_runner/src/watcher/graph_watcher.dart';
-import 'package:build_runner/src/watcher/node_watcher.dart';
-import 'package:build_runner_core/build_runner_core.dart'
- hide BuildResult, BuildStatus;
-import 'package:build_runner_core/build_runner_core.dart' as core
- show BuildStatus;
-import 'package:build_runner_core/src/generate/build_definition.dart';
-import 'package:build_runner_core/src/generate/build_impl.dart';
-import 'package:stream_transform/stream_transform.dart';
-import 'package:watcher/watcher.dart';
-
-import 'change_providers.dart';
-
-/// A Daemon Builder that uses build_runner_core for building.
-class BuildRunnerDaemonBuilder implements DaemonBuilder {
- final _buildResults = StreamController<BuildResults>();
-
- final BuildImpl _builder;
- final BuildOptions _buildOptions;
- final StreamController<ServerLog> _outputStreamController;
- final ChangeProvider changeProvider;
-
- Completer<Null> _buildingCompleter;
-
- @override
- final Stream<ServerLog> logs;
-
- BuildRunnerDaemonBuilder._(
- this._builder,
- this._buildOptions,
- this._outputStreamController,
- this.changeProvider,
- ) : logs = _outputStreamController.stream.asBroadcastStream();
-
- /// Waits for a running build to complete before returning.
- ///
- /// If there is no running build, it will return immediately.
- Future<void> get building => _buildingCompleter?.future;
-
- @override
- Stream<BuildResults> get builds => _buildResults.stream;
-
- FinalizedReader get reader => _builder.finalizedReader;
-
- final _buildScriptUpdateCompleter = Completer();
- Future<void> get buildScriptUpdated => _buildScriptUpdateCompleter.future;
-
- @override
- Future<void> build(
- Set<BuildTarget> targets, Iterable<WatchEvent> fileChanges) async {
- var defaultTargets = targets.cast<DefaultBuildTarget>();
- var changes = fileChanges
- .map<AssetChange>(
- (change) => AssetChange(AssetId.parse(change.path), change.type))
- .toList();
- if (!_buildOptions.skipBuildScriptCheck &&
- _builder.buildScriptUpdates.hasBeenUpdated(
- changes.map<AssetId>((change) => change.id).toSet())) {
- _buildScriptUpdateCompleter.complete();
- return;
- }
- var targetNames = targets.map((t) => t.target).toSet();
- _logMessage(Level.INFO, 'About to build ${targetNames.toList()}...');
- _signalStart(targetNames);
- var results = <BuildResult>[];
- var buildDirs = <BuildDirectory>{};
- var buildFilters = <BuildFilter>{};
- for (var target in defaultTargets) {
- OutputLocation outputLocation;
- if (target.outputLocation != null) {
- outputLocation = OutputLocation(target.outputLocation.output,
- useSymlinks: target.outputLocation.useSymlinks,
- hoist: target.outputLocation.hoist);
- }
- buildDirs
- .add(BuildDirectory(target.target, outputLocation: outputLocation));
- if (target.buildFilters != null && target.buildFilters.isNotEmpty) {
- buildFilters.addAll([
- for (var pattern in target.buildFilters)
- BuildFilter.fromArg(pattern, _buildOptions.packageGraph.root.name)
- ]);
- } else {
- buildFilters
- ..add(BuildFilter.fromArg(
- 'package:*/**', _buildOptions.packageGraph.root.name))
- ..add(BuildFilter.fromArg(
- '${target.target}/**', _buildOptions.packageGraph.root.name));
- }
- }
- try {
- var mergedChanges = collectChanges([changes]);
- var result = await _builder.run(mergedChanges,
- buildDirs: buildDirs, buildFilters: buildFilters);
- for (var target in targets) {
- if (result.status == core.BuildStatus.success) {
- // TODO(grouma) - Can we notify if a target was cached?
- results.add(DefaultBuildResult((b) => b
- ..status = BuildStatus.succeeded
- ..target = target.target));
- } else {
- results.add(DefaultBuildResult((b) => b
- ..status = BuildStatus.failed
- // TODO(grouma) - We should forward the error messages instead.
- // We can use the AssetGraph and FailureReporter to provide a better
- // error message.
- ..error = 'FailureType: ${result.failureType.exitCode}'
- ..target = target.target));
- }
- }
- } catch (e) {
- for (var target in targets) {
- results.add(DefaultBuildResult((b) => b
- ..status = BuildStatus.failed
- ..error = '$e'
- ..target = target.target));
- }
- _logMessage(Level.SEVERE, 'Build Failed:\n${e.toString()}');
- }
- _signalEnd(results);
- }
-
- @override
- Future<void> stop() async {
- await _builder.beforeExit();
- await _buildOptions.logListener.cancel();
- }
-
- void _logMessage(Level level, String message) =>
- _outputStreamController.add(ServerLog(
- (b) => b
- ..message = message
- ..level = level,
- ));
-
- void _signalEnd(Iterable<BuildResult> results) {
- _buildingCompleter.complete();
- _buildResults.add(BuildResults((b) => b..results.addAll(results)));
- }
-
- void _signalStart(Iterable<String> targets) {
- _buildingCompleter = Completer();
- var results = <BuildResult>[];
- for (var target in targets) {
- results.add(DefaultBuildResult((b) => b
- ..status = BuildStatus.started
- ..target = target));
- }
- _buildResults.add(BuildResults((b) => b..results.addAll(results)));
- }
-
- static Future<BuildRunnerDaemonBuilder> create(
- PackageGraph packageGraph,
- List<BuilderApplication> builders,
- DaemonOptions daemonOptions,
- ) async {
- var expectedDeletes = <AssetId>{};
- var outputStreamController = StreamController<ServerLog>();
-
- var environment = OverrideableEnvironment(
- IOEnvironment(packageGraph,
- outputSymlinksOnly: daemonOptions.outputSymlinksOnly),
- onLog: (record) {
- outputStreamController.add(ServerLog.fromLogRecord(record));
- });
-
- var daemonEnvironment = OverrideableEnvironment(environment,
- writer: OnDeleteWriter(environment.writer, expectedDeletes.add));
-
- var logSubscription =
- LogSubscription(environment, verbose: daemonOptions.verbose);
-
- var overrideBuildConfig =
- await findBuildConfigOverrides(packageGraph, daemonOptions.configKey);
-
- var buildOptions = await BuildOptions.create(
- logSubscription,
- packageGraph: packageGraph,
- deleteFilesByDefault: daemonOptions.deleteFilesByDefault,
- overrideBuildConfig: overrideBuildConfig,
- skipBuildScriptCheck: daemonOptions.skipBuildScriptCheck,
- enableLowResourcesMode: daemonOptions.enableLowResourcesMode,
- trackPerformance: daemonOptions.trackPerformance,
- logPerformanceDir: daemonOptions.logPerformanceDir,
- );
-
- var builder = await BuildImpl.create(buildOptions, daemonEnvironment,
- builders, daemonOptions.builderConfigOverrides,
- isReleaseBuild: daemonOptions.isReleaseBuild);
-
- // Only actually used for the AutoChangeProvider.
- Stream<List<WatchEvent>> graphEvents() => PackageGraphWatcher(packageGraph,
- watch: (node) => PackageNodeWatcher(node,
- watch: daemonOptions.directoryWatcherFactory))
- .watch()
- .where((change) => shouldProcess(
- change,
- builder.assetGraph,
- buildOptions,
- // Assume we will create an outputDir.
- true,
- expectedDeletes,
- ))
- .map((data) => WatchEvent(data.type, '${data.id}'))
- .debounceBuffer(buildOptions.debounceDelay);
-
- var changeProvider = daemonOptions.buildMode == BuildMode.Auto
- ? AutoChangeProvider(graphEvents())
- : ManualChangeProvider(AssetTracker(builder.assetGraph,
- daemonEnvironment.reader, buildOptions.targetGraph));
-
- return BuildRunnerDaemonBuilder._(
- builder, buildOptions, outputStreamController, changeProvider);
- }
-}
diff --git a/build_runner/lib/src/entrypoint/base_command.dart b/build_runner/lib/src/entrypoint/base_command.dart
deleted file mode 100644
index 27a8873..0000000
--- a/build_runner/lib/src/entrypoint/base_command.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-
-import 'options.dart';
-import 'runner.dart';
-
-final lineLength = stdout.hasTerminal ? stdout.terminalColumns : 80;
-
-abstract class BuildRunnerCommand extends Command<int> {
- Logger get logger => Logger(name);
-
- List<BuilderApplication> get builderApplications =>
- (runner as BuildCommandRunner).builderApplications;
-
- PackageGraph get packageGraph => (runner as BuildCommandRunner).packageGraph;
-
- BuildRunnerCommand({bool symlinksDefault}) {
- _addBaseFlags(symlinksDefault ?? false);
- }
-
- @override
- final argParser = ArgParser(usageLineLength: lineLength);
-
- void _addBaseFlags(bool symlinksDefault) {
- argParser
- ..addFlag(deleteFilesByDefaultOption,
- help:
- 'By default, the user will be prompted to delete any files which '
- 'already exist but were not known to be generated by this '
- 'specific build script.\n\n'
- 'Enabling this option skips the prompt and deletes the files. '
- 'This should typically be used in continues integration servers '
- 'and tests, but not otherwise.',
- negatable: false,
- defaultsTo: false)
- ..addFlag(lowResourcesModeOption,
- help: 'Reduce the amount of memory consumed by the build process. '
- 'This will slow down builds but allow them to progress in '
- 'resource constrained environments.',
- negatable: false,
- defaultsTo: false)
- ..addOption(configOption,
- help: 'Read `build.<name>.yaml` instead of the default `build.yaml`',
- abbr: 'c')
- ..addFlag('fail-on-severe',
- help: 'Deprecated argument - always enabled',
- negatable: true,
- defaultsTo: true,
- hide: true)
- ..addFlag(trackPerformanceOption,
- help: r'Enables performance tracking and the /$perf page.',
- negatable: true,
- defaultsTo: false)
- ..addOption(logPerformanceOption,
- help: 'A directory to write performance logs to, must be in the '
- 'current package. Implies `--track-performance`.')
- ..addFlag(skipBuildScriptCheckOption,
- help: r'Skip validation for the digests of files imported by the '
- 'build script.',
- hide: true,
- defaultsTo: false)
- ..addMultiOption(outputOption,
- help: 'A directory to copy the fully built package to. Or a mapping '
- 'from a top-level directory in the package to the directory to '
- 'write a filtered build output to. For example "web:deploy".',
- abbr: 'o')
- ..addFlag(verboseOption,
- abbr: 'v',
- defaultsTo: false,
- negatable: false,
- help: 'Enables verbose logging.')
- ..addFlag(releaseOption,
- abbr: 'r',
- defaultsTo: false,
- negatable: true,
- help: 'Build with release mode defaults for builders.')
- ..addMultiOption(defineOption,
- splitCommas: false,
- help: 'Sets the global `options` config for a builder by key.')
- ..addFlag(symlinkOption,
- defaultsTo: symlinksDefault,
- negatable: true,
- help: 'Symlink files in the output directories, instead of copying.')
- ..addMultiOption(buildFilterOption,
- help: 'An explicit filter of files to build. Relative paths and '
- '`package:` uris are supported, including glob syntax for paths '
- 'portions (but not package names).\n\n'
- 'If multiple filters are applied then outputs matching any filter '
- 'will be built (they do not need to match all filters).');
- }
-
- /// Must be called inside [run] so that [argResults] is non-null.
- ///
- /// You may override this to return more specific options if desired, but they
- /// must extend [SharedOptions].
- SharedOptions readOptions() {
- return SharedOptions.fromParsedArgs(
- argResults, argResults.rest, packageGraph.root.name, this);
- }
-}
diff --git a/build_runner/lib/src/entrypoint/build.dart b/build_runner/lib/src/entrypoint/build.dart
deleted file mode 100644
index 2b983ee..0000000
--- a/build_runner/lib/src/entrypoint/build.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-
-import '../generate/build.dart';
-import 'base_command.dart';
-
-/// A command that does a single build and then exits.
-class BuildCommand extends BuildRunnerCommand {
- @override
- String get invocation => '${super.invocation} [directories]';
-
- @override
- String get name => 'build';
-
- @override
- String get description =>
- 'Performs a single build on the specified targets and then exits.';
-
- @override
- Future<int> run() async {
- var options = readOptions();
- var result = await build(
- builderApplications,
- buildFilters: options.buildFilters,
- deleteFilesByDefault: options.deleteFilesByDefault,
- enableLowResourcesMode: options.enableLowResourcesMode,
- configKey: options.configKey,
- buildDirs: options.buildDirs,
- outputSymlinksOnly: options.outputSymlinksOnly,
- packageGraph: packageGraph,
- verbose: options.verbose,
- builderConfigOverrides: options.builderConfigOverrides,
- isReleaseBuild: options.isReleaseBuild,
- trackPerformance: options.trackPerformance,
- skipBuildScriptCheck: options.skipBuildScriptCheck,
- logPerformanceDir: options.logPerformanceDir,
- );
- if (result.status == BuildStatus.success) {
- return ExitCode.success.code;
- } else {
- return result.failureType.exitCode;
- }
- }
-}
diff --git a/build_runner/lib/src/entrypoint/clean.dart b/build_runner/lib/src/entrypoint/clean.dart
deleted file mode 100644
index 9aa4fba..0000000
--- a/build_runner/lib/src/entrypoint/clean.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// 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 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'package:logging/logging.dart';
-
-import '../logging/std_io_logging.dart';
-import 'base_command.dart';
-
-class CleanCommand extends Command<int> {
- @override
- final argParser = ArgParser(usageLineLength: lineLength);
-
- @override
- String get name => 'clean';
-
- @override
- String get description =>
- 'Cleans up output from previous builds. Does not clean up --output '
- 'directories.';
-
- Logger get logger => Logger(name);
-
- @override
- Future<int> run() async {
- var logSubscription = Logger.root.onRecord.listen(stdIOLogListener());
- await cleanFor(assetGraphPath, logger);
- await logSubscription.cancel();
- return 0;
- }
-}
-
-Future<void> cleanFor(String assetGraphPath, Logger logger) async {
- logger.warning('Deleting cache and generated source files.\n'
- 'This shouldn\'t be necessary for most applications, unless you have '
- 'made intentional edits to generated files (i.e. for testing). '
- 'Consider filing a bug at '
- 'https://github.com/dart-lang/build/issues/new if you are using this '
- 'to work around an apparent (and reproducible) bug.');
-
- await logTimedAsync(logger, 'Cleaning up source outputs', () async {
- var assetGraphFile = File(assetGraphPath);
- if (!assetGraphFile.existsSync()) {
- logger.warning('No asset graph found. '
- 'Skipping cleanup of generated files in source directories.');
- return;
- }
- AssetGraph assetGraph;
- try {
- assetGraph = AssetGraph.deserialize(await assetGraphFile.readAsBytes());
- } catch (_) {
- logger.warning('Failed to deserialize AssetGraph. '
- 'Skipping cleanup of generated files in source directories.');
- return;
- }
- var packageGraph = PackageGraph.forThisPackage();
- await _cleanUpSourceOutputs(assetGraph, packageGraph);
- });
-
- await logTimedAsync(
- logger, 'Cleaning up cache directory', _cleanUpGeneratedDirectory);
-}
-
-Future<void> _cleanUpSourceOutputs(
- AssetGraph assetGraph, PackageGraph packageGraph) async {
- var writer = FileBasedAssetWriter(packageGraph);
- for (var id in assetGraph.outputs) {
- if (id.package != packageGraph.root.name) continue;
- var node = assetGraph.get(id) as GeneratedAssetNode;
- if (node.wasOutput) {
- // Note that this does a file.exists check in the root package and
- // only tries to delete the file if it exists. This way we only
- // actually delete to_source outputs, without reading in the build
- // actions.
- await writer.delete(id);
- }
- }
-}
-
-Future<void> _cleanUpGeneratedDirectory() async {
- var generatedDir = Directory(cacheDir);
- if (await generatedDir.exists()) {
- await generatedDir.delete(recursive: true);
- }
-}
diff --git a/build_runner/lib/src/entrypoint/daemon.dart b/build_runner/lib/src/entrypoint/daemon.dart
deleted file mode 100644
index b7ef05b..0000000
--- a/build_runner/lib/src/entrypoint/daemon.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2019, 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:convert';
-import 'dart:io';
-
-import 'package:build_daemon/constants.dart';
-import 'package:build_daemon/daemon.dart';
-import 'package:build_daemon/data/serializers.dart';
-import 'package:build_daemon/data/server_log.dart';
-import 'package:build_runner/src/daemon/constants.dart';
-import 'package:logging/logging.dart' hide Level;
-import 'package:pedantic/pedantic.dart';
-
-import '../daemon/asset_server.dart';
-import '../daemon/daemon_builder.dart';
-import 'options.dart';
-import 'watch.dart';
-
-/// A command that starts the Build Daemon.
-class DaemonCommand extends WatchCommand {
- @override
- String get description => 'Starts the build daemon.';
-
- @override
- bool get hidden => true;
-
- @override
- String get name => 'daemon';
-
- DaemonCommand() {
- argParser.addOption(buildModeFlag,
- help: 'Specify the build mode of the daemon, e.g. auto or manual.',
- defaultsTo: 'BuildMode.Auto');
- }
-
- @override
- DaemonOptions readOptions() => DaemonOptions.fromParsedArgs(
- argResults, argResults.rest, packageGraph.root.name, this);
-
- @override
- Future<int> run() async {
- var workingDirectory = Directory.current.path;
- var options = readOptions();
- var daemon = Daemon(workingDirectory);
- var requestedOptions = argResults.arguments.toSet();
- if (!daemon.hasLock) {
- var runningOptions = await daemon.currentOptions();
- var version = await daemon.runningVersion();
- if (version != currentVersion) {
- stdout
- ..writeln('Running Version: $version')
- ..writeln('Current Version: $currentVersion')
- ..writeln(versionSkew);
- return 1;
- } else if (!(runningOptions.length == requestedOptions.length &&
- runningOptions.containsAll(requestedOptions))) {
- stdout
- ..writeln('Running Options: $runningOptions')
- ..writeln('Requested Options: $requestedOptions')
- ..writeln(optionsSkew);
- return 1;
- } else {
- stdout.writeln('Daemon is already running.');
- print(readyToConnectLog);
- return 0;
- }
- } else {
- stdout.writeln('Starting daemon...');
- BuildRunnerDaemonBuilder builder;
- // Ensure we capture any logs that happen during startup.
- //
- // These are serialized between special `<log-record>` and `</log-record>`
- // tags to make parsing them on stdout easier. They can have multiline
- // strings so we can't just serialize the json on a single line.
- var startupLogSub =
- Logger.root.onRecord.listen((record) => stdout.writeln('''
-$logStartMarker
-${jsonEncode(serializers.serialize(ServerLog.fromLogRecord(record)))}
-$logEndMarker'''));
- builder = await BuildRunnerDaemonBuilder.create(
- packageGraph,
- builderApplications,
- options,
- );
- await startupLogSub.cancel();
-
- // Forward server logs to daemon command STDIO.
- var logSub = builder.logs.listen((log) {
- if (log.level > Level.INFO) {
- var buffer = StringBuffer(log.message);
- if (log.error != null) buffer.writeln(log.error);
- if (log.stackTrace != null) buffer.writeln(log.stackTrace);
- stderr.writeln(buffer);
- } else {
- stdout.writeln(log.message);
- }
- });
- var server = await AssetServer.run(builder, packageGraph.root.name);
- File(assetServerPortFilePath(workingDirectory))
- .writeAsStringSync('${server.port}');
- unawaited(builder.buildScriptUpdated.then((_) async {
- await daemon.stop(
- message: 'Build script updated. Shutting down the Build Daemon.',
- failureType: 75);
- }));
- await daemon.start(requestedOptions, builder, builder.changeProvider,
- timeout: Duration(seconds: 60));
- stdout.writeln(readyToConnectLog);
- await logSub.cancel();
- await daemon.onDone.whenComplete(() async {
- await server.stop();
- });
- // Clients can disconnect from the daemon mid build.
- // As a result we try to relinquish resources which can
- // cause the build to hang. To ensure there are no ghost processes
- // fast exit.
- exit(0);
- }
- return 0;
- }
-}
diff --git a/build_runner/lib/src/entrypoint/doctor.dart b/build_runner/lib/src/entrypoint/doctor.dart
deleted file mode 100644
index c1325e4..0000000
--- a/build_runner/lib/src/entrypoint/doctor.dart
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2019, 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 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/generate/phase.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-
-import '../logging/std_io_logging.dart';
-import '../package_graph/build_config_overrides.dart';
-import 'base_command.dart';
-
-/// A command that validates the build environment.
-class DoctorCommand extends BuildRunnerCommand {
- @override
- String get name => 'doctor';
-
- @override
- bool get hidden => true;
-
- @override
- String get description => 'Check for misconfiguration of the build.';
-
- @override
- Future<int> run() async {
- final options = readOptions();
- final verbose = options.verbose ?? false;
- Logger.root.level = verbose ? Level.ALL : Level.INFO;
- final logSubscription =
- Logger.root.onRecord.listen(stdIOLogListener(verbose: verbose));
-
- final config = await _loadBuilderDefinitions();
-
- var isOk = true;
- for (final builderApplication in builderApplications) {
- final builderOk = _checkBuildExtensions(builderApplication, config);
- isOk = isOk && builderOk;
- }
-
- if (isOk) {
- logger.info('No problems found!\n');
- }
- await logSubscription.cancel();
- return isOk ? ExitCode.success.code : ExitCode.config.code;
- }
-
- Future<Map<String, BuilderDefinition>> _loadBuilderDefinitions() async {
- final packageGraph = PackageGraph.forThisPackage();
- final buildConfigOverrides =
- await findBuildConfigOverrides(packageGraph, null);
- Future<BuildConfig> _packageBuildConfig(PackageNode package) async {
- if (buildConfigOverrides.containsKey(package.name)) {
- return buildConfigOverrides[package.name];
- }
- try {
- return await BuildConfig.fromBuildConfigDir(package.name,
- package.dependencies.map((n) => n.name), package.path);
- } on ArgumentError catch (e) {
- logger.severe(
- 'Failed to parse a `build.yaml` file for ${package.name}', e);
- return BuildConfig.useDefault(
- package.name, package.dependencies.map((n) => n.name));
- }
- }
-
- final allConfig = await Future.wait(
- packageGraph.allPackages.values.map(_packageBuildConfig));
- final allBuilders = <String, BuilderDefinition>{};
- for (final config in allConfig) {
- allBuilders.addAll(config.builderDefinitions);
- }
- return allBuilders;
- }
-
- /// Returns true of [builderApplication] has sane build extension
- /// configuration.
- ///
- /// If there are any problems they will be logged and `false` returned.
- bool _checkBuildExtensions(BuilderApplication builderApplication,
- Map<String, BuilderDefinition> config) {
- var phases = builderApplication.buildPhaseFactories
- .map((f) => f(PackageNode(null, null, null, isRoot: true),
- BuilderOptions.empty, InputSet.anything, InputSet.anything, true))
- .whereType<InBuildPhase>()
- .toList();
- if (phases.isEmpty) return true;
- if (!config.containsKey(builderApplication.builderKey)) return false;
-
- var problemFound = false;
- var allowed = Map.of(config[builderApplication.builderKey].buildExtensions);
- for (final phase in phases.whereType<InBuildPhase>()) {
- final extensions = phase.builder.buildExtensions;
- for (final extension in extensions.entries) {
- if (!allowed.containsKey(extension.key)) {
- logger.warning('Builder ${builderApplication.builderKey} '
- 'uses input extension ${extension.key} '
- 'which is not specified in the `build.yaml`');
- problemFound = true;
- continue;
- }
- final allowedOutputs = List.of(allowed[extension.key]);
- for (final output in extension.value) {
- if (!allowedOutputs.contains(output)) {
- logger.warning('Builder ${builderApplication.builderKey} '
- 'outputs $output from ${extension.key} '
- 'which is not specified in the `build.yaml`');
- problemFound = true;
- }
- // Allow subsequent phases to use these outputs as inputs
- if (allowedOutputs.length > 1) {
- allowed.putIfAbsent(output, () => []).addAll(allowedOutputs);
- }
- }
- }
- }
- return !problemFound;
- }
-}
diff --git a/build_runner/lib/src/entrypoint/options.dart b/build_runner/lib/src/entrypoint/options.dart
deleted file mode 100644
index ad4099d..0000000
--- a/build_runner/lib/src/entrypoint/options.dart
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_daemon/constants.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:watcher/watcher.dart';
-
-import '../generate/directory_watcher_factory.dart';
-
-const buildFilterOption = 'build-filter';
-const configOption = 'config';
-const defineOption = 'define';
-const deleteFilesByDefaultOption = 'delete-conflicting-outputs';
-const failOnSevereOption = 'fail-on-severe';
-const hostnameOption = 'hostname';
-const hotReloadOption = 'hot-reload';
-const liveReloadOption = 'live-reload';
-const logPerformanceOption = 'log-performance';
-const logRequestsOption = 'log-requests';
-const lowResourcesModeOption = 'low-resources-mode';
-const outputOption = 'output';
-const releaseOption = 'release';
-const trackPerformanceOption = 'track-performance';
-const skipBuildScriptCheckOption = 'skip-build-script-check';
-const symlinkOption = 'symlink';
-const usePollingWatcherOption = 'use-polling-watcher';
-const verboseOption = 'verbose';
-
-enum BuildUpdatesOption { none, liveReload, hotReload }
-
-final _defaultWebDirs = const ['web', 'test', 'example', 'benchmark'];
-
-/// Base options that are shared among all commands.
-class SharedOptions {
- /// A set of explicit filters for files to build.
- ///
- /// If provided no other files will be built that don't match these filters
- /// unless they are an input to something matching a filter.
- final Set<BuildFilter> buildFilters;
-
- /// By default, the user will be prompted to delete any files which already
- /// exist but were not generated by this specific build script.
- ///
- /// This option can be set to `true` to skip this prompt.
- final bool deleteFilesByDefault;
-
- final bool enableLowResourcesMode;
-
- /// Read `build.$configKey.yaml` instead of `build.yaml`.
- final String configKey;
-
- /// A set of targets to build with their corresponding output locations.
- final Set<BuildDirectory> buildDirs;
-
- /// Whether or not the output directories should contain only symlinks,
- /// or full copies of all files.
- final bool outputSymlinksOnly;
-
- /// Enables performance tracking and the `/$perf` page.
- final bool trackPerformance;
-
- /// A directory to log performance information to.
- String logPerformanceDir;
-
- /// Check digest of imports to the build script to invalidate the build.
- final bool skipBuildScriptCheck;
-
- final bool verbose;
-
- // Global config overrides by builder.
- //
- // Keys are the builder keys, such as my_package|my_builder, and values
- // represent config objects. All keys in the config will override the parsed
- // config for that key.
- final Map<String, Map<String, dynamic>> builderConfigOverrides;
-
- final bool isReleaseBuild;
-
- SharedOptions._({
- @required this.buildFilters,
- @required this.deleteFilesByDefault,
- @required this.enableLowResourcesMode,
- @required this.configKey,
- @required this.buildDirs,
- @required this.outputSymlinksOnly,
- @required this.trackPerformance,
- @required this.skipBuildScriptCheck,
- @required this.verbose,
- @required this.builderConfigOverrides,
- @required this.isReleaseBuild,
- @required this.logPerformanceDir,
- });
-
- factory SharedOptions.fromParsedArgs(ArgResults argResults,
- Iterable<String> positionalArgs, String rootPackage, Command command) {
- var buildDirs = {
- ..._parseBuildDirs(argResults),
- ..._parsePositionalBuildDirs(positionalArgs, command),
- };
- var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
- return SharedOptions._(
- buildFilters: buildFilters,
- deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
- enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
- configKey: argResults[configOption] as String,
- buildDirs: buildDirs,
- outputSymlinksOnly: argResults[symlinkOption] as bool,
- trackPerformance: argResults[trackPerformanceOption] as bool,
- skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
- verbose: argResults[verboseOption] as bool,
- builderConfigOverrides:
- _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
- isReleaseBuild: argResults[releaseOption] as bool,
- logPerformanceDir: argResults[logPerformanceOption] as String,
- );
- }
-}
-
-/// Options specific to the `daemon` command.
-class DaemonOptions extends WatchOptions {
- BuildMode buildMode;
-
- DaemonOptions._({
- @required Set<BuildFilter> buildFilters,
- @required this.buildMode,
- @required bool deleteFilesByDefault,
- @required bool enableLowResourcesMode,
- @required String configKey,
- @required Set<BuildDirectory> buildDirs,
- @required bool outputSymlinksOnly,
- @required bool trackPerformance,
- @required bool skipBuildScriptCheck,
- @required bool verbose,
- @required Map<String, Map<String, dynamic>> builderConfigOverrides,
- @required bool isReleaseBuild,
- @required String logPerformanceDir,
- @required bool usePollingWatcher,
- }) : super._(
- buildFilters: buildFilters,
- deleteFilesByDefault: deleteFilesByDefault,
- enableLowResourcesMode: enableLowResourcesMode,
- configKey: configKey,
- buildDirs: buildDirs,
- outputSymlinksOnly: outputSymlinksOnly,
- trackPerformance: trackPerformance,
- skipBuildScriptCheck: skipBuildScriptCheck,
- verbose: verbose,
- builderConfigOverrides: builderConfigOverrides,
- isReleaseBuild: isReleaseBuild,
- logPerformanceDir: logPerformanceDir,
- usePollingWatcher: usePollingWatcher,
- );
-
- factory DaemonOptions.fromParsedArgs(ArgResults argResults,
- Iterable<String> positionalArgs, String rootPackage, Command command) {
- var buildDirs = {
- ..._parseBuildDirs(argResults),
- ..._parsePositionalBuildDirs(positionalArgs, command),
- };
- var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
- var buildModeValue = argResults[buildModeFlag] as String;
- BuildMode buildMode;
- if (buildModeValue == BuildMode.Auto.toString()) {
- buildMode = BuildMode.Auto;
- } else if (buildModeValue == BuildMode.Manual.toString()) {
- buildMode = BuildMode.Manual;
- } else {
- throw UsageException(
- 'Unexpected value for $buildModeFlag: $buildModeValue',
- command.usage);
- }
-
- return DaemonOptions._(
- buildFilters: buildFilters,
- buildMode: buildMode,
- deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
- enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
- configKey: argResults[configOption] as String,
- buildDirs: buildDirs,
- outputSymlinksOnly: argResults[symlinkOption] as bool,
- trackPerformance: argResults[trackPerformanceOption] as bool,
- skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
- verbose: argResults[verboseOption] as bool,
- builderConfigOverrides:
- _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
- isReleaseBuild: argResults[releaseOption] as bool,
- logPerformanceDir: argResults[logPerformanceOption] as String,
- usePollingWatcher: argResults[usePollingWatcherOption] as bool,
- );
- }
-}
-
-class WatchOptions extends SharedOptions {
- final bool usePollingWatcher;
-
- DirectoryWatcher Function(String) get directoryWatcherFactory =>
- usePollingWatcher
- ? pollingDirectoryWatcherFactory
- : defaultDirectoryWatcherFactory;
-
- WatchOptions._({
- @required this.usePollingWatcher,
- @required Set<BuildFilter> buildFilters,
- @required bool deleteFilesByDefault,
- @required bool enableLowResourcesMode,
- @required String configKey,
- @required Set<BuildDirectory> buildDirs,
- @required bool outputSymlinksOnly,
- @required bool trackPerformance,
- @required bool skipBuildScriptCheck,
- @required bool verbose,
- @required Map<String, Map<String, dynamic>> builderConfigOverrides,
- @required bool isReleaseBuild,
- @required String logPerformanceDir,
- }) : super._(
- buildFilters: buildFilters,
- deleteFilesByDefault: deleteFilesByDefault,
- enableLowResourcesMode: enableLowResourcesMode,
- configKey: configKey,
- buildDirs: buildDirs,
- outputSymlinksOnly: outputSymlinksOnly,
- trackPerformance: trackPerformance,
- skipBuildScriptCheck: skipBuildScriptCheck,
- verbose: verbose,
- builderConfigOverrides: builderConfigOverrides,
- isReleaseBuild: isReleaseBuild,
- logPerformanceDir: logPerformanceDir,
- );
-
- factory WatchOptions.fromParsedArgs(ArgResults argResults,
- Iterable<String> positionalArgs, String rootPackage, Command command) {
- var buildDirs = {
- ..._parseBuildDirs(argResults),
- ..._parsePositionalBuildDirs(positionalArgs, command),
- };
- var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
- return WatchOptions._(
- buildFilters: buildFilters,
- deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
- enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
- configKey: argResults[configOption] as String,
- buildDirs: buildDirs,
- outputSymlinksOnly: argResults[symlinkOption] as bool,
- trackPerformance: argResults[trackPerformanceOption] as bool,
- skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
- verbose: argResults[verboseOption] as bool,
- builderConfigOverrides:
- _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
- isReleaseBuild: argResults[releaseOption] as bool,
- logPerformanceDir: argResults[logPerformanceOption] as String,
- usePollingWatcher: argResults[usePollingWatcherOption] as bool,
- );
- }
-}
-
-/// Options specific to the `serve` command.
-class ServeOptions extends WatchOptions {
- final String hostName;
- final BuildUpdatesOption buildUpdates;
- final bool logRequests;
- final List<ServeTarget> serveTargets;
-
- ServeOptions._({
- @required this.hostName,
- @required this.buildUpdates,
- @required this.logRequests,
- @required this.serveTargets,
- @required Set<BuildFilter> buildFilters,
- @required bool deleteFilesByDefault,
- @required bool enableLowResourcesMode,
- @required String configKey,
- @required Set<BuildDirectory> buildDirs,
- @required bool outputSymlinksOnly,
- @required bool trackPerformance,
- @required bool skipBuildScriptCheck,
- @required bool verbose,
- @required Map<String, Map<String, dynamic>> builderConfigOverrides,
- @required bool isReleaseBuild,
- @required String logPerformanceDir,
- @required bool usePollingWatcher,
- }) : super._(
- buildFilters: buildFilters,
- deleteFilesByDefault: deleteFilesByDefault,
- enableLowResourcesMode: enableLowResourcesMode,
- configKey: configKey,
- buildDirs: buildDirs,
- outputSymlinksOnly: outputSymlinksOnly,
- trackPerformance: trackPerformance,
- skipBuildScriptCheck: skipBuildScriptCheck,
- verbose: verbose,
- builderConfigOverrides: builderConfigOverrides,
- isReleaseBuild: isReleaseBuild,
- logPerformanceDir: logPerformanceDir,
- usePollingWatcher: usePollingWatcher,
- );
-
- factory ServeOptions.fromParsedArgs(ArgResults argResults,
- Iterable<String> positionalArgs, String rootPackage, Command command) {
- var serveTargets = <ServeTarget>[];
- var nextDefaultPort = 8080;
- for (var arg in positionalArgs) {
- var parts = arg.split(':');
- if (parts.length > 2) {
- throw UsageException(
- 'Invalid format for positional argument to serve `$arg`'
- ', expected <directory>:<port>.',
- command.usage);
- }
-
- var port = parts.length == 2 ? int.tryParse(parts[1]) : nextDefaultPort++;
- if (port == null) {
- throw UsageException(
- 'Unable to parse port number in `$arg`', command.usage);
- }
-
- var path = parts.first;
- var pathParts = p.split(path);
- if (pathParts.length > 1 || path == '.') {
- throw UsageException(
- 'Only top level directories such as `web` or `test` are allowed as '
- 'positional args, but got `$path`',
- command.usage);
- }
-
- serveTargets.add(ServeTarget(path, port));
- }
- if (serveTargets.isEmpty) {
- for (var dir in _defaultWebDirs) {
- if (Directory(dir).existsSync()) {
- serveTargets.add(ServeTarget(dir, nextDefaultPort++));
- }
- }
- }
-
- var buildDirs = _parseBuildDirs(argResults);
- for (var target in serveTargets) {
- buildDirs.add(BuildDirectory(target.dir));
- }
-
- var buildFilters = _parseBuildFilters(argResults, rootPackage);
-
- BuildUpdatesOption buildUpdates;
- if (argResults[liveReloadOption] as bool &&
- argResults[hotReloadOption] as bool) {
- throw UsageException(
- 'Options --$liveReloadOption and --$hotReloadOption '
- "can't both be used together",
- command.usage);
- } else if (argResults[liveReloadOption] as bool) {
- buildUpdates = BuildUpdatesOption.liveReload;
- } else if (argResults[hotReloadOption] as bool) {
- buildUpdates = BuildUpdatesOption.hotReload;
- }
-
- return ServeOptions._(
- buildFilters: buildFilters,
- hostName: argResults[hostnameOption] as String,
- buildUpdates: buildUpdates,
- logRequests: argResults[logRequestsOption] as bool,
- serveTargets: serveTargets,
- deleteFilesByDefault: argResults[deleteFilesByDefaultOption] as bool,
- enableLowResourcesMode: argResults[lowResourcesModeOption] as bool,
- configKey: argResults[configOption] as String,
- buildDirs: buildDirs,
- outputSymlinksOnly: argResults[symlinkOption] as bool,
- trackPerformance: argResults[trackPerformanceOption] as bool,
- skipBuildScriptCheck: argResults[skipBuildScriptCheckOption] as bool,
- verbose: argResults[verboseOption] as bool,
- builderConfigOverrides:
- _parseBuilderConfigOverrides(argResults[defineOption], rootPackage),
- isReleaseBuild: argResults[releaseOption] as bool,
- logPerformanceDir: argResults[logPerformanceOption] as String,
- usePollingWatcher: argResults[usePollingWatcherOption] as bool,
- );
- }
-}
-
-/// A target to serve, representing a directory and a port.
-class ServeTarget {
- final String dir;
- final int port;
-
- ServeTarget(this.dir, this.port);
-}
-
-Map<String, Map<String, dynamic>> _parseBuilderConfigOverrides(
- dynamic parsedArg, String rootPackage) {
- final builderConfigOverrides = <String, Map<String, dynamic>>{};
- if (parsedArg == null) return builderConfigOverrides;
- var allArgs = parsedArg is List<String> ? parsedArg : [parsedArg as String];
- for (final define in allArgs) {
- final parts = define.split('=');
- const expectedFormat = '--define "<builder_key>=<option>=<value>"';
- if (parts.length < 3) {
- throw ArgumentError.value(
- define,
- defineOption,
- 'Expected at least 2 `=` signs, should be of the format like '
- '$expectedFormat');
- } else if (parts.length > 3) {
- var rest = parts.sublist(2);
- parts
- ..removeRange(2, parts.length)
- ..add(rest.join('='));
- }
- final builderKey = normalizeBuilderKeyUsage(parts[0], rootPackage);
- final option = parts[1];
- dynamic value;
- // Attempt to parse the value as JSON, and if that fails then treat it as
- // a normal string.
- try {
- value = json.decode(parts[2]);
- } on FormatException catch (_) {
- value = parts[2];
- }
- final config = builderConfigOverrides.putIfAbsent(
- builderKey, () => <String, dynamic>{});
- if (config.containsKey(option)) {
- throw ArgumentError(
- 'Got duplicate overrides for the same builder option: '
- '$builderKey=$option. Only one is allowed.');
- }
- config[option] = value;
- }
- return builderConfigOverrides;
-}
-
-/// Returns build directories with output information parsed from output
-/// arguments.
-///
-/// Each output option is split on `:` where the first value is the
-/// root input directory and the second value output directory.
-/// If no delimeter is provided the root input directory will be null.
-Set<BuildDirectory> _parseBuildDirs(ArgResults argResults) {
- var outputs = argResults[outputOption] as List<String>;
- if (outputs == null) return <BuildDirectory>{};
- var result = <BuildDirectory>{};
- var outputPaths = <String>{};
-
- void checkExisting(String outputDir) {
- if (outputPaths.contains(outputDir)) {
- throw ArgumentError.value(outputs.join(' '), '--output',
- 'Duplicate output directories are not allowed, got');
- }
- outputPaths.add(outputDir);
- }
-
- for (var option in argResults[outputOption] as List<String>) {
- var split = option.split(':');
- if (split.length == 1) {
- var output = split.first;
- checkExisting(output);
- result.add(BuildDirectory('',
- outputLocation: OutputLocation(output, hoist: false)));
- } else if (split.length >= 2) {
- var output = split.sublist(1).join(':');
- checkExisting(output);
- var root = split.first;
- if (root.contains('/')) {
- throw ArgumentError.value(
- option, '--output', 'Input root can not be nested');
- }
- result.add(
- BuildDirectory(split.first, outputLocation: OutputLocation(output)));
- }
- }
- return result;
-}
-
-/// Throws a [UsageException] if [arg] looks like anything other than a top
-/// level directory.
-String _checkTopLevel(String arg, Command command) {
- var parts = p.split(arg);
- if (parts.length > 1 || arg == '.') {
- throw UsageException(
- 'Only top level directories such as `web` or `test` are allowed as '
- 'positional args, but got `$arg`',
- command.usage);
- }
- return arg;
-}
-
-/// Parses positional arguments as plain build directories.
-Set<BuildDirectory> _parsePositionalBuildDirs(
- Iterable<String> positionalArgs, Command command) =>
- {
- for (var arg in positionalArgs)
- BuildDirectory(_checkTopLevel(arg, command))
- };
-
-/// Returns build filters parsed from [buildFilterOption] arguments.
-///
-/// These support `package:` uri syntax as well as regular path syntax,
-/// with glob support for both package names and paths.
-Set<BuildFilter> _parseBuildFilters(ArgResults argResults, String rootPackage) {
- var filterArgs = argResults[buildFilterOption] as List<String>;
- if (filterArgs?.isEmpty ?? true) return null;
- try {
- return {
- for (var arg in filterArgs) BuildFilter.fromArg(arg, rootPackage),
- };
- } on FormatException catch (e) {
- throw ArgumentError.value(
- e.source,
- '--build-filter',
- 'Not a valid build filter, must be either a relative path or '
- '`package:` uri.\n\n$e');
- }
-}
diff --git a/build_runner/lib/src/entrypoint/run.dart b/build_runner/lib/src/entrypoint/run.dart
deleted file mode 100644
index ceba164..0000000
--- a/build_runner/lib/src/entrypoint/run.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2017, 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 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/ansi.dart' as ansi;
-import 'package:io/io.dart' show ExitCode;
-
-import 'clean.dart';
-import 'runner.dart';
-
-/// A common entry point to parse command line arguments and build or serve with
-/// [builders].
-///
-/// Returns the exit code that should be set when the calling process exits. `0`
-/// implies success.
-Future<int> run(List<String> args, List<BuilderApplication> builders) async {
- var runner = BuildCommandRunner(builders)..addCommand(CleanCommand());
- try {
- var result = await runner.run(args);
- return result ?? 0;
- } on UsageException catch (e) {
- print(ansi.red.wrap(e.message));
- print('');
- print(e.usage);
- return ExitCode.usage.code;
- } on ArgumentError catch (e) {
- print(ansi.red.wrap(e.toString()));
- return ExitCode.usage.code;
- } on CannotBuildException {
- // A message should have already been logged.
- return ExitCode.config.code;
- } on BuildScriptChangedException {
- _deleteAssetGraph();
- if (_runningFromSnapshot) _deleteSelf();
- return ExitCode.tempFail.code;
- } on BuildConfigChangedException {
- return ExitCode.tempFail.code;
- }
-}
-
-/// Deletes the asset graph for the current build script from disk.
-void _deleteAssetGraph() {
- var graph = File(assetGraphPath);
- if (graph.existsSync()) {
- graph.deleteSync();
- }
-}
-
-/// Deletes the current running script.
-///
-/// This should only happen if the current script is a snapshot, and it has
-/// been invalidated.
-void _deleteSelf() {
- var self = File(Platform.script.toFilePath());
- if (self.existsSync()) {
- self.deleteSync();
- }
-}
-
-bool get _runningFromSnapshot => !Platform.script.path.endsWith('.dart');
diff --git a/build_runner/lib/src/entrypoint/run_script.dart b/build_runner/lib/src/entrypoint/run_script.dart
deleted file mode 100644
index 6c4fbd3..0000000
--- a/build_runner/lib/src/entrypoint/run_script.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2019, 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:build_runner/src/logging/std_io_logging.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../generate/build.dart';
-import 'base_command.dart';
-import 'options.dart';
-
-class RunCommand extends BuildRunnerCommand {
- @override
- String get name => 'run';
-
- @override
- String get description => 'Performs a single build, and executes '
- 'a Dart script with the given arguments.';
-
- @override
- String get invocation =>
- '${super.invocation.replaceFirst('[arguments]', '[build-arguments]')} '
- '<executable> [-- [script-arguments]]';
-
- @override
- SharedOptions readOptions() {
- // Here we validate that [argResults.rest] is exactly equal to all the
- // arguments after the `--`.
-
- var separatorPos = argResults.arguments.indexOf('--');
-
- if (separatorPos >= 0) {
- void throwUsageException() {
- throw UsageException(
- 'The `run` command does not support positional args before the '
- '`--` separator which should separate build args from script args.',
- usage);
- }
-
- var expectedRest = argResults.arguments.skip(separatorPos + 1).toList();
-
- // Since we expect the first argument to be the name of a script,
- // we should skip it when comparing extra arguments.
- var effectiveRest = argResults.rest.skip(1).toList();
-
- if (effectiveRest.length != expectedRest.length) {
- throwUsageException();
- }
-
- for (var i = 0; i < effectiveRest.length; i++) {
- if (expectedRest[i] != effectiveRest[i]) {
- throwUsageException();
- }
- }
- }
-
- return SharedOptions.fromParsedArgs(
- argResults, [], packageGraph.root.name, this);
- }
-
- @override
- FutureOr<int> run() async {
- var options = readOptions();
- var logSubscription =
- Logger.root.onRecord.listen(stdIOLogListener(verbose: options.verbose));
-
- try {
- // Ensure that the user passed the name of a file to run.
- if (argResults.rest.isEmpty) {
- logger..severe('Must specify an executable to run.')..severe(usage);
- return ExitCode.usage.code;
- }
-
- var scriptName = argResults.rest[0];
- var passedArgs = argResults.rest.skip(1).toList();
-
- // Ensure the extension is .dart.
- if (p.extension(scriptName) != '.dart') {
- logger.severe('$scriptName is not a valid Dart file '
- 'and cannot be run in the VM.');
- return ExitCode.usage.code;
- }
-
- // Create a temporary directory in which to execute the script.
- var tempPath = Directory.systemTemp
- .createTempSync('build_runner_run_script')
- .absolute
- .uri
- .toFilePath();
-
- // Create two ReceivePorts, so that we can quit when the isolate is done.
- //
- // Define these before starting the isolate, so that we can close
- // them if there is a spawn exception.
- ReceivePort onExit, onError;
-
- // Use a completer to determine the exit code.
- var exitCodeCompleter = Completer<int>();
-
- try {
- var buildDirs = (options.buildDirs ?? <BuildDirectory>{})
- ..add(BuildDirectory('',
- outputLocation: OutputLocation(tempPath,
- useSymlinks: options.outputSymlinksOnly, hoist: false)));
- var result = await build(
- builderApplications,
- deleteFilesByDefault: options.deleteFilesByDefault,
- enableLowResourcesMode: options.enableLowResourcesMode,
- configKey: options.configKey,
- buildDirs: buildDirs,
- packageGraph: packageGraph,
- verbose: options.verbose,
- builderConfigOverrides: options.builderConfigOverrides,
- isReleaseBuild: options.isReleaseBuild,
- trackPerformance: options.trackPerformance,
- skipBuildScriptCheck: options.skipBuildScriptCheck,
- logPerformanceDir: options.logPerformanceDir,
- buildFilters: options.buildFilters,
- );
-
- if (result.status == BuildStatus.failure) {
- logger.warning('Skipping script run due to build failure');
- return result.failureType.exitCode;
- }
-
- // Find the path of the script to run.
- var scriptPath = p.join(tempPath, scriptName);
- var packageConfigPath = p.join(tempPath, '.packages');
-
- onExit = ReceivePort();
- onError = ReceivePort();
-
- // Cleanup after exit.
- onExit.listen((_) {
- // If no error was thrown, return 0.
- if (!exitCodeCompleter.isCompleted) exitCodeCompleter.complete(0);
- });
-
- // On an error, kill the isolate, and log the error.
- onError.listen((e) {
- onExit.close();
- onError.close();
- logger.severe('Unhandled error from script: $scriptName', e[0],
- StackTrace.fromString(e[1].toString()));
- if (!exitCodeCompleter.isCompleted) exitCodeCompleter.complete(1);
- });
-
- await Isolate.spawnUri(
- p.toUri(scriptPath),
- passedArgs,
- null,
- errorsAreFatal: true,
- onExit: onExit.sendPort,
- onError: onError.sendPort,
- packageConfig: p.toUri(packageConfigPath),
- );
-
- return await exitCodeCompleter.future;
- } on IsolateSpawnException catch (e) {
- logger.severe(
- 'Could not spawn isolate. Ensure that your file is in a valid directory (i.e. "bin", "benchmark", "example", "test", "tool").',
- e);
- return ExitCode.ioError.code;
- } finally {
- // Clean up the output dir.
- var dir = Directory(tempPath);
- if (await dir.exists()) await dir.delete(recursive: true);
-
- onExit?.close();
- onError?.close();
- if (!exitCodeCompleter.isCompleted) {
- exitCodeCompleter.complete(ExitCode.success.code);
- }
- }
- } finally {
- await logSubscription.cancel();
- }
- }
-}
diff --git a/build_runner/lib/src/entrypoint/runner.dart b/build_runner/lib/src/entrypoint/runner.dart
deleted file mode 100644
index 4cb309f..0000000
--- a/build_runner/lib/src/entrypoint/runner.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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:convert';
-
-import 'package:args/args.dart';
-import 'package:args/command_runner.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-
-import 'base_command.dart' show lineLength;
-import 'build.dart';
-import 'daemon.dart';
-import 'doctor.dart';
-import 'run_script.dart';
-import 'serve.dart';
-import 'test.dart';
-import 'watch.dart';
-
-/// Unified command runner for all build_runner commands.
-class BuildCommandRunner extends CommandRunner<int> {
- @override
- final argParser = ArgParser(usageLineLength: lineLength);
-
- final List<BuilderApplication> builderApplications;
-
- final packageGraph = PackageGraph.forThisPackage();
-
- BuildCommandRunner(List<BuilderApplication> builderApplications)
- : builderApplications = List.unmodifiable(builderApplications),
- super('build_runner', 'Unified interface for running Dart builds.') {
- addCommand(BuildCommand());
- addCommand(DaemonCommand());
- addCommand(DoctorCommand());
- addCommand(RunCommand());
- addCommand(ServeCommand());
- addCommand(TestCommand(packageGraph));
- addCommand(WatchCommand());
- }
-
- // CommandRunner._usageWithoutDescription is private – this is a reasonable
- // facsimile.
- /// Returns [usage] with [description] removed from the beginning.
- String get usageWithoutDescription => LineSplitter.split(usage)
- .skipWhile((line) => line == description || line.isEmpty)
- .join('\n');
-}
diff --git a/build_runner/lib/src/entrypoint/serve.dart b/build_runner/lib/src/entrypoint/serve.dart
deleted file mode 100644
index aacc363..0000000
--- a/build_runner/lib/src/entrypoint/serve.dart
+++ /dev/null
@@ -1,153 +0,0 @@
-// 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 'package:http_multi_server/http_multi_server.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:logging/logging.dart';
-import 'package:shelf/shelf_io.dart';
-
-import '../generate/build.dart';
-import '../logging/std_io_logging.dart';
-import '../server/server.dart';
-import 'options.dart';
-import 'watch.dart';
-
-/// Extends [WatchCommand] with dev server functionality.
-class ServeCommand extends WatchCommand {
- ServeCommand() {
- argParser
- ..addOption(hostnameOption,
- help: 'Specify the hostname to serve on', defaultsTo: 'localhost')
- ..addFlag(logRequestsOption,
- defaultsTo: false,
- negatable: false,
- help: 'Enables logging for each request to the server.')
- ..addFlag(liveReloadOption,
- defaultsTo: false,
- negatable: false,
- help: 'Enables automatic page reloading on rebuilds. '
- "Can't be used together with --$hotReloadOption.")
- ..addFlag(hotReloadOption,
- defaultsTo: false,
- negatable: false,
- help: 'Enables automatic reloading of changed modules on rebuilds. '
- "Can't be used together with --$liveReloadOption.");
- }
-
- @override
- String get invocation => '${super.invocation} [<directory>[:<port>]]...';
-
- @override
- String get name => 'serve';
-
- @override
- String get description =>
- 'Runs a development server that serves the specified targets and runs '
- 'builds based on file system updates.';
-
- @override
- ServeOptions readOptions() => ServeOptions.fromParsedArgs(
- argResults, argResults.rest, packageGraph.root.name, this);
-
- @override
- Future<int> run() async {
- final servers = <ServeTarget, HttpServer>{};
- return _runServe(servers).whenComplete(() async {
- await Future.wait(
- servers.values.map((server) => server.close(force: true)));
- });
- }
-
- Future<int> _runServe(Map<ServeTarget, HttpServer> servers) async {
- var options = readOptions();
- try {
- await Future.wait(options.serveTargets.map((target) async {
- servers[target] =
- await HttpMultiServer.bind(options.hostName, target.port);
- }));
- } on SocketException catch (e) {
- var listener = Logger.root.onRecord.listen(stdIOLogListener());
- if (e.address != null && e.port != null) {
- logger.severe(
- 'Error starting server at ${e.address.address}:${e.port}, address '
- 'is already in use. Please kill the server running on that port or '
- 'serve on a different port and restart this process.');
- } else {
- logger.severe('Error starting server on ${options.hostName}.');
- }
- await listener.cancel();
- return ExitCode.osError.code;
- }
-
- var handler = await watch(
- builderApplications,
- deleteFilesByDefault: options.deleteFilesByDefault,
- enableLowResourcesMode: options.enableLowResourcesMode,
- configKey: options.configKey,
- buildDirs: options.buildDirs,
- outputSymlinksOnly: options.outputSymlinksOnly,
- packageGraph: packageGraph,
- trackPerformance: options.trackPerformance,
- skipBuildScriptCheck: options.skipBuildScriptCheck,
- verbose: options.verbose,
- builderConfigOverrides: options.builderConfigOverrides,
- isReleaseBuild: options.isReleaseBuild,
- logPerformanceDir: options.logPerformanceDir,
- directoryWatcherFactory: options.directoryWatcherFactory,
- buildFilters: options.buildFilters,
- );
-
- if (handler == null) return ExitCode.config.code;
-
- servers.forEach((target, server) {
- serveRequests(
- server,
- handler.handlerFor(target.dir,
- logRequests: options.logRequests,
- buildUpdates: options.buildUpdates));
- });
-
- _ensureBuildWebCompilersDependency(packageGraph, logger);
-
- final completer = Completer<int>();
- handleBuildResultsStream(handler.buildResults, completer);
- _logServerPorts(handler, options, logger);
- return completer.future;
- }
-
- void _logServerPorts(
- ServeHandler serveHandler, ServeOptions options, Logger logger) async {
- await serveHandler.currentBuild;
- // Warn if in serve mode with no servers.
- if (options.serveTargets.isEmpty) {
- logger.warning(
- 'Found no known web directories to serve, but running in `serve` '
- 'mode. You may expliclity provide a directory to serve with trailing '
- 'args in <dir>[:<port>] format.');
- } else {
- for (var target in options.serveTargets) {
- stdout.writeln('Serving `${target.dir}` on '
- 'http://${options.hostName}:${target.port}');
- }
- }
- }
-}
-
-void _ensureBuildWebCompilersDependency(PackageGraph packageGraph, Logger log) {
- if (!packageGraph.allPackages.containsKey('build_web_compilers')) {
- log.warning('''
- Missing dev dependency on package:build_web_compilers, which is required to serve Dart compiled to JavaScript.
-
- Please update your dev_dependencies section of your pubspec.yaml:
-
- dev_dependencies:
- build_runner: any
- build_test: any
- build_web_compilers: any''');
- }
-}
diff --git a/build_runner/lib/src/entrypoint/test.dart b/build_runner/lib/src/entrypoint/test.dart
deleted file mode 100644
index fbd69db..0000000
--- a/build_runner/lib/src/entrypoint/test.dart
+++ /dev/null
@@ -1,188 +0,0 @@
-// 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 'package:args/command_runner.dart';
-import 'package:async/async.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-import 'package:path/path.dart' as p;
-import 'package:pub_semver/pub_semver.dart';
-import 'package:pubspec_parse/pubspec_parse.dart';
-
-import '../generate/build.dart';
-import 'base_command.dart';
-import 'options.dart';
-
-/// A command that does a single build and then runs tests using the compiled
-/// assets.
-class TestCommand extends BuildRunnerCommand {
- TestCommand(PackageGraph packageGraph)
- : super(
- // Use symlinks by default, if package:test supports it.
- symlinksDefault:
- _packageTestSupportsSymlinks(packageGraph) && !Platform.isWindows,
- );
-
- @override
- String get invocation =>
- '${super.invocation.replaceFirst('[arguments]', '[build-arguments]')} '
- '[-- [test-arguments]]';
-
- @override
- String get name => 'test';
-
- @override
- String get description =>
- 'Performs a single build of the test directory only and then runs tests '
- 'using the compiled assets.';
-
- @override
- SharedOptions readOptions() {
- // This command doesn't allow specifying directories to build, instead it
- // always builds the `test` directory.
- //
- // Here we validate that [argResults.rest] is exactly equal to all the
- // arguments after the `--`.
- if (argResults.rest.isNotEmpty) {
- void throwUsageException() {
- throw UsageException(
- 'The `test` command does not support positional args before the, '
- '`--` separator, which should separate build args from test args.',
- usage);
- }
-
- var separatorPos = argResults.arguments.indexOf('--');
- if (separatorPos < 0) {
- throwUsageException();
- }
- var expectedRest = argResults.arguments.skip(separatorPos + 1).toList();
- if (argResults.rest.length != expectedRest.length) {
- throwUsageException();
- }
- for (var i = 0; i < argResults.rest.length; i++) {
- if (expectedRest[i] != argResults.rest[i]) {
- throwUsageException();
- }
- }
- }
-
- return SharedOptions.fromParsedArgs(
- argResults, ['test'], packageGraph.root.name, this);
- }
-
- @override
- Future<int> run() async {
- SharedOptions options;
- // We always run our tests in a temp dir.
- var tempPath = Directory.systemTemp
- .createTempSync('build_runner_test')
- .absolute
- .uri
- .toFilePath();
- try {
- _ensureBuildTestDependency(packageGraph);
- options = readOptions();
- var buildDirs = (options.buildDirs ?? <BuildDirectory>{})
- // Build test by default.
- ..add(BuildDirectory('test',
- outputLocation: OutputLocation(tempPath,
- useSymlinks: options.outputSymlinksOnly, hoist: false)));
-
- var result = await build(
- builderApplications,
- deleteFilesByDefault: options.deleteFilesByDefault,
- enableLowResourcesMode: options.enableLowResourcesMode,
- configKey: options.configKey,
- buildDirs: buildDirs,
- outputSymlinksOnly: options.outputSymlinksOnly,
- packageGraph: packageGraph,
- trackPerformance: options.trackPerformance,
- skipBuildScriptCheck: options.skipBuildScriptCheck,
- verbose: options.verbose,
- builderConfigOverrides: options.builderConfigOverrides,
- isReleaseBuild: options.isReleaseBuild,
- logPerformanceDir: options.logPerformanceDir,
- buildFilters: options.buildFilters,
- );
-
- if (result.status == BuildStatus.failure) {
- stdout.writeln('Skipping tests due to build failure');
- return result.failureType.exitCode;
- }
-
- return await _runTests(tempPath);
- } on _BuildTestDependencyError catch (e) {
- stdout.writeln(e);
- return ExitCode.config.code;
- } finally {
- // Clean up the output dir.
- await Directory(tempPath).delete(recursive: true);
- }
- }
-
- /// Runs tests using [precompiledPath] as the precompiled test directory.
- Future<int> _runTests(String precompiledPath) async {
- stdout.writeln('Running tests...\n');
- var extraTestArgs = argResults.rest;
- var testProcess = await Process.start(
- pubBinary,
- [
- 'run',
- 'test',
- '--precompiled',
- precompiledPath,
- ...extraTestArgs,
- ],
- mode: ProcessStartMode.inheritStdio);
- _ensureProcessExit(testProcess);
- return testProcess.exitCode;
- }
-}
-
-bool _packageTestSupportsSymlinks(PackageGraph packageGraph) {
- var testPackage = packageGraph['test'];
- if (testPackage == null) return false;
- var pubspecPath = p.join(testPackage.path, 'pubspec.yaml');
- var pubspec = Pubspec.parse(File(pubspecPath).readAsStringSync());
- if (pubspec.version == null) return false;
- return pubspec.version >= Version(1, 3, 0);
-}
-
-void _ensureBuildTestDependency(PackageGraph packageGraph) {
- if (!packageGraph.allPackages.containsKey('build_test')) {
- throw _BuildTestDependencyError();
- }
-}
-
-void _ensureProcessExit(Process process) {
- var signalsSub = _exitProcessSignals.listen((signal) async {
- stdout.writeln('waiting for subprocess to exit...');
- });
- process.exitCode.then((_) {
- signalsSub?.cancel();
- signalsSub = null;
- });
-}
-
-Stream<ProcessSignal> get _exitProcessSignals => Platform.isWindows
- ? ProcessSignal.sigint.watch()
- : StreamGroup.merge(
- [ProcessSignal.sigterm.watch(), ProcessSignal.sigint.watch()]);
-
-class _BuildTestDependencyError extends StateError {
- _BuildTestDependencyError() : super('''
-Missing dev dependency on package:build_test, which is required to run tests.
-
-Please update your dev_dependencies section of your pubspec.yaml:
-
- dev_dependencies:
- build_runner: any
- build_test: any
- # If you need to run web tests, you will also need this dependency.
- build_web_compilers: any
-''');
-}
diff --git a/build_runner/lib/src/entrypoint/watch.dart b/build_runner/lib/src/entrypoint/watch.dart
deleted file mode 100644
index fea22ac..0000000
--- a/build_runner/lib/src/entrypoint/watch.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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 'package:build_runner/src/entrypoint/options.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:io/io.dart';
-
-import '../generate/build.dart';
-import 'base_command.dart';
-
-/// A command that watches the file system for updates and rebuilds as
-/// appropriate.
-class WatchCommand extends BuildRunnerCommand {
- @override
- String get invocation => '${super.invocation} [directories]';
-
- @override
- String get name => 'watch';
-
- @override
- String get description =>
- 'Builds the specified targets, watching the file system for updates and '
- 'rebuilding as appropriate.';
-
- WatchCommand() {
- argParser.addFlag(usePollingWatcherOption,
- help: 'Use a polling watcher instead of the current platforms default '
- 'watcher implementation. This should generally only be used if '
- 'you are having problems with the default watcher, as it is '
- 'generally less efficient.');
- }
-
- @override
- WatchOptions readOptions() => WatchOptions.fromParsedArgs(
- argResults, argResults.rest, packageGraph.root.name, this);
-
- @override
- Future<int> run() async {
- var options = readOptions();
- var handler = await watch(
- builderApplications,
- deleteFilesByDefault: options.deleteFilesByDefault,
- enableLowResourcesMode: options.enableLowResourcesMode,
- configKey: options.configKey,
- buildDirs: options.buildDirs,
- outputSymlinksOnly: options.outputSymlinksOnly,
- packageGraph: packageGraph,
- trackPerformance: options.trackPerformance,
- skipBuildScriptCheck: options.skipBuildScriptCheck,
- verbose: options.verbose,
- builderConfigOverrides: options.builderConfigOverrides,
- isReleaseBuild: options.isReleaseBuild,
- logPerformanceDir: options.logPerformanceDir,
- directoryWatcherFactory: options.directoryWatcherFactory,
- buildFilters: options.buildFilters,
- );
- if (handler == null) return ExitCode.config.code;
-
- final completer = Completer<int>();
- handleBuildResultsStream(handler.buildResults, completer);
- return completer.future;
- }
-
- /// Listens to [buildResults], handling certain types of errors and completing
- /// [completer] appropriately.
- void handleBuildResultsStream(
- Stream<BuildResult> buildResults, Completer<int> completer) async {
- var subscription = buildResults.listen((result) {
- if (completer.isCompleted) return;
- if (result.status == BuildStatus.failure) {
- if (result.failureType == FailureType.buildScriptChanged) {
- completer.completeError(BuildScriptChangedException());
- } else if (result.failureType == FailureType.buildConfigChanged) {
- completer.completeError(BuildConfigChangedException());
- }
- }
- });
- await subscription.asFuture();
- if (!completer.isCompleted) completer.complete(ExitCode.success.code);
- }
-}
diff --git a/build_runner/lib/src/generate/build.dart b/build_runner/lib/src/generate/build.dart
deleted file mode 100644
index c17594a..0000000
--- a/build_runner/lib/src/generate/build.dart
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2016, 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 'package:build/build.dart';
-import 'package:build_runner/src/generate/terminator.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-import 'package:shelf/shelf.dart';
-import 'package:watcher/watcher.dart';
-
-import '../logging/std_io_logging.dart';
-import '../package_graph/build_config_overrides.dart';
-import '../server/server.dart';
-import 'watch_impl.dart' as watch_impl;
-
-/// Runs all of the BuilderApplications in [builders] once.
-///
-/// By default, the user will be prompted to delete any files which already
-/// exist but were not generated by this specific build script. The
-/// [deleteFilesByDefault] option can be set to `true` to skip this prompt.
-///
-/// A [packageGraph] may be supplied, otherwise one will be constructed using
-/// [PackageGraph.forThisPackage]. The default functionality assumes you are
-/// running in the root directory of a package, with both a `pubspec.yaml` and
-/// `.packages` file present.
-///
-/// A [reader] and [writer] may also be supplied, which can read/write assets
-/// to arbitrary locations or file systems. By default they will write directly
-/// to the root package directory, and will use the [packageGraph] to know where
-/// to read files from.
-///
-/// Logging may be customized by passing a custom [logLevel] below which logs
-/// will be ignored, as well as an [onLog] handler which defaults to [print].
-///
-/// The [terminateEventStream] is a stream which can send termination events.
-/// By default the [ProcessSignal.sigint] stream is used. In this mode, it
-/// will simply consume the first event and allow the build to continue.
-/// Multiple termination events will cause a normal shutdown.
-///
-/// If [outputSymlinksOnly] is `true`, then the merged output directories will
-/// contain only symlinks, which is much faster but not generally suitable for
-/// deployment.
-///
-/// If [verbose] is `true` then verbose logging will be enabled. This changes
-/// the default [logLevel] to [Level.ALL] and removes stack frame folding, among
-/// other things.
-Future<BuildResult> build(List<BuilderApplication> builders,
- {bool deleteFilesByDefault,
- bool assumeTty,
- String configKey,
- PackageGraph packageGraph,
- RunnerAssetReader reader,
- RunnerAssetWriter writer,
- Resolvers resolvers,
- Level logLevel,
- void Function(LogRecord) onLog,
- Stream terminateEventStream,
- bool enableLowResourcesMode,
- Set<BuildDirectory> buildDirs,
- bool outputSymlinksOnly,
- bool trackPerformance,
- bool skipBuildScriptCheck,
- bool verbose,
- bool isReleaseBuild,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- String logPerformanceDir,
- Set<BuildFilter> buildFilters}) async {
- builderConfigOverrides ??= const {};
- packageGraph ??= PackageGraph.forThisPackage();
- var environment = OverrideableEnvironment(
- IOEnvironment(
- packageGraph,
- assumeTty: assumeTty,
- outputSymlinksOnly: outputSymlinksOnly,
- ),
- reader: reader,
- writer: writer,
- onLog: onLog ?? stdIOLogListener(assumeTty: assumeTty, verbose: verbose));
- var logSubscription =
- LogSubscription(environment, verbose: verbose, logLevel: logLevel);
- var options = await BuildOptions.create(
- logSubscription,
- deleteFilesByDefault: deleteFilesByDefault,
- packageGraph: packageGraph,
- skipBuildScriptCheck: skipBuildScriptCheck,
- overrideBuildConfig:
- await findBuildConfigOverrides(packageGraph, configKey),
- enableLowResourcesMode: enableLowResourcesMode,
- trackPerformance: trackPerformance,
- logPerformanceDir: logPerformanceDir,
- resolvers: resolvers,
- );
- var terminator = Terminator(terminateEventStream);
- try {
- var build = await BuildRunner.create(
- options,
- environment,
- builders,
- builderConfigOverrides,
- isReleaseBuild: isReleaseBuild ?? false,
- );
- var result =
- await build.run({}, buildDirs: buildDirs, buildFilters: buildFilters);
- await build?.beforeExit();
- return result;
- } finally {
- await terminator.cancel();
- await options.logListener.cancel();
- }
-}
-
-/// Same as [build], except it watches the file system and re-runs builds
-/// automatically.
-///
-/// Call [ServeHandler.handlerFor] to create a [Handler] for use with
-/// `package:shelf`. Requests for assets will be blocked while builds are
-/// running then served with the latest version of the asset. Only source and
-/// generated assets can be served through this handler.
-///
-/// The [debounceDelay] controls how often builds will run. As long as files
-/// keep changing with less than that amount of time apart, builds will be put
-/// off.
-///
-/// The [directoryWatcherFactory] allows you to inject a way of creating custom
-/// `DirectoryWatcher`s. By default a normal `DirectoryWatcher` will be used.
-///
-/// The [terminateEventStream] is a stream which can send termination events.
-/// By default the [ProcessSignal.sigint] stream is used. In this mode, the
-/// first event will allow any ongoing builds to finish, and then the program
-/// will complete normally. Subsequent events are not handled (and will
-/// typically cause a shutdown).
-Future<ServeHandler> watch(List<BuilderApplication> builders,
- {bool deleteFilesByDefault,
- bool assumeTty,
- String configKey,
- PackageGraph packageGraph,
- RunnerAssetReader reader,
- RunnerAssetWriter writer,
- Resolvers resolvers,
- Level logLevel,
- void Function(LogRecord) onLog,
- Duration debounceDelay,
- DirectoryWatcher Function(String) directoryWatcherFactory,
- Stream terminateEventStream,
- bool enableLowResourcesMode,
- Set<BuildDirectory> buildDirs,
- bool outputSymlinksOnly,
- bool trackPerformance,
- bool skipBuildScriptCheck,
- bool verbose,
- bool isReleaseBuild,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- String logPerformanceDir,
- Set<BuildFilter> buildFilters}) =>
- watch_impl.watch(
- builders,
- assumeTty: assumeTty,
- deleteFilesByDefault: deleteFilesByDefault,
- configKey: configKey,
- packageGraph: packageGraph,
- reader: reader,
- writer: writer,
- resolvers: resolvers,
- logLevel: logLevel,
- onLog: onLog,
- debounceDelay: debounceDelay,
- directoryWatcherFactory: directoryWatcherFactory,
- terminateEventStream: terminateEventStream,
- enableLowResourcesMode: enableLowResourcesMode,
- buildDirs: buildDirs,
- outputSymlinksOnly: outputSymlinksOnly,
- trackPerformance: trackPerformance,
- skipBuildScriptCheck: skipBuildScriptCheck,
- verbose: verbose,
- builderConfigOverrides: builderConfigOverrides,
- isReleaseBuild: isReleaseBuild,
- logPerformanceDir: logPerformanceDir,
- buildFilters: buildFilters,
- );
diff --git a/build_runner/lib/src/generate/directory_watcher_factory.dart b/build_runner/lib/src/generate/directory_watcher_factory.dart
deleted file mode 100644
index a211528..0000000
--- a/build_runner/lib/src/generate/directory_watcher_factory.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2016, 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:watcher/watcher.dart';
-
-DirectoryWatcher defaultDirectoryWatcherFactory(String path) =>
- DirectoryWatcher(path);
-
-DirectoryWatcher pollingDirectoryWatcherFactory(String path) =>
- PollingDirectoryWatcher(path);
diff --git a/build_runner/lib/src/generate/terminator.dart b/build_runner/lib/src/generate/terminator.dart
deleted file mode 100644
index 3e44b8c..0000000
--- a/build_runner/lib/src/generate/terminator.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2017, 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';
-
-/// Fires [shouldTerminate] once a `SIGINT` is intercepted.
-///
-/// The `SIGINT` stream can optionally be replaced with another Stream in the
-/// constructor. [cancel] should be called after work is finished. If multiple
-/// events are receieved on the terminate event stream before work is finished
-/// the process will be terminated with [exit].
-class Terminator {
- /// A Future that fires when a signal has been received indicating that builds
- /// should stop.
- final Future shouldTerminate;
- final StreamSubscription _subscription;
-
- factory Terminator([Stream terminateEventStream]) {
- var shouldTerminate = Completer<void>();
- terminateEventStream ??= ProcessSignal.sigint.watch();
- var numEventsSeen = 0;
- var terminateListener = terminateEventStream.listen((_) {
- numEventsSeen++;
- if (numEventsSeen == 1) {
- shouldTerminate.complete();
- } else {
- exit(2);
- }
- });
- return Terminator._(shouldTerminate.future, terminateListener);
- }
-
- Terminator._(this.shouldTerminate, this._subscription);
-
- Future cancel() => _subscription.cancel();
-}
diff --git a/build_runner/lib/src/generate/watch_impl.dart b/build_runner/lib/src/generate/watch_impl.dart
deleted file mode 100644
index 3be7ee4..0000000
--- a/build_runner/lib/src/generate/watch_impl.dart
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright (c) 2016, 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 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_runner/src/package_graph/build_config_overrides.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:build_runner/src/watcher/change_filter.dart';
-import 'package:build_runner/src/watcher/collect_changes.dart';
-import 'package:build_runner/src/watcher/delete_writer.dart';
-import 'package:build_runner/src/watcher/graph_watcher.dart';
-import 'package:build_runner/src/watcher/node_watcher.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/generate/build_impl.dart';
-import 'package:crypto/crypto.dart';
-import 'package:logging/logging.dart';
-import 'package:pedantic/pedantic.dart';
-import 'package:stream_transform/stream_transform.dart';
-import 'package:watcher/watcher.dart';
-
-import '../logging/std_io_logging.dart';
-import '../server/server.dart';
-import 'terminator.dart';
-
-final _logger = Logger('Watch');
-
-Future<ServeHandler> watch(
- List<BuilderApplication> builders, {
- bool deleteFilesByDefault,
- bool assumeTty,
- String configKey,
- PackageGraph packageGraph,
- RunnerAssetReader reader,
- RunnerAssetWriter writer,
- Resolvers resolvers,
- Level logLevel,
- void Function(LogRecord) onLog,
- Duration debounceDelay,
- DirectoryWatcher Function(String) directoryWatcherFactory,
- Stream terminateEventStream,
- bool skipBuildScriptCheck,
- bool enableLowResourcesMode,
- Map<String, BuildConfig> overrideBuildConfig,
- Set<BuildDirectory> buildDirs,
- bool outputSymlinksOnly,
- bool trackPerformance,
- bool verbose,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- bool isReleaseBuild,
- String logPerformanceDir,
- Set<BuildFilter> buildFilters,
-}) async {
- builderConfigOverrides ??= const {};
- packageGraph ??= PackageGraph.forThisPackage();
- buildDirs ??= <BuildDirectory>{};
- buildFilters ??= <BuildFilter>{};
-
- var environment = OverrideableEnvironment(
- IOEnvironment(packageGraph,
- assumeTty: assumeTty, outputSymlinksOnly: outputSymlinksOnly),
- reader: reader,
- writer: writer,
- onLog: onLog ?? stdIOLogListener(assumeTty: assumeTty, verbose: verbose));
- var logSubscription =
- LogSubscription(environment, verbose: verbose, logLevel: logLevel);
- overrideBuildConfig ??=
- await findBuildConfigOverrides(packageGraph, configKey);
- var options = await BuildOptions.create(
- logSubscription,
- deleteFilesByDefault: deleteFilesByDefault,
- packageGraph: packageGraph,
- overrideBuildConfig: overrideBuildConfig,
- debounceDelay: debounceDelay,
- skipBuildScriptCheck: skipBuildScriptCheck,
- enableLowResourcesMode: enableLowResourcesMode,
- trackPerformance: trackPerformance,
- logPerformanceDir: logPerformanceDir,
- resolvers: resolvers,
- );
- var terminator = Terminator(terminateEventStream);
-
- var watch = _runWatch(
- options,
- environment,
- builders,
- builderConfigOverrides,
- terminator.shouldTerminate,
- directoryWatcherFactory,
- configKey,
- buildDirs
- .any((target) => target?.outputLocation?.path?.isNotEmpty ?? false),
- buildDirs,
- buildFilters,
- isReleaseMode: isReleaseBuild ?? false);
-
- unawaited(watch.buildResults.drain().then((_) async {
- await terminator.cancel();
- await options.logListener.cancel();
- }));
-
- return createServeHandler(watch);
-}
-
-/// Repeatedly run builds as files change on disk until [until] fires.
-///
-/// Sets up file watchers and collects changes then triggers new builds. When
-/// [until] fires the file watchers will be stopped and up to one additional
-/// build may run if there were pending changes.
-///
-/// The [BuildState.buildResults] stream will end after the final build has been
-/// run.
-WatchImpl _runWatch(
- BuildOptions options,
- BuildEnvironment environment,
- List<BuilderApplication> builders,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- Future until,
- DirectoryWatcher Function(String) directoryWatcherFactory,
- String configKey,
- bool willCreateOutputDirs,
- Set<BuildDirectory> buildDirs,
- Set<BuildFilter> buildFilters,
- {bool isReleaseMode = false}) =>
- WatchImpl(
- options,
- environment,
- builders,
- builderConfigOverrides,
- until,
- directoryWatcherFactory,
- configKey,
- willCreateOutputDirs,
- buildDirs,
- buildFilters,
- isReleaseMode: isReleaseMode);
-
-class WatchImpl implements BuildState {
- BuildImpl _build;
-
- AssetGraph get assetGraph => _build?.assetGraph;
-
- final _readyCompleter = Completer<void>();
- Future<void> get ready => _readyCompleter.future;
-
- final String _configKey; // may be null
-
- /// Delay to wait for more file watcher events.
- final Duration _debounceDelay;
-
- /// Injectable factory for creating directory watchers.
- final DirectoryWatcher Function(String) _directoryWatcherFactory;
-
- /// Whether or not we will be creating any output directories.
- ///
- /// If not, then we don't care about source edits that don't have outputs.
- final bool _willCreateOutputDirs;
-
- /// Should complete when we need to kill the build.
- final _terminateCompleter = Completer<Null>();
-
- /// The [PackageGraph] for the current program.
- final PackageGraph packageGraph;
-
- /// The directories to build upon file changes and where to output them.
- final Set<BuildDirectory> _buildDirs;
-
- /// Filters for specific files to build.
- final Set<BuildFilter> _buildFilters;
-
- @override
- Future<BuildResult> currentBuild;
-
- /// Pending expected delete events from the build.
- final Set<AssetId> _expectedDeletes = <AssetId>{};
-
- FinalizedReader _reader;
- FinalizedReader get reader => _reader;
-
- WatchImpl(
- BuildOptions options,
- BuildEnvironment environment,
- List<BuilderApplication> builders,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- Future until,
- this._directoryWatcherFactory,
- this._configKey,
- this._willCreateOutputDirs,
- this._buildDirs,
- this._buildFilters,
- {bool isReleaseMode = false})
- : _debounceDelay = options.debounceDelay,
- packageGraph = options.packageGraph {
- buildResults = _run(
- options, environment, builders, builderConfigOverrides, until,
- isReleaseMode: isReleaseMode)
- .asBroadcastStream();
- }
-
- @override
- Stream<BuildResult> buildResults;
-
- /// Runs a build any time relevant files change.
- ///
- /// Only one build will run at a time, and changes are batched.
- ///
- /// File watchers are scheduled synchronously.
- Stream<BuildResult> _run(
- BuildOptions options,
- BuildEnvironment environment,
- List<BuilderApplication> builders,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- Future until,
- {bool isReleaseMode = false}) {
- var watcherEnvironment = OverrideableEnvironment(environment,
- writer: OnDeleteWriter(environment.writer, _expectedDeletes.add));
- var firstBuildCompleter = Completer<BuildResult>();
- currentBuild = firstBuildCompleter.future;
- var controller = StreamController<BuildResult>();
-
- Future<BuildResult> doBuild(List<List<AssetChange>> changes) async {
- assert(_build != null);
- _logger..info('${'-' * 72}\n')..info('Starting Build\n');
- var mergedChanges = collectChanges(changes);
-
- _expectedDeletes.clear();
- if (!options.skipBuildScriptCheck) {
- if (_build.buildScriptUpdates
- .hasBeenUpdated(mergedChanges.keys.toSet())) {
- _terminateCompleter.complete();
- _logger.severe('Terminating builds due to build script update');
- return BuildResult(BuildStatus.failure, [],
- failureType: FailureType.buildScriptChanged);
- }
- }
- return _build.run(mergedChanges,
- buildDirs: _buildDirs, buildFilters: _buildFilters);
- }
-
- var terminate = Future.any([until, _terminateCompleter.future]).then((_) {
- _logger.info('Terminating. No further builds will be scheduled\n');
- });
-
- Digest originalRootPackagesDigest;
- final rootPackagesId = AssetId(packageGraph.root.name, '.packages');
-
- // Start watching files immediately, before the first build is even started.
- var graphWatcher = PackageGraphWatcher(packageGraph,
- logger: _logger,
- watch: (node) =>
- PackageNodeWatcher(node, watch: _directoryWatcherFactory));
- graphWatcher
- .watch()
- .asyncMap<AssetChange>((change) {
- // Delay any events until the first build is completed.
- if (firstBuildCompleter.isCompleted) return change;
- return firstBuildCompleter.future.then((_) => change);
- })
- .asyncMap<AssetChange>((change) {
- var id = change.id;
- assert(originalRootPackagesDigest != null);
- if (id == rootPackagesId) {
- // Kill future builds if the root packages file changes.
- return watcherEnvironment.reader
- .readAsBytes(rootPackagesId)
- .then((bytes) {
- if (md5.convert(bytes) != originalRootPackagesDigest) {
- _terminateCompleter.complete();
- _logger
- .severe('Terminating builds due to package graph update, '
- 'please restart the build.');
- }
- return change;
- });
- } else if (_isBuildYaml(id) ||
- _isConfiguredBuildYaml(id) ||
- _isPackageBuildYamlOverride(id)) {
- controller.add(BuildResult(BuildStatus.failure, [],
- failureType: FailureType.buildConfigChanged));
-
- // Kill future builds if the build.yaml files change.
- _terminateCompleter.complete();
- _logger.severe(
- 'Terminating builds due to ${id.package}:${id.path} update.');
- }
- return change;
- })
- .where((change) {
- assert(_readyCompleter.isCompleted);
- return shouldProcess(
- change,
- assetGraph,
- options,
- _willCreateOutputDirs,
- _expectedDeletes,
- );
- })
- .debounceBuffer(_debounceDelay)
- .takeUntil(terminate)
- .asyncMapBuffer((changes) => currentBuild = doBuild(changes)
- ..whenComplete(() => currentBuild = null))
- .listen((BuildResult result) {
- if (controller.isClosed) return;
- controller.add(result);
- })
- .onDone(() async {
- await currentBuild;
- await _build?.beforeExit();
- if (!controller.isClosed) await controller.close();
- _logger.info('Builds finished. Safe to exit\n');
- });
-
- // Schedule the actual first build for the future so we can return the
- // stream synchronously.
- () async {
- await logTimedAsync(_logger, 'Waiting for all file watchers to be ready',
- () => graphWatcher.ready);
- originalRootPackagesDigest = md5
- .convert(await watcherEnvironment.reader.readAsBytes(rootPackagesId));
-
- BuildResult firstBuild;
- try {
- _build = await BuildImpl.create(
- options, watcherEnvironment, builders, builderConfigOverrides,
- isReleaseBuild: isReleaseMode);
-
- firstBuild = await _build
- .run({}, buildDirs: _buildDirs, buildFilters: _buildFilters);
- } on CannotBuildException {
- _terminateCompleter.complete();
-
- firstBuild = BuildResult(BuildStatus.failure, []);
- } on BuildScriptChangedException {
- _terminateCompleter.complete();
-
- firstBuild = BuildResult(BuildStatus.failure, [],
- failureType: FailureType.buildScriptChanged);
- }
-
- _reader = _build?.finalizedReader;
- _readyCompleter.complete();
- // It is possible this is already closed if the user kills the process
- // early, which results in an exception without this check.
- if (!controller.isClosed) controller.add(firstBuild);
- firstBuildCompleter.complete(firstBuild);
- }();
-
- return controller.stream;
- }
-
- bool _isBuildYaml(AssetId id) => id.path == 'build.yaml';
- bool _isConfiguredBuildYaml(AssetId id) =>
- id.package == packageGraph.root.name &&
- id.path == 'build.$_configKey.yaml';
- bool _isPackageBuildYamlOverride(AssetId id) =>
- id.package == packageGraph.root.name &&
- id.path.contains(_packageBuildYamlRegexp);
- final _packageBuildYamlRegexp = RegExp(r'^[a-z0-9_]+\.build\.yaml$');
-}
diff --git a/build_runner/lib/src/logging/std_io_logging.dart b/build_runner/lib/src/logging/std_io_logging.dart
deleted file mode 100644
index fab916b..0000000
--- a/build_runner/lib/src/logging/std_io_logging.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:io';
-
-import 'package:io/ansi.dart';
-import 'package:logging/logging.dart';
-import 'package:stack_trace/stack_trace.dart';
-
-void Function(LogRecord) stdIOLogListener({bool assumeTty, bool verbose}) =>
- (record) => overrideAnsiOutput(assumeTty == true || ansiOutputEnabled, () {
- _stdIOLogListener(record, verbose: verbose ?? false);
- });
-
-StringBuffer colorLog(LogRecord record, {bool verbose}) {
- AnsiCode color;
- if (record.level < Level.WARNING) {
- color = cyan;
- } else if (record.level < Level.SEVERE) {
- color = yellow;
- } else {
- color = red;
- }
- final level = color.wrap('[${record.level}]');
- final eraseLine = ansiOutputEnabled && !verbose ? '\x1b[2K\r' : '';
- var lines = <Object>[
- '$eraseLine$level ${_recordHeader(record, verbose)}${record.message}'
- ];
-
- if (record.error != null) {
- lines.add(record.error);
- }
-
- if (record.stackTrace != null && verbose) {
- var trace = Trace.from(record.stackTrace).foldFrames((f) {
- return f.package == 'build_runner' || f.package == 'build';
- }, terse: true);
-
- lines.add(trace);
- }
-
- var message = StringBuffer(lines.join('\n'));
-
- // We always add an extra newline at the end of each message, so it
- // isn't multiline unless we see > 2 lines.
- var multiLine = LineSplitter.split(message.toString()).length > 2;
-
- if (record.level > Level.INFO || !ansiOutputEnabled || multiLine || verbose) {
- // Add an extra line to the output so the last line isn't written over.
- message.writeln('');
- }
- return message;
-}
-
-void _stdIOLogListener(LogRecord record, {bool verbose}) =>
- stdout.write(colorLog(record, verbose: verbose));
-
-/// Filter out the Logger names which aren't coming from specific builders and
-/// splits the header for levels >= WARNING.
-String _recordHeader(LogRecord record, bool verbose) {
- var maybeSplit = record.level >= Level.WARNING ? '\n' : '';
- return verbose || record.loggerName.contains(' ')
- ? '${record.loggerName}:$maybeSplit'
- : '';
-}
diff --git a/build_runner/lib/src/package_graph/build_config_overrides.dart b/build_runner/lib/src/package_graph/build_config_overrides.dart
deleted file mode 100644
index 8210b93..0000000
--- a/build_runner/lib/src/package_graph/build_config_overrides.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2017, 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 'package:build_config/build_config.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-final _log = Logger('BuildConfigOverrides');
-
-Future<Map<String, BuildConfig>> findBuildConfigOverrides(
- PackageGraph packageGraph, String configKey) async {
- final configs = <String, BuildConfig>{};
- final configFiles = Glob('*.build.yaml').list();
- await for (final file in configFiles) {
- if (file is File) {
- final packageName = p.basename(file.path).split('.').first;
- final packageNode = packageGraph.allPackages[packageName];
- if (packageNode == null) {
- _log.warning('A build config override is provided for $packageName but '
- 'that package does not exist. '
- 'Remove the ${p.basename(file.path)} override or add a dependency '
- 'on $packageName.');
- continue;
- }
- final yaml = file.readAsStringSync();
- final config = BuildConfig.parse(
- packageName,
- packageNode.dependencies.map((n) => n.name),
- yaml,
- configYamlPath: file.path,
- );
- configs[packageName] = config;
- }
- }
- if (configKey != null) {
- final file = File('build.$configKey.yaml');
- if (!file.existsSync()) {
- _log.warning('Cannot find build.$configKey.yaml for specified config.');
- throw CannotBuildException();
- }
- final yaml = file.readAsStringSync();
- final config = BuildConfig.parse(
- packageGraph.root.name,
- packageGraph.root.dependencies.map((n) => n.name),
- yaml,
- configYamlPath: file.path,
- );
- configs[packageGraph.root.name] = config;
- }
- return configs;
-}
diff --git a/build_runner/lib/src/server/README.md b/build_runner/lib/src/server/README.md
deleted file mode 100644
index e40bb70..0000000
--- a/build_runner/lib/src/server/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## Regenerating the graph_vis_main.dart.js{.map} files
-
-To regenerate these files, you should use the custom build script at
-`tool/build.dart`. This supports all the normal build_runner commands.
diff --git a/build_runner/lib/src/server/asset_graph_handler.dart b/build_runner/lib/src/server/asset_graph_handler.dart
deleted file mode 100644
index 78921e2..0000000
--- a/build_runner/lib/src/server/asset_graph_handler.dart
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:shelf/shelf.dart' as shelf;
-
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'path_to_asset_id.dart';
-
-/// A handler for `/$graph` requests under a specific `rootDir`.
-class AssetGraphHandler {
- final AssetReader _reader;
- final String _rootPackage;
- final AssetGraph _assetGraph;
-
- AssetGraphHandler(this._reader, this._rootPackage, this._assetGraph);
-
- /// Returns a response with the information about a specific node in the
- /// graph.
- ///
- /// For an empty path, returns the HTML page to render the graph.
- ///
- /// For queries with `q=QUERY` will look for the assetNode referenced.
- /// QUERY can be an [AssetId] or a path.
- ///
- /// [AssetId] as `package|path`
- ///
- /// path as:
- /// - `packages/<package>/<path_under_lib>`
- /// - `<path_under_root_package>`
- /// - `<path_under_rootDir>`
- ///
- /// There may be some ambiguity between paths which are under the top-level of
- /// the root package, and those which are under the rootDir. Preference is
- /// given to the asset (if it exists) which is not under the implicit
- /// `rootDir`. For instance if the request is `$graph/web/main.dart` this will
- /// prefer to serve `<package>|web/main.dart`, but if it does not exist will
- /// fall back to `<package>|web/web/main.dart`.
- FutureOr<shelf.Response> handle(shelf.Request request, String rootDir) async {
- switch (request.url.path) {
- case '':
- if (!request.url.hasQuery) {
- return shelf.Response.ok(
- await _reader.readAsString(
- AssetId('build_runner', 'lib/src/server/graph_viz.html')),
- headers: {HttpHeaders.contentTypeHeader: 'text/html'});
- }
-
- var query = request.url.queryParameters['q']?.trim();
- if (query != null && query.isNotEmpty) {
- var filter = request.url.queryParameters['f']?.trim();
- return _handleQuery(query, rootDir, filter: filter);
- }
- break;
- case 'assets.json':
- return _jsonResponse(_assetGraph.serialize());
- }
-
- return shelf.Response.notFound('Bad request: "${request.url}".');
- }
-
- Future<shelf.Response> _handleQuery(String query, String rootDir,
- {String filter}) async {
- var filterGlob = filter != null ? Glob(filter) : null;
- var pipeIndex = query.indexOf('|');
-
- AssetId assetId;
- if (pipeIndex < 0) {
- var querySplit = query.split('/');
-
- assetId = pathToAssetId(
- _rootPackage, querySplit.first, querySplit.skip(1).toList());
-
- if (!_assetGraph.contains(assetId)) {
- var secondTry = pathToAssetId(_rootPackage, rootDir, querySplit);
-
- if (!_assetGraph.contains(secondTry)) {
- return shelf.Response.notFound(
- 'Could not find asset for path "$query". Tried:\n'
- '- $assetId\n'
- '- $secondTry');
- }
- assetId = secondTry;
- }
- } else {
- assetId = AssetId.parse(query);
- if (!_assetGraph.contains(assetId)) {
- return shelf.Response.notFound(
- 'Could not find asset in build graph: $assetId');
- }
- }
- var node = _assetGraph.get(assetId);
- var currentEdge = 0;
- var nodes = [
- {'id': '${node.id}', 'label': '${node.id}'}
- ];
- var edges = <Map<String, String>>[];
- for (final output in node.outputs) {
- if (filterGlob != null && !filterGlob.matches(output.toString())) {
- continue;
- }
- edges.add(
- {'from': '${node.id}', 'to': '$output', 'id': 'e${currentEdge++}'});
- nodes.add({'id': '$output', 'label': '$output'});
- }
- if (node is NodeWithInputs) {
- for (final input in node.inputs) {
- if (filterGlob != null && !filterGlob.matches(input.toString())) {
- continue;
- }
- edges.add(
- {'from': '$input', 'to': '${node.id}', 'id': 'e${currentEdge++}'});
- nodes.add({'id': '$input', 'label': '$input'});
- }
- }
- var result = <String, dynamic>{
- 'primary': {
- 'id': '${node.id}',
- 'hidden': node is GeneratedAssetNode ? node.isHidden : null,
- 'state': node is NodeWithInputs ? '${node.state}' : null,
- 'wasOutput': node is GeneratedAssetNode ? node.wasOutput : null,
- 'isFailure': node is GeneratedAssetNode ? node.isFailure : null,
- 'phaseNumber': node is NodeWithInputs ? node.phaseNumber : null,
- 'type': node.runtimeType.toString(),
- 'glob': node is GlobAssetNode ? node.glob.pattern : null,
- 'lastKnownDigest': node.lastKnownDigest.toString(),
- },
- 'edges': edges,
- 'nodes': nodes,
- };
- return _jsonResponse(_jsonUtf8Encoder.convert(result));
- }
-}
-
-final _jsonUtf8Encoder = JsonUtf8Encoder();
-
-shelf.Response _jsonResponse(List<int> body) => shelf.Response.ok(body,
- headers: {HttpHeaders.contentTypeHeader: 'application/json'});
diff --git a/build_runner/lib/src/server/build_updates_client/module.dart b/build_runner/lib/src/server/build_updates_client/module.dart
deleted file mode 100644
index 6604f9b..0000000
--- a/build_runner/lib/src/server/build_updates_client/module.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-abstract class Library {
- Object onDestroy();
-
- bool onSelfUpdate([Object data]);
-
- bool onChildUpdate(String childId, Library child, [Object data]);
-}
-
-/// Used for representation of amd modules that wraps several dart libraries
-/// inside
-class Module {
- /// Grouped by absolute library path starting with `package:`
- final Map<String, Library> libraries;
-
- Module(this.libraries);
-
- /// Calls onDestroy on each of underlined libraries and combines returned data
- Map<String, Object> onDestroy() {
- var data = <String, Object>{};
- for (var key in libraries.keys) {
- data[key] = libraries[key].onDestroy();
- }
- return data;
- }
-
- /// Calls onSelfUpdate on each of underlined libraries, returns aggregated
- /// result as "maximum" assuming true < null < false. Stops execution on first
- /// false result
- bool onSelfUpdate(Map<String, Object> data) {
- var result = true;
- for (var key in libraries.keys) {
- var success = libraries[key].onSelfUpdate(data[key]);
- if (success == false) {
- return false;
- } else if (success == null) {
- result = success;
- }
- }
- return result;
- }
-
- /// Calls onChildUpdate on each of underlined libraries, returns aggregated
- /// result as "maximum" assuming true < null < false. Stops execution on first
- /// false result
- bool onChildUpdate(String childId, Module child, Map<String, Object> data) {
- var result = true;
- // TODO(inayd): This is a rought implementation with lots of false positive
- // reloads. In current implementation every library in parent module should
- // know how to handle each library in child module. Also [roughLibraryKeyDecode]
- // depends on unreliable implementation details. Proper implementation
- // should rely on inner graph of dependencies between libraries in module,
- // to require only parent libraries which really depend on child ones to
- // handle it's updates. See dart-lang/build#1767.
- for (var parentKey in libraries.keys) {
- for (var childKey in child.libraries.keys) {
- var success = libraries[parentKey]
- .onChildUpdate(childKey, child.libraries[childKey], data[childKey]);
- if (success == false) {
- return false;
- } else if (success == null) {
- result = success;
- }
- }
- }
- return result;
- }
-}
diff --git a/build_runner/lib/src/server/build_updates_client/reload_handler.dart b/build_runner/lib/src/server/build_updates_client/reload_handler.dart
deleted file mode 100644
index 0087931..0000000
--- a/build_runner/lib/src/server/build_updates_client/reload_handler.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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:convert';
-
-import 'reloading_manager.dart';
-
-/// Provides [listener] to handle web socket connection and reload invalidated
-/// modules using [ReloadingManager]
-class ReloadHandler {
- final String Function(String) _moduleIdByPath;
- final Map<String, String> _digests;
- final ReloadingManager _reloadingManager;
-
- ReloadHandler(this._digests, this._moduleIdByPath, this._reloadingManager);
-
- void listener(String data) async {
- var updatedAssetDigests = json.decode(data) as Map<String, dynamic>;
- var moduleIdsToReload = <String>[];
- for (var path in updatedAssetDigests.keys) {
- if (_digests[path] == updatedAssetDigests[path]) {
- continue;
- }
- var moduleId = _moduleIdByPath(path);
- if (_digests.containsKey(path) && moduleId != null) {
- moduleIdsToReload.add(moduleId);
- }
- _digests[path] = updatedAssetDigests[path] as String;
- }
- if (moduleIdsToReload.isNotEmpty) {
- _reloadingManager.updateGraph();
- await _reloadingManager.reload(moduleIdsToReload);
- }
- }
-}
diff --git a/build_runner/lib/src/server/build_updates_client/reloading_manager.dart b/build_runner/lib/src/server/build_updates_client/reloading_manager.dart
deleted file mode 100644
index 969aaee..0000000
--- a/build_runner/lib/src/server/build_updates_client/reloading_manager.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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:collection';
-
-import 'package:graphs/graphs.dart' as graphs;
-
-import 'module.dart';
-
-class HotReloadFailedException implements Exception {
- HotReloadFailedException(this._s);
-
- @override
- String toString() => "HotReloadFailedException: '$_s'";
- final String _s;
-}
-
-/// Handles reloading order and hooks invocation
-class ReloadingManager {
- final Future<Module> Function(String) _reloadModule;
- final Module Function(String) _moduleLibraries;
- final void Function() _reloadPage;
- final List<String> Function(String moduleId) _moduleParents;
- final Iterable<String> Function() _allModules;
-
- final Map<String, int> _moduleOrdering = {};
- SplayTreeSet<String> _dirtyModules;
- Completer<void> _running = Completer()..complete();
-
- int moduleTopologicalCompare(String module1, String module2) {
- var topological =
- Comparable.compare(_moduleOrdering[module2], _moduleOrdering[module1]);
- // If modules are in cycle (same strongly connected component) compare their
- // string id, to ensure total ordering for SplayTreeSet uniqueness.
- return topological != 0 ? topological : module1.compareTo(module2);
- }
-
- void updateGraph() {
- var allModules = _allModules();
- var stronglyConnectedComponents =
- graphs.stronglyConnectedComponents(allModules, _moduleParents);
- _moduleOrdering.clear();
- for (var i = 0; i < stronglyConnectedComponents.length; i++) {
- for (var module in stronglyConnectedComponents[i]) {
- _moduleOrdering[module] = i;
- }
- }
- }
-
- ReloadingManager(this._reloadModule, this._moduleLibraries, this._reloadPage,
- this._moduleParents, this._allModules) {
- _dirtyModules = SplayTreeSet(moduleTopologicalCompare);
- }
-
- Future<void> reload(List<String> modules) async {
- _dirtyModules.addAll(modules);
-
- // As function is async, it can potentially be called second time while
- // first invocation is still running. In this case just mark as dirty and
- // wait until loop from the first call will do the work
- if (!_running.isCompleted) return await _running.future;
- _running = Completer();
-
- var reloadedModules = 0;
-
- try {
- while (_dirtyModules.isNotEmpty) {
- var moduleId = _dirtyModules.first;
- _dirtyModules.remove(moduleId);
- ++reloadedModules;
-
- var existing = _moduleLibraries(moduleId);
- var data = existing.onDestroy();
-
- var newVersion = await _reloadModule(moduleId);
- var success = newVersion.onSelfUpdate(data);
- if (success == true) continue;
- if (success == false) {
- print("Module '$moduleId' is marked as unreloadable. "
- 'Firing full page reload.');
- _reloadPage();
- _running.complete();
- return;
- }
-
- var parentIds = _moduleParents(moduleId);
- if (parentIds == null || parentIds.isEmpty) {
- print("Module reloading wasn't handled by any of parents. "
- 'Firing full page reload.');
- _reloadPage();
- _running.complete();
- return;
- }
- parentIds.sort(moduleTopologicalCompare);
- for (var parentId in parentIds) {
- var parentModule = _moduleLibraries(parentId);
- success = parentModule.onChildUpdate(moduleId, newVersion, data);
- if (success == true) continue;
- if (success == false) {
- print("Module '$moduleId' is marked as unreloadable. "
- 'Firing full page reload.');
- _reloadPage();
- _running.complete();
- return;
- }
- _dirtyModules.add(parentId);
- }
- }
- print('$reloadedModules modules were hot-reloaded.');
- } on HotReloadFailedException catch (e) {
- print('Error during script reloading. Firing full page reload. $e');
- _reloadPage();
- }
- _running.complete();
- }
-}
diff --git a/build_runner/lib/src/server/path_to_asset_id.dart b/build_runner/lib/src/server/path_to_asset_id.dart
deleted file mode 100644
index 3169b0f..0000000
--- a/build_runner/lib/src/server/path_to_asset_id.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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:build/build.dart';
-import 'package:path/path.dart' as p;
-
-AssetId pathToAssetId(
- String rootPackage, String rootDir, List<String> pathSegments) {
- var packagesIndex = pathSegments.indexOf('packages');
- rootDir ??= '';
- return packagesIndex >= 0
- ? AssetId(pathSegments[packagesIndex + 1],
- p.join('lib', p.joinAll(pathSegments.sublist(packagesIndex + 2))))
- : AssetId(rootPackage, p.joinAll([rootDir].followedBy(pathSegments)));
-}
-
-/// Returns null for paths that neither a lib nor starts from a rootDir
-String assetIdToPath(AssetId assetId, String rootDir) =>
- assetId.path.startsWith('lib/')
- ? assetId.path.replaceFirst('lib/', 'packages/${assetId.package}/')
- : assetId.path.startsWith('$rootDir/')
- ? assetId.path.substring(rootDir.length + 1)
- : null;
diff --git a/build_runner/lib/src/server/server.dart b/build_runner/lib/src/server/server.dart
deleted file mode 100644
index 9c568b8..0000000
--- a/build_runner/lib/src/server/server.dart
+++ /dev/null
@@ -1,681 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:build_runner/src/entrypoint/options.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/generate/performance_tracker.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:mime/mime.dart';
-import 'package:path/path.dart' as p;
-import 'package:shelf/shelf.dart' as shelf;
-import 'package:shelf_web_socket/shelf_web_socket.dart';
-import 'package:timing/timing.dart';
-import 'package:web_socket_channel/web_socket_channel.dart';
-
-import '../generate/watch_impl.dart';
-import 'asset_graph_handler.dart';
-import 'path_to_asset_id.dart';
-
-const _performancePath = r'$perf';
-final _graphPath = r'$graph';
-final _assetsDigestPath = r'$assetDigests';
-final _buildUpdatesProtocol = r'$buildUpdates';
-final entrypointExtensionMarker = '/* ENTRYPOINT_EXTENTION_MARKER */';
-
-final _logger = Logger('Serve');
-
-enum PerfSortOrder {
- startTimeAsc,
- startTimeDesc,
- stopTimeAsc,
- stopTimeDesc,
- durationAsc,
- durationDesc,
- innerDurationAsc,
- innerDurationDesc
-}
-
-ServeHandler createServeHandler(WatchImpl watch) {
- var rootPackage = watch.packageGraph.root.name;
- var assetGraphHanderCompleter = Completer<AssetGraphHandler>();
- var assetHandlerCompleter = Completer<AssetHandler>();
- watch.ready.then((_) async {
- assetHandlerCompleter.complete(AssetHandler(watch.reader, rootPackage));
- assetGraphHanderCompleter.complete(
- AssetGraphHandler(watch.reader, rootPackage, watch.assetGraph));
- });
- return ServeHandler._(watch, assetHandlerCompleter.future,
- assetGraphHanderCompleter.future, rootPackage);
-}
-
-class ServeHandler implements BuildState {
- final WatchImpl _state;
- BuildResult _lastBuildResult;
- final String _rootPackage;
-
- final Future<AssetHandler> _assetHandler;
- final Future<AssetGraphHandler> _assetGraphHandler;
-
- final BuildUpdatesWebSocketHandler _webSocketHandler;
-
- ServeHandler._(this._state, this._assetHandler, this._assetGraphHandler,
- this._rootPackage)
- : _webSocketHandler = BuildUpdatesWebSocketHandler(_state) {
- _state.buildResults.listen((result) {
- _lastBuildResult = result;
- _webSocketHandler.emitUpdateMessage(result);
- }).onDone(_webSocketHandler.close);
- }
-
- @override
- Future<BuildResult> get currentBuild => _state.currentBuild;
-
- @override
- Stream<BuildResult> get buildResults => _state.buildResults;
-
- shelf.Handler handlerFor(String rootDir,
- {bool logRequests, BuildUpdatesOption buildUpdates}) {
- buildUpdates ??= BuildUpdatesOption.none;
- logRequests ??= false;
- if (p.url.split(rootDir).length != 1 || rootDir == '.') {
- throw ArgumentError.value(
- rootDir,
- 'directory',
- 'Only top level directories such as `web` or `test` can be served, got',
- );
- }
- _state.currentBuild.then((_) {
- // If the first build fails with a handled exception, we might not have
- // an asset graph and can't do this check.
- if (_state.assetGraph == null) return;
- _warnForEmptyDirectory(rootDir);
- });
- var cascade = shelf.Cascade();
- if (buildUpdates != BuildUpdatesOption.none) {
- cascade = cascade.add(_webSocketHandler.createHandlerByRootDir(rootDir));
- }
- cascade =
- cascade.add(_blockOnCurrentBuild).add((shelf.Request request) async {
- if (request.url.path == _performancePath) {
- return _performanceHandler(request);
- }
- if (request.url.path == _assetsDigestPath) {
- return _assetsDigestHandler(request, rootDir);
- }
- if (request.url.path.startsWith(_graphPath)) {
- var graphHandler = await _assetGraphHandler;
- return await graphHandler.handle(
- request.change(path: _graphPath), rootDir);
- }
- var assetHandler = await _assetHandler;
- return assetHandler.handle(request, rootDir: rootDir);
- });
- var pipeline = shelf.Pipeline();
- if (logRequests) {
- pipeline = pipeline.addMiddleware(_logRequests);
- }
- switch (buildUpdates) {
- case BuildUpdatesOption.liveReload:
- pipeline = pipeline.addMiddleware(_injectLiveReloadClientCode);
- break;
- case BuildUpdatesOption.hotReload:
- pipeline = pipeline.addMiddleware(_injectHotReloadClientCode);
- break;
- case BuildUpdatesOption.none:
- break;
- }
- return pipeline.addHandler(cascade.handler);
- }
-
- Future<shelf.Response> _blockOnCurrentBuild(void _) async {
- await currentBuild;
- return shelf.Response.notFound('');
- }
-
- shelf.Response _performanceHandler(shelf.Request request) {
- var hideSkipped = false;
- var detailedSlices = false;
- var slicesResolution = 5;
- var sortOrder = PerfSortOrder.startTimeAsc;
- var filter = request.url.queryParameters['filter'] ?? '';
- if (request.url.queryParameters['hideSkipped']?.toLowerCase() == 'true') {
- hideSkipped = true;
- }
- if (request.url.queryParameters['detailedSlices']?.toLowerCase() ==
- 'true') {
- detailedSlices = true;
- }
- if (request.url.queryParameters.containsKey('slicesResolution')) {
- slicesResolution =
- int.parse(request.url.queryParameters['slicesResolution']);
- }
- if (request.url.queryParameters.containsKey('sortOrder')) {
- sortOrder = PerfSortOrder
- .values[int.parse(request.url.queryParameters['sortOrder'])];
- }
- return shelf.Response.ok(
- _renderPerformance(_lastBuildResult.performance, hideSkipped,
- detailedSlices, slicesResolution, sortOrder, filter),
- headers: {HttpHeaders.contentTypeHeader: 'text/html'});
- }
-
- Future<shelf.Response> _assetsDigestHandler(
- shelf.Request request, String rootDir) async {
- var assertPathList =
- (jsonDecode(await request.readAsString()) as List).cast<String>();
- var rootPackage = _state.packageGraph.root.name;
- var results = <String, String>{};
- for (final path in assertPathList) {
- try {
- var assetId = pathToAssetId(rootPackage, rootDir, p.url.split(path));
- var digest = await _state.reader.digest(assetId);
- results[path] = digest.toString();
- } on AssetNotFoundException {
- results.remove(path);
- }
- }
- return shelf.Response.ok(jsonEncode(results),
- headers: {HttpHeaders.contentTypeHeader: 'application/json'});
- }
-
- void _warnForEmptyDirectory(String rootDir) {
- if (!_state.assetGraph
- .packageNodes(_rootPackage)
- .any((n) => n.id.path.startsWith('$rootDir/'))) {
- _logger.warning('Requested a server for `$rootDir` but this directory '
- 'has no assets in the build. You may need to add some sources or '
- 'include this directory in some target in your `build.yaml`');
- }
- }
-}
-
-/// Class that manages web socket connection handler to inform clients about
-/// build updates
-class BuildUpdatesWebSocketHandler {
- final connectionsByRootDir = <String, List<WebSocketChannel>>{};
- final shelf.Handler Function(Function, {Iterable<String> protocols})
- _handlerFactory;
- final _internalHandlers = <String, shelf.Handler>{};
- final WatchImpl _state;
-
- BuildUpdatesWebSocketHandler(this._state,
- [this._handlerFactory = webSocketHandler]);
-
- shelf.Handler createHandlerByRootDir(String rootDir) {
- if (!_internalHandlers.containsKey(rootDir)) {
- var closureForRootDir = (WebSocketChannel webSocket, String protocol) =>
- _handleConnection(webSocket, protocol, rootDir);
- _internalHandlers[rootDir] = _handlerFactory(closureForRootDir,
- protocols: [_buildUpdatesProtocol]);
- }
- return _internalHandlers[rootDir];
- }
-
- Future emitUpdateMessage(BuildResult buildResult) async {
- if (buildResult.status != BuildStatus.success) return;
- var digests = <AssetId, String>{};
- for (var assetId in buildResult.outputs) {
- var digest = await _state.reader.digest(assetId);
- digests[assetId] = digest.toString();
- }
- for (var rootDir in connectionsByRootDir.keys) {
- var resultMap = <String, String>{};
- for (var assetId in digests.keys) {
- var path = assetIdToPath(assetId, rootDir);
- if (path != null) {
- resultMap[path] = digests[assetId];
- }
- }
- for (var connection in connectionsByRootDir[rootDir]) {
- connection.sink.add(jsonEncode(resultMap));
- }
- }
- }
-
- void _handleConnection(
- WebSocketChannel webSocket, String protocol, String rootDir) async {
- if (!connectionsByRootDir.containsKey(rootDir)) {
- connectionsByRootDir[rootDir] = [];
- }
- connectionsByRootDir[rootDir].add(webSocket);
- await webSocket.stream.drain();
- connectionsByRootDir[rootDir].remove(webSocket);
- if (connectionsByRootDir[rootDir].isEmpty) {
- connectionsByRootDir.remove(rootDir);
- }
- }
-
- Future<void> close() {
- return Future.wait(connectionsByRootDir.values
- .expand((x) => x)
- .map((connection) => connection.sink.close()));
- }
-}
-
-shelf.Handler Function(shelf.Handler) _injectBuildUpdatesClientCode(
- String scriptName) =>
- (innerHandler) {
- return (shelf.Request request) async {
- if (!request.url.path.endsWith('.js')) {
- return innerHandler(request);
- }
- var response = await innerHandler(request);
- // TODO: Find a way how to check and/or modify body without reading it
- // whole.
- var body = await response.readAsString();
- if (body.startsWith(entrypointExtensionMarker)) {
- body += _buildUpdatesInjectedJS(scriptName);
- var originalEtag = response.headers[HttpHeaders.etagHeader];
- if (originalEtag != null) {
- var newEtag = base64.encode(md5.convert(body.codeUnits).bytes);
- var newHeaders = Map.of(response.headers);
- newHeaders[HttpHeaders.etagHeader] = newEtag;
-
- if (request.headers[HttpHeaders.ifNoneMatchHeader] == newEtag) {
- return shelf.Response.notModified(headers: newHeaders);
- }
-
- response = response.change(headers: newHeaders);
- }
- }
- return response.change(body: body);
- };
- };
-
-final _injectHotReloadClientCode =
- _injectBuildUpdatesClientCode('hot_reload_client.dart');
-
-final _injectLiveReloadClientCode =
- _injectBuildUpdatesClientCode('live_reload_client');
-
-/// Hot-/live- reload config
-///
-/// Listen WebSocket for updates in build results
-String _buildUpdatesInjectedJS(String scriptName) => '''\n
-// Injected by build_runner for build updates support
-window.\$dartLoader.forceLoadModule('packages/build_runner/src/server/build_updates_client/$scriptName');
-''';
-
-class AssetHandler {
- final FinalizedReader _reader;
- final String _rootPackage;
-
- final _typeResolver = MimeTypeResolver();
-
- AssetHandler(this._reader, this._rootPackage);
-
- Future<shelf.Response> handle(shelf.Request request, {String rootDir}) =>
- (request.url.path.endsWith('/') || request.url.path.isEmpty)
- ? _handle(
- request.headers,
- pathToAssetId(
- _rootPackage,
- rootDir,
- request.url.pathSegments
- .followedBy(const ['index.html']).toList()),
- fallbackToDirectoryList: true)
- : _handle(request.headers,
- pathToAssetId(_rootPackage, rootDir, request.url.pathSegments));
-
- Future<shelf.Response> _handle(
- Map<String, String> requestHeaders, AssetId assetId,
- {bool fallbackToDirectoryList = false}) async {
- try {
- if (!await _reader.canRead(assetId)) {
- var reason = await _reader.unreadableReason(assetId);
- switch (reason) {
- case UnreadableReason.failed:
- return shelf.Response.internalServerError(
- body: 'Build failed for $assetId');
- case UnreadableReason.notOutput:
- return shelf.Response.notFound('$assetId was not output');
- case UnreadableReason.notFound:
- if (fallbackToDirectoryList) {
- return shelf.Response.notFound(await _findDirectoryList(assetId));
- }
- return shelf.Response.notFound('Not Found');
- default:
- return shelf.Response.notFound('Not Found');
- }
- }
- } on ArgumentError catch (_) {
- return shelf.Response.notFound('Not Found');
- }
-
- var etag = base64.encode((await _reader.digest(assetId)).bytes);
- var contentType = _typeResolver.lookup(assetId.path);
- if (contentType == 'text/x-dart') contentType += '; charset=utf-8';
- var headers = {
- HttpHeaders.contentTypeHeader: contentType,
- HttpHeaders.etagHeader: etag,
- // We always want this revalidated, which requires specifying both
- // max-age=0 and must-revalidate.
- //
- // See spec https://goo.gl/Lhvttg for more info about this header.
- HttpHeaders.cacheControlHeader: 'max-age=0, must-revalidate',
- };
-
- if (requestHeaders[HttpHeaders.ifNoneMatchHeader] == etag) {
- // This behavior is still useful for cases where a file is hit
- // without a cache-busting query string.
- return shelf.Response.notModified(headers: headers);
- }
-
- var bytes = await _reader.readAsBytes(assetId);
- headers[HttpHeaders.contentLengthHeader] = '${bytes.length}';
- return shelf.Response.ok(bytes, headers: headers);
- }
-
- Future<String> _findDirectoryList(AssetId from) async {
- var directoryPath = p.url.dirname(from.path);
- var glob = p.url.join(directoryPath, '*');
- var result =
- await _reader.findAssets(Glob(glob)).map((a) => a.path).toList();
- var message = StringBuffer('Could not find ${from.path}');
- if (result.isEmpty) {
- message.write(' or any files in $directoryPath. ');
- } else {
- message
- ..write('. $directoryPath contains:')
- ..writeAll(result, '\n')
- ..writeln();
- }
- message
- .write(' See https://github.com/dart-lang/build/blob/master/docs/faq.md'
- '#why-cant-i-see-a-file-i-know-exists');
- return '$message';
- }
-}
-
-String _renderPerformance(
- BuildPerformance performance,
- bool hideSkipped,
- bool detailedSlices,
- int slicesResolution,
- PerfSortOrder sortOrder,
- String filter) {
- try {
- var rows = StringBuffer();
- final resolution = Duration(milliseconds: slicesResolution);
- var count = 0,
- maxSlices = 1,
- max = 0,
- min = performance.stopTime.millisecondsSinceEpoch -
- performance.startTime.millisecondsSinceEpoch;
-
- void writeRow(BuilderActionPerformance action,
- BuilderActionStagePerformance stage, TimeSlice slice) {
- var actionKey = '${action.builderKey}:${action.primaryInput}';
- var tooltip = '<div class=perf-tooltip>'
- '<p><b>Builder:</b> ${action.builderKey}</p>'
- '<p><b>Input:</b> ${action.primaryInput}</p>'
- '<p><b>Stage:</b> ${stage.label}</p>'
- '<p><b>Stage time:</b> '
- '${stage.startTime.difference(performance.startTime).inMilliseconds / 1000}s - '
- '${stage.stopTime.difference(performance.startTime).inMilliseconds / 1000}s</p>'
- '<p><b>Stage real duration:</b> ${stage.duration.inMilliseconds / 1000} seconds</p>'
- '<p><b>Stage user duration:</b> ${stage.innerDuration.inMilliseconds / 1000} seconds</p>';
- if (slice != stage) {
- tooltip += '<p><b>Slice time:</b> '
- '${slice.startTime.difference(performance.startTime).inMilliseconds / 1000}s - '
- '${slice.stopTime.difference(performance.startTime).inMilliseconds / 1000}s</p>'
- '<p><b>Slice duration:</b> ${slice.duration.inMilliseconds / 1000} seconds</p>';
- }
- tooltip += '</div>';
- var start = slice.startTime.millisecondsSinceEpoch -
- performance.startTime.millisecondsSinceEpoch;
- var end = slice.stopTime.millisecondsSinceEpoch -
- performance.startTime.millisecondsSinceEpoch;
-
- if (min > start) min = start;
- if (max < end) max = end;
-
- rows.writeln(
- ' ["$actionKey", "${stage.label}", "$tooltip", $start, $end],');
- ++count;
- }
-
- final filterRegex = filter.isNotEmpty ? RegExp(filter) : null;
-
- final actions = performance.actions
- .where((action) =>
- !hideSkipped ||
- action.stages.any((stage) => stage.label == 'Build'))
- .where((action) =>
- filterRegex == null ||
- filterRegex.hasMatch('${action.builderKey}:${action.primaryInput}'))
- .toList();
-
- int Function(BuilderActionPerformance, BuilderActionPerformance) comparator;
- switch (sortOrder) {
- case PerfSortOrder.startTimeAsc:
- comparator = (a1, a2) => a1.startTime.compareTo(a2.startTime);
- break;
- case PerfSortOrder.startTimeDesc:
- comparator = (a1, a2) => a2.startTime.compareTo(a1.startTime);
- break;
- case PerfSortOrder.stopTimeAsc:
- comparator = (a1, a2) => a1.stopTime.compareTo(a2.stopTime);
- break;
- case PerfSortOrder.stopTimeDesc:
- comparator = (a1, a2) => a2.stopTime.compareTo(a1.stopTime);
- break;
- case PerfSortOrder.durationAsc:
- comparator = (a1, a2) => a1.duration.compareTo(a2.duration);
- break;
- case PerfSortOrder.durationDesc:
- comparator = (a1, a2) => a2.duration.compareTo(a1.duration);
- break;
- case PerfSortOrder.innerDurationAsc:
- comparator = (a1, a2) => a1.innerDuration.compareTo(a2.innerDuration);
- break;
- case PerfSortOrder.innerDurationDesc:
- comparator = (a1, a2) => a2.innerDuration.compareTo(a1.innerDuration);
- break;
- }
- actions.sort(comparator);
-
- for (var action in actions) {
- if (hideSkipped &&
- !action.stages.any((stage) => stage.label == 'Build')) {
- continue;
- }
- for (var stage in action.stages) {
- if (!detailedSlices) {
- writeRow(action, stage, stage);
- continue;
- }
- var slices = stage.slices.fold<List<TimeSlice>>([], (list, slice) {
- if (list.isNotEmpty &&
- slice.startTime.difference(list.last.stopTime) < resolution) {
- // concat with previous if gap less than resolution
- list.last = TimeSlice(list.last.startTime, slice.stopTime);
- } else {
- if (list.length > 1 && list.last.duration < resolution) {
- // remove previous if its duration less than resolution
- list.last = slice;
- } else {
- list.add(slice);
- }
- }
- return list;
- });
- if (slices.isNotEmpty) {
- for (var slice in slices) {
- writeRow(action, stage, slice);
- }
- } else {
- writeRow(action, stage, stage);
- }
- if (maxSlices < slices.length) maxSlices = slices.length;
- }
- }
- if (max - min < 1000) {
- rows.writeln(' ['
- '"https://github.com/google/google-visualization-issues/issues/2269"'
- ', "", "", $min, ${min + 1000}]');
- }
- return '''
- <html>
- <head>
- <script src="https://www.gstatic.com/charts/loader.js"></script>
- <script>
- google.charts.load('current', {'packages':['timeline']});
- google.charts.setOnLoadCallback(drawChart);
- function drawChart() {
- var container = document.getElementById('timeline');
- var chart = new google.visualization.Timeline(container);
- var dataTable = new google.visualization.DataTable();
-
- dataTable.addColumn({ type: 'string', id: 'ActionKey' });
- dataTable.addColumn({ type: 'string', id: 'Stage' });
- dataTable.addColumn({ type: 'string', role: 'tooltip', p: { html: true } });
- dataTable.addColumn({ type: 'number', id: 'Start' });
- dataTable.addColumn({ type: 'number', id: 'End' });
- dataTable.addRows([
- $rows
- ]);
-
- console.log('rendering', $count, 'blocks, max', $maxSlices,
- 'slices in stage, resolution', $slicesResolution, 'ms');
- var options = {
- tooltip: { isHtml: true }
- };
- var statusText = document.getElementById('status');
- var timeoutId;
- var updateFunc = function () {
- if (timeoutId) {
- // don't schedule more than one at a time
- return;
- }
- statusText.innerText = 'Drawing table...';
- console.time('draw-time');
-
- timeoutId = setTimeout(function () {
- chart.draw(dataTable, options);
- console.timeEnd('draw-time');
- statusText.innerText = '';
- timeoutId = null;
- });
- };
-
- updateFunc();
-
- window.addEventListener('resize', updateFunc);
- }
- </script>
- <style>
- html, body {
- width: 100%;
- height: 100%;
- margin: 0;
- }
-
- body {
- display: flex;
- flex-direction: column;
- }
-
- #timeline {
- display: flex;
- flex-direction: row;
- flex: 1;
- }
- .controls-header p {
- display: inline-block;
- margin: 0.5em;
- }
- .perf-tooltip {
- margin: 0.5em;
- }
- </style>
- </head>
- <body>
- <form class="controls-header" action="/$_performancePath" onchange="this.submit()">
- <p><label><input type="checkbox" name="hideSkipped" value="true" ${hideSkipped ? 'checked' : ''}> Hide Skipped Actions</label></p>
- <p><label><input type="checkbox" name="detailedSlices" value="true" ${detailedSlices ? 'checked' : ''}> Show Async Slices</label></p>
- <p>Sort by: <select name="sortOrder">
- <option value="0" ${sortOrder.index == 0 ? 'selected' : ''}>Start Time Asc</option>
- <option value="1" ${sortOrder.index == 1 ? 'selected' : ''}>Start Time Desc</option>
- <option value="2" ${sortOrder.index == 2 ? 'selected' : ''}>Stop Time Asc</option>
- <option value="3" ${sortOrder.index == 3 ? 'selected' : ''}>Stop Time Desc</option>
- <option value="5" ${sortOrder.index == 4 ? 'selected' : ''}>Real Duration Asc</option>
- <option value="5" ${sortOrder.index == 5 ? 'selected' : ''}>Real Duration Desc</option>
- <option value="6" ${sortOrder.index == 6 ? 'selected' : ''}>User Duration Asc</option>
- <option value="7" ${sortOrder.index == 7 ? 'selected' : ''}>User Duration Desc</option>
- </select></p>
- <p>Slices Resolution: <select name="slicesResolution">
- <option value="0" ${slicesResolution == 0 ? 'selected' : ''}>0</option>
- <option value="1" ${slicesResolution == 1 ? 'selected' : ''}>1</option>
- <option value="3" ${slicesResolution == 3 ? 'selected' : ''}>3</option>
- <option value="5" ${slicesResolution == 5 ? 'selected' : ''}>5</option>
- <option value="10" ${slicesResolution == 10 ? 'selected' : ''}>10</option>
- <option value="15" ${slicesResolution == 15 ? 'selected' : ''}>15</option>
- <option value="20" ${slicesResolution == 20 ? 'selected' : ''}>20</option>
- <option value="25" ${slicesResolution == 25 ? 'selected' : ''}>25</option>
- </select></p>
- <p>Filter (RegExp): <input type="text" name="filter" value="$filter"></p>
- <p id="status"></p>
- </form>
- <div id="timeline"></div>
- </body>
- </html>
- ''';
- } on UnimplementedError catch (_) {
- return _enablePerformanceTracking;
- } on UnsupportedError catch (_) {
- return _enablePerformanceTracking;
- }
-}
-
-final _enablePerformanceTracking = '''
-<html>
- <body>
- <p>
- Performance information not available, you must pass the
- `--track-performance` command line arg to enable performance tracking.
- </p>
- <body>
-</html>
-''';
-
-/// [shelf.Middleware] that logs all requests, inspired by [shelf.logRequests].
-shelf.Handler _logRequests(shelf.Handler innerHandler) {
- return (shelf.Request request) {
- var startTime = DateTime.now();
- var watch = Stopwatch()..start();
-
- return Future.sync(() => innerHandler(request)).then((response) {
- var logFn = response.statusCode >= 500 ? _logger.warning : _logger.info;
- var msg = _getMessage(startTime, response.statusCode,
- request.requestedUri, request.method, watch.elapsed);
- logFn(msg);
- return response;
- }, onError: (dynamic error, StackTrace stackTrace) {
- if (error is shelf.HijackException) throw error;
- var msg = _getMessage(
- startTime, 500, request.requestedUri, request.method, watch.elapsed);
- _logger.severe('$msg\r\n$error\r\n$stackTrace', true);
- throw error;
- });
- };
-}
-
-String _getMessage(DateTime requestTime, int statusCode, Uri requestedUri,
- String method, Duration elapsedTime) {
- return '${requestTime.toIso8601String()} '
- '${humanReadable(elapsedTime)} '
- '$method [$statusCode] '
- '${requestedUri.path}${_formatQuery(requestedUri.query)}\r\n';
-}
-
-String _formatQuery(String query) {
- return query == '' ? '' : '?$query';
-}
diff --git a/build_runner/lib/src/watcher/asset_change.dart b/build_runner/lib/src/watcher/asset_change.dart
deleted file mode 100644
index 7796ede..0000000
--- a/build_runner/lib/src/watcher/asset_change.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2017, 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:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:watcher/watcher.dart';
-
-import 'package:build_runner_core/build_runner_core.dart';
-
-/// Represents an [id] that was modified on disk as a result of [type].
-class AssetChange {
- /// Asset that was changed.
- final AssetId id;
-
- /// What caused the asset to be detected as changed.
- final ChangeType type;
-
- const AssetChange(this.id, this.type);
-
- /// Creates a new change record in [package] from an existing watcher [event].
- factory AssetChange.fromEvent(PackageNode package, WatchEvent event) {
- return AssetChange(
- AssetId(
- package.name,
- _normalizeRelativePath(package, event),
- ),
- event.type,
- );
- }
-
- static String _normalizeRelativePath(PackageNode package, WatchEvent event) {
- final pkgPath = package.path;
- var absoluteEventPath =
- p.isAbsolute(event.path) ? event.path : p.absolute(event.path);
- if (!p.isWithin(pkgPath, absoluteEventPath)) {
- throw ArgumentError('"$absoluteEventPath" is not in "$pkgPath".');
- }
- return p.relative(absoluteEventPath, from: pkgPath);
- }
-
- @override
- int get hashCode => id.hashCode ^ type.hashCode;
-
- @override
- bool operator ==(Object other) =>
- other is AssetChange && other.id == id && other.type == type;
-
- @override
- String toString() => 'AssetChange {asset: $id, type: $type}';
-}
diff --git a/build_runner/lib/src/watcher/change_filter.dart b/build_runner/lib/src/watcher/change_filter.dart
deleted file mode 100644
index 3da8192..0000000
--- a/build_runner/lib/src/watcher/change_filter.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, 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:build/build.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/asset_graph/graph.dart';
-import 'package:build_runner_core/src/asset_graph/node.dart';
-import 'package:watcher/watcher.dart';
-
-/// Returns if a given asset change should be considered for building.
-bool shouldProcess(
- AssetChange change,
- AssetGraph assetGraph,
- BuildOptions buildOptions,
- bool willCreateOutputDir,
- Set<AssetId> expectedDeletes,
-) {
- if (_isCacheFile(change) && !assetGraph.contains(change.id)) return false;
- var node = assetGraph.get(change.id);
- if (node != null) {
- if (!willCreateOutputDir && !node.isInteresting) return false;
- if (_isAddOrEditOnGeneratedFile(node, change.type)) return false;
- } else {
- if (change.type != ChangeType.ADD) return false;
- if (!buildOptions.targetGraph.anyMatchesAsset(change.id)) return false;
- }
- if (_isExpectedDelete(change, expectedDeletes)) return false;
- return true;
-}
-
-bool _isAddOrEditOnGeneratedFile(AssetNode node, ChangeType changeType) =>
- node.isGenerated && changeType != ChangeType.REMOVE;
-
-bool _isCacheFile(AssetChange change) => change.id.path.startsWith(cacheDir);
-
-bool _isExpectedDelete(AssetChange change, Set<AssetId> expectedDeletes) =>
- expectedDeletes.remove(change.id);
diff --git a/build_runner/lib/src/watcher/collect_changes.dart b/build_runner/lib/src/watcher/collect_changes.dart
deleted file mode 100644
index eb6b8d8..0000000
--- a/build_runner/lib/src/watcher/collect_changes.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2019, 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:build/build.dart';
-import 'package:build_runner/src/watcher/asset_change.dart';
-import 'package:watcher/watcher.dart';
-
-/// Merges [AssetChange] events.
-///
-/// For example, if an asset was added then immediately deleted, no event will
-/// be recorded for the given asset.
-Map<AssetId, ChangeType> collectChanges(List<List<AssetChange>> changes) {
- var changeMap = <AssetId, ChangeType>{};
- for (var change in changes.expand((l) => l)) {
- var originalChangeType = changeMap[change.id];
- if (originalChangeType != null) {
- switch (originalChangeType) {
- case ChangeType.ADD:
- if (change.type == ChangeType.REMOVE) {
- // ADD followed by REMOVE, just remove the change.
- changeMap.remove(change.id);
- }
- break;
- case ChangeType.REMOVE:
- if (change.type == ChangeType.ADD) {
- // REMOVE followed by ADD, convert to a MODIFY
- changeMap[change.id] = ChangeType.MODIFY;
- } else if (change.type == ChangeType.MODIFY) {
- // REMOVE followed by MODIFY isn't sensible, just throw.
- throw StateError(
- 'Internal error, got REMOVE event followed by MODIFY event for '
- '${change.id}.');
- }
- break;
- case ChangeType.MODIFY:
- if (change.type == ChangeType.REMOVE) {
- // MODIFY followed by REMOVE, convert to REMOVE
- changeMap[change.id] = change.type;
- } else if (change.type == ChangeType.ADD) {
- // MODIFY followed by ADD isn't sensible, just throw.
- throw StateError(
- 'Internal error, got MODIFY event followed by ADD event for '
- '${change.id}.');
- }
- break;
- }
- } else {
- changeMap[change.id] = change.type;
- }
- }
- return changeMap;
-}
diff --git a/build_runner/lib/src/watcher/delete_writer.dart b/build_runner/lib/src/watcher/delete_writer.dart
deleted file mode 100644
index e8092f5..0000000
--- a/build_runner/lib/src/watcher/delete_writer.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2019, 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:convert';
-
-import 'package:build/build.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-
-/// A [RunnerAssetWriter] that forwards delete events to [_onDelete];
-class OnDeleteWriter implements RunnerAssetWriter {
- final RunnerAssetWriter _writer;
- final void Function(AssetId id) _onDelete;
-
- OnDeleteWriter(this._writer, this._onDelete);
-
- @override
- Future delete(AssetId id) {
- _onDelete(id);
- return _writer.delete(id);
- }
-
- @override
- Future writeAsBytes(AssetId id, List<int> bytes) =>
- _writer.writeAsBytes(id, bytes);
-
- @override
- Future writeAsString(AssetId id, String contents,
- {Encoding encoding = utf8}) =>
- _writer.writeAsString(id, contents, encoding: encoding);
-}
diff --git a/build_runner/lib/src/watcher/graph_watcher.dart b/build_runner/lib/src/watcher/graph_watcher.dart
deleted file mode 100644
index 816d1dd..0000000
--- a/build_runner/lib/src/watcher/graph_watcher.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2017, 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 'package:async/async.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:logging/logging.dart';
-
-import 'asset_change.dart';
-import 'node_watcher.dart';
-
-PackageNodeWatcher _default(PackageNode node) => PackageNodeWatcher(node);
-
-/// Allows watching an entire graph of packages to schedule rebuilds.
-class PackageGraphWatcher {
- // TODO: Consider pulling logging out and providing hooks instead.
- final Logger _logger;
- final PackageNodeWatcher Function(PackageNode) _strategy;
- final PackageGraph _graph;
-
- final _readyCompleter = Completer<void>();
- Future<void> get ready => _readyCompleter.future;
-
- bool _isWatching = false;
-
- /// Creates a new watcher for a [PackageGraph].
- ///
- /// May optionally specify a [watch] strategy, otherwise will attempt a
- /// reasonable default based on the current platform.
- PackageGraphWatcher(
- this._graph, {
- Logger logger,
- PackageNodeWatcher Function(PackageNode node) watch,
- }) : _logger = logger ?? Logger('build_runner'),
- _strategy = watch ?? _default;
-
- /// Returns a stream of records for assets that changed in the package graph.
- Stream<AssetChange> watch() {
- assert(!_isWatching);
- _isWatching = true;
- return LazyStream(
- () => logTimedSync(_logger, 'Setting up file watchers', _watch));
- }
-
- Stream<AssetChange> _watch() {
- final allWatchers = _graph.allPackages.values
- .where((node) => node.dependencyType == DependencyType.path)
- .map(_strategy)
- .toList();
- final filteredEvents = allWatchers
- .map((w) => w
- .watch()
- .where(_nestedPathFilter(w.node))
- .handleError((dynamic e, StackTrace s) {
- _logger.severe(
- 'Error from directory watcher for package:${w.node.name}\n\n'
- 'If you see this consistently then it is recommended that '
- 'you enable the polling file watcher with '
- '--use-polling-watcher.');
- throw e;
- }))
- .toList();
- // Asynchronously complete the `_readyCompleter` once all the watchers
- // are done.
- () async {
- await Future.wait(
- allWatchers.map((nodeWatcher) => nodeWatcher.watcher.ready));
- _readyCompleter.complete();
- }();
- return StreamGroup.merge(filteredEvents);
- }
-
- bool Function(AssetChange) _nestedPathFilter(PackageNode rootNode) {
- final ignorePaths = _nestedPaths(rootNode);
- return (change) => !ignorePaths.any(change.id.path.startsWith);
- }
-
- // Returns a set of all package paths that are "nested" within a node.
- //
- // This allows the watcher to optimize and avoid duplicate events.
- List<String> _nestedPaths(PackageNode rootNode) {
- return _graph.allPackages.values
- .where((node) {
- return node.path.length > rootNode.path.length &&
- node.path.startsWith(rootNode.path);
- })
- .map((node) =>
- node.path.substring(rootNode.path.length + 1) +
- Platform.pathSeparator)
- .toList();
- }
-}
diff --git a/build_runner/lib/src/watcher/node_watcher.dart b/build_runner/lib/src/watcher/node_watcher.dart
deleted file mode 100644
index ebfd119..0000000
--- a/build_runner/lib/src/watcher/node_watcher.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2017, 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 'package:build_runner_core/build_runner_core.dart';
-import 'package:watcher/watcher.dart';
-
-import 'asset_change.dart';
-
-Watcher _default(String path) => Watcher(path);
-
-/// Allows watching significant files and directories in a given package.
-class PackageNodeWatcher {
- final Watcher Function(String) _strategy;
- final PackageNode node;
-
- /// The actual watcher instance.
- Watcher _watcher;
- Watcher get watcher => _watcher;
-
- /// Creates a new watcher for a [PackageNode].
- ///
- /// May optionally specify a [watch] strategy, otherwise will attempt a
- /// reasonable default based on the current platform and the type of path
- /// (i.e. a file versus directory).
- PackageNodeWatcher(
- this.node, {
- Watcher Function(String path) watch,
- }) : _strategy = watch ?? _default;
-
- /// Returns a stream of records for assets that change recursively.
- Stream<AssetChange> watch() {
- assert(_watcher == null);
- _watcher = _strategy(node.path);
- final events = _watcher.events;
- return events.map((e) => AssetChange.fromEvent(node, e));
- }
-}
diff --git a/build_runner/mono_pkg.yaml b/build_runner/mono_pkg.yaml
deleted file mode 100644
index f61139b..0000000
--- a/build_runner/mono_pkg.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - unit_test:
- - test: -x integration
- - e2e_test:
- - test: -t integration --total-shards 5 --shard-index 0
- - test: -t integration --total-shards 5 --shard-index 1
- - test: -t integration --total-shards 5 --shard-index 2
- - test: -t integration --total-shards 5 --shard-index 3
- - test: -t integration --total-shards 5 --shard-index 4
diff --git a/build_runner/pubspec.yaml b/build_runner/pubspec.yaml
deleted file mode 100644
index 9429017..0000000
--- a/build_runner/pubspec.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: build_runner
-version: 1.7.4
-description: Tools to write binaries that run builders.
-homepage: https://github.com/dart-lang/build/tree/master/build_runner
-
-environment:
- sdk: ">=2.6.0 <3.0.0"
-
-dependencies:
- args: ">=1.4.0 <2.0.0"
- async: ">=1.13.3 <3.0.0"
- build: ">=1.0.0 <1.3.0"
- build_config: ">=0.4.1 <0.4.3"
- build_daemon: ^2.1.0
- build_resolvers: "^1.0.0"
- build_runner_core: ^4.0.0
- code_builder: ">2.3.0 <4.0.0"
- collection: ^1.14.0
- crypto: ">=0.9.2 <3.0.0"
- dart_style: ^1.0.0
- glob: ^1.1.0
- graphs: ^0.2.0
- http_multi_server: ^2.1.0
- io: ^0.3.0
- js: ^0.6.1+1
- logging: ^0.11.2
- meta: ^1.1.0
- mime: ^0.9.3+3
- path: ^1.1.0
- pedantic: ^1.0.0
- pool: ^1.0.0
- pub_semver: ^1.4.0
- pubspec_parse: ^0.1.0
- shelf: ">=0.6.5 <0.8.0"
- shelf_web_socket: ^0.2.2+4
- stack_trace: ^1.9.0
- stream_transform: ">=0.0.20 <2.0.0"
- timing: ^0.1.1
- watcher: ^0.9.7
- web_socket_channel: ^1.0.9
- yaml: ^2.1.0
-
-dev_dependencies:
- build_test: ^0.10.0
- build_web_compilers: ^2.0.0
- mockito: ^4.0.0
- package_resolver: ^1.0.2
- stream_channel: ">=1.6.0 <3.0.0"
- test: ^1.3.3
- test_descriptor: ^1.0.0
- test_process: ^1.0.0
- _test_common:
- path: ../_test_common
diff --git a/build_runner/tool/builders.dart b/build_runner/tool/builders.dart
deleted file mode 100644
index c8eb2ff..0000000
--- a/build_runner/tool/builders.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019, 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:build/build.dart';
-
-Builder copyCompiledJs(void _) => _CopyBuilder();
-
-/// A Builder to copy compiled dart2js output to source.
-class _CopyBuilder extends Builder {
- @override
- final buildExtensions = {
- 'web/graph_viz_main.dart.js': ['lib/src/server/graph_viz_main.dart.js'],
- 'web/hot_reload_client.dart.js': [
- 'lib/src/server/build_updates_client/hot_reload_client.dart.js'
- ]
- };
-
- @override
- void build(BuildStep buildStep) {
- if (!buildExtensions.containsKey(buildStep.inputId.path)) {
- throw StateError('Unexpected input for `CopyBuilder` '
- 'expected only ${buildExtensions.keys}');
- }
- buildStep.writeAsString(
- AssetId(buildStep.inputId.package,
- buildExtensions[buildStep.inputId.path].single),
- buildStep.readAsString(buildStep.inputId));
- }
-}
diff --git a/build_runner/web/graph_viz_main.dart b/build_runner/web/graph_viz_main.dart
deleted file mode 100644
index b2d5e54..0000000
--- a/build_runner/web/graph_viz_main.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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:convert';
-import 'dart:html';
-import 'dart:js' as js;
-
-final _graphReference = js.context[r'$build'];
-final _details = document.getElementById('details');
-
-void main() async {
- var filterBox = document.getElementById('filter') as InputElement;
- var searchBox = document.getElementById('searchbox') as InputElement;
- var searchForm = document.getElementById('searchform');
- searchForm.onSubmit.listen((e) {
- e.preventDefault();
- _focus(searchBox.value.trim(),
- filter: filterBox.value.isNotEmpty ? filterBox.value : null);
- return null;
- });
- _graphReference.callMethod('initializeGraph', [_focus]);
-}
-
-void _error(String message, [Object error, StackTrace stack]) {
- var msg = [message, error, stack].where((e) => e != null).join('\n');
- _details.innerHtml = '<pre>$msg</pre>';
-}
-
-Future _focus(String query, {String filter}) async {
- if (query.isEmpty) {
- _error('Provide content in the query.');
- return;
- }
-
- Map nodeInfo;
- var queryParams = {'q': query};
- if (filter != null) queryParams['f'] = filter;
- var uri = Uri(queryParameters: queryParams);
- try {
- nodeInfo = json.decode(await HttpRequest.getString(uri.toString()))
- as Map<String, dynamic>;
- } catch (e, stack) {
- var msg = 'Error requesting query "$query".';
- if (e is ProgressEvent) {
- var target = e.target;
- if (target is HttpRequest) {
- msg = [
- msg,
- '${target.status} ${target.statusText}',
- target.responseText
- ].join('\n');
- }
- _error(msg);
- } else {
- _error(msg, e, stack);
- }
- return;
- }
-
- var graphData = {'edges': nodeInfo['edges'], 'nodes': nodeInfo['nodes']};
- _graphReference.callMethod('setData', [js.JsObject.jsify(graphData)]);
- var primaryNode = nodeInfo['primary'];
- _details.innerHtml = '<strong>ID:</strong> ${primaryNode['id']} <br />'
- '<strong>Type:</strong> ${primaryNode['type']}<br />'
- '<strong>Hidden:</strong> ${primaryNode['hidden']} <br />'
- '<strong>State:</strong> ${primaryNode['state']} <br />'
- '<strong>Was Output:</strong> ${primaryNode['wasOutput']} <br />'
- '<strong>Failed:</strong> ${primaryNode['isFailure']} <br />'
- '<strong>Phase:</strong> ${primaryNode['phaseNumber']} <br />'
- '<strong>Glob:</strong> ${primaryNode['glob']}<br />'
- '<strong>Last Digest:</strong> ${primaryNode['lastKnownDigest']}<br />';
-}
diff --git a/build_runner/web/hot_reload_client.dart b/build_runner/web/hot_reload_client.dart
deleted file mode 100644
index 5735341..0000000
--- a/build_runner/web/hot_reload_client.dart
+++ /dev/null
@@ -1,203 +0,0 @@
-// 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.
-
-@JS()
-library hot_reload_client;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:html';
-
-import 'package:js/js.dart';
-import 'package:js/js_util.dart';
-
-import 'package:build_runner/src/server/build_updates_client/module.dart';
-import 'package:build_runner/src/server/build_updates_client/reload_handler.dart';
-import 'package:build_runner/src/server/build_updates_client/reloading_manager.dart';
-
-final _assetsDigestPath = r'$assetDigests';
-final _buildUpdatesProtocol = r'$buildUpdates';
-
-@anonymous
-@JS()
-abstract class HotReloadableLibrary {
- /// Implement this function with any code to release resources before destroy.
- ///
- /// Any object returned from this function will be passed to update hooks. Use
- /// it to save any state you need to be preserved between hot reloadings.
- /// Try do not use any custom types here, as it might prevent their code from
- /// reloading. Better serialise to JSON or plain types.
- ///
- /// This function will be called on old version of module before unloading.
- @JS()
- external Object hot$onDestroy();
-
- /// Implement this function to handle update of the module itself.
- ///
- /// May return nullable bool. To indicate that reload completes successfully
- /// return true. To indicate that hot-reload is undoable return false - this
- /// will lead to full page reload. If null returned, reloading will be
- /// propagated to parent.
- ///
- /// If any state was saved from previous version, it will be passed to [data].
- ///
- /// This function will be called on new version of module after reloading.
- @JS()
- external bool hot$onSelfUpdate([Object data]);
-
- /// Implement this function to handle update of child modules.
- ///
- /// May return nullable bool. To indicate that reload of child completes
- /// successfully return true. To indicate that hot-reload is undoable for this
- /// child return false - this will lead to full page reload. If null returned,
- /// reloading will be propagated to current module itself.
- ///
- /// The name of the child will be provided in [childId]. New version of child
- /// module object will be provided in [child].
- /// If any state was saved from previous version, it will be passed to [data].
- ///
- /// This function will be called on old version of module current after child
- /// reloading.
- @JS()
- external bool hot$onChildUpdate(String childId, HotReloadableLibrary child,
- [Object data]);
-}
-
-class LibraryWrapper implements Library {
- final HotReloadableLibrary _internal;
-
- LibraryWrapper(this._internal);
-
- @override
- Object onDestroy() {
- if (_internal != null && hasProperty(_internal, r'hot$onDestroy')) {
- return _internal.hot$onDestroy();
- }
- return null;
- }
-
- @override
- bool onSelfUpdate([Object data]) {
- if (_internal != null && hasProperty(_internal, r'hot$onSelfUpdate')) {
- return _internal.hot$onSelfUpdate(data);
- }
- // ignore: avoid_returning_null
- return null;
- }
-
- @override
- bool onChildUpdate(String childId, Library child, [Object data]) {
- if (_internal != null && hasProperty(_internal, r'hot$onChildUpdate')) {
- return _internal.hot$onChildUpdate(
- childId, (child as LibraryWrapper)._internal, data);
- }
- // ignore: avoid_returning_null
- return null;
- }
-}
-
-@JS('Map')
-abstract class JsMap<K, V> {
- @JS()
- external Object keys();
-
- @JS()
- external V get(K key);
-}
-
-@JS('Error')
-abstract class JsError {
- @JS()
- external String get message;
-
- @JS()
- external String get stack;
-}
-
-@anonymous
-@JS()
-class DartLoader {
- @JS()
- external JsMap<String, String> get urlToModuleId;
-
- @JS()
- external JsMap<String, List<String>> get moduleParentsGraph;
-
- @JS()
- external void forceLoadModule(String moduleId, void Function() callback,
- void Function(JsError e) onError);
-
- @JS()
- external Object getModuleLibraries(String moduleId);
-}
-
-@JS(r'$dartLoader')
-external DartLoader get dartLoader;
-
-@JS('Array.from')
-external List _jsArrayFrom(Object any);
-
-@JS('Object.keys')
-external List _jsObjectKeys(Object any);
-
-@JS('Object.values')
-external List _jsObjectValues(Object any);
-
-List<K> keys<K, V>(JsMap<K, V> map) {
- return List.from(_jsArrayFrom(map.keys()));
-}
-
-Module _moduleLibraries(String moduleId) {
- var moduleObj = dartLoader.getModuleLibraries(moduleId);
- if (moduleObj == null) {
- throw HotReloadFailedException("Failed to get module '$moduleId'. "
- "This error might appear if such module doesn't exist or isn't already loaded");
- }
- var moduleKeys = List<String>.from(_jsObjectKeys(moduleObj));
- var moduleValues =
- List<HotReloadableLibrary>.from(_jsObjectValues(moduleObj));
- var moduleLibraries = moduleValues.map((x) => LibraryWrapper(x));
- return Module(Map.fromIterables(moduleKeys, moduleLibraries));
-}
-
-Future<Module> _reloadModule(String moduleId) {
- var completer = Completer<Module>();
- var stackTrace = StackTrace.current;
- dartLoader.forceLoadModule(moduleId, allowInterop(() {
- completer.complete(_moduleLibraries(moduleId));
- }),
- allowInterop((e) => completer.completeError(
- HotReloadFailedException(e.message), stackTrace)));
- return completer.future;
-}
-
-void _reloadPage() {
- window.location.reload();
-}
-
-void main() async {
- var currentOrigin = '${window.location.origin}/';
- var modulePaths = keys(dartLoader.urlToModuleId)
- .map((key) => key.replaceFirst(currentOrigin, ''))
- .toList();
- var modulePathsJson = json.encode(modulePaths);
-
- var request = await HttpRequest.request('/$_assetsDigestPath',
- responseType: 'json', sendData: modulePathsJson, method: 'POST');
- var digests = (request.response as Map).cast<String, String>();
-
- var manager = ReloadingManager(
- _reloadModule,
- _moduleLibraries,
- _reloadPage,
- (module) => dartLoader.moduleParentsGraph.get(module),
- () => keys(dartLoader.moduleParentsGraph));
-
- var handler = ReloadHandler(digests,
- (path) => dartLoader.urlToModuleId.get(currentOrigin + path), manager);
-
- var webSocket =
- WebSocket('ws://${window.location.host}', [_buildUpdatesProtocol]);
- webSocket.onMessage.listen((event) => handler.listener(event.data as String));
-}
diff --git a/build_runner_core/BUILD.gn b/build_runner_core/BUILD.gn
deleted file mode 100644
index f234d4c..0000000
--- a/build_runner_core/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is generated by importer.py for build_runner_core-4.4.0
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_runner_core") {
- package_name = "build_runner_core"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/pedantic",
- "//third_party/dart-pkg/pub/glob",
- "//third_party/dart-pkg/pub/collection",
- "//third_party/dart-pkg/pub/watcher",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/timing",
- "//third_party/dart-pkg/pub/build_config",
- "//third_party/dart-pkg/pub/pool",
- "//third_party/dart-pkg/pub/convert",
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/graphs",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/yaml",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/build_resolvers",
- "//third_party/dart-pkg/pub/async",
- "//third_party/dart-pkg/pub/json_annotation",
- ]
-}
diff --git a/build_runner_core/CHANGELOG.md b/build_runner_core/CHANGELOG.md
deleted file mode 100644
index 466bba4..0000000
--- a/build_runner_core/CHANGELOG.md
+++ /dev/null
@@ -1,305 +0,0 @@
-## 4.4.0
-
-- Support the `auto_apply_builders` target configuration added in
- `build_config` version `0.4.2`.
-
-## 4.3.0
-
-- Add the `$package$` synthetic placeholder file and update the docs to prefer
- using only that or `lib/$lib$`.
-- Add the `assets` directory and `$package$` placeholders to the default
- sources whitelist.
-
-## 4.2.1
-
-- Bug fix: Changing the root package name will no longer cause subsequent
- builds to fail (Issue #2566).
-
-## 4.2.0
-
-### New Feature
-
-- Allow reading assets created previously by the same `BuildStep`.
-
-## 4.1.0
-
-- Add support for trimming builds based on `BuildStep.reportUnusedAssets`
- calls. See the `build` package for more details.
-- Include `node/**` in the default set of sources (when there is no target
- defined) for the root package.
-
-## 4.0.0
-
-### New Feature: Build Filters
-
-- Added a new `BuildFilter` class which matches a set of assets with glob
- syntax support for both package and file names.
-- Added `buildFilters` to `BuildOptions` which is a `Set<BuildFilter>` and
- is used to filter exactly which outputs will be generated.
- - Note that any inputs to the specified files will also necessarily be built.
-- `BuildRunner.run` also now accepts an optional `Set<BuildFilter>` argument.
-- `FinalizedReader` also now accepts a `Set<BuildFilter>` optional parameter
- and will only allow reading matched files.
- - This means you can create output directories or servers that respect build
- filters.
-
-### Breaking Changes
-
-- `FinalizedReader.reset` now requires an additional `Set<BuildFilter>`
- argument.
-
-## 3.1.1
-
-- When skipping build script updates, don't check if the build script is a
- part of the asset graph either.
-
-## 3.1.0
-
-- Factor out the logic to do a manual file system scan for changes into a
- new `AssetTracker` class.
- - This is not exposed publicly and is only intended to be used from the
- `build_runner` package.
-
-## 3.0.9
-
-- Support the latest release of `package:json_annotation`.
-
-## 3.0.8
-
-- Fix --log-performance crash on windows by ensuring we use valid
- windows directory names.
-
-## 3.0.7
-
-- Support the latest `package:build_config`.
-
-## 3.0.6
-
-- Handle symlink creation failures and link to dev mode docs for windows.
-
-## 3.0.5
-
-- Explicitly require Dart SDK `>=2.2.0 <3.0.0`.
-- Fix an error that could occur when serializing outdated glob nodes.
-
-## 3.0.4
-
-- Add additional error details and a fallback for
- https://github.com/dart-lang/build/issues/1804
-
-## 3.0.3
-
-- Share an asset graph when building regardless of whether the build script was
- started from a snapshot.
-
-## 3.0.2
-
-- Only track valid and readable assets as inputs to globs. Fixes a crash when
- attempting to check outputs from an invalid asset.
-
-## 3.0.1
-
-- Remove usage of set literals to fix errors on older sdks that don't support
- them.
-
-## 3.0.0
-
-- Fix an issue where `--symlink` was forcing outputs to not be hoisted.
-- `BuildImpl` now takes an optional list of `BuildTargets` instead of a list of
- `buildDirs`.
-- Warn when there are no assets to write in a specified output directory.
-
-## 2.0.3
-
-- Handle asset graph decode failures.
-
-## 2.0.2
-
-- Update `build_resolvers` to version `1.0.0`.
-
-## 2.0.1
-
-- Fix an issue where the `finalizedReader` was not `reset` prior to build.
-
-## 2.0.0
-
-- The `build` method now requires a list of `buildDirs`.
-- Remove `buildDirs` from `BuildOptions`.
-- Added the `overrideGeneratedDirectory` method which overrides the directory
- for generated outputs.
- - Must be invoked before creating a `BuildRunner` instance.
-
-## 1.1.3
-
-- Update to `package:graphs` version `0.2.0`.
-- Allow `build` version `1.1.x`.
-- Update the way combined input hashes are computed to not rely on ordering.
- - Digest implementations must now include the AssetId, not just the contents.
-- Require package:build version 1.1.0, which meets the new requirements for
- digests.
-
-## 1.1.2
-
-- Fix a `NoSuchMethodError` that the user could get when adding new
- dependencies.
-
-## 1.1.1
-
-- Fix a bug where adding new dependencies or removing dependencies could cause
- subsequent build errors, requiring a `pub run build_runner clean` to fix.
-
-## 1.1.0
-
-- Support running the build script as a snapshot.
-- Added new exceptions, `BuildScriptChangedException` and
- `BuildConfigChangedException`. These should be handled by scripts as described
- in the documentation.
-- Added new `FailureType`s of `buildScriptChanged` and `buildConfigChanged`.
-
-## 1.0.2
-
-- Support the latest `package:json_annotation`.
-
-## 1.0.1
-
-- Update `package:build` version constraint to `>1.0.0 <1.0.1`.
-
-## 1.0.0
-
-### Breaking Changes
-
-- The performance tracking apis have changed significantly, and performance
- tracking now uses the `timing` package.
-- The `BuildOptions` static factory now takes a `LogSubscription` instead of a
- `BuildEnvironment`. Logging should be start as early as possible to catch logs
- emitted during setup.
-
-### New Features
-
-- Use the `timing` package for performance tracking.
-- Added support for `BuildStep.trackStage` to track performance of custom build
- stages within your builder.
-
-### Bug Fixes
-
-- Fixed a node invalidation issue when fixing build errors that could cause a
- situation which was only resolvable with a full rebuild.
-
-## 0.3.1+5
-
-- Fixed an issue where builders that didn't read their primary input would get
- invalidated on fresh builds when they shouldn't.
-
-## 0.3.1+4
-
-- Removed the constraint on reading files that output to cache from files that
- output to source.
-
-## 0.3.1+3
-
-- Bug Fix: Don't output a `packages` symlink within the `packages` directory.
-
-## 0.3.1+2
-
-- Restore `new` keyword for a working release on Dart 1 VM.
-- Bug Fix: Don't include any non-lib assets from dependencies in the build, even
- if they are a source in a target.
-
-## 0.3.1+1
-
-- Bug Fix: Don't include any non-lib assets from dependencies in the build, even
- if they are a source in a target.
-- Release broken on Dart 1 VM.
-
-## 0.3.1
-
-- Migrated glob tracking to a specialized node type to fix dart-lang/build#1702.
-
-## 0.3.0
-
-### Breaking Changes
-
-- Implementations of `BuildEnvironment` must now implement the `finalizeBuild`
- method. There is a default implementation if you extend `BuildEnvironment`
- that is a no-op.
- - This method is invoked at the end of the build that allows you to do
- arbitrary additional work, such as creating merged output directories.
-- The `assumeTty` argument on `IOEnvironment` has moved to a named argument
- since `null` is an accepted value.
-- The `outputMap` field on `BuildOptions` has moved to the `IOEnvironment`
- class.
-
-### New Features/Updates
-
-- Added a `outputSymlinksOnly` option to `IOEnvironment` constructor, that
- causes the merged output directories to contain only symlinks, which is much
- faster than copying files.
-- Added the `FinalizedAssetView` class which provides a list of all available
- assets to the `BuildEnvironment` during the build finalization phase.
- - `outputMap` has moved from `BuildOptions` to this constructor, as a named
- argument.
-- The `OverridableEnvironment` now supports overriding the new `finalizeBuild`
- api.
-- The number of concurrent actions per phase is now limited (currently to 16),
- which should help with memory and cpu usage for large builds.
-
-## 0.2.2+2
-
-- Support `package:json_annotation` v1.
-
-## 0.2.2+1
-
-- Tag errors from cached actions when they are printed.
-
-## 0.2.2
-
-- Changed the default file caching logic to use an LRU cache.
-
-## 0.2.1+2
-
-- Clarify wording for conflicting output directory options. No behavioral
- differences.
-- Reduce the memory consumption required to create an output dir significantly.
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.2.1+1
-
-- Allow reuse cache between machines with different OS
-
-## 0.2.1
-
-- The hash dir for the asset graph under `.dart_tool/build` is now based on a
- relative path to the build script instead of the absolute path.
- - This enables `.dart_tool/build` directories to be reused across different
- computers and directories for the same project.
-
-## 0.2.0
-
-### New Features
-
-- The `BuildPerformance` class is now serializable, it has a `fromJson`
- constructor and a `toJson` instance method.
-- Added `BuildOptions.logPerformanceDir`, performance logs will be continuously
- written to that directory if provided.
-- Added support for `global_options` in `build.yaml` of the root package.
-- Allow overriding the default `Resolvers` implementation.
-- Allows building with symlinked files. Note that changes to the linked files
- will not trigger rebuilds in watch or serve mode.
-
-### Breaking changes
-
-- `BuildPhasePerformance.action` has been replaced with
- `BuildPhasePerformance.builderKeys`.
-- `BuilderActionPerformance.builder` has been replaced with
- `BuilderActionPerformance.builderKey`.
-- `BuildResult` no longer has an `exception` or `stackTrace` field.
-- Dropped `failOnSevere` arguments. Severe logs are always considered failing.
-
-### Internal changes
-
-- Remove dependency on package:cli_util.
-
-## 0.1.0
-
-Initial release, migrating the core functionality of package:build_runner to
-this package.
diff --git a/build_runner_core/LICENSE b/build_runner_core/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/build_runner_core/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_runner_core/README.md b/build_runner_core/README.md
deleted file mode 100644
index 0fabf3e..0000000
--- a/build_runner_core/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-<p align="center">
- Core functionality of the build_runner package. Exposes the imperative apis
- for running pure Dart builds for
- <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
- <br>
- <a href="https://travis-ci.org/dart-lang/build">
- <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
- </a>
- <a href="https://github.com/dart-lang/build/labels/package%3A%20build_runner">
- <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_runner_core.svg" alt="Issues related to build_runner_core" />
- </a>
- <a href="https://pub.dev/packages/build_runner_core">
- <img src="https://img.shields.io/pub/v/build_runner_core.svg" alt="Pub Package Version" />
- </a>
- <a href="https://pub.dev/documentation/build_runner_core/latest">
- <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
- </a>
- <a href="https://gitter.im/dart-lang/build">
- <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
- </a>
-</p>
diff --git a/build_runner_core/lib/build_runner_core.dart b/build_runner_core/lib/build_runner_core.dart
deleted file mode 100644
index e908e19..0000000
--- a/build_runner_core/lib/build_runner_core.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.
-
-export 'package:build/build.dart' show PostProcessBuilder, PostProcessBuildStep;
-
-export 'src/asset/file_based.dart';
-export 'src/asset/finalized_reader.dart';
-export 'src/asset/reader.dart' show RunnerAssetReader;
-export 'src/asset/writer.dart';
-export 'src/environment/build_environment.dart';
-export 'src/environment/io_environment.dart';
-export 'src/environment/overridable_environment.dart';
-export 'src/generate/build_directory.dart';
-export 'src/generate/build_result.dart';
-export 'src/generate/build_runner.dart';
-export 'src/generate/exceptions.dart'
- show
- BuildConfigChangedException,
- BuildScriptChangedException,
- CannotBuildException;
-export 'src/generate/finalized_assets_view.dart' show FinalizedAssetsView;
-export 'src/generate/options.dart'
- show
- defaultRootPackageWhitelist,
- LogSubscription,
- BuildOptions,
- BuildFilter;
-export 'src/generate/performance_tracker.dart'
- show BuildPerformance, BuilderActionPerformance, BuildPhasePerformance;
-export 'src/logging/human_readable_duration.dart';
-export 'src/logging/logging.dart';
-export 'src/package_graph/apply_builders.dart'
- show
- BuilderApplication,
- apply,
- applyPostProcess,
- applyToRoot,
- toAll,
- toAllPackages,
- toDependentsOf,
- toNoneByDefault,
- toPackage,
- toPackages,
- toRoot;
-export 'src/package_graph/package_graph.dart';
-export 'src/util/constants.dart';
diff --git a/build_runner_core/lib/src/asset/build_cache.dart b/build_runner_core/lib/src/asset/build_cache.dart
deleted file mode 100644
index b052ba3..0000000
--- a/build_runner_core/lib/src/asset/build_cache.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../util/constants.dart';
-import 'reader.dart';
-import 'writer.dart';
-
-/// Wraps an [AssetReader] and translates reads for generated files into reads
-/// from the build cache directory
-class BuildCacheReader implements AssetReader {
- final AssetGraph _assetGraph;
- final AssetReader _delegate;
- final String _rootPackage;
-
- BuildCacheReader._(this._delegate, this._assetGraph, this._rootPackage);
-
- factory BuildCacheReader(
- AssetReader delegate, AssetGraph assetGraph, String rootPackage) =>
- delegate is PathProvidingAssetReader
- ? _PathProvidingBuildCacheReader._(delegate, assetGraph, rootPackage)
- : BuildCacheReader._(delegate, assetGraph, rootPackage);
-
- @override
- Future<bool> canRead(AssetId id) =>
- _delegate.canRead(_cacheLocation(id, _assetGraph, _rootPackage));
-
- @override
- Future<Digest> digest(AssetId id) =>
- _delegate.digest(_cacheLocation(id, _assetGraph, _rootPackage));
-
- @override
- Future<List<int>> readAsBytes(AssetId id) =>
- _delegate.readAsBytes(_cacheLocation(id, _assetGraph, _rootPackage));
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) =>
- _delegate.readAsString(_cacheLocation(id, _assetGraph, _rootPackage),
- encoding: encoding);
-
- @override
- Stream<AssetId> findAssets(Glob glob) => throw UnimplementedError(
- 'Asset globbing should be done per phase with the AssetGraph');
-}
-
-class _PathProvidingBuildCacheReader extends BuildCacheReader
- implements PathProvidingAssetReader {
- @override
- PathProvidingAssetReader get _delegate =>
- super._delegate as PathProvidingAssetReader;
-
- _PathProvidingBuildCacheReader._(PathProvidingAssetReader delegate,
- AssetGraph assetGraph, String rootPackage)
- : super._(delegate, assetGraph, rootPackage);
-
- @override
- String pathTo(AssetId id) =>
- _delegate.pathTo(_cacheLocation(id, _assetGraph, _rootPackage));
-}
-
-class BuildCacheWriter implements RunnerAssetWriter {
- final AssetGraph _assetGraph;
- final RunnerAssetWriter _delegate;
- final String _rootPackage;
-
- BuildCacheWriter(this._delegate, this._assetGraph, this._rootPackage);
-
- @override
- Future writeAsBytes(AssetId id, List<int> content) => _delegate.writeAsBytes(
- _cacheLocation(id, _assetGraph, _rootPackage), content);
-
- @override
- Future writeAsString(AssetId id, String content,
- {Encoding encoding = utf8}) =>
- _delegate.writeAsString(
- _cacheLocation(id, _assetGraph, _rootPackage), content,
- encoding: encoding);
-
- @override
- Future delete(AssetId id) =>
- _delegate.delete(_cacheLocation(id, _assetGraph, _rootPackage));
-}
-
-AssetId _cacheLocation(AssetId id, AssetGraph assetGraph, String rootPackage) {
- if (id.path.startsWith(generatedOutputDirectory) ||
- id.path.startsWith(cacheDir)) {
- return id;
- }
- if (!assetGraph.contains(id)) {
- return id;
- }
- final assetNode = assetGraph.get(id);
- if (assetNode is GeneratedAssetNode && assetNode.isHidden) {
- return AssetId(
- rootPackage, '$generatedOutputDirectory/${id.package}/${id.path}');
- }
- return id;
-}
diff --git a/build_runner_core/lib/src/asset/cache.dart b/build_runner_core/lib/src/asset/cache.dart
deleted file mode 100644
index 12fabeb..0000000
--- a/build_runner_core/lib/src/asset/cache.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:typed_data';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import 'lru_cache.dart';
-import 'reader.dart';
-
-/// An [AssetReader] that caches all results from the delegate.
-///
-/// Assets are cached until [invalidate] is invoked.
-///
-/// Does not implement [findAssets].
-class CachingAssetReader implements AssetReader {
- /// Cached results of [readAsBytes].
- final _bytesContentCache = LruCache<AssetId, List<int>>(
- 1024 * 1024,
- 1024 * 1024 * 512,
- (value) => value is Uint8List ? value.lengthInBytes : value.length * 8);
-
- /// Pending [readAsBytes] operations.
- final _pendingBytesContentCache = <AssetId, Future<List<int>>>{};
-
- /// Cached results of [canRead].
- ///
- /// Don't bother using an LRU cache for this since it's just booleans.
- final _canReadCache = <AssetId, Future<bool>>{};
-
- /// Cached results of [readAsString].
- ///
- /// These are computed and stored lazily using [readAsBytes].
- ///
- /// Only files read with [utf8] encoding (the default) will ever be cached.
- final _stringContentCache = LruCache<AssetId, String>(
- 1024 * 1024, 1024 * 1024 * 512, (value) => value.length);
-
- /// Pending `readAsString` operations.
- final _pendingStringContentCache = <AssetId, Future<String>>{};
-
- final AssetReader _delegate;
-
- CachingAssetReader._(this._delegate);
-
- factory CachingAssetReader(AssetReader delegate) =>
- delegate is PathProvidingAssetReader
- ? _PathProvidingCachingAssetReader._(delegate)
- : CachingAssetReader._(delegate);
-
- @override
- Future<bool> canRead(AssetId id) =>
- _canReadCache.putIfAbsent(id, () => _delegate.canRead(id));
-
- @override
- Future<Digest> digest(AssetId id) => _delegate.digest(id);
-
- @override
- Stream<AssetId> findAssets(Glob glob) =>
- throw UnimplementedError('unimplemented!');
-
- @override
- Future<List<int>> readAsBytes(AssetId id, {bool cache = true}) {
- var cached = _bytesContentCache[id];
- if (cached != null) return Future.value(cached);
-
- return _pendingBytesContentCache.putIfAbsent(
- id,
- () => _delegate.readAsBytes(id).then((result) {
- if (cache) _bytesContentCache[id] = result;
- _pendingBytesContentCache.remove(id);
- return result;
- }));
- }
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding}) {
- encoding ??= utf8;
-
- if (encoding != utf8) {
- // Fallback case, we never cache the String value for the non-default,
- // encoding but we do allow it to cache the bytes.
- return readAsBytes(id).then(encoding.decode);
- }
-
- var cached = _stringContentCache[id];
- if (cached != null) return Future.value(cached);
-
- return _pendingStringContentCache.putIfAbsent(
- id,
- () => readAsBytes(id, cache: false).then((bytes) {
- var decoded = encoding.decode(bytes);
- _stringContentCache[id] = decoded;
- _pendingStringContentCache.remove(id);
- return decoded;
- }));
- }
-
- /// Clears all [ids] from all caches.
- void invalidate(Iterable<AssetId> ids) {
- for (var id in ids) {
- _bytesContentCache.remove(id);
- _canReadCache.remove(id);
- _stringContentCache.remove(id);
-
- _pendingBytesContentCache.remove(id);
- _pendingStringContentCache.remove(id);
- }
- }
-}
-
-/// A version of a [CachingAssetReader] that implements
-/// [PathProvidingAssetReader].
-class _PathProvidingCachingAssetReader extends CachingAssetReader
- implements PathProvidingAssetReader {
- @override
- PathProvidingAssetReader get _delegate =>
- super._delegate as PathProvidingAssetReader;
-
- _PathProvidingCachingAssetReader._(AssetReader delegate) : super._(delegate);
-
- @override
- String pathTo(AssetId id) => _delegate.pathTo(id);
-}
diff --git a/build_runner_core/lib/src/asset/file_based.dart b/build_runner_core/lib/src/asset/file_based.dart
deleted file mode 100644
index 4b1efc0..0000000
--- a/build_runner_core/lib/src/asset/file_based.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:path/path.dart' as path;
-import 'package:pool/pool.dart';
-
-import '../package_graph/package_graph.dart';
-import 'reader.dart';
-import 'writer.dart';
-
-/// Pool for async file operations, we don't want to use too many file handles.
-final _descriptorPool = Pool(32);
-
-/// Basic [AssetReader] which uses a [PackageGraph] to look up where to read
-/// files from disk.
-class FileBasedAssetReader extends AssetReader
- implements RunnerAssetReader, PathProvidingAssetReader {
- final PackageGraph packageGraph;
-
- FileBasedAssetReader(this.packageGraph);
-
- @override
- Future<bool> canRead(AssetId id) =>
- _descriptorPool.withResource(() => _fileFor(id, packageGraph).exists());
-
- @override
- Future<List<int>> readAsBytes(AssetId id) => _fileForOrThrow(id, packageGraph)
- .then((file) => _descriptorPool.withResource(file.readAsBytes));
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding}) =>
- _fileForOrThrow(id, packageGraph).then((file) => _descriptorPool
- .withResource(() => file.readAsString(encoding: encoding ?? utf8)));
-
- @override
- Stream<AssetId> findAssets(Glob glob, {String package}) {
- var packageNode =
- package == null ? packageGraph.root : packageGraph[package];
- if (packageNode == null) {
- throw ArgumentError(
- "Could not find package '$package' which was listed as "
- 'an input. Please ensure you have that package in your deps, or '
- 'remove it from your input sets.');
- }
- return glob
- .list(followLinks: true, root: packageNode.path)
- .where((e) => e is File && !path.basename(e.path).startsWith('._'))
- .cast<File>()
- .map((file) => _fileToAssetId(file, packageNode));
- }
-
- @override
- String pathTo(AssetId id) => _filePathFor(id, packageGraph);
-}
-
-/// Creates an [AssetId] for [file], which is a part of [packageNode].
-AssetId _fileToAssetId(File file, PackageNode packageNode) {
- var filePath = path.normalize(file.absolute.path);
- var relativePath = path.relative(filePath, from: packageNode.path);
- return AssetId(packageNode.name, relativePath);
-}
-
-/// Basic [AssetWriter] which uses a [PackageGraph] to look up where to write
-/// files to disk.
-class FileBasedAssetWriter implements RunnerAssetWriter {
- final PackageGraph packageGraph;
-
- FileBasedAssetWriter(this.packageGraph);
-
- @override
- Future writeAsBytes(AssetId id, List<int> bytes) async {
- var file = _fileFor(id, packageGraph);
- await _descriptorPool.withResource(() async {
- await file.create(recursive: true);
- await file.writeAsBytes(bytes);
- });
- }
-
- @override
- Future writeAsString(AssetId id, String contents,
- {Encoding encoding = utf8}) async {
- var file = _fileFor(id, packageGraph);
- await _descriptorPool.withResource(() async {
- await file.create(recursive: true);
- await file.writeAsString(contents, encoding: encoding);
- });
- }
-
- @override
- Future delete(AssetId id) {
- if (id.package != packageGraph.root.name) {
- throw InvalidOutputException(
- id, 'Should not delete assets outside of ${packageGraph.root.name}');
- }
-
- var file = _fileFor(id, packageGraph);
- return _descriptorPool.withResource(() async {
- if (await file.exists()) {
- await file.delete();
- }
- });
- }
-}
-
-/// Returns the path to [id] for a given [packageGraph].
-String _filePathFor(AssetId id, PackageGraph packageGraph) {
- var package = packageGraph[id.package];
- if (package == null) {
- throw PackageNotFoundException(id.package);
- }
- return path.join(package.path, id.path);
-}
-
-/// Returns a [File] for [id] given [packageGraph].
-File _fileFor(AssetId id, PackageGraph packageGraph) {
- return File(_filePathFor(id, packageGraph));
-}
-
-/// Returns a [Future<File>] for [id] given [packageGraph].
-///
-/// Throws an `AssetNotFoundException` if it doesn't exist.
-Future<File> _fileForOrThrow(AssetId id, PackageGraph packageGraph) {
- if (packageGraph[id.package] == null) {
- return Future.error(PackageNotFoundException(id.package));
- }
- var file = _fileFor(id, packageGraph);
- return _descriptorPool.withResource(file.exists).then((exists) {
- if (!exists) throw AssetNotFoundException(id);
- return file;
- });
-}
diff --git a/build_runner_core/lib/src/asset/finalized_reader.dart b/build_runner_core/lib/src/asset/finalized_reader.dart
deleted file mode 100644
index 38bdb03..0000000
--- a/build_runner_core/lib/src/asset/finalized_reader.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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:convert';
-
-import 'package:build/build.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-import 'package:build_runner_core/src/generate/phase.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../asset_graph/optional_output_tracker.dart';
-
-/// An [AssetReader] which ignores deleted files.
-class FinalizedReader implements AssetReader {
- final AssetReader _delegate;
- final AssetGraph _assetGraph;
- OptionalOutputTracker _optionalOutputTracker;
- final String _rootPackage;
- final List<BuildPhase> _buildPhases;
-
- void reset(Set<String> buildDirs, Set<BuildFilter> buildFilters) {
- _optionalOutputTracker = OptionalOutputTracker(
- _assetGraph, buildDirs, buildFilters, _buildPhases);
- }
-
- FinalizedReader(
- this._delegate, this._assetGraph, this._buildPhases, this._rootPackage);
-
- /// Returns a reason why [id] is not readable, or null if it is readable.
- Future<UnreadableReason> unreadableReason(AssetId id) async {
- if (!_assetGraph.contains(id)) return UnreadableReason.notFound;
- var node = _assetGraph.get(id);
- if (node.isDeleted) return UnreadableReason.deleted;
- if (!node.isReadable) return UnreadableReason.assetType;
- if (node is GeneratedAssetNode) {
- if (node.isFailure) return UnreadableReason.failed;
- if (!(node.wasOutput && (_optionalOutputTracker.isRequired(node.id)))) {
- return UnreadableReason.notOutput;
- }
- }
- if (await _delegate.canRead(id)) return null;
- return UnreadableReason.unknown;
- }
-
- @override
- Future<bool> canRead(AssetId id) async =>
- (await unreadableReason(id)) == null;
-
- @override
- Future<Digest> digest(AssetId id) => _delegate.digest(id);
-
- @override
- Future<List<int>> readAsBytes(AssetId id) => _delegate.readAsBytes(id);
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async {
- if (_assetGraph.get(id)?.isDeleted ?? true) {
- throw AssetNotFoundException(id);
- }
- return _delegate.readAsString(id, encoding: encoding);
- }
-
- @override
- Stream<AssetId> findAssets(Glob glob) async* {
- var potentialNodes = _assetGraph
- .packageNodes(_rootPackage)
- .where((n) => glob.matches(n.id.path))
- .toList();
- var potentialIds = potentialNodes.map((n) => n.id).toList();
-
- for (var id in potentialIds) {
- if (await _delegate.canRead(id)) {
- yield id;
- }
- }
- }
-}
-
-enum UnreadableReason {
- notFound,
- notOutput,
- assetType,
- deleted,
- failed,
- unknown,
-}
diff --git a/build_runner_core/lib/src/asset/lru_cache.dart b/build_runner_core/lib/src/asset/lru_cache.dart
deleted file mode 100644
index c1e2299..0000000
--- a/build_runner_core/lib/src/asset/lru_cache.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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.
-
-/// A basic LRU Cache.
-class LruCache<K, V> {
- _Link<K, V> _head;
- _Link<K, V> _tail;
-
- final int Function(V) _computeWeight;
-
- int _currentWeightTotal = 0;
- final int _individualWeightMax;
- final int _totalWeightMax;
-
- final _entries = <K, _Link<K, V>>{};
-
- LruCache(
- this._individualWeightMax, this._totalWeightMax, this._computeWeight);
-
- V operator [](K key) {
- var entry = _entries[key];
- if (entry == null) return null;
-
- _promote(entry);
- return entry.value;
- }
-
- void operator []=(K key, V value) {
- var entry = _Link(key, value, _computeWeight(value));
- // Don't cache at all if above the individual weight max.
- if (entry.weight > _individualWeightMax) {
- return;
- }
-
- _entries[key] = entry;
- _currentWeightTotal += entry.weight;
- _promote(entry);
-
- while (_currentWeightTotal > _totalWeightMax) {
- assert(_tail != null);
- remove(_tail.key);
- }
- }
-
- /// Removes the value at [key] from the cache, and returns the value if it
- /// existed.
- V remove(K key) {
- var entry = _entries[key];
- if (entry == null) return null;
-
- _currentWeightTotal -= entry.weight;
- _entries.remove(key);
-
- if (entry == _tail) {
- _tail = entry.next;
- _tail?.previous = null;
- }
- if (entry == _head) {
- _head = entry.previous;
- _head?.next = null;
- }
-
- return entry.value;
- }
-
- /// Moves [link] to the [_head] of the list.
- void _promote(_Link<K, V> link) {
- if (link == _head) return;
-
- if (link == _tail) {
- _tail = link.next;
- }
-
- if (link.previous != null) {
- link.previous.next = link.next;
- }
- if (link.next != null) {
- link.next.previous = link.previous;
- }
-
- _head?.next = link;
- link.previous = _head;
- _head = link;
- _tail ??= link;
- link.next = null;
- }
-}
-
-/// A [MapEntry] which is also a part of a doubly linked list.
-class _Link<K, V> implements MapEntry<K, V> {
- _Link<K, V> next;
- _Link<K, V> previous;
-
- final int weight;
-
- @override
- final K key;
-
- @override
- final V value;
-
- _Link(this.key, this.value, this.weight);
-}
diff --git a/build_runner_core/lib/src/asset/reader.dart b/build_runner_core/lib/src/asset/reader.dart
deleted file mode 100644
index f3c0131..0000000
--- a/build_runner_core/lib/src/asset/reader.dart
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-import 'dart:convert';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:meta/meta.dart';
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../util/async.dart';
-
-/// A [RunnerAssetReader] must implement [MultiPackageAssetReader].
-abstract class RunnerAssetReader implements MultiPackageAssetReader {}
-
-/// An [AssetReader] that can provide actual paths to assets on disk.
-abstract class PathProvidingAssetReader implements AssetReader {
- String pathTo(AssetId id);
-}
-
-/// Describes if and how a [SingleStepReader] should read an [AssetId].
-class Readability {
- final bool canRead;
- final bool inSamePhase;
-
- const Readability({@required this.canRead, @required this.inSamePhase});
-
- /// Determines readability for a node written in a previous build phase, which
- /// means that [ownOutput] is impossible.
- factory Readability.fromPreviousPhase(bool readable) =>
- readable ? Readability.readable : Readability.notReadable;
-
- static const Readability notReadable =
- Readability(canRead: false, inSamePhase: false);
- static const Readability readable =
- Readability(canRead: true, inSamePhase: false);
- static const Readability ownOutput =
- Readability(canRead: true, inSamePhase: true);
-}
-
-typedef IsReadable = FutureOr<Readability> Function(
- AssetNode node, int phaseNum, AssetWriterSpy writtenAssets);
-
-/// An [AssetReader] with a lifetime equivalent to that of a single step in a
-/// build.
-///
-/// A step is a single Builder and primary input (or package for package
-/// builders) combination.
-///
-/// Limits reads to the assets which are sources or were generated by previous
-/// phases.
-///
-/// Tracks the assets and globs read during this step for input dependency
-/// tracking.
-class SingleStepReader implements AssetReader {
- final AssetGraph _assetGraph;
- final AssetReader _delegate;
- final int _phaseNumber;
- final String _primaryPackage;
- final AssetWriterSpy _writtenAssets;
- final IsReadable _isReadableNode;
- final FutureOr<GlobAssetNode> Function(
- Glob glob, String package, int phaseNum) _getGlobNode;
-
- /// The assets read during this step.
- final assetsRead = HashSet<AssetId>();
-
- SingleStepReader(this._delegate, this._assetGraph, this._phaseNumber,
- this._primaryPackage, this._isReadableNode,
- [this._getGlobNode, this._writtenAssets]);
-
- /// Checks whether [id] can be read by this step - attempting to build the
- /// asset if necessary.
- FutureOr<bool> _isReadable(AssetId id) {
- final node = _assetGraph.get(id);
- if (node == null) {
- assetsRead.add(id);
- _assetGraph.add(SyntheticSourceAssetNode(id));
- return false;
- }
-
- return doAfter(_isReadableNode(node, _phaseNumber, _writtenAssets),
- (Readability readability) {
- if (!readability.inSamePhase) {
- assetsRead.add(id);
- }
-
- return readability.canRead;
- });
- }
-
- @override
- Future<bool> canRead(AssetId id) {
- return toFuture(doAfter(_isReadable(id), (bool isReadable) {
- if (!isReadable) return false;
- var node = _assetGraph.get(id);
- FutureOr<bool> _canRead() {
- if (node is GeneratedAssetNode) {
- // Short circut, we know this file exists because its readable and it was
- // output.
- return true;
- } else {
- return _delegate.canRead(id);
- }
- }
-
- return doAfter(_canRead(), (bool canRead) {
- if (!canRead) return false;
- return doAfter(_ensureDigest(id), (_) => true);
- });
- }));
- }
-
- @override
- Future<Digest> digest(AssetId id) {
- return toFuture(doAfter(_isReadable(id), (bool isReadable) {
- if (!isReadable) {
- return Future.error(AssetNotFoundException(id));
- }
- return _ensureDigest(id);
- }));
- }
-
- @override
- Future<List<int>> readAsBytes(AssetId id) {
- return toFuture(doAfter(_isReadable(id), (bool isReadable) {
- if (!isReadable) {
- return Future.error(AssetNotFoundException(id));
- }
- return doAfter(_ensureDigest(id), (_) => _delegate.readAsBytes(id));
- }));
- }
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) {
- return toFuture(doAfter(_isReadable(id), (bool isReadable) {
- if (!isReadable) {
- return Future.error(AssetNotFoundException(id));
- }
- return doAfter(_ensureDigest(id),
- (_) => _delegate.readAsString(id, encoding: encoding));
- }));
- }
-
- @override
- Stream<AssetId> findAssets(Glob glob) {
- var streamCompleter = StreamCompleter<AssetId>();
-
- doAfter(_getGlobNode(glob, _primaryPackage, _phaseNumber),
- (GlobAssetNode globNode) {
- assetsRead.add(globNode.id);
- streamCompleter.setSourceStream(Stream.fromIterable(globNode.results));
- });
- return streamCompleter.stream;
- }
-
- FutureOr<Digest> _ensureDigest(AssetId id) {
- var node = _assetGraph.get(id);
- if (node?.lastKnownDigest != null) return node.lastKnownDigest;
- return _delegate.digest(id).then((digest) => node.lastKnownDigest = digest);
- }
-}
diff --git a/build_runner_core/lib/src/asset/writer.dart b/build_runner_core/lib/src/asset/writer.dart
deleted file mode 100644
index e0c1827..0000000
--- a/build_runner_core/lib/src/asset/writer.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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 'package:build/build.dart';
-
-@deprecated
-typedef OnDelete = void Function(AssetId id);
-
-abstract class RunnerAssetWriter implements AssetWriter {
- Future delete(AssetId id);
-}
diff --git a/build_runner_core/lib/src/asset_graph/exceptions.dart b/build_runner_core/lib/src/asset_graph/exceptions.dart
deleted file mode 100644
index 46f9d69..0000000
--- a/build_runner_core/lib/src/asset_graph/exceptions.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2016, 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:build/build.dart';
-
-class DuplicateAssetNodeException implements Exception {
- final String rootPackage;
- final AssetId assetId;
- final String initialBuilderLabel;
- final String newBuilderLabel;
-
- DuplicateAssetNodeException(this.rootPackage, this.assetId,
- this.initialBuilderLabel, this.newBuilderLabel);
- @override
- String toString() {
- final friendlyAsset =
- assetId.package == rootPackage ? assetId.path : assetId.uri;
- return 'Both $initialBuilderLabel and $newBuilderLabel may output '
- '$friendlyAsset. Potential outputs must be unique across all builders. '
- 'See https://github.com/dart-lang/build/blob/master/docs/faq.md'
- '#why-do-builders-need-unique-outputs';
- }
-}
-
-class AssetGraphCorruptedException implements Exception {}
diff --git a/build_runner_core/lib/src/asset_graph/graph.dart b/build_runner_core/lib/src/asset_graph/graph.dart
deleted file mode 100644
index d7e6444..0000000
--- a/build_runner_core/lib/src/asset_graph/graph.dart
+++ /dev/null
@@ -1,556 +0,0 @@
-// Copyright (c) 2016, 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:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:convert/convert.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:meta/meta.dart';
-import 'package:watcher/watcher.dart';
-
-import '../generate/phase.dart';
-import '../package_graph/package_graph.dart';
-import 'exceptions.dart';
-import 'node.dart';
-
-part 'serialization.dart';
-
-/// All the [AssetId]s involved in a build, and all of their outputs.
-class AssetGraph {
- /// All the [AssetNode]s in the graph, indexed by package and then path.
- final _nodesByPackage = <String, Map<String, AssetNode>>{};
-
- /// A [Digest] of the build actions this graph was originally created with.
- ///
- /// When an [AssetGraph] is deserialized we check whether or not it matches
- /// the new [BuildPhase]s and throw away the graph if it doesn't.
- final Digest buildPhasesDigest;
-
- /// The [Platform.version] this graph was created with.
- final String dartVersion;
-
- AssetGraph._(this.buildPhasesDigest, this.dartVersion);
-
- /// Deserializes this graph.
- factory AssetGraph.deserialize(List<int> serializedGraph) =>
- _AssetGraphDeserializer(serializedGraph).deserialize();
-
- static Future<AssetGraph> build(
- List<BuildPhase> buildPhases,
- Set<AssetId> sources,
- Set<AssetId> internalSources,
- PackageGraph packageGraph,
- AssetReader digestReader) async {
- var graph =
- AssetGraph._(computeBuildPhasesDigest(buildPhases), Platform.version);
- var placeholders = graph._addPlaceHolderNodes(packageGraph);
- var sourceNodes = graph._addSources(sources);
- graph
- .._addBuilderOptionsNodes(buildPhases)
- .._addOutputsForSources(buildPhases, sources, packageGraph.root.name,
- placeholders: placeholders);
- // Pre-emptively compute digests for the nodes we know have outputs.
- await graph._setLastKnownDigests(
- sourceNodes.where((node) => node.primaryOutputs.isNotEmpty),
- digestReader);
- // Always compute digests for all internal nodes.
- var internalNodes = graph._addInternalSources(internalSources);
- await graph._setLastKnownDigests(internalNodes, digestReader);
- return graph;
- }
-
- List<int> serialize() => _AssetGraphSerializer(this).serialize();
-
- /// Checks if [id] exists in the graph.
- bool contains(AssetId id) =>
- _nodesByPackage[id.package]?.containsKey(id.path) ?? false;
-
- /// Gets the [AssetNode] for [id], if one exists.
- AssetNode get(AssetId id) {
- var pkg = _nodesByPackage[id?.package];
- if (pkg == null) return null;
- return pkg[id.path];
- }
-
- /// Adds [node] to the graph if it doesn't exist.
- ///
- /// Throws a [StateError] if it already exists in the graph.
- void _add(AssetNode node) {
- var existing = get(node.id);
- if (existing != null) {
- if (existing is SyntheticSourceAssetNode) {
- // Don't call _removeRecursive, that recursively removes all transitive
- // primary outputs. We only want to remove this node.
- _nodesByPackage[existing.id.package].remove(existing.id.path);
- node.outputs.addAll(existing.outputs);
- node.primaryOutputs.addAll(existing.primaryOutputs);
- } else {
- throw StateError(
- 'Tried to add node ${node.id} to the asset graph but it already '
- 'exists.');
- }
- }
- _nodesByPackage.putIfAbsent(node.id.package, () => {})[node.id.path] = node;
- }
-
- /// Adds [assetIds] as [InternalAssetNode]s to this graph.
- Iterable<AssetNode> _addInternalSources(Set<AssetId> assetIds) sync* {
- for (var id in assetIds) {
- var node = InternalAssetNode(id);
- _add(node);
- yield node;
- }
- }
-
- /// Adds [PlaceHolderAssetNode]s for every package in [packageGraph].
- Set<AssetId> _addPlaceHolderNodes(PackageGraph packageGraph) {
- var placeholders = placeholderIdsFor(packageGraph);
- for (var id in placeholders) {
- _add(PlaceHolderAssetNode(id));
- }
- return placeholders;
- }
-
- /// Adds [assetIds] as [AssetNode]s to this graph, and returns the newly
- /// created nodes.
- List<AssetNode> _addSources(Set<AssetId> assetIds) {
- return assetIds.map((id) {
- var node = SourceAssetNode(id);
- _add(node);
- return node;
- }).toList();
- }
-
- /// Adds [BuilderOptionsAssetNode]s for all [buildPhases] to this graph.
- void _addBuilderOptionsNodes(List<BuildPhase> buildPhases) {
- for (var phaseNum = 0; phaseNum < buildPhases.length; phaseNum++) {
- var phase = buildPhases[phaseNum];
- if (phase is InBuildPhase) {
- add(BuilderOptionsAssetNode(builderOptionsIdForAction(phase, phaseNum),
- computeBuilderOptionsDigest(phase.builderOptions)));
- } else if (phase is PostBuildPhase) {
- var actionNum = 0;
- for (var builderAction in phase.builderActions) {
- add(BuilderOptionsAssetNode(
- builderOptionsIdForAction(builderAction, actionNum),
- computeBuilderOptionsDigest(builderAction.builderOptions)));
- actionNum++;
- }
- } else {
- throw StateError('Invalid action type $phase');
- }
- }
- }
-
- /// Uses [digestReader] to compute the [Digest] for [nodes] and set the
- /// `lastKnownDigest` field.
- Future<void> _setLastKnownDigests(
- Iterable<AssetNode> nodes, AssetReader digestReader) async {
- await Future.wait(nodes.map((node) async {
- node.lastKnownDigest = await digestReader.digest(node.id);
- }));
- }
-
- /// Removes the node representing [id] from the graph, and all of its
- /// `primaryOutput`s.
- ///
- /// Also removes all edges between all removed nodes and other nodes.
- ///
- /// Returns a [Set<AssetId>] of all removed nodes.
- Set<AssetId> _removeRecursive(AssetId id, {Set<AssetId> removedIds}) {
- removedIds ??= <AssetId>{};
- var node = get(id);
- if (node == null) return removedIds;
- removedIds.add(id);
- for (var anchor in node.anchorOutputs.toList()) {
- _removeRecursive(anchor, removedIds: removedIds);
- }
- for (var output in node.primaryOutputs.toList()) {
- _removeRecursive(output, removedIds: removedIds);
- }
- for (var output in node.outputs) {
- var inputsNode = get(output) as NodeWithInputs;
- if (inputsNode != null) {
- inputsNode.inputs.remove(id);
- if (inputsNode is GlobAssetNode) {
- inputsNode.results.remove(id);
- }
- }
- }
- if (node is NodeWithInputs) {
- for (var input in node.inputs) {
- var inputNode = get(input);
- // We may have already removed this node entirely.
- if (inputNode != null) {
- inputNode.outputs.remove(id);
- inputNode.primaryOutputs.remove(id);
- }
- }
- if (node is GeneratedAssetNode) {
- get(node.builderOptionsId).outputs.remove(id);
- }
- }
- // Synthetic nodes need to be kept to retain dependency tracking.
- if (node is! SyntheticSourceAssetNode) {
- _nodesByPackage[id.package].remove(id.path);
- }
- return removedIds;
- }
-
- /// All nodes in the graph, whether source files or generated outputs.
- Iterable<AssetNode> get allNodes =>
- _nodesByPackage.values.expand((pkdIds) => pkdIds.values);
-
- /// All nodes in the graph for `package`.
- Iterable<AssetNode> packageNodes(String package) =>
- _nodesByPackage[package]?.values ?? [];
-
- /// All the generated outputs in the graph.
- Iterable<AssetId> get outputs =>
- allNodes.where((n) => n.isGenerated).map((n) => n.id);
-
- /// The outputs which were, or would have been, produced by failing actions.
- Iterable<GeneratedAssetNode> get failedOutputs => allNodes
- .where((n) =>
- n is GeneratedAssetNode &&
- n.isFailure &&
- n.state == NodeState.upToDate)
- .map((n) => n as GeneratedAssetNode);
-
- /// All the generated outputs for a particular phase.
- Iterable<GeneratedAssetNode> outputsForPhase(String package, int phase) =>
- packageNodes(package)
- .whereType<GeneratedAssetNode>()
- .where((n) => n.phaseNumber == phase);
-
- /// All the source files in the graph.
- Iterable<AssetId> get sources =>
- allNodes.whereType<SourceAssetNode>().map((n) => n.id);
-
- /// Updates graph structure, invalidating and deleting any outputs that were
- /// affected.
- ///
- /// Returns the list of [AssetId]s that were invalidated.
- Future<Set<AssetId>> updateAndInvalidate(
- List<BuildPhase> buildPhases,
- Map<AssetId, ChangeType> updates,
- String rootPackage,
- Future Function(AssetId id) delete,
- AssetReader digestReader) async {
- var newIds = <AssetId>{};
- var modifyIds = <AssetId>{};
- var removeIds = <AssetId>{};
- updates.forEach((id, changeType) {
- if (changeType != ChangeType.ADD && get(id) == null) return;
- switch (changeType) {
- case ChangeType.ADD:
- newIds.add(id);
- break;
- case ChangeType.MODIFY:
- modifyIds.add(id);
- break;
- case ChangeType.REMOVE:
- removeIds.add(id);
- break;
- }
- });
-
- var newAndModifiedNodes = modifyIds.map(get).toList()
- ..addAll(_addSources(newIds));
- // Pre-emptively compute digests for the new and modified nodes we know have
- // outputs.
- await _setLastKnownDigests(
- newAndModifiedNodes.where((node) =>
- node.isValidInput &&
- (node.outputs.isNotEmpty ||
- node.primaryOutputs.isNotEmpty ||
- node.lastKnownDigest != null)),
- digestReader);
-
- // Collects the set of all transitive ids to be removed from the graph,
- // based on the removed `SourceAssetNode`s by following the
- // `primaryOutputs`.
- var transitiveRemovedIds = <AssetId>{};
- void addTransitivePrimaryOutputs(AssetId id) {
- transitiveRemovedIds.add(id);
- get(id).primaryOutputs.forEach(addTransitivePrimaryOutputs);
- }
-
- removeIds
- .where((id) => get(id) is SourceAssetNode)
- .forEach(addTransitivePrimaryOutputs);
-
- // The generated nodes to actually delete from the file system.
- var idsToDelete = Set<AssetId>.from(transitiveRemovedIds)
- ..removeAll(removeIds);
-
- // We definitely need to update manually deleted outputs.
- for (var deletedOutput
- in removeIds.map(get).whereType<GeneratedAssetNode>()) {
- deletedOutput.state = NodeState.definitelyNeedsUpdate;
- }
-
- // Transitively invalidates all assets. This needs to happen after the
- // structure of the graph has been updated.
- var invalidatedIds = <AssetId>{};
-
- var newGeneratedOutputs =
- _addOutputsForSources(buildPhases, newIds, rootPackage);
- var allNewAndDeletedIds =
- Set.of(newGeneratedOutputs.followedBy(transitiveRemovedIds));
-
- void invalidateNodeAndDeps(AssetId id) {
- var node = get(id);
- if (node == null) return;
- if (!invalidatedIds.add(id)) return;
-
- if (node is NodeWithInputs && node.state == NodeState.upToDate) {
- node.state = NodeState.mayNeedUpdate;
- }
-
- // Update all outputs of this asset as well.
- for (var output in node.outputs) {
- invalidateNodeAndDeps(output);
- }
- }
-
- for (var changed in updates.keys.followedBy(newGeneratedOutputs)) {
- invalidateNodeAndDeps(changed);
- }
-
- // For all new or deleted assets, check if they match any glob nodes and
- // invalidate those.
- for (var id in allNewAndDeletedIds) {
- var samePackageGlobNodes = packageNodes(id.package)
- .whereType<GlobAssetNode>()
- .where((n) => n.state == NodeState.upToDate);
- for (final node in samePackageGlobNodes) {
- if (node.glob.matches(id.path)) {
- invalidateNodeAndDeps(node.id);
- node.state = NodeState.mayNeedUpdate;
- }
- }
- }
-
- // Delete all the invalidated assets, then remove them from the graph. This
- // order is important because some `AssetWriter`s throw if the id is not in
- // the graph.
- await Future.wait(idsToDelete.map(delete));
-
- // Remove all deleted source assets from the graph, which also recursively
- // removes all their primary outputs.
- for (var id in removeIds.where((id) => get(id) is SourceAssetNode)) {
- invalidateNodeAndDeps(id);
- _removeRecursive(id);
- }
-
- return invalidatedIds;
- }
-
- /// Crawl up primary inputs to see if the original Source file matches the
- /// glob on [action].
- bool _actionMatches(BuildAction action, AssetId input) {
- if (input.package != action.package) return false;
- if (!action.generateFor.matches(input)) return false;
- Iterable<String> inputExtensions;
- if (action is InBuildPhase) {
- inputExtensions = action.builder.buildExtensions.keys;
- } else if (action is PostBuildAction) {
- inputExtensions = action.builder.inputExtensions;
- } else {
- throw StateError('Unrecognized action type $action');
- }
- if (!inputExtensions.any(input.path.endsWith)) {
- return false;
- }
- var inputNode = get(input);
- while (inputNode is GeneratedAssetNode) {
- inputNode = get((inputNode as GeneratedAssetNode).primaryInput);
- }
- return action.targetSources.matches(inputNode.id);
- }
-
- /// Returns a set containing [newSources] plus any new generated sources
- /// based on [buildPhases], and updates this graph to contain all the
- /// new outputs.
- ///
- /// If [placeholders] is supplied they will be added to [newSources] to create
- /// the full input set.
- Set<AssetId> _addOutputsForSources(
- List<BuildPhase> buildPhases, Set<AssetId> newSources, String rootPackage,
- {Set<AssetId> placeholders}) {
- var allInputs = Set<AssetId>.from(newSources);
- if (placeholders != null) allInputs.addAll(placeholders);
-
- for (var phaseNum = 0; phaseNum < buildPhases.length; phaseNum++) {
- var phase = buildPhases[phaseNum];
- if (phase is InBuildPhase) {
- allInputs.addAll(_addInBuildPhaseOutputs(
- phase,
- phaseNum,
- allInputs,
- buildPhases,
- rootPackage,
- ));
- } else if (phase is PostBuildPhase) {
- _addPostBuildPhaseAnchors(phase, allInputs);
- } else {
- throw StateError('Unrecognized phase type $phase');
- }
- }
- return allInputs;
- }
-
- /// Adds all [GeneratedAssetNode]s for [phase] given [allInputs].
- ///
- /// May remove some items from [allInputs], if they are deemed to actually be
- /// outputs of this phase and not original sources.
- ///
- /// Returns all newly created asset ids.
- Set<AssetId> _addInBuildPhaseOutputs(
- InBuildPhase phase,
- int phaseNum,
- Set<AssetId> allInputs,
- List<BuildPhase> buildPhases,
- String rootPackage) {
- var phaseOutputs = <AssetId>{};
- var buildOptionsNodeId = builderOptionsIdForAction(phase, phaseNum);
- var builderOptionsNode = get(buildOptionsNodeId) as BuilderOptionsAssetNode;
- var inputs =
- allInputs.where((input) => _actionMatches(phase, input)).toList();
- for (var input in inputs) {
- // We might have deleted some inputs during this loop, if they turned
- // out to be generated assets.
- if (!allInputs.contains(input)) continue;
- var node = get(input);
- assert(node != null, 'The node from `$input` does not exist.');
-
- var outputs = expectedOutputs(phase.builder, input);
- phaseOutputs.addAll(outputs);
- node.primaryOutputs.addAll(outputs);
- var deleted = _addGeneratedOutputs(
- outputs, phaseNum, builderOptionsNode, buildPhases, rootPackage,
- primaryInput: input, isHidden: phase.hideOutput);
- allInputs.removeAll(deleted);
- // We may delete source nodes that were producing outputs previously.
- // Detect this by checking for deleted nodes that no longer exist in the
- // graph at all, and remove them from `phaseOutputs`.
- phaseOutputs.removeAll(deleted.where((id) => !contains(id)));
- }
- return phaseOutputs;
- }
-
- /// Adds all [PostProcessAnchorNode]s for [phase] given [allInputs];
- ///
- /// Does not return anything because [PostProcessAnchorNode]s are synthetic
- /// and should not be treated as inputs.
- void _addPostBuildPhaseAnchors(PostBuildPhase phase, Set<AssetId> allInputs) {
- var actionNum = 0;
- for (var action in phase.builderActions) {
- var inputs = allInputs.where((input) => _actionMatches(action, input));
- for (var input in inputs) {
- var buildOptionsNodeId = builderOptionsIdForAction(action, actionNum);
- var anchor = PostProcessAnchorNode.forInputAndAction(
- input, actionNum, buildOptionsNodeId);
- add(anchor);
- get(input).anchorOutputs.add(anchor.id);
- }
- actionNum++;
- }
- }
-
- /// Adds [outputs] as [GeneratedAssetNode]s to the graph.
- ///
- /// If there are existing [SourceAssetNode]s or [SyntheticSourceAssetNode]s
- /// that overlap the [GeneratedAssetNode]s, then they will be replaced with
- /// [GeneratedAssetNode]s, and all their `primaryOutputs` will be removed
- /// from the graph as well. The return value is the set of assets that were
- /// removed from the graph.
- Set<AssetId> _addGeneratedOutputs(
- Iterable<AssetId> outputs,
- int phaseNumber,
- BuilderOptionsAssetNode builderOptionsNode,
- List<BuildPhase> buildPhases,
- String rootPackage,
- {AssetId primaryInput,
- @required bool isHidden}) {
- var removed = <AssetId>{};
- for (var output in outputs) {
- AssetNode existing;
- // When any outputs aren't hidden we can pick up old generated outputs as
- // regular `AssetNode`s, we need to delete them and all their primary
- // outputs, and replace them with a `GeneratedAssetNode`.
- if (contains(output)) {
- existing = get(output);
- if (existing is GeneratedAssetNode) {
- throw DuplicateAssetNodeException(
- rootPackage,
- existing.id,
- (buildPhases[existing.phaseNumber] as InBuildPhase).builderLabel,
- (buildPhases[phaseNumber] as InBuildPhase).builderLabel);
- }
- _removeRecursive(output, removedIds: removed);
- }
-
- var newNode = GeneratedAssetNode(output,
- phaseNumber: phaseNumber,
- primaryInput: primaryInput,
- state: NodeState.definitelyNeedsUpdate,
- wasOutput: false,
- isFailure: false,
- builderOptionsId: builderOptionsNode.id,
- isHidden: isHidden);
- if (existing != null) {
- newNode.outputs.addAll(existing.outputs);
- }
- builderOptionsNode.outputs.add(output);
- _add(newNode);
- }
- return removed;
- }
-
- @override
- String toString() => allNodes.toList().toString();
-
- // TODO remove once tests are updated
- void add(AssetNode node) => _add(node);
- Set<AssetId> remove(AssetId id) => _removeRecursive(id);
-}
-
-/// Computes a [Digest] for [buildPhases] which can be used to compare one set
-/// of [BuildPhase]s against another.
-Digest computeBuildPhasesDigest(Iterable<BuildPhase> buildPhases) {
- var digestSink = AccumulatorSink<Digest>();
- md5.startChunkedConversion(digestSink)
- ..add(buildPhases.map((phase) => phase.identity).toList())
- ..close();
- assert(digestSink.events.length == 1);
- return digestSink.events.first;
-}
-
-Digest computeBuilderOptionsDigest(BuilderOptions options) =>
- md5.convert(utf8.encode(json.encode(options.config)));
-
-AssetId builderOptionsIdForAction(BuildAction action, int actionNum) {
- if (action is InBuildPhase) {
- return AssetId(action.package, 'Phase$actionNum.builderOptions');
- } else if (action is PostBuildAction) {
- return AssetId(action.package, 'PostPhase$actionNum.builderOptions');
- } else {
- throw StateError('Unsupported action type $action');
- }
-}
-
-Set<AssetId> placeholderIdsFor(PackageGraph packageGraph) =>
- Set<AssetId>.from(packageGraph.allPackages.keys.expand((package) => [
- AssetId(package, r'lib/$lib$'),
- AssetId(package, r'test/$test$'),
- AssetId(package, r'web/$web$'),
- AssetId(package, r'$package$'),
- ]));
diff --git a/build_runner_core/lib/src/asset_graph/node.dart b/build_runner_core/lib/src/asset_graph/node.dart
deleted file mode 100644
index 5419caa..0000000
--- a/build_runner_core/lib/src/asset_graph/node.dart
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright (c) 2016, 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:collection';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:meta/meta.dart';
-
-import '../generate/phase.dart';
-
-/// A node in the asset graph which may be an input to other assets.
-abstract class AssetNode {
- final AssetId id;
-
- /// The assets that any [Builder] in the build graph declares it may output
- /// when run on this asset.
- final Set<AssetId> primaryOutputs = <AssetId>{};
-
- /// The [AssetId]s of all generated assets which are output by a [Builder]
- /// which reads this asset.
- final Set<AssetId> outputs = <AssetId>{};
-
- /// The [AssetId]s of all [PostProcessAnchorNode] assets for which this node
- /// is the primary input.
- final Set<AssetId> anchorOutputs = <AssetId>{};
-
- /// The [Digest] for this node in its last known state.
- ///
- /// May be `null` if this asset has no outputs, or if it doesn't actually
- /// exist.
- Digest lastKnownDigest;
-
- /// Whether or not this node was an output of this build.
- bool get isGenerated => false;
-
- /// Whether or not this asset type can be read.
- ///
- /// This does not indicate whether or not this specific node actually exists
- /// at this moment in time.
- bool get isReadable => true;
-
- /// The IDs of the [PostProcessAnchorNode] for post process builder which
- /// requested to delete this asset.
- final Set<AssetId> deletedBy = <AssetId>{};
-
- /// Whether the node is deleted.
- ///
- /// Deleted nodes are ignored in the final merge step and watch handlers.
- bool get isDeleted => deletedBy.isNotEmpty;
-
- /// Whether or not this node can be read by a builder as a primary or
- /// secondary input.
- ///
- /// Some nodes are valid primary inputs but are not readable (see
- /// [PlaceHolderAssetNode]), while others are readable in the overall build
- /// system but are not valid builder inputs (see [InternalAssetNode]).
- bool get isValidInput => true;
-
- /// Whether or not changes to this node will have any effect on other nodes.
- ///
- /// Be default, if we haven't computed a digest for this asset and it has no
- /// outputs, then it isn't interesting.
- ///
- /// Checking for a digest alone isn't enough because a file may be deleted
- /// and re-added, in which case it won't have a digest.
- bool get isInteresting => outputs.isNotEmpty || lastKnownDigest != null;
-
- AssetNode(this.id, {this.lastKnownDigest});
-
- /// Work around issue where you can't mixin classes into a class with optional
- /// constructor args.
- AssetNode._forMixins(this.id);
-
- /// Work around issue where you can't mixin classes into a class with optional
- /// constructor args, this one includes the digest.
- AssetNode._forMixinsWithDigest(this.id, this.lastKnownDigest);
-
- @override
- String toString() => 'AssetNode: $id';
-}
-
-/// A node representing some internal asset.
-///
-/// These nodes are not used as primary inputs, but they are tracked in the
-/// asset graph and are readable.
-class InternalAssetNode extends AssetNode {
- // These don't have [outputs] but they are interesting regardless.
- @override
- bool get isInteresting => true;
-
- @override
- bool get isValidInput => false;
-
- InternalAssetNode(AssetId id, {Digest lastKnownDigest})
- : super(id, lastKnownDigest: lastKnownDigest);
-
- @override
- String toString() => 'InternalAssetNode: $id';
-}
-
-/// A node which is an original source asset (not generated).
-class SourceAssetNode extends AssetNode {
- SourceAssetNode(AssetId id, {Digest lastKnownDigest})
- : super(id, lastKnownDigest: lastKnownDigest);
-
- @override
- String toString() => 'SourceAssetNode: $id';
-}
-
-/// States for nodes that can be invalidated.
-enum NodeState {
- // This node does not need an update, and no checks need to be performed.
- upToDate,
- // This node may need an update, the inputs hash should be checked for
- // changes.
- mayNeedUpdate,
- // This node definitely needs an update, the inputs hash check can be skipped.
- definitelyNeedsUpdate,
-}
-
-/// A generated node in the asset graph.
-class GeneratedAssetNode extends AssetNode implements NodeWithInputs {
- @override
- bool get isGenerated => true;
-
- @override
- final int phaseNumber;
-
- /// The primary input which generated this node.
- final AssetId primaryInput;
-
- @override
- NodeState state;
-
- /// Whether the asset was actually output.
- bool wasOutput;
-
- /// All the inputs that were read when generating this asset, or deciding not
- /// to generate it.
- ///
- /// This needs to be an ordered set because we compute combined input digests
- /// using this later on.
- @override
- HashSet<AssetId> inputs;
-
- /// A digest combining all digests of all previous inputs.
- ///
- /// Used to determine whether all the inputs to a build step are identical to
- /// the previous run, indicating that the previous output is still valid.
- Digest previousInputsDigest;
-
- /// Whether the action which did or would produce this node failed.
- bool isFailure;
-
- /// The [AssetId] of the node representing the [BuilderOptions] used to create
- /// this node.
- final AssetId builderOptionsId;
-
- /// Whether the asset should be placed in the build cache.
- final bool isHidden;
-
- GeneratedAssetNode(
- AssetId id, {
- Digest lastKnownDigest,
- Iterable<AssetId> inputs,
- this.previousInputsDigest,
- @required this.isHidden,
- @required this.state,
- @required this.phaseNumber,
- @required this.wasOutput,
- @required this.isFailure,
- @required this.primaryInput,
- @required this.builderOptionsId,
- }) : inputs = inputs != null ? HashSet.from(inputs) : HashSet(),
- super(id, lastKnownDigest: lastKnownDigest);
-
- @override
- String toString() =>
- 'GeneratedAssetNode: $id generated from input $primaryInput.';
-}
-
-/// A node which is not a generated or source asset.
-///
-/// These are typically not readable or valid as inputs.
-abstract class _SyntheticAssetNode implements AssetNode {
- @override
- bool get isReadable => false;
-
- @override
- bool get isValidInput => false;
-}
-
-/// A [_SyntheticAssetNode] representing a non-existent source.
-///
-/// Typically these are created as a result of `canRead` calls for assets that
-/// don't exist in the graph. We still need to set up proper dependencies so
-/// that if that asset gets added later the outputs are properly invalidated.
-class SyntheticSourceAssetNode extends AssetNode with _SyntheticAssetNode {
- SyntheticSourceAssetNode(AssetId id) : super._forMixins(id);
-}
-
-/// A [_SyntheticAssetNode] which represents an individual [BuilderOptions]
-/// object.
-///
-/// These are used to track the state of a [BuilderOptions] object, and all
-/// [GeneratedAssetNode]s should depend on one of these nodes, which represents
-/// their configuration.
-class BuilderOptionsAssetNode extends AssetNode with _SyntheticAssetNode {
- BuilderOptionsAssetNode(AssetId id, Digest lastKnownDigest)
- : super._forMixinsWithDigest(id, lastKnownDigest);
-
- @override
- String toString() => 'BuildOptionsAssetNode: $id';
-}
-
-/// Placeholder assets are magic files that are usable as inputs but are not
-/// readable.
-class PlaceHolderAssetNode extends AssetNode with _SyntheticAssetNode {
- @override
- bool get isValidInput => true;
-
- PlaceHolderAssetNode(AssetId id) : super._forMixins(id);
-
- @override
- String toString() => 'PlaceHolderAssetNode: $id';
-}
-
-/// A [_SyntheticAssetNode] which is created for each [primaryInput] to a
-/// [PostBuildAction].
-///
-/// The [outputs] of this node are the individual outputs created for the
-/// [primaryInput] during the [PostBuildAction] at index [actionNumber].
-class PostProcessAnchorNode extends AssetNode with _SyntheticAssetNode {
- final int actionNumber;
- final AssetId builderOptionsId;
- final AssetId primaryInput;
- Digest previousInputsDigest;
-
- PostProcessAnchorNode(
- AssetId id, this.primaryInput, this.actionNumber, this.builderOptionsId,
- {this.previousInputsDigest})
- : super._forMixins(id);
-
- factory PostProcessAnchorNode.forInputAndAction(
- AssetId primaryInput, int actionNumber, AssetId builderOptionsId) {
- return PostProcessAnchorNode(
- primaryInput.addExtension('.post_anchor.$actionNumber'),
- primaryInput,
- actionNumber,
- builderOptionsId);
- }
-}
-
-/// A node representing a glob ran from a builder.
-///
-/// The [id] must always be unique to a given package, phase, and glob
-/// pattern.
-class GlobAssetNode extends InternalAssetNode implements NodeWithInputs {
- final Glob glob;
-
- /// All the potential inputs matching this glob.
- ///
- /// This field differs from [results] in that [GeneratedAssetNode] which may
- /// have been readable but were not output are included here and not in
- /// [results].
- @override
- HashSet<AssetId> inputs;
-
- @override
- bool get isReadable => false;
-
- @override
- final int phaseNumber;
-
- /// The actual results of the glob.
- List<AssetId> results;
-
- @override
- NodeState state;
-
- GlobAssetNode(AssetId id, this.glob, this.phaseNumber, this.state,
- {this.inputs, Digest lastKnownDigest, this.results})
- : super(id, lastKnownDigest: lastKnownDigest);
-
- static AssetId createId(String package, Glob glob, int phaseNum) => AssetId(
- package, 'glob.$phaseNum.${base64.encode(utf8.encode(glob.pattern))}');
-}
-
-/// A node which has [inputs], a [NodeState], and a [phaseNumber].
-abstract class NodeWithInputs implements AssetNode {
- HashSet<AssetId> inputs;
-
- int get phaseNumber;
-
- NodeState state;
-}
diff --git a/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart b/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart
deleted file mode 100644
index f5a40b4..0000000
--- a/build_runner_core/lib/src/asset_graph/optional_output_tracker.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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:build/build.dart';
-import 'package:build_runner_core/build_runner_core.dart';
-
-import '../generate/phase.dart';
-import '../util/build_dirs.dart';
-import 'graph.dart';
-import 'node.dart';
-
-/// A cache of the results of checking whether outputs from optional build steps
-/// were required by in the current build.
-///
-/// An optional output becomes required if:
-/// - Any of it's transitive outputs is required (based on the criteria below).
-/// - It was output by the same build step as any required output.
-///
-/// Any outputs from non-optional phases are considered required, unless the
-/// following are all true.
-/// - [_buildDirs] is non-empty.
-/// - The output lives in a non-lib directory.
-/// - The outputs path is not prefixed by one of [_buildDirs].
-/// - If [_buildFilters] is non-empty and the output doesn't match one of the
-/// filters.
-///
-/// Non-required optional output might still exist in the generated directory
-/// and the asset graph but we should avoid serving them, outputting them in
-/// the merged directories, or considering a failed output as an overall.
-class OptionalOutputTracker {
- final _checkedOutputs = <AssetId, bool>{};
- final AssetGraph _assetGraph;
- final Set<String> _buildDirs;
- final Set<BuildFilter> _buildFilters;
- final List<BuildPhase> _buildPhases;
-
- OptionalOutputTracker(
- this._assetGraph, this._buildDirs, this._buildFilters, this._buildPhases);
-
- /// Returns whether [output] is required.
- ///
- /// If necessary crawls transitive outputs that read [output] or any other
- /// assets generated by the same phase until it finds one which is required.
- ///
- /// [currentlyChecking] is used to aovid repeatedly checking the same outputs.
- bool isRequired(AssetId output, [Set<AssetId> currentlyChecking]) {
- currentlyChecking ??= <AssetId>{};
- if (currentlyChecking.contains(output)) return false;
- currentlyChecking.add(output);
-
- final node = _assetGraph.get(output);
- if (node is! GeneratedAssetNode) return true;
- final generatedNode = node as GeneratedAssetNode;
- final phase = _buildPhases[generatedNode.phaseNumber];
- if (!phase.isOptional &&
- shouldBuildForDirs(output, _buildDirs, _buildFilters, phase)) {
- return true;
- }
- return _checkedOutputs.putIfAbsent(
- output,
- () =>
- generatedNode.outputs
- .any((o) => isRequired(o, currentlyChecking)) ||
- _assetGraph
- .outputsForPhase(output.package, generatedNode.phaseNumber)
- .where((n) => n.primaryInput == generatedNode.primaryInput)
- .map((n) => n.id)
- .any((o) => isRequired(o, currentlyChecking)));
- }
-
- /// Clears the cache of which assets were required.
- ///
- /// If the tracker is used across multiple builds it must be reset in between
- /// each one.
- void reset() {
- _checkedOutputs.clear();
- }
-}
diff --git a/build_runner_core/lib/src/asset_graph/serialization.dart b/build_runner_core/lib/src/asset_graph/serialization.dart
deleted file mode 100644
index de14470..0000000
--- a/build_runner_core/lib/src/asset_graph/serialization.dart
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright (c) 2017, 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.
-
-part of 'graph.dart';
-
-/// Part of the serialized graph, used to ensure versioning constraints.
-///
-/// This should be incremented any time the serialize/deserialize formats
-/// change.
-const _version = 22;
-
-/// Deserializes an [AssetGraph] from a [Map].
-class _AssetGraphDeserializer {
- // Iteration order does not matter
- final _idToAssetId = HashMap<int, AssetId>();
- final Map _serializedGraph;
-
- _AssetGraphDeserializer._(this._serializedGraph);
-
- factory _AssetGraphDeserializer(List<int> bytes) {
- dynamic decoded;
- try {
- decoded = jsonDecode(utf8.decode(bytes));
- } on FormatException {
- throw AssetGraphCorruptedException();
- }
- if (decoded is! Map) throw AssetGraphCorruptedException();
- final serializedGraph = decoded as Map;
- if (serializedGraph['version'] != _version) {
- throw AssetGraphCorruptedException();
- }
- return _AssetGraphDeserializer._(serializedGraph);
- }
-
- /// Perform the deserialization, should only be called once.
- AssetGraph deserialize() {
- var graph = AssetGraph._(
- _deserializeDigest(_serializedGraph['buildActionsDigest'] as String),
- _serializedGraph['dart_version'] as String);
-
- var packageNames = _serializedGraph['packages'] as List;
-
- // Read in the id => AssetId map from the graph first.
- var assetPaths = _serializedGraph['assetPaths'] as List;
- for (var i = 0; i < assetPaths.length; i += 2) {
- var packageName = packageNames[assetPaths[i + 1] as int] as String;
- _idToAssetId[i ~/ 2] = AssetId(packageName, assetPaths[i] as String);
- }
-
- // Read in all the nodes and their outputs.
- //
- // Note that this does not read in the inputs of generated nodes.
- for (var serializedItem in _serializedGraph['nodes']) {
- graph._add(_deserializeAssetNode(serializedItem as List));
- }
-
- // Update the inputs of all generated nodes based on the outputs of the
- // current nodes.
- for (var node in graph.allNodes) {
- // These aren't explicitly added as inputs.
- if (node is BuilderOptionsAssetNode) continue;
-
- for (var output in node.outputs) {
- if (output == null) {
- log.severe('Found a null output from ${node.id} which is a '
- '${node.runtimeType}. If you encounter this error please copy '
- 'the details from this message and add them to '
- 'https://github.com/dart-lang/build/issues/1804.');
- throw AssetGraphCorruptedException();
- }
- var inputsNode = graph.get(output) as NodeWithInputs;
- if (inputsNode == null) {
- log.severe('Failed to locate $output referenced from ${node.id} '
- 'which is a ${node.runtimeType}. If you encounter this error '
- 'please copy the details from this message and add them to '
- 'https://github.com/dart-lang/build/issues/1804.');
- throw AssetGraphCorruptedException();
- }
- inputsNode.inputs ??= HashSet<AssetId>();
- inputsNode.inputs.add(node.id);
- }
-
- if (node is PostProcessAnchorNode) {
- graph.get(node.primaryInput).anchorOutputs.add(node.id);
- }
- }
-
- return graph;
- }
-
- AssetNode _deserializeAssetNode(List serializedNode) {
- AssetNode node;
- var typeId =
- _NodeType.values[serializedNode[_AssetField.NodeType.index] as int];
- var id = _idToAssetId[serializedNode[_AssetField.Id.index] as int];
- var serializedDigest = serializedNode[_AssetField.Digest.index] as String;
- var digest = _deserializeDigest(serializedDigest);
- switch (typeId) {
- case _NodeType.Source:
- assert(serializedNode.length == _WrappedAssetNode._length);
- node = SourceAssetNode(id, lastKnownDigest: digest);
- break;
- case _NodeType.SyntheticSource:
- assert(serializedNode.length == _WrappedAssetNode._length);
- node = SyntheticSourceAssetNode(id);
- break;
- case _NodeType.Generated:
- assert(serializedNode.length == _WrappedGeneratedAssetNode._length);
- var offset = _AssetField.values.length;
- node = GeneratedAssetNode(
- id,
- phaseNumber:
- serializedNode[_GeneratedField.PhaseNumber.index + offset] as int,
- primaryInput: _idToAssetId[
- serializedNode[_GeneratedField.PrimaryInput.index + offset]
- as int],
- state: NodeState.values[
- serializedNode[_GeneratedField.State.index + offset] as int],
- wasOutput: _deserializeBool(
- serializedNode[_GeneratedField.WasOutput.index + offset] as int),
- isFailure: _deserializeBool(
- serializedNode[_GeneratedField.IsFailure.index + offset] as int),
- builderOptionsId: _idToAssetId[
- serializedNode[_GeneratedField.BuilderOptions.index + offset]
- as int],
- lastKnownDigest: digest,
- previousInputsDigest: _deserializeDigest(serializedNode[
- _GeneratedField.PreviousInputsDigest.index + offset] as String),
- isHidden: _deserializeBool(
- serializedNode[_GeneratedField.IsHidden.index + offset] as int),
- );
- break;
- case _NodeType.Glob:
- assert(serializedNode.length == _WrappedGlobAssetNode._length);
- var offset = _AssetField.values.length;
- node = GlobAssetNode(
- id,
- Glob(serializedNode[_GlobField.Glob.index + offset] as String),
- serializedNode[_GlobField.PhaseNumber.index + offset] as int,
- NodeState
- .values[serializedNode[_GlobField.State.index + offset] as int],
- lastKnownDigest: digest,
- results: _deserializeAssetIds(
- serializedNode[_GlobField.Results.index + offset] as List)
- ?.toList(),
- );
- break;
- case _NodeType.Internal:
- assert(serializedNode.length == _WrappedAssetNode._length);
- node = InternalAssetNode(id, lastKnownDigest: digest);
- break;
- case _NodeType.BuilderOptions:
- assert(serializedNode.length == _WrappedAssetNode._length);
- node = BuilderOptionsAssetNode(id, digest);
- break;
- case _NodeType.Placeholder:
- assert(serializedNode.length == _WrappedAssetNode._length);
- node = PlaceHolderAssetNode(id);
- break;
- case _NodeType.PostProcessAnchor:
- assert(serializedNode.length == _WrappedPostProcessAnchorNode._length);
- var offset = _AssetField.values.length;
- node = PostProcessAnchorNode(
- id,
- _idToAssetId[
- serializedNode[_PostAnchorField.PrimaryInput.index + offset]
- as int],
- serializedNode[_PostAnchorField.ActionNumber.index + offset] as int,
- _idToAssetId[
- serializedNode[_PostAnchorField.BuilderOptions.index + offset]
- as int],
- previousInputsDigest: _deserializeDigest(serializedNode[
- _PostAnchorField.PreviousInputsDigest.index + offset]
- as String));
- break;
- }
- node.outputs.addAll(_deserializeAssetIds(
- serializedNode[_AssetField.Outputs.index] as List));
- node.primaryOutputs.addAll(_deserializeAssetIds(
- serializedNode[_AssetField.PrimaryOutputs.index] as List));
- node.deletedBy.addAll(_deserializeAssetIds(
- (serializedNode[_AssetField.DeletedBy.index] as List)?.cast<int>()));
- return node;
- }
-
- Iterable<AssetId> _deserializeAssetIds(List serializedIds) =>
- serializedIds.map((id) => _idToAssetId[id]);
-
- bool _deserializeBool(int value) => value != 0;
-}
-
-/// Serializes an [AssetGraph] into a [Map].
-class _AssetGraphSerializer {
- // Iteration order does not matter
- final _assetIdToId = HashMap<AssetId, int>();
-
- final AssetGraph _graph;
-
- _AssetGraphSerializer(this._graph);
-
- /// Perform the serialization, should only be called once.
- List<int> serialize() {
- var pathId = 0;
- // [path0, packageId0, path1, packageId1, ...]
- var assetPaths = <dynamic>[];
- var packages = _graph._nodesByPackage.keys.toList(growable: false);
- for (var node in _graph.allNodes) {
- _assetIdToId[node.id] = pathId;
- pathId++;
- assetPaths..add(node.id.path)..add(packages.indexOf(node.id.package));
- }
-
- var result = <String, dynamic>{
- 'version': _version,
- 'dart_version': _graph.dartVersion,
- 'nodes': _graph.allNodes.map(_serializeNode).toList(growable: false),
- 'buildActionsDigest': _serializeDigest(_graph.buildPhasesDigest),
- 'packages': packages,
- 'assetPaths': assetPaths,
- };
- return utf8.encode(json.encode(result));
- }
-
- List _serializeNode(AssetNode node) {
- if (node is GeneratedAssetNode) {
- return _WrappedGeneratedAssetNode(node, this);
- } else if (node is PostProcessAnchorNode) {
- return _WrappedPostProcessAnchorNode(node, this);
- } else if (node is GlobAssetNode) {
- return _WrappedGlobAssetNode(node, this);
- } else {
- return _WrappedAssetNode(node, this);
- }
- }
-
- int findAssetIndex(AssetId id,
- {@required AssetId from, @required String field}) {
- final index = _assetIdToId[id];
- if (index == null) {
- log.severe('The $field field in $from references a non-existent asset '
- '$id and will corrupt the asset graph. '
- 'If you encounter this error please copy '
- 'the details from this message and add them to '
- 'https://github.com/dart-lang/build/issues/1804.');
- }
- return index;
- }
-}
-
-/// Used to serialize the type of a node using an int.
-enum _NodeType {
- Source,
- SyntheticSource,
- Generated,
- Internal,
- BuilderOptions,
- Placeholder,
- PostProcessAnchor,
- Glob,
-}
-
-/// Field indexes for all [AssetNode]s
-enum _AssetField {
- NodeType,
- Id,
- Outputs,
- PrimaryOutputs,
- Digest,
- DeletedBy,
-}
-
-/// Field indexes for [GeneratedAssetNode]s
-enum _GeneratedField {
- PrimaryInput,
- WasOutput,
- IsFailure,
- PhaseNumber,
- State,
- PreviousInputsDigest,
- BuilderOptions,
- IsHidden,
-}
-
-/// Field indexes for [GlobAssetNode]s
-enum _GlobField {
- PhaseNumber,
- State,
- Glob,
- Results,
-}
-
-/// Field indexes for [PostProcessAnchorNode]s.
-enum _PostAnchorField {
- ActionNumber,
- BuilderOptions,
- PreviousInputsDigest,
- PrimaryInput,
-}
-
-/// Wraps an [AssetNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedAssetNode extends Object with ListMixin implements List {
- final AssetNode node;
- final _AssetGraphSerializer serializer;
-
- _WrappedAssetNode(this.node, this.serializer);
-
- static final int _length = _AssetField.values.length;
-
- @override
- int get length => _length;
-
- @override
- set length(void _) => throw UnsupportedError(
- 'length setter not unsupported for WrappedAssetNode');
-
- @override
- Object operator [](int index) {
- var fieldId = _AssetField.values[index];
- switch (fieldId) {
- case _AssetField.NodeType:
- if (node is SourceAssetNode) {
- return _NodeType.Source.index;
- } else if (node is GeneratedAssetNode) {
- return _NodeType.Generated.index;
- } else if (node is GlobAssetNode) {
- return _NodeType.Glob.index;
- } else if (node is SyntheticSourceAssetNode) {
- return _NodeType.SyntheticSource.index;
- } else if (node is InternalAssetNode) {
- return _NodeType.Internal.index;
- } else if (node is BuilderOptionsAssetNode) {
- return _NodeType.BuilderOptions.index;
- } else if (node is PlaceHolderAssetNode) {
- return _NodeType.Placeholder.index;
- } else if (node is PostProcessAnchorNode) {
- return _NodeType.PostProcessAnchor.index;
- } else {
- throw StateError('Unrecognized node type');
- }
- break;
- case _AssetField.Id:
- return serializer.findAssetIndex(node.id, from: node.id, field: 'id');
- case _AssetField.Outputs:
- return node.outputs
- .map((id) =>
- serializer.findAssetIndex(id, from: node.id, field: 'outputs'))
- .toList(growable: false);
- case _AssetField.PrimaryOutputs:
- return node.primaryOutputs
- .map((id) => serializer.findAssetIndex(id,
- from: node.id, field: 'primaryOutputs'))
- .toList(growable: false);
- case _AssetField.Digest:
- return _serializeDigest(node.lastKnownDigest);
- case _AssetField.DeletedBy:
- return node.deletedBy
- .map((id) => serializer.findAssetIndex(id,
- from: node.id, field: 'deletedBy'))
- .toList(growable: false);
- default:
- throw RangeError.index(index, this);
- }
- }
-
- @override
- operator []=(void _, void __) =>
- throw UnsupportedError('[]= not supported for WrappedAssetNode');
-}
-
-/// Wraps a [GeneratedAssetNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedGeneratedAssetNode extends _WrappedAssetNode {
- final GeneratedAssetNode generatedNode;
-
- /// Offset in the serialized format for additional fields in this class but
- /// not in [_WrappedAssetNode].
- ///
- /// Indexes below this number are forwarded to `super[index]`.
- static final int _serializedOffset = _AssetField.values.length;
-
- static final int _length = _serializedOffset + _GeneratedField.values.length;
-
- @override
- int get length => _length;
-
- _WrappedGeneratedAssetNode(
- this.generatedNode, _AssetGraphSerializer serializer)
- : super(generatedNode, serializer);
-
- @override
- Object operator [](int index) {
- if (index < _serializedOffset) return super[index];
- var fieldId = _GeneratedField.values[index - _serializedOffset];
- switch (fieldId) {
- case _GeneratedField.PrimaryInput:
- return generatedNode.primaryInput != null
- ? serializer.findAssetIndex(generatedNode.primaryInput,
- from: generatedNode.id, field: 'primaryInput')
- : null;
- case _GeneratedField.WasOutput:
- return _serializeBool(generatedNode.wasOutput);
- case _GeneratedField.IsFailure:
- return _serializeBool(generatedNode.isFailure);
- case _GeneratedField.PhaseNumber:
- return generatedNode.phaseNumber;
- case _GeneratedField.State:
- return generatedNode.state.index;
- case _GeneratedField.PreviousInputsDigest:
- return _serializeDigest(generatedNode.previousInputsDigest);
- case _GeneratedField.BuilderOptions:
- return serializer.findAssetIndex(generatedNode.builderOptionsId,
- from: generatedNode.id, field: 'builderOptions');
- case _GeneratedField.IsHidden:
- return _serializeBool(generatedNode.isHidden);
- default:
- throw RangeError.index(index, this);
- }
- }
-}
-
-/// Wraps a [GlobAssetNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedGlobAssetNode extends _WrappedAssetNode {
- final GlobAssetNode globNode;
-
- /// Offset in the serialized format for additional fields in this class but
- /// not in [_WrappedAssetNode].
- ///
- /// Indexes below this number are forwarded to `super[index]`.
- static final int _serializedOffset = _AssetField.values.length;
-
- static final int _length = _serializedOffset + _GlobField.values.length;
-
- @override
- int get length => _length;
-
- _WrappedGlobAssetNode(this.globNode, _AssetGraphSerializer serializer)
- : super(globNode, serializer);
-
- @override
- Object operator [](int index) {
- if (index < _serializedOffset) return super[index];
- var fieldId = _GlobField.values[index - _serializedOffset];
- switch (fieldId) {
- case _GlobField.PhaseNumber:
- return globNode.phaseNumber;
- case _GlobField.State:
- return globNode.state.index;
- case _GlobField.Glob:
- return globNode.glob.pattern;
- case _GlobField.Results:
- return globNode.results
- .map((id) => serializer.findAssetIndex(id,
- from: globNode.id, field: 'results'))
- .toList(growable: false);
- default:
- throw RangeError.index(index, this);
- }
- }
-}
-
-/// Wraps a [PostProcessAnchorNode] in a class that implements [List] instead of
-/// creating a new list for each one.
-class _WrappedPostProcessAnchorNode extends _WrappedAssetNode {
- final PostProcessAnchorNode wrappedNode;
-
- /// Offset in the serialized format for additional fields in this class but
- /// not in [_WrappedAssetNode].
- ///
- /// Indexes below this number are forwarded to `super[index]`.
- static final int _serializedOffset = _AssetField.values.length;
-
- static final int _length = _serializedOffset + _PostAnchorField.values.length;
-
- @override
- int get length => _length;
-
- _WrappedPostProcessAnchorNode(
- this.wrappedNode, _AssetGraphSerializer serializer)
- : super(wrappedNode, serializer);
-
- @override
- Object operator [](int index) {
- if (index < _serializedOffset) return super[index];
- var fieldId = _PostAnchorField.values[index - _serializedOffset];
- switch (fieldId) {
- case _PostAnchorField.ActionNumber:
- return wrappedNode.actionNumber;
- case _PostAnchorField.BuilderOptions:
- return serializer.findAssetIndex(wrappedNode.builderOptionsId,
- from: wrappedNode.id, field: 'builderOptions');
- case _PostAnchorField.PreviousInputsDigest:
- return _serializeDigest(wrappedNode.previousInputsDigest);
- case _PostAnchorField.PrimaryInput:
- return wrappedNode.primaryInput != null
- ? serializer.findAssetIndex(wrappedNode.primaryInput,
- from: wrappedNode.id, field: 'primaryInput')
- : null;
- default:
- throw RangeError.index(index, this);
- }
- }
-}
-
-Digest _deserializeDigest(String serializedDigest) =>
- serializedDigest == null ? null : Digest(base64.decode(serializedDigest));
-
-String _serializeDigest(Digest digest) =>
- digest == null ? null : base64.encode(digest.bytes);
-
-int _serializeBool(bool value) => value ? 1 : 0;
diff --git a/build_runner_core/lib/src/changes/build_script_updates.dart b/build_runner_core/lib/src/changes/build_script_updates.dart
deleted file mode 100644
index ed4c4f1..0000000
--- a/build_runner_core/lib/src/changes/build_script_updates.dart
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2017, 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:mirrors';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../asset/reader.dart';
-import '../asset_graph/graph.dart';
-import '../package_graph/package_graph.dart';
-
-/// Functionality for detecting if the build script itself or any of its
-/// transitive imports have changed.
-abstract class BuildScriptUpdates {
- /// Checks if the current running program has been updated, based on
- /// [updatedIds].
- bool hasBeenUpdated(Set<AssetId> updatedIds);
-
- /// Creates a [BuildScriptUpdates] object, using [reader] to ensure that
- /// the [assetGraph] is tracking digests for all transitive sources.
- ///
- /// If [disabled] is `true` then all checks are skipped and
- /// [hasBeenUpdated] will always return `false`.
- static Future<BuildScriptUpdates> create(RunnerAssetReader reader,
- PackageGraph packageGraph, AssetGraph assetGraph,
- {bool disabled = false}) async {
- disabled ??= false;
- if (disabled) return _NoopBuildScriptUpdates();
- return _MirrorBuildScriptUpdates.create(reader, packageGraph, assetGraph);
- }
-}
-
-/// Uses mirrors to find all transitive imports of the current script.
-class _MirrorBuildScriptUpdates implements BuildScriptUpdates {
- final Set<AssetId> _allSources;
- final bool _supportsIncrementalRebuilds;
-
- _MirrorBuildScriptUpdates._(
- this._supportsIncrementalRebuilds, this._allSources);
-
- static Future<BuildScriptUpdates> create(RunnerAssetReader reader,
- PackageGraph packageGraph, AssetGraph graph) async {
- var supportsIncrementalRebuilds = true;
- var rootPackage = packageGraph.root.name;
- Set<AssetId> allSources;
- var logger = Logger('BuildScriptUpdates');
- try {
- allSources = _urisForThisScript
- .map((id) => _idForUri(id, rootPackage))
- .where((id) => id != null)
- .toSet();
- var missing = allSources.firstWhere((id) => !graph.contains(id),
- orElse: () => null);
- if (missing != null) {
- supportsIncrementalRebuilds = false;
- logger.warning('$missing was not found in the asset graph, '
- 'incremental builds will not work.\n This probably means you '
- 'don\'t have your dependencies specified fully in your '
- 'pubspec.yaml.');
- } else {
- // Make sure we are tracking changes for all ids in [allSources].
- for (var id in allSources) {
- graph.get(id).lastKnownDigest ??= await reader.digest(id);
- }
- }
- } on ArgumentError catch (_) {
- supportsIncrementalRebuilds = false;
- allSources = <AssetId>{};
- }
- return _MirrorBuildScriptUpdates._(supportsIncrementalRebuilds, allSources);
- }
-
- static Iterable<Uri> get _urisForThisScript =>
- currentMirrorSystem().libraries.keys;
-
- /// Checks if the current running program has been updated, based on
- /// [updatedIds].
- @override
- bool hasBeenUpdated(Set<AssetId> updatedIds) {
- if (!_supportsIncrementalRebuilds) return true;
- return updatedIds.intersection(_allSources).isNotEmpty;
- }
-
- /// Attempts to return an [AssetId] for [uri].
- ///
- /// Returns `null` if the uri should be ignored, or throws an [ArgumentError]
- /// if the [uri] is not recognized.
- static AssetId _idForUri(Uri uri, String _rootPackage) {
- switch (uri.scheme) {
- case 'dart':
- // TODO: check for sdk updates!
- break;
- case 'package':
- var parts = uri.pathSegments;
- return AssetId(parts[0],
- p.url.joinAll(['lib', ...parts.getRange(1, parts.length)]));
- case 'file':
- var relativePath = p.relative(uri.toFilePath(), from: p.current);
- return AssetId(_rootPackage, relativePath);
- case 'data':
- // Test runner uses a `data` scheme, don't invalidate for those.
- if (uri.path.contains('package:test')) break;
- continue unsupported;
- case 'http':
- continue unsupported;
- unsupported:
- default:
- throw ArgumentError('Unsupported uri scheme `${uri.scheme}` found for '
- 'library in build script.\n'
- 'This probably means you are running in an unsupported '
- 'context, such as in an isolate or via `pub run`.\n'
- 'Full uri was: $uri.');
- }
- return null;
- }
-}
-
-/// Always returns false for [hasBeenUpdated], used when we want to skip
-/// the build script checks.
-class _NoopBuildScriptUpdates implements BuildScriptUpdates {
- @override
- bool hasBeenUpdated(void _) => false;
-}
diff --git a/build_runner_core/lib/src/environment/build_environment.dart b/build_runner_core/lib/src/environment/build_environment.dart
deleted file mode 100644
index 23335d8..0000000
--- a/build_runner_core/lib/src/environment/build_environment.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:logging/logging.dart';
-
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../generate/build_directory.dart';
-import '../generate/build_result.dart';
-import '../generate/finalized_assets_view.dart';
-
-/// Utilities to interact with the environment in which a build is running.
-///
-/// All side effects and user interaction should go through the build
-/// environment. An IO based environment can write to disk and interact through
-/// stdout/stdin, while a theoretical web or remote environment might interact
-/// over HTTP.
-abstract class BuildEnvironment {
- RunnerAssetReader get reader;
- RunnerAssetWriter get writer;
-
- void onLog(LogRecord record);
-
- /// Prompt the user for input.
- ///
- /// The message and choices are displayed to the user and the index of the
- /// chosen option is returned.
- ///
- /// If this environmment is non-interactive (such as when running in a test)
- /// this method should throw [NonInteractiveBuildException].
- Future<int> prompt(String message, List<String> choices);
-
- /// Invoked after each build, can modify the [BuildResult] in any way, even
- /// converting it to a failure.
- ///
- /// The [finalizedAssetsView] can only be used until the returned [Future]
- /// completes, it will expire afterwords since it can no longer guarantee a
- /// consistent state.
- ///
- /// By default this returns the original result.
- ///
- /// Any operation may be performed, as determined by environment.
- Future<BuildResult> finalizeBuild(
- BuildResult buildResult,
- FinalizedAssetsView finalizedAssetsView,
- AssetReader assetReader,
- Set<BuildDirectory> buildDirs) =>
- Future.value(buildResult);
-}
-
-/// Thrown when the build attempts to prompt the users but no prompt is
-/// possible.
-class NonInteractiveBuildException implements Exception {}
diff --git a/build_runner_core/lib/src/environment/create_merged_dir.dart b/build_runner_core/lib/src/environment/create_merged_dir.dart
deleted file mode 100644
index 24ea463..0000000
--- a/build_runner_core/lib/src/environment/create_merged_dir.dart
+++ /dev/null
@@ -1,323 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-import 'package:pool/pool.dart';
-
-import '../asset/reader.dart';
-import '../environment/build_environment.dart';
-import '../generate/build_directory.dart';
-import '../generate/finalized_assets_view.dart';
-import '../logging/logging.dart';
-import '../package_graph/package_graph.dart';
-
-/// Pool for async file operations, we don't want to use too many file handles.
-final _descriptorPool = Pool(32);
-
-final _logger = Logger('CreateOutputDir');
-const _manifestName = '.build.manifest';
-const _manifestSeparator = '\n';
-
-/// Creates merged output directories for each [OutputLocation].
-///
-/// Returns whether it succeeded or not.
-Future<bool> createMergedOutputDirectories(
- Set<BuildDirectory> buildDirs,
- PackageGraph packageGraph,
- BuildEnvironment environment,
- AssetReader reader,
- FinalizedAssetsView finalizedAssetsView,
- bool outputSymlinksOnly) async {
- if (outputSymlinksOnly && reader is! PathProvidingAssetReader) {
- _logger.severe(
- 'The current environment does not support symlinks, but symlinks were '
- 'requested.');
- return false;
- }
- var conflictingOutputs = _conflicts(buildDirs);
- if (conflictingOutputs.isNotEmpty) {
- _logger.severe('Unable to create merged directory. '
- 'Conflicting outputs for $conflictingOutputs');
- return false;
- }
-
- for (var target in buildDirs) {
- var output = target.outputLocation?.path;
- if (output != null) {
- if (!await _createMergedOutputDir(
- output,
- target.directory,
- packageGraph,
- environment,
- reader,
- finalizedAssetsView,
- // TODO(grouma) - retrieve symlink information from target only.
- outputSymlinksOnly || target.outputLocation.useSymlinks,
- target.outputLocation.hoist)) {
- _logger.severe('Unable to create merged directory for $output.');
- return false;
- }
- }
- }
- return true;
-}
-
-Set<String> _conflicts(Set<BuildDirectory> buildDirs) {
- final seen = <String>{};
- final conflicts = <String>{};
- var outputLocations =
- buildDirs.map((d) => d.outputLocation?.path).where((p) => p != null);
- for (var location in outputLocations) {
- if (!seen.add(location)) conflicts.add(location);
- }
- return conflicts;
-}
-
-Future<bool> _createMergedOutputDir(
- String outputPath,
- String root,
- PackageGraph packageGraph,
- BuildEnvironment environment,
- AssetReader reader,
- FinalizedAssetsView finalizedOutputsView,
- bool symlinkOnly,
- bool hoist) async {
- try {
- if (root == null) return false;
- var outputDir = Directory(outputPath);
- var outputDirExists = await outputDir.exists();
- if (outputDirExists) {
- if (!await _cleanUpOutputDir(outputDir, environment)) return false;
- }
- var builtAssets = finalizedOutputsView.allAssets(rootDir: root).toList();
- if (root != '' &&
- !builtAssets
- .where((id) => id.package == packageGraph.root.name)
- .any((id) => p.isWithin(root, id.path))) {
- _logger.severe('No assets exist in $root, skipping output');
- return false;
- }
-
- var outputAssets = <AssetId>[];
-
- await logTimedAsync(_logger, 'Creating merged output dir `$outputPath`',
- () async {
- if (!outputDirExists) {
- await outputDir.create(recursive: true);
- }
-
- outputAssets.addAll(await Future.wait(builtAssets.map((id) => _writeAsset(
- id, outputDir, root, packageGraph, reader, symlinkOnly, hoist))));
-
- var packagesFileContent = packageGraph.allPackages.keys
- .map((p) => '$p:packages/$p/')
- .join('\r\n');
- var packagesAsset = AssetId(packageGraph.root.name, '.packages');
- await _writeAsString(outputDir, packagesAsset, packagesFileContent);
- outputAssets.add(packagesAsset);
-
- if (!hoist) {
- for (var dir in _findRootDirs(builtAssets, outputPath)) {
- var link = Link(p.join(outputDir.path, dir, 'packages'));
- if (!link.existsSync()) {
- link.createSync(p.join('..', 'packages'), recursive: true);
- }
- }
- }
- });
-
- await logTimedAsync(_logger, 'Writing asset manifest', () async {
- var paths = outputAssets.map((id) => id.path).toList()..sort();
- var content = paths.join(_manifestSeparator);
- await _writeAsString(
- outputDir, AssetId(packageGraph.root.name, _manifestName), content);
- });
-
- return true;
- } on FileSystemException catch (e) {
- if (e.osError?.errorCode != 1314) rethrow;
- var devModeLink =
- 'https://docs.microsoft.com/en-us/windows/uwp/get-started/'
- 'enable-your-device-for-development';
- _logger.severe('Unable to create symlink ${e.path}. Note that to create '
- 'symlinks on windows you need to either run in a console with admin '
- 'privileges or enable developer mode (see $devModeLink).');
- return false;
- }
-}
-
-Set<String> _findRootDirs(Iterable<AssetId> allAssets, String outputPath) {
- var rootDirs = <String>{};
- for (var id in allAssets) {
- var parts = p.url.split(id.path);
- if (parts.length == 1) continue;
- var dir = parts.first;
- if (dir == outputPath || dir == 'lib') continue;
- rootDirs.add(parts.first);
- }
- return rootDirs;
-}
-
-Future<AssetId> _writeAsset(
- AssetId id,
- Directory outputDir,
- String root,
- PackageGraph packageGraph,
- AssetReader reader,
- bool symlinkOnly,
- bool hoist) {
- return _descriptorPool.withResource(() async {
- String assetPath;
- if (id.path.startsWith('lib/')) {
- assetPath =
- p.url.join('packages', id.package, id.path.substring('lib/'.length));
- } else {
- assetPath = id.path;
- assert(id.package == packageGraph.root.name);
- if (hoist && p.isWithin(root, id.path)) {
- assetPath = p.relative(id.path, from: root);
- }
- }
-
- var outputId = AssetId(packageGraph.root.name, assetPath);
- try {
- if (symlinkOnly) {
- await Link(_filePathFor(outputDir, outputId)).create(
- // We assert at the top of `createMergedOutputDirectories` that the
- // reader implements this type when requesting symlinks.
- (reader as PathProvidingAssetReader).pathTo(id),
- recursive: true);
- } else {
- await _writeAsBytes(outputDir, outputId, await reader.readAsBytes(id));
- }
- } on AssetNotFoundException catch (e, __) {
- if (p.basename(id.path).startsWith('.')) {
- _logger.fine('Skipping missing hidden file ${id.path}');
- } else {
- _logger.severe(
- 'Missing asset ${e.assetId}, it may have been deleted during the '
- 'build. Please try rebuilding and if you continue to see the '
- 'error then file a bug at '
- 'https://github.com/dart-lang/build/issues/new.');
- rethrow;
- }
- }
- return outputId;
- });
-}
-
-Future<void> _writeAsBytes(Directory outputDir, AssetId id, List<int> bytes) =>
- _fileFor(outputDir, id).then((file) => file.writeAsBytes(bytes));
-
-Future<void> _writeAsString(Directory outputDir, AssetId id, String contents) =>
- _fileFor(outputDir, id).then((file) => file.writeAsString(contents));
-
-Future<File> _fileFor(Directory outputDir, AssetId id) {
- return File(_filePathFor(outputDir, id)).create(recursive: true);
-}
-
-String _filePathFor(Directory outputDir, AssetId id) {
- String relativePath;
- if (id.path.startsWith('lib')) {
- relativePath =
- p.join('packages', id.package, p.joinAll(p.url.split(id.path).skip(1)));
- } else {
- relativePath = id.path;
- }
- return p.join(outputDir.path, relativePath);
-}
-
-/// Checks for a manifest file in [outputDir] and deletes all referenced files.
-///
-/// Prompts the user with a few options if no manifest file is found.
-///
-/// Returns whether or not the directory was successfully cleaned up.
-Future<bool> _cleanUpOutputDir(
- Directory outputDir, BuildEnvironment environment) async {
- var outputPath = outputDir.path;
- var manifestFile = File(p.join(outputPath, _manifestName));
- if (!manifestFile.existsSync()) {
- if (outputDir.listSync(recursive: false).isNotEmpty) {
- var choices = [
- 'Leave the directory unchanged and skip writing the build output',
- 'Delete the directory and all contents',
- 'Leave the directory in place and write over any existing files',
- ];
- int choice;
- try {
- choice = await environment.prompt(
- 'Found existing directory `$outputPath` but no manifest file.\n'
- 'Please choose one of the following options:',
- choices);
- } on NonInteractiveBuildException catch (_) {
- _logger.severe('Unable to create merged directory at $outputPath.\n'
- 'Choose a different directory or delete the contents of that '
- 'directory.');
- return false;
- }
- switch (choice) {
- case 0:
- _logger.severe('Skipped creation of the merged output directory.');
- return false;
- case 1:
- try {
- outputDir.deleteSync(recursive: true);
- } catch (e) {
- _logger.severe(
- 'Failed to delete output dir at `$outputPath` with error:\n\n'
- '$e');
- return false;
- }
- // Actually recreate the directory, but as an empty one.
- outputDir.createSync();
- break;
- case 2:
- // Just do nothing here, we overwrite files by default.
- break;
- }
- }
- } else {
- var previousOutputs = logTimedSync(
- _logger,
- 'Reading manifest at ${manifestFile.path}',
- () => manifestFile.readAsStringSync().split(_manifestSeparator));
-
- logTimedSync(_logger, 'Deleting previous outputs in `$outputPath`', () {
- for (var path in previousOutputs) {
- var file = File(p.join(outputPath, path));
- if (file.existsSync()) file.deleteSync();
- }
- _cleanEmptyDirectories(outputPath, previousOutputs);
- });
- }
- return true;
-}
-
-/// Deletes all the directories which used to contain any path in
-/// [removedFilePaths] if that directory is now empty.
-void _cleanEmptyDirectories(
- String outputPath, Iterable<String> removedFilePaths) {
- for (var directory in removedFilePaths
- .map((path) => p.join(outputPath, p.dirname(path)))
- .toSet()) {
- _deleteUp(directory, outputPath);
- }
-}
-
-/// Deletes the directory at [from] and and any parent directories which are
-/// subdirectories of [to] if they are empty.
-void _deleteUp(String from, String to) {
- var directoryPath = from;
- while (p.isWithin(to, directoryPath)) {
- var directory = Directory(directoryPath);
- if (!directory.existsSync() || directory.listSync().isNotEmpty) return;
- directory.deleteSync();
- directoryPath = p.dirname(directoryPath);
- }
-}
diff --git a/build_runner_core/lib/src/environment/io_environment.dart b/build_runner_core/lib/src/environment/io_environment.dart
deleted file mode 100644
index a2d4948..0000000
--- a/build_runner_core/lib/src/environment/io_environment.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:logging/logging.dart';
-
-import '../asset/file_based.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../generate/build_directory.dart';
-import '../generate/build_result.dart';
-import '../generate/finalized_assets_view.dart';
-import '../package_graph/package_graph.dart';
-import 'build_environment.dart';
-import 'create_merged_dir.dart';
-
-final _logger = Logger('IOEnvironment');
-
-/// A [BuildEnvironment] writing to disk and stdout.
-class IOEnvironment implements BuildEnvironment {
- @override
- final RunnerAssetReader reader;
-
- @override
- final RunnerAssetWriter writer;
-
- final bool _isInteractive;
-
- final bool _outputSymlinksOnly;
-
- final PackageGraph _packageGraph;
-
- IOEnvironment(this._packageGraph, {bool assumeTty, bool outputSymlinksOnly})
- : _isInteractive = assumeTty == true || _canPrompt(),
- _outputSymlinksOnly = outputSymlinksOnly ?? false,
- reader = FileBasedAssetReader(_packageGraph),
- writer = FileBasedAssetWriter(_packageGraph) {
- if (_outputSymlinksOnly && Platform.isWindows) {
- _logger.warning('Symlinks to files are not yet working on Windows, you '
- 'may experience issues using this mode. Follow '
- 'https://github.com/dart-lang/sdk/issues/33966 for updates.');
- }
- }
-
- @override
- void onLog(LogRecord record) {
- if (record.level >= Level.SEVERE) {
- stderr.writeln(record);
- } else {
- stdout.writeln(record);
- }
- }
-
- @override
- Future<int> prompt(String message, List<String> choices) async {
- if (!_isInteractive) throw NonInteractiveBuildException();
- while (true) {
- stdout.writeln('\n$message');
- for (var i = 0, l = choices.length; i < l; i++) {
- stdout.writeln('${i + 1} - ${choices[i]}');
- }
- final input = stdin.readLineSync();
- final choice = int.tryParse(input) ?? -1;
- if (choice > 0 && choice <= choices.length) return choice - 1;
- stdout.writeln('Unrecognized option $input, '
- 'a number between 1 and ${choices.length} expected');
- }
- }
-
- @override
- Future<BuildResult> finalizeBuild(
- BuildResult buildResult,
- FinalizedAssetsView finalizedAssetsView,
- AssetReader reader,
- Set<BuildDirectory> buildDirs) async {
- if (buildDirs.any(
- (target) => target.outputLocation?.path?.isNotEmpty ?? false) &&
- buildResult.status == BuildStatus.success) {
- if (!await createMergedOutputDirectories(buildDirs, _packageGraph, this,
- reader, finalizedAssetsView, _outputSymlinksOnly)) {
- return _convertToFailure(buildResult,
- failureType: FailureType.cantCreate);
- }
- }
- return buildResult;
- }
-}
-
-bool _canPrompt() =>
- stdioType(stdin) == StdioType.terminal &&
- // Assume running inside a test if the code is running as a `data:` URI
- Platform.script.scheme != 'data';
-
-BuildResult _convertToFailure(BuildResult previous,
- {FailureType failureType}) =>
- BuildResult(
- BuildStatus.failure,
- previous.outputs,
- performance: previous.performance,
- failureType: failureType,
- );
diff --git a/build_runner_core/lib/src/environment/overridable_environment.dart b/build_runner_core/lib/src/environment/overridable_environment.dart
deleted file mode 100644
index a5575aa..0000000
--- a/build_runner_core/lib/src/environment/overridable_environment.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:logging/logging.dart';
-
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../generate/build_directory.dart';
-import '../generate/build_result.dart';
-import '../generate/finalized_assets_view.dart';
-import 'build_environment.dart';
-
-/// A [BuildEnvironment] which can have individual features overridden.
-class OverrideableEnvironment implements BuildEnvironment {
- final BuildEnvironment _default;
-
- final RunnerAssetReader _reader;
- final RunnerAssetWriter _writer;
-
- final void Function(LogRecord) _onLog;
-
- final Future<BuildResult> Function(
- BuildResult, FinalizedAssetsView, AssetReader, Set<BuildDirectory>)
- _finalizeBuild;
-
- OverrideableEnvironment(
- this._default, {
- RunnerAssetReader reader,
- RunnerAssetWriter writer,
- void Function(LogRecord) onLog,
- Future<BuildResult> Function(
- BuildResult, FinalizedAssetsView, AssetReader, Set<BuildDirectory>)
- finalizeBuild,
- }) : _reader = reader,
- _writer = writer,
- _onLog = onLog,
- _finalizeBuild = finalizeBuild;
-
- @override
- RunnerAssetReader get reader => _reader ?? _default.reader;
-
- @override
- RunnerAssetWriter get writer => _writer ?? _default.writer;
-
- @override
- Future<BuildResult> finalizeBuild(
- BuildResult buildResult,
- FinalizedAssetsView finalizedAssetsView,
- AssetReader reader,
- Set<BuildDirectory> buildDirs) =>
- (_finalizeBuild ?? _default.finalizeBuild)(
- buildResult, finalizedAssetsView, reader, buildDirs);
-
- @override
- void onLog(LogRecord record) {
- if (_onLog != null) {
- _onLog(record);
- } else {
- _default.onLog(record);
- }
- }
-
- @override
- Future<int> prompt(String message, List<String> choices) =>
- _default.prompt(message, choices);
-}
diff --git a/build_runner_core/lib/src/generate/build_definition.dart b/build_runner_core/lib/src/generate/build_definition.dart
deleted file mode 100644
index 447ef22..0000000
--- a/build_runner_core/lib/src/generate/build_definition.dart
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright (c) 2017, 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 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:watcher/watcher.dart';
-
-import '../asset/build_cache.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../asset_graph/exceptions.dart';
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../changes/build_script_updates.dart';
-import '../environment/build_environment.dart';
-import '../logging/failure_reporter.dart';
-import '../logging/logging.dart';
-import '../package_graph/package_graph.dart';
-import '../package_graph/target_graph.dart';
-import '../util/constants.dart';
-import '../util/sdk_version_match.dart';
-import 'exceptions.dart';
-import 'options.dart';
-import 'phase.dart';
-
-final _logger = Logger('BuildDefinition');
-
-class BuildDefinition {
- final AssetGraph assetGraph;
- final TargetGraph targetGraph;
-
- final AssetReader reader;
- final RunnerAssetWriter writer;
-
- final PackageGraph packageGraph;
- final bool deleteFilesByDefault;
- final ResourceManager resourceManager;
-
- final BuildScriptUpdates buildScriptUpdates;
-
- /// Whether or not to run in a mode that conserves RAM at the cost of build
- /// speed.
- final bool enableLowResourcesMode;
-
- final BuildEnvironment environment;
-
- BuildDefinition._(
- this.assetGraph,
- this.targetGraph,
- this.reader,
- this.writer,
- this.packageGraph,
- this.deleteFilesByDefault,
- this.resourceManager,
- this.buildScriptUpdates,
- this.enableLowResourcesMode,
- this.environment);
-
- static Future<BuildDefinition> prepareWorkspace(BuildEnvironment environment,
- BuildOptions options, List<BuildPhase> buildPhases) =>
- _Loader(environment, options, buildPhases).prepareWorkspace();
-}
-
-/// Understands how to find all assets relevant to a build as well as compute
-/// updates to those assets.
-class AssetTracker {
- final AssetGraph _assetGraph;
- final RunnerAssetReader _reader;
- final TargetGraph _targetGraph;
-
- AssetTracker(this._assetGraph, this._reader, this._targetGraph);
-
- /// Checks for and returns any file system changes compared to the current
- /// state of the asset graph.
- Future<Map<AssetId, ChangeType>> collectChanges() async {
- var inputSources = await _findInputSources();
- var generatedSources = await _findCacheDirSources();
- var internalSources = await _findInternalSources();
- return _computeSourceUpdates(
- inputSources, generatedSources, internalSources);
- }
-
- /// Returns the all the sources found in the cache directory.
- Future<Set<AssetId>> _findCacheDirSources() =>
- _listGeneratedAssetIds().toSet();
-
- /// Returns the set of original package inputs on disk.
- Future<Set<AssetId>> _findInputSources() {
- final targets =
- Stream<TargetNode>.fromIterable(_targetGraph.allModules.values);
- return targets.asyncExpand(_listAssetIds).toSet();
- }
-
- /// Returns all the internal sources, such as those under [entryPointDir].
- Future<Set<AssetId>> _findInternalSources() =>
- _listIdsSafe(Glob('$entryPointDir/**')).toSet();
-
- /// Finds the asset changes which have happened while unwatched between builds
- /// by taking a difference between the assets in the graph and the assets on
- /// disk.
- Future<Map<AssetId, ChangeType>> _computeSourceUpdates(
- Set<AssetId> inputSources,
- Set<AssetId> generatedSources,
- Set<AssetId> internalSources) async {
- final allSources = <AssetId>{}
- ..addAll(inputSources)
- ..addAll(generatedSources)
- ..addAll(internalSources);
- var updates = <AssetId, ChangeType>{};
- void addUpdates(Iterable<AssetId> assets, ChangeType type) {
- for (var asset in assets) {
- updates[asset] = type;
- }
- }
-
- var newSources = inputSources.difference(_assetGraph.allNodes
- .where((node) => node.isValidInput)
- .map((node) => node.id)
- .toSet());
- addUpdates(newSources, ChangeType.ADD);
- var removedAssets = _assetGraph.allNodes
- .where((n) {
- if (!n.isReadable) return false;
- if (n is GeneratedAssetNode) return n.wasOutput;
- return true;
- })
- .map((n) => n.id)
- .where((id) => !allSources.contains(id));
-
- addUpdates(removedAssets, ChangeType.REMOVE);
-
- var originalGraphSources = _assetGraph.sources.toSet();
- var preExistingSources = originalGraphSources.intersection(inputSources)
- ..addAll(internalSources.where(_assetGraph.contains));
- var modifyChecks = preExistingSources.map((id) async {
- var node = _assetGraph.get(id);
- assert(node != null);
- var originalDigest = node.lastKnownDigest;
- if (originalDigest == null) return;
- var currentDigest = await _reader.digest(id);
- if (currentDigest != originalDigest) {
- updates[id] = ChangeType.MODIFY;
- }
- });
- await Future.wait(modifyChecks);
- return updates;
- }
-
- Stream<AssetId> _listAssetIds(TargetNode targetNode) => targetNode
- .sourceIncludes.isEmpty
- ? Stream<AssetId>.empty()
- : StreamGroup.merge(targetNode.sourceIncludes.map((glob) =>
- _listIdsSafe(glob, package: targetNode.package.name)
- .where((id) =>
- targetNode.package.isRoot || id.pathSegments.first == 'lib')
- .where((id) => !targetNode.excludesSource(id))));
-
- Stream<AssetId> _listGeneratedAssetIds() {
- var glob = Glob('$generatedOutputDirectory/**');
-
- return _listIdsSafe(glob).map((id) {
- var packagePath = id.path.substring(generatedOutputDirectory.length + 1);
- var firstSlash = packagePath.indexOf('/');
- if (firstSlash == -1) return null;
- var package = packagePath.substring(0, firstSlash);
- var path = packagePath.substring(firstSlash + 1);
- return AssetId(package, path);
- }).where((id) => id != null);
- }
-
- /// Lists asset ids and swallows file not found errors.
- ///
- /// Ideally we would warn but in practice the default whitelist will give this
- /// error a lot and it would be noisy.
- Stream<AssetId> _listIdsSafe(Glob glob, {String package}) =>
- _reader.findAssets(glob, package: package).handleError((void _) {},
- test: (e) => e is FileSystemException && e.osError.errorCode == 2);
-}
-
-class _Loader {
- final List<BuildPhase> _buildPhases;
- final BuildOptions _options;
- final BuildEnvironment _environment;
-
- _Loader(this._environment, this._options, this._buildPhases);
-
- Future<BuildDefinition> prepareWorkspace() async {
- _checkBuildPhases();
-
- _logger.info('Initializing inputs');
-
- var assetGraph = await _tryReadCachedAssetGraph();
- var assetTracker =
- AssetTracker(assetGraph, _environment.reader, _options.targetGraph);
- var inputSources = await assetTracker._findInputSources();
- var cacheDirSources = await assetTracker._findCacheDirSources();
- var internalSources = await assetTracker._findInternalSources();
-
- BuildScriptUpdates buildScriptUpdates;
- if (assetGraph != null) {
- var updates = await logTimedAsync(
- _logger,
- 'Checking for updates since last build',
- () => _updateAssetGraph(assetGraph, assetTracker, _buildPhases,
- inputSources, cacheDirSources, internalSources));
-
- buildScriptUpdates = await BuildScriptUpdates.create(
- _environment.reader, _options.packageGraph, assetGraph,
- disabled: _options.skipBuildScriptCheck);
- if (!_options.skipBuildScriptCheck &&
- buildScriptUpdates.hasBeenUpdated(updates.keys.toSet())) {
- _logger.warning('Invalidating asset graph due to build script update!');
- var deletedSourceOutputs = await _cleanupOldOutputs(assetGraph);
-
- if (_runningFromSnapshot) {
- // We have to be regenerated if running from a snapshot.
- throw BuildScriptChangedException();
- }
-
- inputSources.removeAll(deletedSourceOutputs);
- assetGraph = null;
- buildScriptUpdates = null;
- }
- }
-
- if (assetGraph == null) {
- Set<AssetId> conflictingOutputs;
-
- await logTimedAsync(_logger, 'Building new asset graph', () async {
- try {
- assetGraph = await AssetGraph.build(_buildPhases, inputSources,
- internalSources, _options.packageGraph, _environment.reader);
- } on DuplicateAssetNodeException catch (e, st) {
- _logger.severe('Conflicting outputs', e, st);
- throw CannotBuildException();
- }
- buildScriptUpdates = await BuildScriptUpdates.create(
- _environment.reader, _options.packageGraph, assetGraph,
- disabled: _options.skipBuildScriptCheck);
- conflictingOutputs = assetGraph.outputs
- .where((n) => n.package == _options.packageGraph.root.name)
- .where(inputSources.contains)
- .toSet();
- final conflictsInDeps = assetGraph.outputs
- .where((n) => n.package != _options.packageGraph.root.name)
- .where(inputSources.contains)
- .toSet();
- if (conflictsInDeps.isNotEmpty) {
- log.severe('There are existing files in dependencies which conflict '
- 'with files that a Builder may produce. These must be removed or '
- 'the Builders disabled before a build can continue: '
- '${conflictsInDeps.map((a) => a.uri).join('\n')}');
- throw CannotBuildException();
- }
- });
-
- await logTimedAsync(
- _logger,
- 'Checking for unexpected pre-existing outputs.',
- () => _initialBuildCleanup(conflictingOutputs,
- _wrapWriter(_environment.writer, assetGraph)));
- }
-
- return BuildDefinition._(
- assetGraph,
- _options.targetGraph,
- _wrapReader(_environment.reader, assetGraph),
- _wrapWriter(_environment.writer, assetGraph),
- _options.packageGraph,
- _options.deleteFilesByDefault,
- ResourceManager(),
- buildScriptUpdates,
- _options.enableLowResourcesMode,
- _environment);
- }
-
- /// Checks that the [_buildPhases] are valid based on whether they are
- /// written to the build cache.
- void _checkBuildPhases() {
- final root = _options.packageGraph.root.name;
- for (final action in _buildPhases) {
- if (!action.hideOutput) {
- // Only `InBuildPhase`s can be not hidden.
- if (action is InBuildPhase && action.package != root) {
- // This should happen only with a manual build script since the build
- // script generation filters these out.
- _logger.severe('A build phase (${action.builderLabel}) is attempting '
- 'to operate on package "${action.package}", but the build script '
- 'is located in package "$root". It\'s not valid to attempt to '
- 'generate files for another package unless the BuilderApplication'
- 'specified "hideOutput".'
- '\n\n'
- 'Did you mean to write:\n'
- ' new BuilderApplication(..., toRoot())\n'
- 'or\n'
- ' new BuilderApplication(..., hideOutput: true)\n'
- '... instead?');
- throw CannotBuildException();
- }
- }
- }
- }
-
- /// Deletes the generated output directory.
- ///
- /// Typically this should be done whenever an asset graph is thrown away.
- Future<void> _deleteGeneratedDir() async {
- var generatedDir = Directory(generatedOutputDirectory);
- if (await generatedDir.exists()) {
- await generatedDir.delete(recursive: true);
- }
- }
-
- /// Attempts to read in an [AssetGraph] from disk, and returns `null` if it
- /// fails for any reason.
- Future<AssetGraph> _tryReadCachedAssetGraph() async {
- final assetGraphId =
- AssetId(_options.packageGraph.root.name, assetGraphPath);
- if (!await _environment.reader.canRead(assetGraphId)) {
- return null;
- }
-
- return logTimedAsync(_logger, 'Reading cached asset graph', () async {
- try {
- var cachedGraph = AssetGraph.deserialize(
- await _environment.reader.readAsBytes(assetGraphId));
- if (computeBuildPhasesDigest(_buildPhases) !=
- cachedGraph.buildPhasesDigest) {
- _logger.warning(
- 'Throwing away cached asset graph because the build phases have '
- 'changed. This most commonly would happen as a result of adding a '
- 'new dependency or updating your dependencies.');
- await Future.wait([
- _cleanupOldOutputs(cachedGraph),
- FailureReporter.cleanErrorCache(),
- ]);
- if (_runningFromSnapshot) {
- throw BuildScriptChangedException();
- }
- return null;
- }
- if (!isSameSdkVersion(cachedGraph.dartVersion, Platform.version)) {
- _logger.warning(
- 'Throwing away cached asset graph due to Dart SDK update.');
- await Future.wait([
- _cleanupOldOutputs(cachedGraph),
- FailureReporter.cleanErrorCache(),
- ]);
- if (_runningFromSnapshot) {
- throw BuildScriptChangedException();
- }
- return null;
- }
- return cachedGraph;
- } on AssetGraphCorruptedException catch (_) {
- // Start fresh if the cached asset_graph cannot be deserialized
- _logger.warning('Throwing away cached asset graph due to '
- 'version mismatch or corrupted asset graph.');
- await Future.wait([
- _deleteGeneratedDir(),
- FailureReporter.cleanErrorCache(),
- ]);
- return null;
- }
- });
- }
-
- /// Deletes all the old outputs from [graph] that were written to the source
- /// tree, and deletes the entire generated directory.
- Future<Iterable<AssetId>> _cleanupOldOutputs(AssetGraph graph) async {
- var deletedSources = <AssetId>[];
- await logTimedAsync(_logger, 'Cleaning up outputs from previous builds.',
- () async {
- // Delete all the non-hidden outputs.
- await Future.wait(graph.outputs.map((id) {
- var node = graph.get(id) as GeneratedAssetNode;
- if (node.wasOutput && !node.isHidden) {
- var idToDelete = id;
- // If the package no longer exists, then the user must have renamed
- // the root package.
- //
- // In that case we change `idToDelete` to be in the root package.
- if (_options.packageGraph[id.package] == null) {
- idToDelete = AssetId(_options.packageGraph.root.name, id.path);
- }
- deletedSources.add(idToDelete);
- return _environment.writer.delete(idToDelete);
- }
- return null;
- }).whereType<Future>());
-
- await _deleteGeneratedDir();
- });
- return deletedSources;
- }
-
- /// Updates [assetGraph] based on a the new view of the world.
- ///
- /// Once done, this returns a map of [AssetId] to [ChangeType] for all the
- /// changes.
- Future<Map<AssetId, ChangeType>> _updateAssetGraph(
- AssetGraph assetGraph,
- AssetTracker assetTracker,
- List<BuildPhase> buildPhases,
- Set<AssetId> inputSources,
- Set<AssetId> cacheDirSources,
- Set<AssetId> internalSources) async {
- var updates = await assetTracker._computeSourceUpdates(
- inputSources, cacheDirSources, internalSources);
- updates.addAll(_computeBuilderOptionsUpdates(assetGraph, buildPhases));
- await assetGraph.updateAndInvalidate(
- _buildPhases,
- updates,
- _options.packageGraph.root.name,
- (id) => _wrapWriter(_environment.writer, assetGraph).delete(id),
- _wrapReader(_environment.reader, assetGraph));
- return updates;
- }
-
- /// Wraps [original] in a [BuildCacheWriter].
- RunnerAssetWriter _wrapWriter(
- RunnerAssetWriter original, AssetGraph assetGraph) {
- assert(assetGraph != null);
- return BuildCacheWriter(
- original, assetGraph, _options.packageGraph.root.name);
- }
-
- /// Wraps [original] in a [BuildCacheReader].
- AssetReader _wrapReader(AssetReader original, AssetGraph assetGraph) {
- assert(assetGraph != null);
- return BuildCacheReader(
- original, assetGraph, _options.packageGraph.root.name);
- }
-
- /// Checks for any updates to the [BuilderOptionsAssetNode]s for
- /// [buildPhases] compared to the last known state.
- Map<AssetId, ChangeType> _computeBuilderOptionsUpdates(
- AssetGraph assetGraph, List<BuildPhase> buildPhases) {
- var result = <AssetId, ChangeType>{};
-
- void updateBuilderOptionsNode(
- AssetId builderOptionsId, BuilderOptions options) {
- var builderOptionsNode =
- assetGraph.get(builderOptionsId) as BuilderOptionsAssetNode;
- var oldDigest = builderOptionsNode.lastKnownDigest;
- builderOptionsNode.lastKnownDigest = computeBuilderOptionsDigest(options);
- if (builderOptionsNode.lastKnownDigest != oldDigest) {
- result[builderOptionsId] = ChangeType.MODIFY;
- }
- }
-
- for (var phase = 0; phase < buildPhases.length; phase++) {
- var action = buildPhases[phase];
- if (action is InBuildPhase) {
- updateBuilderOptionsNode(
- builderOptionsIdForAction(action, phase), action.builderOptions);
- } else if (action is PostBuildPhase) {
- var actionNum = 0;
- for (var builderAction in action.builderActions) {
- updateBuilderOptionsNode(
- builderOptionsIdForAction(builderAction, actionNum),
- builderAction.builderOptions);
- actionNum++;
- }
- }
- }
- return result;
- }
-
- /// Handles cleanup of pre-existing outputs for initial builds (where there is
- /// no cached graph).
- Future<void> _initialBuildCleanup(
- Set<AssetId> conflictingAssets, RunnerAssetWriter writer) async {
- if (conflictingAssets.isEmpty) return;
-
- // Skip the prompt if using this option.
- if (_options.deleteFilesByDefault) {
- _logger.info('Deleting ${conflictingAssets.length} declared outputs '
- 'which already existed on disk.');
- await Future.wait(conflictingAssets.map((id) => writer.delete(id)));
- return;
- }
-
- // Prompt the user to delete files that are declared as outputs.
- _logger.info('Found ${conflictingAssets.length} declared outputs '
- 'which already exist on disk. This is likely because the'
- '`$cacheDir` folder was deleted, or you are submitting generated '
- 'files to your source repository.');
-
- var done = false;
- while (!done) {
- try {
- var choice = await _environment.prompt('Delete these files?',
- ['Delete', 'Cancel build', 'List conflicts']);
- switch (choice) {
- case 0:
- _logger.info('Deleting files...');
- done = true;
- await Future.wait(conflictingAssets.map((id) => writer.delete(id)));
- break;
- case 1:
- _logger.severe('The build will not be able to contiue until the '
- 'conflicting assets are removed or the Builders which may '
- 'output them are disabled. The outputs are: '
- '${conflictingAssets.map((a) => a.path).join('\n')}');
- throw CannotBuildException();
- break;
- case 2:
- _logger.info('Conflicts:\n${conflictingAssets.join('\n')}');
- // Logging should be sync :(
- await Future(() {});
- }
- } on NonInteractiveBuildException {
- _logger.severe('Conflicting outputs were detected and the build '
- 'is unable to prompt for permission to remove them. '
- 'These outputs must be removed manually or the build can be '
- 'run with `--delete-conflicting-outputs`. The outputs are: '
- '${conflictingAssets.map((a) => a.path).join('\n')}');
- throw CannotBuildException();
- }
- }
- }
-}
-
-bool get _runningFromSnapshot => !Platform.script.path.endsWith('.dart');
diff --git a/build_runner_core/lib/src/generate/build_directory.dart b/build_runner_core/lib/src/generate/build_directory.dart
deleted file mode 100644
index bbfedff..0000000
--- a/build_runner_core/lib/src/generate/build_directory.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2019, 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 '../util/hash.dart';
-
-class BuildDirectory {
- final String directory;
- final OutputLocation outputLocation;
- BuildDirectory(this.directory, {this.outputLocation});
-
- @override
- bool operator ==(Object other) =>
- other is BuildDirectory &&
- other.directory == directory &&
- other.outputLocation == outputLocation;
-
- @override
- int get hashCode {
- var hash = 0;
- hash = hashCombine(hash, directory.hashCode);
- hash = hashCombine(hash, outputLocation.hashCode);
- return hashComplete(hash);
- }
-}
-
-class OutputLocation {
- final String path;
- final bool useSymlinks;
- final bool hoist;
- OutputLocation(this.path, {bool useSymlinks, bool hoist})
- : useSymlinks = useSymlinks ?? false,
- hoist = hoist ?? true {
- if (path.isEmpty && hoist) {
- throw ArgumentError('Can not build everything and hoist');
- }
- }
-
- @override
- bool operator ==(Object other) =>
- other is OutputLocation &&
- other.path == path &&
- other.useSymlinks == useSymlinks &&
- other.hoist == hoist;
-
- @override
- int get hashCode {
- var hash = 0;
- hash = hashCombine(hash, path.hashCode);
- hash = hashCombine(hash, useSymlinks.hashCode);
- hash = hashCombine(hash, hoist.hashCode);
- return hashComplete(hash);
- }
-}
diff --git a/build_runner_core/lib/src/generate/build_impl.dart b/build_runner_core/lib/src/generate/build_impl.dart
deleted file mode 100644
index 4c3180a..0000000
--- a/build_runner_core/lib/src/generate/build_impl.dart
+++ /dev/null
@@ -1,896 +0,0 @@
-// Copyright (c) 2016, 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:collection';
-import 'dart:convert';
-import 'dart:typed_data';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
-import 'package:pool/pool.dart';
-import 'package:watcher/watcher.dart';
-
-import '../asset/cache.dart';
-import '../asset/finalized_reader.dart';
-import '../asset/reader.dart';
-import '../asset/writer.dart';
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../asset_graph/optional_output_tracker.dart';
-import '../changes/build_script_updates.dart';
-import '../environment/build_environment.dart';
-import '../logging/build_for_input_logger.dart';
-import '../logging/failure_reporter.dart';
-import '../logging/human_readable_duration.dart';
-import '../logging/logging.dart';
-import '../package_graph/apply_builders.dart';
-import '../package_graph/package_graph.dart';
-import '../performance_tracking/performance_tracking_resolvers.dart';
-import '../util/async.dart';
-import '../util/build_dirs.dart';
-import '../util/constants.dart';
-import 'build_definition.dart';
-import 'build_directory.dart';
-import 'build_result.dart';
-import 'finalized_assets_view.dart';
-import 'heartbeat.dart';
-import 'options.dart';
-import 'performance_tracker.dart';
-import 'phase.dart';
-
-final _logger = Logger('Build');
-
-Set<String> _buildPaths(Set<BuildDirectory> buildDirs) =>
- // The empty string means build everything.
- buildDirs.any((b) => b.directory == '')
- ? <String>{}
- : buildDirs.map((b) => b.directory).toSet();
-
-class BuildImpl {
- final FinalizedReader finalizedReader;
-
- final AssetGraph assetGraph;
-
- final BuildScriptUpdates buildScriptUpdates;
-
- final List<BuildPhase> _buildPhases;
- final PackageGraph _packageGraph;
- final AssetReader _reader;
- final Resolvers _resolvers;
- final ResourceManager _resourceManager;
- final RunnerAssetWriter _writer;
- final bool _trackPerformance;
- final BuildEnvironment _environment;
- final String _logPerformanceDir;
-
- Future<void> beforeExit() => _resourceManager.beforeExit();
-
- BuildImpl._(BuildDefinition buildDefinition, BuildOptions options,
- this._buildPhases, this.finalizedReader)
- : buildScriptUpdates = buildDefinition.buildScriptUpdates,
- _packageGraph = buildDefinition.packageGraph,
- _reader = options.enableLowResourcesMode
- ? buildDefinition.reader
- : CachingAssetReader(buildDefinition.reader),
- _resolvers = options.resolvers,
- _writer = buildDefinition.writer,
- assetGraph = buildDefinition.assetGraph,
- _resourceManager = buildDefinition.resourceManager,
- _environment = buildDefinition.environment,
- _trackPerformance = options.trackPerformance,
- _logPerformanceDir = options.logPerformanceDir;
-
- Future<BuildResult> run(Map<AssetId, ChangeType> updates,
- {Set<BuildDirectory> buildDirs, Set<BuildFilter> buildFilters}) {
- buildDirs ??= <BuildDirectory>{};
- buildFilters ??= {};
- finalizedReader.reset(_buildPaths(buildDirs), buildFilters);
- return _SingleBuild(this, buildDirs, buildFilters).run(updates)
- ..whenComplete(_resolvers.reset);
- }
-
- static Future<BuildImpl> create(
- BuildOptions options,
- BuildEnvironment environment,
- List<BuilderApplication> builders,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- {bool isReleaseBuild = false}) async {
- // Don't allow any changes to the generated asset directory after this
- // point.
- lockGeneratedOutputDirectory();
-
- var buildPhases = await createBuildPhases(
- options.targetGraph, builders, builderConfigOverrides, isReleaseBuild);
- if (buildPhases.isEmpty) {
- _logger.severe('Nothing can be built, yet a build was requested.');
- }
- var buildDefinition = await BuildDefinition.prepareWorkspace(
- environment, options, buildPhases);
- var singleStepReader = SingleStepReader(
- buildDefinition.reader,
- buildDefinition.assetGraph,
- buildPhases.length,
- options.packageGraph.root.name,
- _isReadableAfterBuildFactory(buildPhases));
- var finalizedReader = FinalizedReader(
- singleStepReader,
- buildDefinition.assetGraph,
- buildPhases,
- options.packageGraph.root.name);
- var build =
- BuildImpl._(buildDefinition, options, buildPhases, finalizedReader);
- return build;
- }
-
- static IsReadable _isReadableAfterBuildFactory(List<BuildPhase> buildPhases) {
- return (AssetNode node, int phaseNum, AssetWriterSpy writtenAssets) {
- if (node is GeneratedAssetNode) {
- return Readability.fromPreviousPhase(node.wasOutput && !node.isFailure);
- }
-
- return Readability.fromPreviousPhase(
- node.isReadable && node.isValidInput);
- };
- }
-}
-
-/// Performs a single build and manages state that only lives for a single
-/// build.
-class _SingleBuild {
- final AssetGraph _assetGraph;
- final Set<BuildFilter> _buildFilters;
- final List<BuildPhase> _buildPhases;
- final List<Pool> _buildPhasePool;
- final BuildEnvironment _environment;
- final _lazyPhases = <String, Future<Iterable<AssetId>>>{};
- final _lazyGlobs = <AssetId, Future<void>>{};
- final PackageGraph _packageGraph;
- final BuildPerformanceTracker _performanceTracker;
- final AssetReader _reader;
- final Resolvers _resolvers;
- final ResourceManager _resourceManager;
- final RunnerAssetWriter _writer;
- final Set<BuildDirectory> _buildDirs;
- final String _logPerformanceDir;
- final _failureReporter = FailureReporter();
-
- int actionsCompletedCount = 0;
- int actionsStartedCount = 0;
-
- final pendingActions = SplayTreeMap<int, Set<String>>();
-
- /// Can't be final since it needs access to [pendingActions].
- HungActionsHeartbeat hungActionsHeartbeat;
-
- _SingleBuild(BuildImpl buildImpl, Set<BuildDirectory> buildDirs,
- Set<BuildFilter> buildFilters)
- : _assetGraph = buildImpl.assetGraph,
- _buildFilters = buildFilters,
- _buildPhases = buildImpl._buildPhases,
- _buildPhasePool = List(buildImpl._buildPhases.length),
- _environment = buildImpl._environment,
- _packageGraph = buildImpl._packageGraph,
- _performanceTracker = buildImpl._trackPerformance
- ? BuildPerformanceTracker()
- : BuildPerformanceTracker.noOp(),
- _reader = buildImpl._reader,
- _resolvers = buildImpl._resolvers,
- _resourceManager = buildImpl._resourceManager,
- _writer = buildImpl._writer,
- _buildDirs = buildDirs,
- _logPerformanceDir = buildImpl._logPerformanceDir {
- hungActionsHeartbeat = HungActionsHeartbeat(() {
- final message = StringBuffer();
- const actionsToLogMax = 5;
- var descriptions = pendingActions.values.fold(
- <String>[],
- (combined, actions) =>
- combined..addAll(actions)).take(actionsToLogMax);
- for (final description in descriptions) {
- message.writeln(' - $description');
- }
- var additionalActionsCount =
- actionsStartedCount - actionsCompletedCount - actionsToLogMax;
- if (additionalActionsCount > 0) {
- message.writeln(' .. and $additionalActionsCount more');
- }
- return '$message';
- });
- }
-
- Future<BuildResult> run(Map<AssetId, ChangeType> updates) async {
- var watch = Stopwatch()..start();
- var result = await _safeBuild(updates);
- var optionalOutputTracker = OptionalOutputTracker(
- _assetGraph, _buildPaths(_buildDirs), _buildFilters, _buildPhases);
- if (result.status == BuildStatus.success) {
- final failures = _assetGraph.failedOutputs
- .where((n) => optionalOutputTracker.isRequired(n.id));
- if (failures.isNotEmpty) {
- await _failureReporter.reportErrors(failures);
- result = BuildResult(BuildStatus.failure, result.outputs,
- performance: result.performance);
- }
- }
- await _resourceManager.disposeAll();
- result = await _environment.finalizeBuild(
- result,
- FinalizedAssetsView(_assetGraph, optionalOutputTracker),
- _reader,
- _buildDirs);
- if (result.status == BuildStatus.success) {
- _logger.info('Succeeded after ${humanReadable(watch.elapsed)} with '
- '${result.outputs.length} outputs '
- '($actionsCompletedCount actions)\n');
- } else {
- _logger.severe('Failed after ${humanReadable(watch.elapsed)}');
- }
- return result;
- }
-
- Future<void> _updateAssetGraph(Map<AssetId, ChangeType> updates) async {
- await logTimedAsync(_logger, 'Updating asset graph', () async {
- var invalidated = await _assetGraph.updateAndInvalidate(
- _buildPhases, updates, _packageGraph.root.name, _delete, _reader);
- if (_reader is CachingAssetReader) {
- (_reader as CachingAssetReader).invalidate(invalidated);
- }
- });
- }
-
- /// Runs a build inside a zone with an error handler and stack chain
- /// capturing.
- Future<BuildResult> _safeBuild(Map<AssetId, ChangeType> updates) {
- var done = Completer<BuildResult>();
-
- var heartbeat = HeartbeatLogger(
- transformLog: (original) => '$original, ${_buildProgress()}',
- waitDuration: Duration(seconds: 1))
- ..start();
- hungActionsHeartbeat.start();
- done.future.whenComplete(() {
- heartbeat.stop();
- hungActionsHeartbeat.stop();
- });
-
- runZoned(() async {
- if (updates.isNotEmpty) {
- await _updateAssetGraph(updates);
- }
- // Run a fresh build.
- var result = await logTimedAsync(_logger, 'Running build', _runPhases);
-
- // Write out the dependency graph file.
- await logTimedAsync(_logger, 'Caching finalized dependency graph',
- () async {
- await _writer.writeAsBytes(
- AssetId(_packageGraph.root.name, assetGraphPath),
- _assetGraph.serialize());
- });
-
- // Log performance information if requested
- if (_logPerformanceDir != null) {
- assert(result.performance != null);
- var now = DateTime.now();
- var logPath = p.join(
- _logPerformanceDir,
- '${now.year}-${_twoDigits(now.month)}-${_twoDigits(now.day)}'
- '_${_twoDigits(now.hour)}-${_twoDigits(now.minute)}-'
- '${_twoDigits(now.second)}');
- await logTimedAsync(_logger, 'Writing performance log to $logPath', () {
- var performanceLogId = AssetId(_packageGraph.root.name, logPath);
- var serialized = jsonEncode(result.performance);
- return _writer.writeAsString(performanceLogId, serialized);
- });
- }
-
- if (!done.isCompleted) done.complete(result);
- }, onError: (Object e, StackTrace st) {
- if (!done.isCompleted) {
- _logger.severe('Unhandled build failure!', e, st);
- done.complete(BuildResult(BuildStatus.failure, []));
- }
- });
- return done.future;
- }
-
- /// Returns a message describing the progress of the current build.
- String _buildProgress() =>
- '$actionsCompletedCount/$actionsStartedCount actions completed.';
-
- /// Runs the actions in [_buildPhases] and returns a [Future<BuildResult>]
- /// which completes once all [BuildPhase]s are done.
- Future<BuildResult> _runPhases() {
- return _performanceTracker.track(() async {
- final outputs = <AssetId>[];
- for (var phaseNum = 0; phaseNum < _buildPhases.length; phaseNum++) {
- var phase = _buildPhases[phaseNum];
- if (phase.isOptional) continue;
- outputs
- .addAll(await _performanceTracker.trackBuildPhase(phase, () async {
- if (phase is InBuildPhase) {
- var primaryInputs =
- await _matchingPrimaryInputs(phase.package, phaseNum);
- return _runBuilder(phaseNum, phase, primaryInputs);
- } else if (phase is PostBuildPhase) {
- return _runPostProcessPhase(phaseNum, phase);
- } else {
- throw StateError('Unrecognized BuildPhase type $phase');
- }
- }));
- }
- await Future.forEach(
- _lazyPhases.values,
- (Future<Iterable<AssetId>> lazyOuts) async =>
- outputs.addAll(await lazyOuts));
- // Assume success, `_assetGraph.failedOutputs` will be checked later.
- return BuildResult(BuildStatus.success, outputs,
- performance: _performanceTracker);
- });
- }
-
- /// Gets a list of all inputs matching the [phaseNumber], as well as
- /// its [Builder]s primary inputs.
- ///
- /// Lazily builds any optional build actions that might potentially produce
- /// a primary input to this phase.
- Future<Set<AssetId>> _matchingPrimaryInputs(
- String package, int phaseNumber) async {
- var ids = <AssetId>{};
- var phase = _buildPhases[phaseNumber];
- await Future.wait(
- _assetGraph.outputsForPhase(package, phaseNumber).map((node) async {
- if (!shouldBuildForDirs(
- node.id, _buildPaths(_buildDirs), _buildFilters, phase)) {
- return;
- }
-
- var input = _assetGraph.get(node.primaryInput);
- if (input is GeneratedAssetNode) {
- if (input.state != NodeState.upToDate) {
- await _runLazyPhaseForInput(input.phaseNumber, input.primaryInput);
- }
- if (!input.wasOutput) return;
- if (input.isFailure) return;
- }
- ids.add(input.id);
- }));
- return ids;
- }
-
- /// Runs a normal builder with [primaryInputs] as inputs and returns only the
- /// outputs that were newly created.
- ///
- /// Does not return outputs that didn't need to be re-ran or were declared
- /// but not output.
- Future<Iterable<AssetId>> _runBuilder(int phaseNumber, InBuildPhase action,
- Iterable<AssetId> primaryInputs) async {
- var outputLists = await Future.wait(
- primaryInputs.map((input) => _runForInput(phaseNumber, action, input)));
- return outputLists.fold<List<AssetId>>(
- <AssetId>[], (combined, next) => combined..addAll(next));
- }
-
- /// Lazily runs [phaseNumber] with [input]..
- Future<Iterable<AssetId>> _runLazyPhaseForInput(
- int phaseNumber, AssetId input) {
- return _lazyPhases.putIfAbsent('$phaseNumber|$input', () async {
- // First check if `input` is generated, and whether or not it was
- // actually output. If it wasn't then we just return an empty list here.
- var inputNode = _assetGraph.get(input);
- if (inputNode is GeneratedAssetNode) {
- // Make sure the `inputNode` is up to date, and rebuild it if not.
- if (inputNode.state != NodeState.upToDate) {
- await _runLazyPhaseForInput(
- inputNode.phaseNumber, inputNode.primaryInput);
- }
- if (!inputNode.wasOutput || inputNode.isFailure) return <AssetId>[];
- }
-
- // We can never lazily build `PostProcessBuildAction`s.
- var action = _buildPhases[phaseNumber] as InBuildPhase;
-
- return _runForInput(phaseNumber, action, input);
- });
- }
-
- /// Checks whether [node] can be read by this step - attempting to build the
- /// asset if necessary.
- FutureOr<Readability> _isReadableNode(
- AssetNode node, int phaseNum, AssetWriterSpy writtenAssets) {
- if (node is GeneratedAssetNode) {
- if (node.phaseNumber > phaseNum) {
- return Readability.notReadable;
- } else if (node.phaseNumber == phaseNum) {
- // allow a build step to read its outputs (contained in writtenAssets)
- final isInBuild = _buildPhases[phaseNum] is InBuildPhase &&
- writtenAssets.assetsWritten.contains(node.id);
-
- return isInBuild ? Readability.ownOutput : Readability.notReadable;
- }
-
- return doAfter(
- // ignore: void_checks
- _ensureAssetIsBuilt(node),
- (_) =>
- Readability.fromPreviousPhase(node.wasOutput && !node.isFailure));
- }
- return Readability.fromPreviousPhase(node.isReadable && node.isValidInput);
- }
-
- FutureOr<void> _ensureAssetIsBuilt(AssetNode node) {
- if (node is GeneratedAssetNode && node.state != NodeState.upToDate) {
- return _runLazyPhaseForInput(node.phaseNumber, node.primaryInput);
- }
- return null;
- }
-
- Future<Iterable<AssetId>> _runForInput(
- int phaseNumber, InBuildPhase phase, AssetId input) {
- var pool = _buildPhasePool[phaseNumber] ??= Pool(buildPhasePoolSize);
- return pool.withResource(() {
- final builder = phase.builder;
- var tracker =
- _performanceTracker.addBuilderAction(input, phase.builderLabel);
- return tracker.track(() async {
- var builderOutputs = expectedOutputs(builder, input);
-
- // Add `builderOutputs` to the primary outputs of the input.
- var inputNode = _assetGraph.get(input);
- assert(inputNode != null,
- 'Inputs should be known in the static graph. Missing $input');
- assert(
- inputNode.primaryOutputs.containsAll(builderOutputs),
- 'input $input with builder $builder missing primary outputs: \n'
- 'Got ${inputNode.primaryOutputs.join(', ')} '
- 'which was missing:\n' +
- builderOutputs
- .where((id) => !inputNode.primaryOutputs.contains(id))
- .join(', '));
-
- var wrappedWriter = AssetWriterSpy(_writer);
-
- var wrappedReader = SingleStepReader(_reader, _assetGraph, phaseNumber,
- input.package, _isReadableNode, _getUpdatedGlobNode, wrappedWriter);
-
- if (!await tracker.trackStage(
- 'Setup', () => _buildShouldRun(builderOutputs, wrappedReader))) {
- return <AssetId>[];
- }
-
- await _cleanUpStaleOutputs(builderOutputs);
- await FailureReporter.clean(phaseNumber, input);
-
- // We may have read some inputs in the call to `_buildShouldRun`, we want
- // to remove those.
- wrappedReader.assetsRead.clear();
-
- var actionDescription =
- _actionLoggerName(phase, input, _packageGraph.root.name);
- var logger = BuildForInputLogger(Logger(actionDescription));
-
- actionsStartedCount++;
- pendingActions
- .putIfAbsent(phaseNumber, () => <String>{})
- .add(actionDescription);
-
- var unusedAssets = <AssetId>{};
- await tracker.trackStage(
- 'Build',
- () => runBuilder(
- builder,
- [input],
- wrappedReader,
- wrappedWriter,
- PerformanceTrackingResolvers(_resolvers, tracker),
- logger: logger,
- resourceManager: _resourceManager,
- stageTracker: tracker,
- reportUnusedAssetsForInput: (_, assets) =>
- unusedAssets.addAll(assets),
- ).catchError((void _) {
- // Errors tracked through the logger
- }));
- actionsCompletedCount++;
- hungActionsHeartbeat.ping();
- pendingActions[phaseNumber].remove(actionDescription);
-
- // Reset the state for all the `builderOutputs` nodes based on what was
- // read and written.
- await tracker.trackStage(
- 'Finalize',
- () => _setOutputsState(
- builderOutputs,
- wrappedReader,
- wrappedWriter,
- actionDescription,
- logger.errorsSeen,
- unusedAssets: unusedAssets,
- ));
-
- return wrappedWriter.assetsWritten;
- });
- });
- }
-
- Future<Iterable<AssetId>> _runPostProcessPhase(
- int phaseNum, PostBuildPhase phase) async {
- var actionNum = 0;
- var outputLists = await Future.wait(phase.builderActions
- .map((action) => _runPostProcessAction(phaseNum, actionNum++, action)));
- return outputLists.fold<List<AssetId>>(
- <AssetId>[], (combined, next) => combined..addAll(next));
- }
-
- Future<Iterable<AssetId>> _runPostProcessAction(
- int phaseNum, int actionNum, PostBuildAction action) async {
- var anchorNodes = _assetGraph.packageNodes(action.package).where((node) {
- if (node is PostProcessAnchorNode && node.actionNumber == actionNum) {
- var inputNode = _assetGraph.get(node.primaryInput);
- if (inputNode is SourceAssetNode) {
- return true;
- } else if (inputNode is GeneratedAssetNode) {
- return inputNode.wasOutput &&
- !inputNode.isFailure &&
- inputNode.state == NodeState.upToDate;
- }
- }
- return false;
- }).cast<PostProcessAnchorNode>();
- var outputLists = await Future.wait(anchorNodes.map((anchorNode) =>
- _runPostProcessBuilderForAnchor(
- phaseNum, actionNum, action.builder, anchorNode)));
- return outputLists.fold<List<AssetId>>(
- <AssetId>[], (combined, next) => combined..addAll(next));
- }
-
- Future<Iterable<AssetId>> _runPostProcessBuilderForAnchor(
- int phaseNum,
- int actionNum,
- PostProcessBuilder builder,
- PostProcessAnchorNode anchorNode) async {
- var input = anchorNode.primaryInput;
- var inputNode = _assetGraph.get(input);
- assert(inputNode != null,
- 'Inputs should be known in the static graph. Missing $input');
-
- var wrappedWriter = AssetWriterSpy(_writer);
- var wrappedReader = SingleStepReader(_reader, _assetGraph, phaseNum,
- input.package, _isReadableNode, null, wrappedWriter);
-
- if (!await _postProcessBuildShouldRun(anchorNode, wrappedReader)) {
- return <AssetId>[];
- }
- // We may have read some inputs in the call to `_buildShouldRun`, we want
- // to remove those.
- wrappedReader.assetsRead.clear();
-
- // Clean out the impacts of the previous run
- await FailureReporter.clean(phaseNum, input);
- await _cleanUpStaleOutputs(anchorNode.outputs);
- anchorNode.outputs
- ..toList().forEach(_assetGraph.remove)
- ..clear();
- inputNode.deletedBy.remove(anchorNode.id);
-
- var actionDescription = '$builder on $input';
- var logger = BuildForInputLogger(Logger(actionDescription));
-
- actionsStartedCount++;
- pendingActions
- .putIfAbsent(phaseNum, () => <String>{})
- .add(actionDescription);
-
- await runPostProcessBuilder(
- builder, input, wrappedReader, wrappedWriter, logger,
- addAsset: (assetId) {
- if (_assetGraph.contains(assetId)) {
- throw InvalidOutputException(assetId, 'Asset already exists');
- }
- var node = GeneratedAssetNode(assetId,
- primaryInput: input,
- builderOptionsId: anchorNode.builderOptionsId,
- isHidden: true,
- phaseNumber: phaseNum,
- wasOutput: true,
- isFailure: false,
- state: NodeState.upToDate);
- _assetGraph.add(node);
- anchorNode.outputs.add(assetId);
- }, deleteAsset: (assetId) {
- if (!_assetGraph.contains(assetId)) {
- throw AssetNotFoundException(assetId);
- }
- if (assetId != input) {
- throw InvalidOutputException(assetId, 'Can only delete primary input');
- }
- _assetGraph.get(assetId).deletedBy.add(anchorNode.id);
- }).catchError((void _) {
- // Errors tracked through the logger
- });
- actionsCompletedCount++;
- hungActionsHeartbeat.ping();
- pendingActions[phaseNum].remove(actionDescription);
-
- var assetsWritten = wrappedWriter.assetsWritten.toSet();
-
- // Reset the state for all the output nodes based on what was read and
- // written.
- inputNode.primaryOutputs.addAll(assetsWritten);
- await _setOutputsState(assetsWritten, wrappedReader, wrappedWriter,
- actionDescription, logger.errorsSeen);
-
- return assetsWritten;
- }
-
- /// Checks and returns whether any [outputs] need to be updated.
- Future<bool> _buildShouldRun(
- Iterable<AssetId> outputs, AssetReader reader) async {
- assert(
- outputs.every(_assetGraph.contains),
- 'Outputs should be known statically. Missing '
- '${outputs.where((o) => !_assetGraph.contains(o)).toList()}');
- assert(outputs.isNotEmpty, 'Can\'t run a build with no outputs');
-
- // We only check the first output, because all outputs share the same inputs
- // and invalidation state.
- var firstOutput = outputs.first;
- var node = _assetGraph.get(firstOutput) as GeneratedAssetNode;
- assert(
- outputs.skip(1).every((output) =>
- (_assetGraph.get(output) as GeneratedAssetNode)
- .inputs
- .difference(node.inputs)
- .isEmpty),
- 'All outputs of a build action should share the same inputs.');
-
- // No need to build an up to date output
- if (node.state == NodeState.upToDate) return false;
- // Early bail out condition, this is a forced update.
- if (node.state == NodeState.definitelyNeedsUpdate) return true;
- // This is a fresh build or the first time we've seen this output.
- if (node.previousInputsDigest == null) return true;
-
- var digest = await _computeCombinedDigest(
- node.inputs, node.builderOptionsId, reader);
- if (digest != node.previousInputsDigest) {
- return true;
- } else {
- // Make sure to update the `state` field for all outputs.
- for (var id in outputs) {
- (_assetGraph.get(id) as NodeWithInputs).state = NodeState.upToDate;
- }
- return false;
- }
- }
-
- /// Checks if a post process build should run based on [anchorNode].
- Future<bool> _postProcessBuildShouldRun(
- PostProcessAnchorNode anchorNode, AssetReader reader) async {
- var inputsDigest = await _computeCombinedDigest(
- [anchorNode.primaryInput], anchorNode.builderOptionsId, reader);
-
- if (inputsDigest != anchorNode.previousInputsDigest) {
- anchorNode.previousInputsDigest = inputsDigest;
- return true;
- }
-
- return false;
- }
-
- /// Deletes any of [outputs] which previously were output.
- ///
- /// This should be called after deciding that an asset really needs to be
- /// regenerated based on its inputs hash changing. All assets in [outputs]
- /// must correspond to a [GeneratedAssetNode].
- Future<void> _cleanUpStaleOutputs(Iterable<AssetId> outputs) =>
- Future.wait(outputs
- .map(_assetGraph.get)
- .cast<GeneratedAssetNode>()
- .where((n) => n.wasOutput)
- .map((n) => _delete(n.id)));
-
- Future<GlobAssetNode> _getUpdatedGlobNode(
- Glob glob, String package, int phaseNum) {
- var globNodeId = GlobAssetNode.createId(package, glob, phaseNum);
- var globNode = _assetGraph.get(globNodeId) as GlobAssetNode;
- if (globNode == null) {
- globNode = GlobAssetNode(
- globNodeId, glob, phaseNum, NodeState.definitelyNeedsUpdate);
- _assetGraph.add(globNode);
- }
-
- return toFuture(doAfter(
- // ignore: void_checks
- _updateGlobNodeIfNecessary(globNode),
- (_) => globNode));
- }
-
- FutureOr<void> _updateGlobNodeIfNecessary(GlobAssetNode globNode) {
- if (globNode.state == NodeState.upToDate) return null;
-
- return _lazyGlobs.putIfAbsent(globNode.id, () async {
- var potentialNodes = _assetGraph
- .packageNodes(globNode.id.package)
- .where((n) => n.isReadable && n.isValidInput)
- .where((n) =>
- n is! GeneratedAssetNode ||
- (n as GeneratedAssetNode).phaseNumber < globNode.phaseNumber)
- .where((n) => globNode.glob.matches(n.id.path))
- .toList();
-
- await Future.wait(potentialNodes
- .whereType<GeneratedAssetNode>()
- .map(_ensureAssetIsBuilt)
- .map(toFuture));
-
- var actualMatches = <AssetId>[];
- for (var node in potentialNodes) {
- node.outputs.add(globNode.id);
- if (node is GeneratedAssetNode && (!node.wasOutput || node.isFailure)) {
- continue;
- }
- actualMatches.add(node.id);
- }
-
- globNode
- ..results = actualMatches
- ..inputs = HashSet.of(potentialNodes.map((n) => n.id))
- ..state = NodeState.upToDate
- ..lastKnownDigest =
- md5.convert(utf8.encode(globNode.results.join(' ')));
-
- unawaited(_lazyGlobs.remove(globNode.id));
- });
- }
-
- /// Computes a single [Digest] based on the combined [Digest]s of [ids] and
- /// [builderOptionsId].
- Future<Digest> _computeCombinedDigest(Iterable<AssetId> ids,
- AssetId builderOptionsId, AssetReader reader) async {
- var combinedBytes = Uint8List.fromList(List.filled(16, 0));
- void _combine(Uint8List other) {
- assert(other.length == 16);
- assert(other is Uint8List);
- for (var i = 0; i < 16; i++) {
- combinedBytes[i] ^= other[i];
- }
- }
-
- var builderOptionsNode = _assetGraph.get(builderOptionsId);
- _combine(builderOptionsNode.lastKnownDigest.bytes as Uint8List);
-
- // Limit the total number of digests we are computing at a time. Otherwise
- // this can overload the event queue.
- await Future.wait(ids.map((id) async {
- var node = _assetGraph.get(id);
- if (node is GlobAssetNode) {
- await _updateGlobNodeIfNecessary(node);
- } else if (!await reader.canRead(id)) {
- // We want to add something here, a missing/unreadable input should be
- // different from no input at all.
- //
- // This needs to be unique per input so we use the md5 hash of the id.
- _combine(md5.convert(id.toString().codeUnits).bytes as Uint8List);
- return;
- } else {
- node.lastKnownDigest ??= await reader.digest(id);
- }
- _combine(node.lastKnownDigest.bytes as Uint8List);
- }));
-
- return Digest(combinedBytes);
- }
-
- /// Sets the state for all [outputs] of a build step, by:
- ///
- /// - Setting `needsUpdate` to `false` for each output
- /// - Setting `wasOutput` based on `writer.assetsWritten`.
- /// - Setting `isFailed` based on action success.
- /// - Adding `outputs` as outputs to all `reader.assetsRead`.
- /// - Setting the `lastKnownDigest` on each output based on the new contents.
- /// - Setting the `previousInputsDigest` on each output based on the inputs.
- /// - Storing the error message with the [_failureReporter].
- Future<void> _setOutputsState(
- Iterable<AssetId> outputs,
- SingleStepReader reader,
- AssetWriterSpy writer,
- String actionDescription,
- Iterable<ErrorReport> errors,
- {Set<AssetId> unusedAssets}) async {
- if (outputs.isEmpty) return;
- var usedInputs = unusedAssets != null
- ? reader.assetsRead.difference(unusedAssets)
- : reader.assetsRead;
-
- final inputsDigest = await _computeCombinedDigest(
- usedInputs,
- (_assetGraph.get(outputs.first) as GeneratedAssetNode).builderOptionsId,
- reader);
-
- final isFailure = errors.isNotEmpty;
-
- for (var output in outputs) {
- var wasOutput = writer.assetsWritten.contains(output);
- var digest = wasOutput ? await _reader.digest(output) : null;
- var node = _assetGraph.get(output) as GeneratedAssetNode;
-
- // **IMPORTANT**: All updates to `node` must be synchronous. With lazy
- // builders we can run arbitrary code between updates otherwise, at which
- // time a node might not be in a valid state.
- _removeOldInputs(node, usedInputs);
- _addNewInputs(node, usedInputs);
- node
- ..state = NodeState.upToDate
- ..wasOutput = wasOutput
- ..isFailure = isFailure
- ..lastKnownDigest = digest
- ..previousInputsDigest = inputsDigest;
-
- if (isFailure) {
- await _failureReporter.markReported(actionDescription, node, errors);
- var needsMarkAsFailure = Queue.of(node.primaryOutputs);
- var allSkippedFailures = <GeneratedAssetNode>[];
- while (needsMarkAsFailure.isNotEmpty) {
- var output = needsMarkAsFailure.removeLast();
- var outputNode = _assetGraph.get(output) as GeneratedAssetNode
- ..state = NodeState.upToDate
- ..wasOutput = false
- ..isFailure = true
- ..lastKnownDigest = null
- ..previousInputsDigest = null;
- allSkippedFailures.add(outputNode);
- needsMarkAsFailure.addAll(outputNode.primaryOutputs);
-
- // Make sure output invalidation follows primary outputs for builds
- // that won't run.
- node.outputs.add(output);
- outputNode.inputs.add(node.id);
- }
- await _failureReporter.markSkipped(allSkippedFailures);
- }
- }
- }
-
- /// Removes old inputs from [node] based on [updatedInputs], and cleans up all
- /// the old edges.
- void _removeOldInputs(GeneratedAssetNode node, Set<AssetId> updatedInputs) {
- var removedInputs = node.inputs.difference(updatedInputs);
- node.inputs.removeAll(removedInputs);
- for (var input in removedInputs) {
- var inputNode = _assetGraph.get(input);
- assert(inputNode != null, 'Asset Graph is missing $input');
- inputNode.outputs.remove(node.id);
- }
- }
-
- /// Adds new inputs to [node] based on [updatedInputs], and adds the
- /// appropriate edges.
- void _addNewInputs(GeneratedAssetNode node, Set<AssetId> updatedInputs) {
- var newInputs = updatedInputs.difference(node.inputs);
- node.inputs.addAll(newInputs);
- for (var input in newInputs) {
- var inputNode = _assetGraph.get(input);
- assert(inputNode != null, 'Asset Graph is missing $input');
- inputNode.outputs.add(node.id);
- }
- }
-
- Future _delete(AssetId id) => _writer.delete(id);
-}
-
-String _actionLoggerName(
- InBuildPhase phase, AssetId primaryInput, String rootPackageName) {
- var asset = primaryInput.package == rootPackageName
- ? primaryInput.path
- : primaryInput.uri;
- return '${phase.builderLabel} on $asset';
-}
-
-String _twoDigits(int n) => '$n'.padLeft(2, '0');
diff --git a/build_runner_core/lib/src/generate/build_result.dart b/build_runner_core/lib/src/generate/build_result.dart
deleted file mode 100644
index d96e52f..0000000
--- a/build_runner_core/lib/src/generate/build_result.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2016, 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 'package:build/build.dart';
-import 'package:meta/meta.dart';
-
-import 'performance_tracker.dart';
-
-/// The result of an individual build, this may be an incremental build or
-/// a full build.
-class BuildResult {
- /// The status of this build.
- final BuildStatus status;
-
- /// The type of failure.
- final FailureType failureType;
-
- /// All outputs created/updated during this build.
- final List<AssetId> outputs;
-
- /// The [BuildPerformance] broken out by build action, may be `null`.
- @experimental
- final BuildPerformance performance;
-
- BuildResult(this.status, List<AssetId> outputs,
- {this.performance, FailureType failureType})
- : outputs = List.unmodifiable(outputs),
- failureType = failureType == null && status == BuildStatus.failure
- ? FailureType.general
- : failureType;
- @override
- String toString() {
- if (status == BuildStatus.success) {
- return '''
-
-Build Succeeded!
-''';
- } else {
- return '''
-
-Build Failed :(
-''';
- }
- }
-}
-
-/// The status of a build.
-enum BuildStatus {
- success,
- failure,
-}
-
-/// The type of failure
-class FailureType {
- static final general = FailureType._(1);
- static final cantCreate = FailureType._(73);
- static final buildConfigChanged = FailureType._(75);
- static final buildScriptChanged = FailureType._(75);
- final int exitCode;
- FailureType._(this.exitCode);
-}
-
-abstract class BuildState {
- Future<BuildResult> get currentBuild;
- Stream<BuildResult> get buildResults;
-}
diff --git a/build_runner_core/lib/src/generate/build_runner.dart b/build_runner_core/lib/src/generate/build_runner.dart
deleted file mode 100644
index b19e265..0000000
--- a/build_runner_core/lib/src/generate/build_runner.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:watcher/watcher.dart';
-
-import '../environment/build_environment.dart';
-import '../package_graph/apply_builders.dart';
-import 'build_directory.dart';
-import 'build_impl.dart';
-import 'build_result.dart';
-import 'options.dart';
-
-class BuildRunner {
- final BuildImpl _build;
- BuildRunner._(this._build);
-
- Future<void> beforeExit() => _build.beforeExit();
-
- Future<BuildResult> run(Map<AssetId, ChangeType> updates,
- {Set<BuildDirectory> buildDirs, Set<BuildFilter> buildFilters}) =>
- _build.run(updates, buildDirs: buildDirs, buildFilters: buildFilters);
-
- static Future<BuildRunner> create(
- BuildOptions options,
- BuildEnvironment environment,
- List<BuilderApplication> builders,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- {bool isReleaseBuild = false}) async {
- return BuildRunner._(await BuildImpl.create(
- options, environment, builders, builderConfigOverrides,
- isReleaseBuild: isReleaseBuild));
- }
-}
diff --git a/build_runner_core/lib/src/generate/exceptions.dart b/build_runner_core/lib/src/generate/exceptions.dart
deleted file mode 100644
index 659d8ae..0000000
--- a/build_runner_core/lib/src/generate/exceptions.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2016, 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.
-
-/// Indicates that a build config file has changed, and the build needs to be
-/// re-ran.
-///
-/// An exit code of 75 should be set when handling this exception.
-class BuildConfigChangedException implements Exception {
- const BuildConfigChangedException();
-}
-
-/// Indicates that the build script itself has changed, and needs to be re-ran.
-///
-/// If the build is running from a snapshot, the snapshot should also be
-/// deleted before exiting.
-///
-/// An exit code of 75 should be set when handling this exception.
-class BuildScriptChangedException implements Exception {
- const BuildScriptChangedException();
-}
-
-/// Indicates that the build cannot be attempted.
-///
-/// Before throwing this exception a user actionable message should be logged.
-class CannotBuildException implements Exception {
- const CannotBuildException();
-}
diff --git a/build_runner_core/lib/src/generate/finalized_assets_view.dart b/build_runner_core/lib/src/generate/finalized_assets_view.dart
deleted file mode 100644
index 9f74ae3..0000000
--- a/build_runner_core/lib/src/generate/finalized_assets_view.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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:build/build.dart';
-import 'package:path/path.dart' as p;
-
-import '../asset_graph/graph.dart';
-import '../asset_graph/node.dart';
-import '../asset_graph/optional_output_tracker.dart';
-
-/// A lazily computed view of all the assets available after a build.
-///
-/// Note that this class has a limited lifetime during which it is available,
-/// and should not be used outside of the scope in which it is given. It will
-/// throw a [StateError] if you attempt to use it once it has expired.
-class FinalizedAssetsView {
- final AssetGraph _assetGraph;
- final OptionalOutputTracker _optionalOutputTracker;
-
- bool _expired = false;
-
- FinalizedAssetsView(this._assetGraph, this._optionalOutputTracker);
-
- List<AssetId> allAssets({String rootDir}) {
- if (_expired) {
- throw StateError(
- 'Cannot use a FinalizedAssetsView after it has expired!');
- }
- return _assetGraph.allNodes
- .map((node) {
- if (_shouldSkipNode(node, rootDir, _optionalOutputTracker)) {
- return null;
- }
- return node.id;
- })
- .where((id) => id != null)
- .toList();
- }
-
- void markExpired() {
- assert(!_expired);
- _expired = true;
- }
-}
-
-bool _shouldSkipNode(AssetNode node, String rootDir,
- OptionalOutputTracker optionalOutputTracker) {
- if (!node.isReadable) return true;
- if (node.isDeleted) return true;
- if (rootDir != null &&
- !node.id.path.startsWith('lib/') &&
- !p.isWithin(rootDir, node.id.path)) {
- return true;
- }
- if (node is InternalAssetNode) return true;
- if (node is GeneratedAssetNode) {
- if (!node.wasOutput || node.isFailure || node.state != NodeState.upToDate) {
- return true;
- }
- return !optionalOutputTracker.isRequired(node.id);
- }
- if (node.id.path == '.packages') return true;
- return false;
-}
diff --git a/build_runner_core/lib/src/generate/heartbeat.dart b/build_runner_core/lib/src/generate/heartbeat.dart
deleted file mode 100644
index 2917f54..0000000
--- a/build_runner_core/lib/src/generate/heartbeat.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2017, 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 'package:logging/logging.dart';
-
-import '../logging/human_readable_duration.dart';
-
-var _logger = Logger('Heartbeat');
-
-/// Base class for a heartbeat implementation.
-///
-/// Once [start]ed, if [waitDuration] passes between calls to [ping], then
-/// [onTimeout] will be invoked with the duration.
-abstract class Heartbeat {
- Stopwatch _intervalWatch;
- Timer _timer;
-
- /// The interval at which to check if [waitDuration] has passed.
- final Duration checkInterval;
-
- /// The amount of time between heartbeats.
- final Duration waitDuration;
-
- Heartbeat({Duration checkInterval, Duration waitDuration})
- : checkInterval = checkInterval ?? const Duration(milliseconds: 100),
- waitDuration = waitDuration ?? const Duration(seconds: 5);
-
- /// Invoked if [waitDuration] time has elapsed since the last call to [ping].
- void onTimeout(Duration elapsed);
-
- /// Resets the internal timers. If more than [waitDuration] elapses without
- /// this method being called, then [onTimeout] will be invoked with the
- /// duration since the last ping.
- void ping() {
- _intervalWatch.reset();
- }
-
- /// Starts this heartbeat logger, must not already be started.
- ///
- /// This method can be overridden to add additional logic for handling calls
- /// to [ping], but you must call `super.start()`.
- void start() {
- if (_intervalWatch != null || _timer != null) {
- throw StateError('HeartbeatLogger already started');
- }
- _intervalWatch = Stopwatch()..start();
- ping();
- _timer = Timer.periodic(checkInterval, _checkDuration);
- }
-
- /// Stops this heartbeat logger, must already be started.
- ///
- /// This method can be overridden to add additional logic for cleanup
- /// purposes, but you must call `super.stop()`.
- void stop() {
- if (_intervalWatch == null || _timer == null) {
- throw StateError('HeartbeatLogger was never started');
- }
- _intervalWatch.stop();
- _intervalWatch = null;
- _timer.cancel();
- _timer = null;
- }
-
- void _checkDuration(void _) {
- if (_intervalWatch.elapsed < waitDuration) return;
- onTimeout(_intervalWatch.elapsed);
- ping();
- }
-}
-
-/// Watches [Logger.root] and if there are no logs for [waitDuration] then it
-/// will log a heartbeat message with the current elapsed time since [start] was
-/// originally invoked.
-class HeartbeatLogger extends Heartbeat {
- StreamSubscription<LogRecord> _listener;
- Stopwatch _totalWatch;
-
- /// Will be invoked with each original log message and the returned value will
- /// be logged instead.
- final String Function(String original) transformLog;
-
- HeartbeatLogger(
- {Duration checkInterval, Duration waitDuration, this.transformLog})
- : super(checkInterval: checkInterval, waitDuration: waitDuration);
-
- /// Start listening to logs.
- @override
- void start() {
- _totalWatch = Stopwatch()..start();
- super.start();
- _listener = Logger.root.onRecord.listen((_) => ping());
- }
-
- /// Stops listenting to the logger;
- @override
- void stop() {
- super.stop();
- _listener.cancel();
- _listener = null;
- _totalWatch.stop();
- _totalWatch = null;
- }
-
- /// Logs a heartbeat message if we reach the timeout.
- @override
- void onTimeout(void _) {
- var formattedTime = humanReadable(_totalWatch.elapsed);
- var message = '$formattedTime elapsed';
- if (transformLog != null) {
- message = transformLog(message);
- }
- _logger.info(message);
- }
-}
-
-class HungActionsHeartbeat extends Heartbeat {
- /// Returns a description of pending actions
- final String Function() listActions;
-
- HungActionsHeartbeat(this.listActions,
- {Duration checkInterval, Duration waitDuration})
- : super(
- checkInterval: checkInterval,
- waitDuration: waitDuration ?? Duration(seconds: 15));
-
- @override
- void onTimeout(Duration elapsed) {
- var formattedTime = humanReadable(elapsed);
- var message = 'No actions completed for $formattedTime, '
- 'waiting on:\n${listActions()}';
- _logger.warning(message);
- }
-}
diff --git a/build_runner_core/lib/src/generate/input_matcher.dart b/build_runner_core/lib/src/generate/input_matcher.dart
deleted file mode 100644
index dc644aa..0000000
--- a/build_runner_core/lib/src/generate/input_matcher.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2016, 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:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:collection/collection.dart';
-import 'package:glob/glob.dart';
-
-/// A filter on files to run through a Builder.
-class InputMatcher {
- /// The files to include
- ///
- /// Null or empty means include everything.
- final List<Glob> includeGlobs;
-
- /// The files within [includeGlobs] to exclude.
- ///
- /// Null or empty means exclude nothing.
- final List<Glob> excludeGlobs;
-
- InputMatcher(InputSet inputSet, {List<String> defaultInclude})
- : includeGlobs =
- (inputSet.include ?? defaultInclude)?.map((p) => Glob(p))?.toList(),
- excludeGlobs = inputSet.exclude?.map((p) => Glob(p))?.toList();
-
- /// Whether [input] is included in this set of assets.
- bool matches(AssetId input) => includes(input) && !excludes(input);
-
- /// Whether [input] matches any [includeGlobs].
- ///
- /// If there are no [includeGlobs] this always returns `true`.
- bool includes(AssetId input) =>
- includeGlobs == null ||
- includeGlobs.isEmpty ||
- includeGlobs.any((g) => g.matches(input.path));
-
- /// Whether [input] matches any [excludeGlobs].
- ///
- /// If there are no [excludeGlobs] this always returns `false`.
- bool excludes(AssetId input) =>
- excludeGlobs != null &&
- excludeGlobs.isNotEmpty &&
- excludeGlobs.any((g) => g.matches(input.path));
-
- @override
- String toString() {
- final result = StringBuffer();
- if (includeGlobs == null || includeGlobs.isEmpty) {
- result.write('any assets');
- } else {
- result.write('assets matching ${_patterns(includeGlobs).toList()}');
- }
- if (excludeGlobs != null && excludeGlobs.isNotEmpty) {
- result.write(' except ${_patterns(excludeGlobs).toList()}');
- }
- return '$result';
- }
-
- @override
- bool operator ==(Object other) =>
- identical(this, other) ||
- (other is InputMatcher &&
- _deepEquals.equals(
- _patterns(includeGlobs), _patterns(other.includeGlobs)) &&
- _deepEquals.equals(
- _patterns(excludeGlobs), _patterns(other.excludeGlobs)));
-
- @override
- int get hashCode =>
- _deepEquals.hash([_patterns(includeGlobs), _patterns(excludeGlobs)]);
-}
-
-final _deepEquals = const DeepCollectionEquality();
-
-Iterable<String> _patterns(Iterable<Glob> globs) =>
- globs?.map((g) => g.pattern);
diff --git a/build_runner_core/lib/src/generate/options.dart b/build_runner_core/lib/src/generate/options.dart
deleted file mode 100644
index eb2681e..0000000
--- a/build_runner_core/lib/src/generate/options.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2016, 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 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:build_resolvers/build_resolvers.dart';
-import 'package:glob/glob.dart';
-import 'package:logging/logging.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-
-import '../environment/build_environment.dart';
-import '../package_graph/package_graph.dart';
-import '../package_graph/target_graph.dart';
-import '../util/hash.dart';
-import 'exceptions.dart';
-
-/// The default list of files to include when an explicit include is not
-/// provided.
-const List<String> defaultRootPackageWhitelist = [
- 'assets/**',
- 'benchmark/**',
- 'bin/**',
- 'example/**',
- 'lib/**',
- 'test/**',
- 'tool/**',
- 'web/**',
- 'node/**',
- 'pubspec.yaml',
- 'pubspec.lock',
- r'$package$',
-];
-
-final _logger = Logger('BuildOptions');
-
-class LogSubscription {
- factory LogSubscription(BuildEnvironment environment,
- {bool verbose, Level logLevel}) {
- // Set up logging
- verbose ??= false;
- logLevel ??= verbose ? Level.ALL : Level.INFO;
-
- // Severe logs can fail the build and should always be shown.
- if (logLevel == Level.OFF) logLevel = Level.SEVERE;
-
- Logger.root.level = logLevel;
-
- var logListener = Logger.root.onRecord.listen(environment.onLog);
- return LogSubscription._(logListener);
- }
-
- LogSubscription._(this.logListener);
-
- final StreamSubscription<LogRecord> logListener;
-}
-
-/// Describes a set of files that should be built.
-class BuildFilter {
- /// The package name glob that files must live under in order to match.
- final Glob _package;
-
- /// A glob for files under [_package] that must match.
- final Glob _path;
-
- BuildFilter(this._package, this._path);
-
- /// Builds a [BuildFilter] from a command line argument.
- ///
- /// Both relative paths and package: uris are supported. Relative
- /// paths are treated as relative to the [rootPackage].
- ///
- /// Globs are supported in package names and paths.
- factory BuildFilter.fromArg(String arg, String rootPackage) {
- var uri = Uri.parse(arg);
- if (uri.scheme == 'package') {
- var package = uri.pathSegments.first;
- var glob = Glob(p.url.joinAll([
- 'lib',
- ...uri.pathSegments.skip(1),
- ]));
- return BuildFilter(Glob(package), glob);
- } else if (uri.scheme.isEmpty) {
- return BuildFilter(Glob(rootPackage), Glob(uri.path));
- } else {
- throw FormatException('Unsupported scheme ${uri.scheme}', uri);
- }
- }
-
- /// Returns whether or not [id] mathes this filter.
- bool matches(AssetId id) =>
- _package.matches(id.package) && _path.matches(id.path);
-
- @override
- int get hashCode {
- var hash = 0;
- hash = hashCombine(hash, _package.context.hashCode);
- hash = hashCombine(hash, _package.pattern.hashCode);
- hash = hashCombine(hash, _package.recursive.hashCode);
- hash = hashCombine(hash, _path.context.hashCode);
- hash = hashCombine(hash, _path.pattern.hashCode);
- hash = hashCombine(hash, _path.recursive.hashCode);
- return hashComplete(hash);
- }
-
- @override
- bool operator ==(Object other) =>
- other is BuildFilter &&
- other._path.context == _path.context &&
- other._path.pattern == _path.pattern &&
- other._path.recursive == _path.recursive &&
- other._package.context == _package.context &&
- other._package.pattern == _package.pattern &&
- other._package.recursive == _package.recursive;
-}
-
-/// Manages setting up consistent defaults for all options and build modes.
-class BuildOptions {
- final bool deleteFilesByDefault;
- final bool enableLowResourcesMode;
- final StreamSubscription logListener;
-
- /// If present, the path to a directory to write performance logs to.
- final String logPerformanceDir;
-
- final PackageGraph packageGraph;
- final Resolvers resolvers;
- final TargetGraph targetGraph;
- final bool trackPerformance;
-
- // Watch mode options.
- Duration debounceDelay;
-
- // For testing only, skips the build script updates check.
- bool skipBuildScriptCheck;
-
- BuildOptions._({
- @required this.debounceDelay,
- @required this.deleteFilesByDefault,
- @required this.enableLowResourcesMode,
- @required this.logListener,
- @required this.packageGraph,
- @required this.skipBuildScriptCheck,
- @required this.trackPerformance,
- @required this.targetGraph,
- @required this.logPerformanceDir,
- @required this.resolvers,
- });
-
- static Future<BuildOptions> create(
- LogSubscription logSubscription, {
- Duration debounceDelay,
- bool deleteFilesByDefault,
- bool enableLowResourcesMode,
- @required PackageGraph packageGraph,
- Map<String, BuildConfig> overrideBuildConfig,
- bool skipBuildScriptCheck,
- bool trackPerformance,
- String logPerformanceDir,
- Resolvers resolvers,
- }) async {
- TargetGraph targetGraph;
- try {
- targetGraph = await TargetGraph.forPackageGraph(packageGraph,
- overrideBuildConfig: overrideBuildConfig,
- defaultRootPackageWhitelist: defaultRootPackageWhitelist);
- } on BuildConfigParseException catch (e, s) {
- _logger.severe(
- 'Failed to parse `build.yaml` for ${e.packageName}.', e.exception, s);
- throw CannotBuildException();
- }
-
- /// Set up other defaults.
- debounceDelay ??= const Duration(milliseconds: 250);
- deleteFilesByDefault ??= false;
- skipBuildScriptCheck ??= false;
- enableLowResourcesMode ??= false;
- trackPerformance ??= false;
- if (logPerformanceDir != null) {
- // Requiring this to be under the root package allows us to use an
- // `AssetWriter` to write logs.
- if (!p.isWithin(p.current, logPerformanceDir)) {
- _logger.severe('Performance logs may only be output under the root '
- 'package, but got `$logPerformanceDir` which is not.');
- throw CannotBuildException();
- }
- trackPerformance = true;
- }
- resolvers ??= AnalyzerResolvers();
-
- return BuildOptions._(
- debounceDelay: debounceDelay,
- deleteFilesByDefault: deleteFilesByDefault,
- enableLowResourcesMode: enableLowResourcesMode,
- logListener: logSubscription.logListener,
- packageGraph: packageGraph,
- skipBuildScriptCheck: skipBuildScriptCheck,
- trackPerformance: trackPerformance,
- targetGraph: targetGraph,
- logPerformanceDir: logPerformanceDir,
- resolvers: resolvers,
- );
- }
-}
diff --git a/build_runner_core/lib/src/generate/performance_tracker.dart b/build_runner_core/lib/src/generate/performance_tracker.dart
deleted file mode 100644
index beb598a..0000000
--- a/build_runner_core/lib/src/generate/performance_tracker.dart
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright (c) 2017, 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.
-
-@experimental
-library build_runner.src.generate.performance_tracker;
-
-import 'dart:async';
-
-import 'package:build/build.dart';
-import 'package:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-import 'package:timing/timing.dart';
-
-import 'phase.dart';
-
-part 'performance_tracker.g.dart';
-
-/// The [TimeSlice] of an entire build, including all its [actions].
-@JsonSerializable()
-class BuildPerformance extends TimeSlice {
- /// The [TimeSlice] of each phase ran in this build.
- final Iterable<BuildPhasePerformance> phases;
-
- /// The [TimeSlice] of running an individual [Builder] on an individual input.
- final Iterable<BuilderActionPerformance> actions;
-
- BuildPerformance(
- this.phases, this.actions, DateTime startTime, DateTime stopTime)
- : super(startTime, stopTime);
-
- factory BuildPerformance.fromJson(Map<String, dynamic> json) =>
- _$BuildPerformanceFromJson(json);
-
- @override
- Map<String, dynamic> toJson() => _$BuildPerformanceToJson(this);
-}
-
-/// The [TimeSlice] of a full [BuildPhase] within a larger build.
-@JsonSerializable()
-class BuildPhasePerformance extends TimeSlice {
- final List<String> builderKeys;
-
- BuildPhasePerformance(this.builderKeys, DateTime startTime, DateTime stopTime)
- : super(startTime, stopTime);
-
- factory BuildPhasePerformance.fromJson(Map<String, dynamic> json) =>
- _$BuildPhasePerformanceFromJson(json);
-
- @override
- Map<String, dynamic> toJson() => _$BuildPhasePerformanceToJson(this);
-}
-
-/// The [TimeSlice] of a [builderKey] running on [primaryInput] within a build.
-@JsonSerializable()
-class BuilderActionPerformance extends TimeSlice {
- final String builderKey;
-
- @JsonKey(fromJson: _assetIdFromJson, toJson: _assetIdToJson)
- final AssetId primaryInput;
-
- final Iterable<BuilderActionStagePerformance> stages;
-
- Duration get innerDuration => stages.fold(
- Duration.zero, (duration, stage) => duration + stage.innerDuration);
-
- BuilderActionPerformance(this.builderKey, this.primaryInput, this.stages,
- DateTime startTime, DateTime stopTime)
- : super(startTime, stopTime);
-
- factory BuilderActionPerformance.fromJson(Map<String, dynamic> json) =>
- _$BuilderActionPerformanceFromJson(json);
-
- @override
- Map<String, dynamic> toJson() => _$BuilderActionPerformanceToJson(this);
-}
-
-/// The [TimeSlice] of a particular task within a builder action.
-///
-/// This is some slice of overall [BuilderActionPerformance].
-@JsonSerializable()
-class BuilderActionStagePerformance extends TimeSliceGroup {
- final String label;
-
- BuilderActionStagePerformance(this.label, List<TimeSlice> slices)
- : super(slices);
-
- factory BuilderActionStagePerformance.fromJson(Map<String, dynamic> json) =>
- _$BuilderActionStagePerformanceFromJson(json);
-
- @override
- Map<String, dynamic> toJson() => _$BuilderActionStagePerformanceToJson(this);
-}
-
-/// Interface for tracking the overall performance of a build.
-abstract class BuildPerformanceTracker
- implements TimeTracker, BuildPerformance {
- /// Tracks [runPhase] which performs [action] on all inputs in a phase, and
- /// return the outputs generated.
- Future<Iterable<AssetId>> trackBuildPhase(
- BuildPhase action, Future<Iterable<AssetId>> Function() runPhase);
-
- /// Returns a [BuilderActionTracker] for tracking [builderKey] on
- /// [primaryInput] and adds it to [actions].
- BuilderActionTracker addBuilderAction(
- AssetId primaryInput, String builderKey);
-
- factory BuildPerformanceTracker() => _BuildPerformanceTrackerImpl();
-
- /// A [BuildPerformanceTracker] with as little overhead as possible. Does no
- /// actual tracking and does not implement many fields/methods.
- factory BuildPerformanceTracker.noOp() =>
- _NoOpBuildPerformanceTracker.sharedInstance;
-}
-
-/// Real implementation of [BuildPerformanceTracker].
-///
-/// Use [BuildPerformanceTracker] factory to get an instance.
-class _BuildPerformanceTrackerImpl extends SimpleAsyncTimeTracker
- implements BuildPerformanceTracker {
- @override
- Iterable<BuildPhaseTracker> get phases => _phases;
- final _phases = <BuildPhaseTracker>[];
-
- @override
- Iterable<BuilderActionTracker> get actions => _actions;
- final _actions = <BuilderActionTracker>[];
-
- /// Tracks [action] which is ran with [runPhase].
- ///
- /// This represents running a [Builder] on a group of sources.
- ///
- /// Returns all the outputs generated by the phase.
- @override
- Future<Iterable<AssetId>> trackBuildPhase(
- BuildPhase action, Future<Iterable<AssetId>> Function() runPhase) {
- assert(isTracking);
- var tracker = BuildPhaseTracker(action);
- _phases.add(tracker);
- return tracker.track(runPhase);
- }
-
- /// Returns a new [BuilderActionTracker] and adds it to [actions].
- ///
- /// The [BuilderActionTracker] will already be started, but you must stop it.
- @override
- BuilderActionTracker addBuilderAction(
- AssetId primaryInput, String builderKey) {
- assert(isTracking);
- var tracker = BuilderActionTracker(primaryInput, builderKey);
- _actions.add(tracker);
- return tracker;
- }
-
- @override
- Map<String, dynamic> toJson() => _$BuildPerformanceToJson(this);
-}
-
-/// No-op implementation of [BuildPerformanceTracker].
-///
-/// Read-only fields will throw, and tracking methods just directly invoke their
-/// closures without tracking anything.
-///
-/// Use [BuildPerformanceTracker.noOp] to get an instance.
-class _NoOpBuildPerformanceTracker extends NoOpTimeTracker
- implements BuildPerformanceTracker {
- static final _NoOpBuildPerformanceTracker sharedInstance =
- _NoOpBuildPerformanceTracker();
-
- @override
- Iterable<BuilderActionTracker> get actions => throw UnimplementedError();
-
- @override
- Iterable<BuildPhaseTracker> get phases => throw UnimplementedError();
-
- @override
- BuilderActionTracker addBuilderAction(
- AssetId primaryInput, String builderKey) =>
- BuilderActionTracker.noOp();
-
- @override
- Future<Iterable<AssetId>> trackBuildPhase(
- BuildPhase action, Future<Iterable<AssetId>> Function() runPhase) =>
- runPhase();
-
- @override
- Map<String, dynamic> toJson() => _$BuildPerformanceToJson(this);
-}
-
-/// Internal class that tracks the [TimeSlice] of an entire [BuildPhase].
-///
-/// Tracks total time it took to run on all inputs available to that action.
-///
-/// Use [track] to start actually tracking an operation.
-///
-/// This is only meaningful for non-lazy phases.
-class BuildPhaseTracker extends SimpleAsyncTimeTracker
- implements BuildPhasePerformance {
- @override
- final List<String> builderKeys;
-
- BuildPhaseTracker(BuildPhase action)
- : builderKeys = action is InBuildPhase
- ? [action.builderLabel]
- : (action as PostBuildPhase)
- .builderActions
- .map((action) => action.builderLabel)
- .toList();
-
- @override
- Map<String, dynamic> toJson() => _$BuildPhasePerformanceToJson(this);
-}
-
-/// Interface for tracking the [TimeSlice] of an individual [Builder] on a given
-/// primary input.
-abstract class BuilderActionTracker
- implements TimeTracker, BuilderActionPerformance, StageTracker {
- /// Tracks the time of [runStage] and associates it with [label].
- ///
- /// You can specify [runStage] as [isExternal] (waiting for some external
- /// resource like network, process or file IO). In that case [runStage] will
- /// be tracked as single time slice from the beginning of the stage till
- /// completion of Future returned by [runStage].
- ///
- /// Otherwise all separate time slices of asynchronous execution will be
- /// tracked, but waiting for external resources will be a gap.
- @override
- T trackStage<T>(String label, T Function() runStage,
- {bool isExternal = false});
-
- factory BuilderActionTracker(AssetId primaryInput, String builderKey) =>
- _BuilderActionTrackerImpl(primaryInput, builderKey);
-
- /// A [BuilderActionTracker] with as little overhead as possible. Does no
- /// actual tracking and does not implement many fields/methods.
- factory BuilderActionTracker.noOp() =>
- _NoOpBuilderActionTracker._sharedInstance;
-}
-
-/// Real implementation of [BuilderActionTracker] which records timings.
-///
-/// Use the [BuilderActionTracker] factory to get an instance.
-class _BuilderActionTrackerImpl extends SimpleAsyncTimeTracker
- implements BuilderActionTracker {
- @override
- final String builderKey;
- @override
- final AssetId primaryInput;
-
- @override
- final List<BuilderActionStageTracker> stages = [];
-
- @override
- Duration get innerDuration => stages.fold(
- Duration.zero, (duration, stage) => duration + stage.innerDuration);
-
- _BuilderActionTrackerImpl(this.primaryInput, this.builderKey);
-
- @override
- T trackStage<T>(String label, T Function() action,
- {bool isExternal = false}) {
- var tracker = isExternal
- ? BuilderActionStageSimpleTracker(label)
- : BuilderActionStageAsyncTracker(label);
- stages.add(tracker);
- return tracker.track(action);
- }
-
- @override
- Map<String, dynamic> toJson() => _$BuilderActionPerformanceToJson(this);
-}
-
-/// No-op instance of [BuilderActionTracker] which does nothing and throws an
-/// unimplemented error for everything but [trackStage], which delegates directly to
-/// the wrapped function.
-///
-/// Use the [BuilderActionTracker.noOp] factory to get an instance.
-class _NoOpBuilderActionTracker extends NoOpTimeTracker
- implements BuilderActionTracker {
- static final _NoOpBuilderActionTracker _sharedInstance =
- _NoOpBuilderActionTracker();
-
- @override
- String get builderKey => throw UnimplementedError();
-
- @override
- Duration get duration => throw UnimplementedError();
-
- @override
- Iterable<BuilderActionStagePerformance> get stages =>
- throw UnimplementedError();
-
- @override
- Duration get innerDuration => throw UnimplementedError();
-
- @override
- AssetId get primaryInput => throw UnimplementedError();
-
- @override
- T trackStage<T>(String label, T Function() runStage,
- {bool isExternal = false}) =>
- runStage();
-
- @override
- Map<String, dynamic> toJson() => _$BuilderActionPerformanceToJson(this);
-}
-
-/// Tracks the [TimeSliceGroup] of an individual task.
-///
-/// These represent a slice of the [BuilderActionPerformance].
-abstract class BuilderActionStageTracker
- implements BuilderActionStagePerformance {
- T track<T>(T Function() action);
-}
-
-class BuilderActionStageAsyncTracker extends AsyncTimeTracker
- implements BuilderActionStageTracker {
- @override
- final String label;
-
- BuilderActionStageAsyncTracker(this.label) : super(trackNested: false);
-
- @override
- Map<String, dynamic> toJson() => _$BuilderActionStagePerformanceToJson(this);
-}
-
-class BuilderActionStageSimpleTracker extends BuilderActionStagePerformance
- implements BuilderActionStageTracker {
- final _tracker = SimpleAsyncTimeTracker();
-
- BuilderActionStageSimpleTracker(String label) : super(label, []) {
- slices.add(_tracker);
- }
-
- @override
- T track<T>(T Function() action) => _tracker.track(action);
-}
-
-AssetId _assetIdFromJson(String json) => AssetId.parse(json);
-
-String _assetIdToJson(AssetId id) => id.toString();
diff --git a/build_runner_core/lib/src/generate/performance_tracker.g.dart b/build_runner_core/lib/src/generate/performance_tracker.g.dart
deleted file mode 100644
index 29ea027..0000000
--- a/build_runner_core/lib/src/generate/performance_tracker.g.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of build_runner.src.generate.performance_tracker;
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-BuildPerformance _$BuildPerformanceFromJson(Map<String, dynamic> json) {
- return BuildPerformance(
- (json['phases'] as List)?.map((e) => e == null
- ? null
- : BuildPhasePerformance.fromJson(e as Map<String, dynamic>)),
- (json['actions'] as List)?.map((e) => e == null
- ? null
- : BuilderActionPerformance.fromJson(e as Map<String, dynamic>)),
- json['startTime'] == null
- ? null
- : DateTime.parse(json['startTime'] as String),
- json['stopTime'] == null
- ? null
- : DateTime.parse(json['stopTime'] as String));
-}
-
-Map<String, dynamic> _$BuildPerformanceToJson(BuildPerformance instance) =>
- <String, dynamic>{
- 'startTime': instance.startTime?.toIso8601String(),
- 'stopTime': instance.stopTime?.toIso8601String(),
- 'phases': instance.phases?.toList(),
- 'actions': instance.actions?.toList()
- };
-
-BuildPhasePerformance _$BuildPhasePerformanceFromJson(
- Map<String, dynamic> json) {
- return BuildPhasePerformance(
- (json['builderKeys'] as List)?.map((e) => e as String)?.toList(),
- json['startTime'] == null
- ? null
- : DateTime.parse(json['startTime'] as String),
- json['stopTime'] == null
- ? null
- : DateTime.parse(json['stopTime'] as String));
-}
-
-Map<String, dynamic> _$BuildPhasePerformanceToJson(
- BuildPhasePerformance instance) =>
- <String, dynamic>{
- 'startTime': instance.startTime?.toIso8601String(),
- 'stopTime': instance.stopTime?.toIso8601String(),
- 'builderKeys': instance.builderKeys
- };
-
-BuilderActionPerformance _$BuilderActionPerformanceFromJson(
- Map<String, dynamic> json) {
- return BuilderActionPerformance(
- json['builderKey'] as String,
- _assetIdFromJson(json['primaryInput'] as String),
- (json['stages'] as List)?.map((e) => e == null
- ? null
- : BuilderActionStagePerformance.fromJson(e as Map<String, dynamic>)),
- json['startTime'] == null
- ? null
- : DateTime.parse(json['startTime'] as String),
- json['stopTime'] == null
- ? null
- : DateTime.parse(json['stopTime'] as String));
-}
-
-Map<String, dynamic> _$BuilderActionPerformanceToJson(
- BuilderActionPerformance instance) =>
- <String, dynamic>{
- 'startTime': instance.startTime?.toIso8601String(),
- 'stopTime': instance.stopTime?.toIso8601String(),
- 'builderKey': instance.builderKey,
- 'primaryInput': _assetIdToJson(instance.primaryInput),
- 'stages': instance.stages?.toList()
- };
-
-BuilderActionStagePerformance _$BuilderActionStagePerformanceFromJson(
- Map<String, dynamic> json) {
- return BuilderActionStagePerformance(
- json['label'] as String,
- (json['slices'] as List)
- ?.map((e) =>
- e == null ? null : TimeSlice.fromJson(e as Map<String, dynamic>))
- ?.toList());
-}
-
-Map<String, dynamic> _$BuilderActionStagePerformanceToJson(
- BuilderActionStagePerformance instance) =>
- <String, dynamic>{'slices': instance.slices, 'label': instance.label};
diff --git a/build_runner_core/lib/src/generate/phase.dart b/build_runner_core/lib/src/generate/phase.dart
deleted file mode 100644
index b6b83b0..0000000
--- a/build_runner_core/lib/src/generate/phase.dart
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) 2016, 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:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:collection/collection.dart';
-import 'package:meta/meta.dart';
-
-import 'input_matcher.dart';
-
-/// A "phase" in the build graph, which represents running a one or more
-/// builders on a set of sources.
-abstract class BuildPhase {
- /// Whether to run lazily when an output is read.
- ///
- /// An optional build action will only run if one of its outputs is read by
- /// a later [Builder], or is used as a primary input to a later [Builder].
- ///
- /// If no build actions read the output of an optional action, then it will
- /// never run.
- bool get isOptional;
-
- /// Whether generated assets should be placed in the build cache.
- ///
- /// When this is `false` the Builder may not run on any package other than
- /// the root.
- bool get hideOutput;
-
- /// The identity of this action in terms of a build graph. If the identity of
- /// any action changes the build will be invalidated.
- ///
- /// This should take into account everything except for the builderOptions,
- /// which are tracked separately via a `BuilderOptionsNode` which supports
- /// more fine grained invalidation.
- int get identity;
-}
-
-/// An "action" in the build graph which represents running a single builder
-/// on a set of sources.
-abstract class BuildAction {
- /// Either a [Builder] or a [PostProcessBuilder].
- dynamic get builder;
- String get builderLabel;
- BuilderOptions get builderOptions;
- InputMatcher get generateFor;
- String get package;
- InputMatcher get targetSources;
-}
-
-/// A [BuildPhase] that uses a single [Builder] to generate files.
-class InBuildPhase extends BuildPhase implements BuildAction {
- @override
- final Builder builder;
- @override
- final String builderLabel;
- @override
- final BuilderOptions builderOptions;
- @override
- final InputMatcher generateFor;
- @override
- final String package;
- @override
- final InputMatcher targetSources;
-
- @override
- final bool isOptional;
- @override
- final bool hideOutput;
-
- InBuildPhase._(this.package, this.builder, this.builderOptions,
- {@required this.targetSources,
- @required this.generateFor,
- @required this.builderLabel,
- bool isOptional,
- bool hideOutput})
- : isOptional = isOptional ?? false,
- hideOutput = hideOutput ?? false;
-
- /// Creates an [BuildPhase] for a normal [Builder].
- ///
- /// The build target is defined by [package] as well as [targetSources]. By
- /// default all sources in the target are used as primary inputs to the
- /// builder, but it can be further filtered with [generateFor].
- ///
- /// [isOptional] specifies that a Builder may not be run unless some other
- /// Builder in a later phase attempts to read one of the potential outputs.
- ///
- /// [hideOutput] specifies that the generated asses should be placed in the
- /// build cache rather than the source tree.
- factory InBuildPhase(
- Builder builder,
- String package, {
- String builderKey,
- InputSet targetSources,
- InputSet generateFor,
- BuilderOptions builderOptions,
- bool isOptional,
- bool hideOutput,
- }) {
- var targetSourceMatcher = InputMatcher(targetSources ?? const InputSet());
- var generateForMatcher = InputMatcher(generateFor ?? const InputSet());
- builderOptions ??= const BuilderOptions({});
- return InBuildPhase._(package, builder, builderOptions,
- targetSources: targetSourceMatcher,
- generateFor: generateForMatcher,
- builderLabel: builderKey == null || builderKey.isEmpty
- ? _builderLabel(builder)
- : _simpleBuilderKey(builderKey),
- isOptional: isOptional,
- hideOutput: hideOutput);
- }
-
- @override
- String toString() {
- final settings = <String>[];
- if (isOptional) settings.add('optional');
- if (hideOutput) settings.add('hidden');
- var result = '$builderLabel on $targetSources in $package';
- if (settings.isNotEmpty) result += ' $settings';
- return result;
- }
-
- @override
- int get identity => _deepEquals.hash([
- builderLabel,
- builder.buildExtensions,
- package,
- targetSources,
- generateFor,
- isOptional,
- hideOutput
- ]);
-}
-
-/// A [BuildPhase] that can run multiple [PostBuildAction]s to
-/// generate files.
-///
-/// There should only be one of these per build, and it should be the final
-/// phase.
-class PostBuildPhase extends BuildPhase {
- final List<PostBuildAction> builderActions;
-
- @override
- bool get hideOutput => true;
- @override
- bool get isOptional => false;
-
- PostBuildPhase(this.builderActions);
-
- @override
- String toString() =>
- '${builderActions.map((a) => a.builderLabel).join(', ')}';
-
- @override
- int get identity =>
- _deepEquals.hash(builderActions.map<dynamic>((b) => b.identity).toList()
- ..addAll([
- isOptional,
- hideOutput,
- ]));
-}
-
-/// Part of a larger [PostBuildPhase], applies a single
-/// [PostProcessBuilder] to a single [package] with some additional options.
-class PostBuildAction implements BuildAction {
- @override
- final PostProcessBuilder builder;
- @override
- final String builderLabel;
- @override
- final BuilderOptions builderOptions;
- @override
- final InputMatcher generateFor;
- @override
- final String package;
- @override
- final InputMatcher targetSources;
-
- PostBuildAction(this.builder, this.package,
- {String builderKey,
- @required BuilderOptions builderOptions,
- @required InputSet targetSources,
- @required InputSet generateFor})
- : builderLabel = builderKey == null || builderKey.isEmpty
- ? _builderLabel(builder)
- : _simpleBuilderKey(builderKey),
- builderOptions = builderOptions ?? const BuilderOptions({}),
- targetSources = InputMatcher(targetSources ?? const InputSet()),
- generateFor = InputMatcher(generateFor ?? const InputSet());
-
- int get identity => _deepEquals.hash([
- builderLabel,
- builder.inputExtensions.toList(),
- generateFor,
- package,
- targetSources,
- ]);
-}
-
-/// If we have no key find a human friendly name for the Builder.
-String _builderLabel(Object builder) {
- var label = '$builder';
- if (label.startsWith('Instance of \'')) {
- label = label.substring(13, label.length - 1);
- }
- return label;
-}
-
-/// Change "angular|angular" to "angular".
-String _simpleBuilderKey(String builderKey) {
- if (!builderKey.contains('|')) return builderKey;
- var parts = builderKey.split('|');
- if (parts[0] == parts[1]) return parts[0];
- return builderKey;
-}
-
-final _deepEquals = const DeepCollectionEquality();
diff --git a/build_runner_core/lib/src/logging/build_for_input_logger.dart b/build_runner_core/lib/src/logging/build_for_input_logger.dart
deleted file mode 100644
index 1e45120..0000000
--- a/build_runner_core/lib/src/logging/build_for_input_logger.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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 'package:logging/logging.dart';
-
-import 'failure_reporter.dart';
-
-/// A delegating [Logger] that records if any logs of level >= [Level.SEVERE]
-/// were seen.
-class BuildForInputLogger implements Logger {
- final Logger _delegate;
-
- final errorsSeen = <ErrorReport>[];
-
- BuildForInputLogger(this._delegate);
-
- @override
- Level get level => _delegate.level;
-
- @override
- set level(Level level) => _delegate.level = level;
-
- @override
- Map<String, Logger> get children => _delegate.children;
-
- @override
- void clearListeners() => _delegate.clearListeners();
-
- @override
- void config(Object message, [Object error, StackTrace stackTrace]) =>
- _delegate.config(message, error, stackTrace);
-
- @override
- void fine(Object message, [Object error, StackTrace stackTrace]) =>
- _delegate.fine(message, error, stackTrace);
-
- @override
- void finer(Object message, [Object error, StackTrace stackTrace]) =>
- _delegate.finer(message, error, stackTrace);
-
- @override
- void finest(Object message, [Object error, StackTrace stackTrace]) =>
- _delegate.finest(message, error, stackTrace);
-
- @override
- String get fullName => _delegate.fullName;
-
- @override
- void info(Object message, [Object error, StackTrace stackTrace]) =>
- _delegate.info(message, error, stackTrace);
-
- @override
- bool isLoggable(Level value) => _delegate.isLoggable(value);
-
- @override
- void log(Level logLevel, Object message,
- [Object error, StackTrace stackTrace, Zone zone]) {
- if (logLevel >= Level.SEVERE) {
- errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
- }
- _delegate.log(logLevel, message, error, stackTrace, zone);
- }
-
- @override
- String get name => _delegate.name;
-
- @override
- Stream<LogRecord> get onRecord => _delegate.onRecord;
-
- @override
- Logger get parent => _delegate.parent;
-
- @override
- void severe(Object message, [Object error, StackTrace stackTrace]) {
- errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
- _delegate.severe(message, error, stackTrace);
- }
-
- @override
- void shout(Object message, [Object error, StackTrace stackTrace]) {
- errorsSeen.add(ErrorReport('$message', '${error ?? ''}', stackTrace));
- _delegate.shout(message, error, stackTrace);
- }
-
- @override
- void warning(Object message, [Object error, StackTrace stackTrace]) =>
- _delegate.warning(message, error, stackTrace);
-}
diff --git a/build_runner_core/lib/src/logging/failure_reporter.dart b/build_runner_core/lib/src/logging/failure_reporter.dart
deleted file mode 100644
index 75bb4f8..0000000
--- a/build_runner_core/lib/src/logging/failure_reporter.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:path/path.dart' as p;
-
-import '../asset_graph/node.dart';
-import '../util/constants.dart';
-
-/// A tracker for the errors which have already been reported during the current
-/// build.
-///
-/// Errors that occur due to actions that are run within this build will be
-/// reported directly as they happen. When an action is skipped and remains a
-/// failure the error will not have been reported by the time we check wether
-/// the build is failed.
-///
-/// The lifetime of this class should be a single build.
-class FailureReporter {
- /// Removes all stored errors from previous builds.
- ///
- /// This should be called any time the build phases change since the naming
- /// scheme is dependent on the build phases.
- static Future<void> cleanErrorCache() async {
- final errorCacheDirectory = Directory(p.fromUri(errorCachePath));
- if (await errorCacheDirectory.exists()) {
- await errorCacheDirectory.delete(recursive: true);
- }
- }
-
- /// Remove the stored error for [phaseNumber] runnon on [primaryInput].
- ///
- /// This should be called anytime the action is being run.
- static Future<void> clean(int phaseNumber, AssetId primaryInput) async {
- final errorFile =
- File(_errorPathForPrimaryInput(phaseNumber, primaryInput));
- if (await errorFile.exists()) {
- await errorFile.delete();
- }
- }
-
- /// A set of Strings which uniquely identify a particular build action and
- /// it's primary input.
- final _reportedActions = <String>{};
-
- /// Indicate that a failure reason for the build step which would produce
- /// [output] and all other outputs from the same build step has been printed.
- Future<void> markReported(String actionDescription, GeneratedAssetNode output,
- Iterable<ErrorReport> errors) async {
- if (!_reportedActions.add(_actionKey(output))) return;
- final errorFile =
- await File(_errorPathForOutput(output)).create(recursive: true);
- await errorFile.writeAsString(jsonEncode(<dynamic>[actionDescription]
- .followedBy(errors
- .map((e) => [e.message, e.error, e.stackTrace?.toString() ?? '']))
- .toList()));
- }
-
- /// Indicate that the build steps which would produce [outputs] are failing
- /// due to a dependency and being skipped so no actuall error will be
- /// produced.
- Future<void> markSkipped(Iterable<GeneratedAssetNode> outputs) =>
- Future.wait(outputs.map((output) async {
- if (!_reportedActions.add(_actionKey(output))) return;
- await clean(output.phaseNumber, output.primaryInput);
- }));
-
- /// Log stored errors for any build steps which would output nodes in
- /// [failingNodes] which haven't already been reported.
- Future<void> reportErrors(Iterable<GeneratedAssetNode> failingNodes) {
- final errorFiles = <File>[];
- for (final failure in failingNodes) {
- final key = _actionKey(failure);
- if (!_reportedActions.add(key)) continue;
- errorFiles.add(File(_errorPathForOutput(failure)));
- }
- return Future.wait(errorFiles.map((errorFile) async {
- if (await errorFile.exists()) {
- final errorReports = jsonDecode(await errorFile.readAsString());
- final actionDescription = '${(errorReports as List).first} (cached)';
- final logger = Logger(actionDescription);
- for (final List error in errorReports.skip(1)) {
- final stackTraceString = error[2] as String;
- final stackTrace = stackTraceString.isEmpty
- ? null
- : StackTrace.fromString(stackTraceString);
- logger.severe(error[0], error[1], stackTrace);
- }
- }
- }));
- }
-}
-
-/// Matches the call to [Logger.severe] except the [message] and [error] are
-/// eagerly converted to String.
-class ErrorReport {
- final String message;
- final String error;
- final StackTrace stackTrace;
- ErrorReport(this.message, this.error, this.stackTrace);
-}
-
-String _actionKey(GeneratedAssetNode node) =>
- '${node.builderOptionsId} on ${node.primaryInput}';
-
-String _errorPathForOutput(GeneratedAssetNode output) => p.join(
- p.fromUri(errorCachePath),
- output.id.package,
- '${output.phaseNumber}',
- p.fromUri(output.primaryInput.path));
-
-String _errorPathForPrimaryInput(int phaseNumber, AssetId primaryInput) =>
- p.join(p.fromUri(errorCachePath), primaryInput.package, '$phaseNumber',
- p.fromUri(primaryInput.path));
diff --git a/build_runner_core/lib/src/logging/human_readable_duration.dart b/build_runner_core/lib/src/logging/human_readable_duration.dart
deleted file mode 100644
index b03aee9..0000000
--- a/build_runner_core/lib/src/logging/human_readable_duration.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.
-
-/// Returns a human readable string for a duration.
-///
-/// Handles durations that span up to hours - this will not be a good fit for
-/// durations that are longer than days.
-///
-/// Always attempts 2 'levels' of precision. Will show hours/minutes,
-/// minutes/seconds, seconds/tenths of a second, or milliseconds depending on
-/// the largest level that needs to be displayed.
-String humanReadable(Duration duration) {
- if (duration < const Duration(seconds: 1)) {
- return '${duration.inMilliseconds}ms';
- }
- if (duration < const Duration(minutes: 1)) {
- return '${(duration.inMilliseconds / 1000.0).toStringAsFixed(1)}s';
- }
- if (duration < const Duration(hours: 1)) {
- final minutes = duration.inMinutes;
- final remaining = duration - Duration(minutes: minutes);
- return '${minutes}m ${remaining.inSeconds}s';
- }
- final hours = duration.inHours;
- final remaining = duration - Duration(hours: hours);
- return '${hours}h ${remaining.inMinutes}m';
-}
diff --git a/build_runner_core/lib/src/logging/logging.dart b/build_runner_core/lib/src/logging/logging.dart
deleted file mode 100644
index 1d93542..0000000
--- a/build_runner_core/lib/src/logging/logging.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2016, 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 'package:logging/logging.dart';
-
-import 'human_readable_duration.dart';
-
-// Ensures this message does not get overwritten by later logs.
-final _logSuffix = '\n';
-
-/// Logs an asynchronous [action] with [description] before and after.
-///
-/// Returns a future that completes after the action and logging finishes.
-Future<T> logTimedAsync<T>(
- Logger logger,
- String description,
- Future<T> Function() action, {
- Level level = Level.INFO,
-}) async {
- final watch = Stopwatch()..start();
- logger.log(level, '$description...');
- final result = await action();
- watch.stop();
- final time = '${humanReadable(watch.elapsed)}$_logSuffix';
- logger.log(level, '$description completed, took $time');
- return result;
-}
-
-/// Logs a synchronous [action] with [description] before and after.
-///
-/// Returns a future that completes after the action and logging finishes.
-T logTimedSync<T>(
- Logger logger,
- String description,
- T Function() action, {
- Level level = Level.INFO,
-}) {
- final watch = Stopwatch()..start();
- logger.log(level, '$description...');
- final result = action();
- watch.stop();
- final time = '${humanReadable(watch.elapsed)}$_logSuffix';
- logger.log(level, '$description completed, took $time');
- return result;
-}
diff --git a/build_runner_core/lib/src/package_graph/apply_builders.dart b/build_runner_core/lib/src/package_graph/apply_builders.dart
deleted file mode 100644
index a151016..0000000
--- a/build_runner_core/lib/src/package_graph/apply_builders.dart
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-
-import 'package:build/build.dart';
-import 'package:build/src/builder/logging.dart';
-import 'package:build_config/build_config.dart';
-import 'package:graphs/graphs.dart';
-import 'package:logging/logging.dart';
-
-import '../generate/exceptions.dart';
-import '../generate/phase.dart';
-import '../validation/config_validation.dart';
-import 'package_graph.dart';
-import 'target_graph.dart';
-
-typedef BuildPhaseFactory = BuildPhase Function(
- PackageNode package,
- BuilderOptions options,
- InputSet targetSources,
- InputSet generateFor,
- bool isReleaseBuild);
-
-typedef PackageFilter = bool Function(PackageNode node);
-
-/// Run a builder on all packages in the package graph.
-PackageFilter toAllPackages() => (_) => true;
-
-/// Require manual configuration to opt in to a builder.
-PackageFilter toNoneByDefault() => (_) => false;
-
-/// Run a builder on all packages with an immediate dependency on [packageName].
-PackageFilter toDependentsOf(String packageName) =>
- (p) => p.dependencies.any((d) => d.name == packageName);
-
-/// Run a builder on a single package.
-PackageFilter toPackage(String package) => (p) => p.name == package;
-
-/// Run a builder on a collection of packages.
-PackageFilter toPackages(Set<String> packages) =>
- (p) => packages.contains(p.name);
-
-/// Run a builders if the package matches any of [filters]
-PackageFilter toAll(Iterable<PackageFilter> filters) =>
- (p) => filters.any((f) => f(p));
-
-PackageFilter toRoot() => (p) => p.isRoot;
-
-/// Apply [builder] to the root package.
-///
-/// Creates a `BuilderApplication` which corresponds to an empty builder key so
-/// that no other `build.yaml` based configuration will apply.
-BuilderApplication applyToRoot(Builder builder,
- {bool isOptional = false,
- bool hideOutput = false,
- InputSet generateFor}) =>
- BuilderApplication.forBuilder('', [(_) => builder], toRoot(),
- isOptional: isOptional,
- hideOutput: hideOutput,
- defaultGenerateFor: generateFor);
-
-/// Apply each builder from [builderFactories] to the packages matching
-/// [filter].
-///
-/// If the builder should only run on a subset of files within a target pass
-/// globs to [defaultGenerateFor]. This can be overridden by any target which
-/// configured the builder manually.
-///
-/// If [isOptional] is true the builder will only run if one of its outputs is
-/// read by a later builder, or is used as a primary input to a later builder.
-/// If no build actions read the output of an optional action, then it will
-/// never run.
-///
-/// Any existing Builders which match a key in [appliesBuilders] will
-/// automatically be applied to any target which runs this Builder, whether
-/// because it matches [filter] or because it was enabled manually.
-BuilderApplication apply(String builderKey,
- List<BuilderFactory> builderFactories, PackageFilter filter,
- {bool isOptional,
- bool hideOutput,
- InputSet defaultGenerateFor,
- BuilderOptions defaultOptions,
- BuilderOptions defaultDevOptions,
- BuilderOptions defaultReleaseOptions,
- Iterable<String> appliesBuilders}) =>
- BuilderApplication.forBuilder(
- builderKey,
- builderFactories,
- filter,
- isOptional: isOptional,
- hideOutput: hideOutput,
- defaultGenerateFor: defaultGenerateFor,
- defaultOptions: defaultOptions,
- defaultDevOptions: defaultDevOptions,
- defaultReleaseOptions: defaultReleaseOptions,
- appliesBuilders: appliesBuilders,
- );
-
-/// Same as [apply] except it takes [PostProcessBuilderFactory]s.
-///
-/// Does not provide options for `isOptional` or `hideOutput` because they
-/// aren't configurable for these types of builders. They are never optional and
-/// always hidden.
-BuilderApplication applyPostProcess(
- String builderKey, PostProcessBuilderFactory builderFactory,
- {InputSet defaultGenerateFor,
- BuilderOptions defaultOptions,
- BuilderOptions defaultDevOptions,
- BuilderOptions defaultReleaseOptions}) =>
- BuilderApplication.forPostProcessBuilder(
- builderKey,
- builderFactory,
- defaultGenerateFor: defaultGenerateFor,
- defaultOptions: defaultOptions,
- defaultDevOptions: defaultDevOptions,
- defaultReleaseOptions: defaultReleaseOptions,
- );
-
-/// A description of which packages need a given [Builder] or
-/// [PostProcessBuilder] applied.
-class BuilderApplication {
- /// Factories that create [BuildPhase]s for all [Builder]s or
- /// [PostProcessBuilder]s that should be applied.
- final List<BuildPhaseFactory> buildPhaseFactories;
-
- /// Determines whether a given package needs builder applied.
- final PackageFilter filter;
-
- /// Builder keys which, when applied to a target, will also apply this Builder
- /// even if [filter] does not match.
- final Iterable<String> appliesBuilders;
-
- /// A uniqe key for this builder.
- ///
- /// Ignored when null or empty.
- final String builderKey;
-
- /// Whether genereated assets should be placed in the build cache.
- final bool hideOutput;
-
- const BuilderApplication._(
- this.builderKey,
- this.buildPhaseFactories,
- this.filter,
- this.hideOutput,
- Iterable<String> appliesBuilders,
- ) : appliesBuilders = appliesBuilders ?? const [];
-
- factory BuilderApplication.forBuilder(
- String builderKey,
- List<BuilderFactory> builderFactories,
- PackageFilter filter, {
- bool isOptional,
- bool hideOutput,
- InputSet defaultGenerateFor,
- BuilderOptions defaultOptions,
- BuilderOptions defaultDevOptions,
- BuilderOptions defaultReleaseOptions,
- Iterable<String> appliesBuilders,
- }) {
- hideOutput ??= true;
- var phaseFactories = builderFactories.map((builderFactory) {
- return (PackageNode package, BuilderOptions options,
- InputSet targetSources, InputSet generateFor, bool isReleaseBuild) {
- generateFor ??= defaultGenerateFor;
-
- var optionsWithDefaults = (defaultOptions ?? BuilderOptions.empty)
- .overrideWith(
- isReleaseBuild ? defaultReleaseOptions : defaultDevOptions)
- .overrideWith(options);
- if (package.isRoot) {
- optionsWithDefaults =
- optionsWithDefaults.overrideWith(BuilderOptions.forRoot);
- }
-
- final logger = Logger(builderKey);
- final builder =
- _scopeLogSync(() => builderFactory(optionsWithDefaults), logger);
- if (builder == null) {
- logger.severe(_factoryFailure(package.name, optionsWithDefaults));
- throw CannotBuildException();
- }
- return InBuildPhase(builder, package.name,
- builderKey: builderKey,
- targetSources: targetSources,
- generateFor: generateFor,
- builderOptions: optionsWithDefaults,
- hideOutput: hideOutput,
- isOptional: isOptional);
- };
- }).toList();
- return BuilderApplication._(
- builderKey, phaseFactories, filter, hideOutput, appliesBuilders);
- }
-
- /// Note that these builder applications each create their own phase, but they
- /// will all eventually be merged into a single phase.
- factory BuilderApplication.forPostProcessBuilder(
- String builderKey,
- PostProcessBuilderFactory builderFactory, {
- InputSet defaultGenerateFor,
- BuilderOptions defaultOptions,
- BuilderOptions defaultDevOptions,
- BuilderOptions defaultReleaseOptions,
- }) {
- var phaseFactory = (PackageNode package, BuilderOptions options,
- InputSet targetSources, InputSet generateFor, bool isReleaseBuild) {
- generateFor ??= defaultGenerateFor;
-
- var optionsWithDefaults = (defaultOptions ?? BuilderOptions.empty)
- .overrideWith(
- isReleaseBuild ? defaultReleaseOptions : defaultDevOptions)
- .overrideWith(options);
- if (package.isRoot) {
- optionsWithDefaults =
- optionsWithDefaults.overrideWith(BuilderOptions.forRoot);
- }
-
- final logger = Logger(builderKey);
- final builder =
- _scopeLogSync(() => builderFactory(optionsWithDefaults), logger);
- if (builder == null) {
- logger.severe(_factoryFailure(package.name, optionsWithDefaults));
- throw CannotBuildException();
- }
- var builderAction = PostBuildAction(builder, package.name,
- builderOptions: optionsWithDefaults,
- generateFor: generateFor,
- targetSources: targetSources);
- return PostBuildPhase([builderAction]);
- };
- return BuilderApplication._(
- builderKey, [phaseFactory], toNoneByDefault(), true, []);
- }
-}
-
-final _logger = Logger('ApplyBuilders');
-
-/// Creates a [BuildPhase] to apply each builder in [builderApplications] to
-/// each target in [targetGraph] such that all builders are run for dependencies
-/// before moving on to later packages.
-///
-/// When there is a package cycle the builders are applied to each packages
-/// within the cycle before moving on to packages that depend on any package
-/// within the cycle.
-///
-/// Builders may be filtered, for instance to run only on package which have a
-/// dependency on some other package by choosing the appropriate
-/// [BuilderApplication].
-Future<List<BuildPhase>> createBuildPhases(
- TargetGraph targetGraph,
- Iterable<BuilderApplication> builderApplications,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- bool isReleaseMode) async {
- validateBuilderConfig(builderApplications, targetGraph.rootPackageConfig,
- builderConfigOverrides, _logger);
- final globalOptions = targetGraph.rootPackageConfig.globalOptions.map(
- (key, config) => MapEntry(
- key,
- _options(config?.options).overrideWith(isReleaseMode
- ? _options(config?.releaseOptions)
- : _options(config?.devOptions))));
- for (final key in builderConfigOverrides.keys) {
- final overrides = BuilderOptions(builderConfigOverrides[key]);
- globalOptions[key] =
- (globalOptions[key] ?? BuilderOptions.empty).overrideWith(overrides);
- }
-
- final cycles = stronglyConnectedComponents<TargetNode>(
- targetGraph.allModules.values,
- (node) => node.target.dependencies?.map((key) {
- if (!targetGraph.allModules.containsKey(key)) {
- _logger.severe('${node.target.key} declares a dependency on $key '
- 'but it does not exist');
- throw CannotBuildException();
- }
- return targetGraph.allModules[key];
- })?.where((n) => n != null),
- equals: (a, b) => a.target.key == b.target.key,
- hashCode: (node) => node.target.key.hashCode);
- final applyWith = _applyWith(builderApplications);
- final allBuilders = Map<String, BuilderApplication>.fromIterable(
- builderApplications,
- key: (b) => (b as BuilderApplication).builderKey);
- final expandedPhases = cycles
- .expand((cycle) => _createBuildPhasesWithinCycle(
- cycle,
- builderApplications,
- globalOptions,
- applyWith,
- allBuilders,
- isReleaseMode))
- .toList();
-
- final inBuildPhases = expandedPhases.whereType<InBuildPhase>();
-
- final postBuildPhases = expandedPhases.whereType<PostBuildPhase>().toList();
- final collapsedPostBuildPhase = <PostBuildPhase>[];
- if (postBuildPhases.isNotEmpty) {
- collapsedPostBuildPhase.add(postBuildPhases
- .fold<PostBuildPhase>(PostBuildPhase([]), (previous, next) {
- previous.builderActions.addAll(next.builderActions);
- return previous;
- }));
- }
-
- return <BuildPhase>[...inBuildPhases, ...collapsedPostBuildPhase];
-}
-
-Iterable<BuildPhase> _createBuildPhasesWithinCycle(
- Iterable<TargetNode> cycle,
- Iterable<BuilderApplication> builderApplications,
- Map<String, BuilderOptions> globalOptions,
- Map<String, List<BuilderApplication>> applyWith,
- Map<String, BuilderApplication> allBuilders,
- bool isReleaseMode) =>
- builderApplications.expand((builderApplication) =>
- _createBuildPhasesForBuilderInCycle(
- cycle,
- builderApplication,
- globalOptions[builderApplication.builderKey] ??
- BuilderOptions.empty,
- applyWith,
- allBuilders,
- isReleaseMode));
-
-Iterable<BuildPhase> _createBuildPhasesForBuilderInCycle(
- Iterable<TargetNode> cycle,
- BuilderApplication builderApplication,
- BuilderOptions globalOptionOverrides,
- Map<String, List<BuilderApplication>> applyWith,
- Map<String, BuilderApplication> allBuilders,
- bool isReleaseMode) {
- TargetBuilderConfig targetConfig(TargetNode node) =>
- node.target.builders[builderApplication.builderKey];
- return builderApplication.buildPhaseFactories.expand((createPhase) => cycle
- .where((targetNode) => _shouldApply(
- builderApplication, targetNode, applyWith, allBuilders))
- .map((node) {
- final builderConfig = targetConfig(node);
- final options = _options(builderConfig?.options)
- .overrideWith(isReleaseMode
- ? _options(builderConfig?.releaseOptions)
- : _options(builderConfig?.devOptions))
- .overrideWith(globalOptionOverrides);
- return createPhase(node.package, options, node.target.sources,
- builderConfig?.generateFor, isReleaseMode);
- }));
-}
-
-bool _shouldApply(
- BuilderApplication builderApplication,
- TargetNode node,
- Map<String, List<BuilderApplication>> applyWith,
- Map<String, BuilderApplication> allBuilders) {
- if (!(builderApplication.hideOutput &&
- builderApplication.appliesBuilders
- .every((b) => allBuilders[b]?.hideOutput ?? true)) &&
- !node.package.isRoot) {
- return false;
- }
- final builderConfig = node.target.builders[builderApplication.builderKey];
- if (builderConfig?.isEnabled != null) {
- return builderConfig.isEnabled;
- }
- final shouldAutoApply =
- node.target.autoApplyBuilders && builderApplication.filter(node.package);
- return shouldAutoApply ||
- (applyWith[builderApplication.builderKey] ?? const []).any(
- (anchorBuilder) =>
- _shouldApply(anchorBuilder, node, applyWith, allBuilders));
-}
-
-/// Inverts the dependency map from 'applies builders' to 'applied with
-/// builders'.
-Map<String, List<BuilderApplication>> _applyWith(
- Iterable<BuilderApplication> builderApplications) {
- final applyWith = <String, List<BuilderApplication>>{};
- for (final builderApplication in builderApplications) {
- for (final alsoApply in builderApplication.appliesBuilders) {
- applyWith.putIfAbsent(alsoApply, () => []).add(builderApplication);
- }
- }
- return applyWith;
-}
-
-/// Runs [fn] in an error handling [Zone].
-///
-/// Any calls to [print] will be logged with `log.info`, and any errors will be
-/// logged with `log.severe`.
-T _scopeLogSync<T>(T Function() fn, Logger log) {
- return runZoned(fn,
- zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- log.info(message);
- }),
- zoneValues: {logKey: log},
- onError: (Object e, StackTrace s) {
- log.severe('', e, s);
- });
-}
-
-String _factoryFailure(String packageName, BuilderOptions options) =>
- 'Failed to instantiate builder for $packageName with configuration:\n'
- '${JsonEncoder.withIndent(' ').convert(options.config)}';
-
-BuilderOptions _options(Map<String, dynamic> options) =>
- options?.isEmpty ?? true ? BuilderOptions.empty : BuilderOptions(options);
diff --git a/build_runner_core/lib/src/package_graph/package_graph.dart b/build_runner_core/lib/src/package_graph/package_graph.dart
deleted file mode 100644
index 2ef4a56..0000000
--- a/build_runner_core/lib/src/package_graph/package_graph.dart
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (c) 2016, 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:io';
-
-import 'package:path/path.dart' as p;
-import 'package:yaml/yaml.dart';
-
-import '../util/constants.dart';
-
-/// The SDK package, we filter this to the core libs and dev compiler
-/// resources.
-final PackageNode _sdkPackageNode =
- PackageNode(r'$sdk', sdkPath, DependencyType.hosted);
-
-/// A graph of the package dependencies for an application.
-class PackageGraph {
- /// The root application package.
- final PackageNode root;
-
- /// All [PackageNode]s indexed by package name.
- final Map<String, PackageNode> allPackages;
-
- PackageGraph._(this.root, Map<String, PackageNode> allPackages)
- : allPackages = Map.unmodifiable(
- Map<String, PackageNode>.from(allPackages)
- ..putIfAbsent(r'$sdk', () => _sdkPackageNode)) {
- if (!root.isRoot) {
- throw ArgumentError('Root node must indicate `isRoot`');
- }
- if (allPackages.values.where((n) => n != root).any((n) => n.isRoot)) {
- throw ArgumentError('No nodes other than the root may indicate `isRoot`');
- }
- }
-
- /// Creates a [PackageGraph] given the [root] [PackageNode].
- factory PackageGraph.fromRoot(PackageNode root) {
- final allPackages = <String, PackageNode>{root.name: root};
-
- void addDeps(PackageNode package) {
- for (var dep in package.dependencies) {
- if (allPackages.containsKey(dep.name)) continue;
- allPackages[dep.name] = dep;
- addDeps(dep);
- }
- }
-
- addDeps(root);
-
- return PackageGraph._(root, allPackages);
- }
-
- /// Creates a [PackageGraph] for the package whose top level directory lives
- /// at [packagePath] (no trailing slash).
- factory PackageGraph.forPath(String packagePath) {
- /// Read in the pubspec file and parse it as yaml.
- final pubspec = File(p.join(packagePath, 'pubspec.yaml'));
- if (!pubspec.existsSync()) {
- throw StateError(
- 'Unable to generate package graph, no `pubspec.yaml` found. '
- 'This program must be ran from the root directory of your package.');
- }
- final rootPubspec = _pubspecForPath(packagePath);
- final rootPackageName = rootPubspec['name'] as String;
-
- final packageLocations = _parsePackageLocations(packagePath)
- ..remove(rootPackageName);
-
- final dependencyTypes = _parseDependencyTypes(packagePath);
-
- final nodes = <String, PackageNode>{};
- final rootNode = PackageNode(
- rootPackageName, packagePath, DependencyType.path,
- isRoot: true);
- nodes[rootPackageName] = rootNode;
- for (final packageName in packageLocations.keys) {
- if (packageName == rootPackageName) continue;
- nodes[packageName] = PackageNode(packageName,
- packageLocations[packageName], dependencyTypes[packageName],
- isRoot: false);
- }
-
- rootNode.dependencies
- .addAll(_depsFromYaml(rootPubspec, isRoot: true).map((n) => nodes[n]));
-
- final packageDependencies = _parsePackageDependencies(packageLocations);
- for (final packageName in packageDependencies.keys) {
- nodes[packageName]
- .dependencies
- .addAll(packageDependencies[packageName].map((n) => nodes[n]));
- }
- return PackageGraph._(rootNode, nodes);
- }
-
- /// Creates a [PackageGraph] for the package in which you are currently
- /// running.
- factory PackageGraph.forThisPackage() => PackageGraph.forPath('./');
-
- /// Shorthand to get a package by name.
- PackageNode operator [](String packageName) => allPackages[packageName];
-
- @override
- String toString() {
- var buffer = StringBuffer();
- for (var package in allPackages.values) {
- buffer.writeln('$package');
- }
- return buffer.toString();
- }
-}
-
-/// A node in a [PackageGraph].
-class PackageNode {
- /// The name of the package as listed in `pubspec.yaml`.
- final String name;
-
- /// The type of dependency being used to pull in this package.
- ///
- /// May be `null`.
- final DependencyType dependencyType;
-
- /// All the packages that this package directly depends on.
- final List<PackageNode> dependencies = [];
-
- /// The absolute path of the current version of this package.
- ///
- /// Paths are platform dependent.
- final String path;
-
- /// Whether this node is the [PackageGraph.root].
- final bool isRoot;
-
- PackageNode(this.name, String path, this.dependencyType, {bool isRoot})
- : path = _toAbsolute(path),
- isRoot = isRoot ?? false;
-
- @override
- String toString() => '''
- $name:
- type: $dependencyType
- path: $path
- dependencies: [${dependencies.map((d) => d.name).join(', ')}]''';
-
- /// Converts [path] to a canonical absolute path, returns `null` if given
- /// `null`.
- static String _toAbsolute(String path) =>
- (path == null) ? null : p.canonicalize(path);
-}
-
-/// Parse the `.packages` file and return a Map from package name to the file
-/// location for that package.
-Map<String, String> _parsePackageLocations(String rootPackagePath) {
- var packagesFile = File(p.join(rootPackagePath, '.packages'));
- if (!packagesFile.existsSync()) {
- throw StateError('Unable to generate package graph, no `.packages` found. '
- 'This program must be ran from the root directory of your package.');
- }
- var packageLocations = <String, String>{};
- for (final line in packagesFile.readAsLinesSync().skip(1)) {
- var firstColon = line.indexOf(':');
- var name = line.substring(0, firstColon);
- assert(line.endsWith('lib/'));
- // Start after package_name:, and strip out trailing 'lib/'.
- var uriString = line.substring(firstColon + 1, line.length - 4);
- // Strip the trailing slash, if present.
- if (uriString.endsWith('/')) {
- uriString = uriString.substring(0, uriString.length - 1);
- }
- var uri = Uri.tryParse(uriString) ?? Uri.file(uriString);
- if (!uri.isAbsolute) {
- uri = p.toUri(p.join(rootPackagePath, uri.path));
- }
- packageLocations[name] = uri.toFilePath(windows: Platform.isWindows);
- }
- return packageLocations;
-}
-
-/// The type of dependency being used. This dictates how the package should be
-/// watched for changes.
-enum DependencyType { github, path, hosted }
-
-/// Parse the `pubspec.lock` file and return a Map from package name to the type
-/// of dependency.
-Map<String, DependencyType> _parseDependencyTypes(String rootPackagePath) {
- final pubspecLock = File(p.join(rootPackagePath, 'pubspec.lock'));
- if (!pubspecLock.existsSync()) {
- throw StateError(
- 'Unable to generate package graph, no `pubspec.lock` found. '
- 'This program must be ran from the root directory of your package.');
- }
- final dependencyTypes = <String, DependencyType>{};
- final dependencies = loadYaml(pubspecLock.readAsStringSync()) as YamlMap;
- for (final packageName in dependencies['packages'].keys) {
- final source = dependencies['packages'][packageName]['source'];
- dependencyTypes[packageName as String] =
- _dependencyTypeFromSource(source as String);
- }
- return dependencyTypes;
-}
-
-DependencyType _dependencyTypeFromSource(String source) {
- switch (source) {
- case 'git':
- return DependencyType.github;
- case 'hosted':
- return DependencyType.hosted;
- case 'path':
- case 'sdk': // Until Flutter supports another type, assum same as path.
- return DependencyType.path;
- }
- throw ArgumentError('Unable to determine dependency type:\n$source');
-}
-
-/// Read the pubspec for each package in [packageLocations] and finds it's
-/// dependencies.
-Map<String, Set<String>> _parsePackageDependencies(
- Map<String, String> packageLocations) {
- final dependencies = <String, Set<String>>{};
- for (final packageName in packageLocations.keys) {
- final pubspec = _pubspecForPath(packageLocations[packageName]);
- dependencies[packageName] = _depsFromYaml(pubspec);
- }
- return dependencies;
-}
-
-/// Gets the deps from a yaml file, taking into account dependency_overrides.
-Set<String> _depsFromYaml(YamlMap yaml, {bool isRoot = false}) {
- var deps = <String>{}..addAll(_stringKeys(yaml['dependencies'] as Map));
- if (isRoot) {
- deps
- ..addAll(_stringKeys(yaml['dev_dependencies'] as Map))
- ..addAll(_stringKeys(yaml['dependency_overrides'] as Map));
- }
- return deps;
-}
-
-Iterable<String> _stringKeys(Map m) =>
- m == null ? const [] : m.keys.cast<String>();
-
-/// Should point to the top level directory for the package.
-YamlMap _pubspecForPath(String absolutePath) {
- var pubspecPath = p.join(absolutePath, 'pubspec.yaml');
- var pubspec = File(pubspecPath);
- if (!pubspec.existsSync()) {
- throw StateError(
- 'Unable to generate package graph, no `$pubspecPath` found.');
- }
- return loadYaml(pubspec.readAsStringSync()) as YamlMap;
-}
diff --git a/build_runner_core/lib/src/package_graph/target_graph.dart b/build_runner_core/lib/src/package_graph/target_graph.dart
deleted file mode 100644
index d66b158..0000000
--- a/build_runner_core/lib/src/package_graph/target_graph.dart
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart';
-import 'package:build_config/build_config.dart';
-import 'package:glob/glob.dart';
-
-import '../generate/input_matcher.dart';
-import 'package_graph.dart';
-
-/// Like a [PackageGraph] but packages are further broken down into modules
-/// based on build config.
-class TargetGraph {
- /// All [TargetNode]s indexed by `"$packageName:$targetName"`.
- final Map<String, TargetNode> allModules;
-
- /// All [TargetNode]s by package name.
- final Map<String, List<TargetNode>> modulesByPackage;
-
- /// The [BuildConfig] of the root package.
- final BuildConfig rootPackageConfig;
-
- TargetGraph._(this.allModules, this.modulesByPackage, this.rootPackageConfig);
-
- static Future<TargetGraph> forPackageGraph(PackageGraph packageGraph,
- {Map<String, BuildConfig> overrideBuildConfig,
- List<String> defaultRootPackageWhitelist}) async {
- overrideBuildConfig ??= const {};
- final modulesByKey = <String, TargetNode>{};
- final modulesByPackage = <String, List<TargetNode>>{};
- BuildConfig rootPackageConfig;
- for (final package in packageGraph.allPackages.values) {
- final config = overrideBuildConfig[package.name] ??
- await _packageBuildConfig(package);
- List<String> defaultInclude;
- if (package.isRoot) {
- defaultInclude = defaultRootPackageWhitelist;
- rootPackageConfig = config;
- } else if (package.name == r'$sdk') {
- defaultInclude = const [
- 'lib/dev_compiler/**.js',
- 'lib/_internal/**.sum',
- ];
- } else {
- defaultInclude = const ['lib/**'];
- }
- final nodes = config.buildTargets.values.map((target) =>
- TargetNode(target, package, defaultInclude: defaultInclude));
- for (final node in nodes) {
- modulesByKey[node.target.key] = node;
- modulesByPackage.putIfAbsent(node.target.package, () => []).add(node);
- }
- }
- return TargetGraph._(modulesByKey, modulesByPackage, rootPackageConfig);
- }
-
- /// Whether or not [id] is included in the sources of any target in the graph.
- bool anyMatchesAsset(AssetId id) =>
- modulesByPackage[id.package]?.any((t) => t.matchesSource(id)) ?? false;
-}
-
-class TargetNode {
- final BuildTarget target;
- final PackageNode package;
-
- List<Glob> get sourceIncludes => _sourcesMatcher.includeGlobs;
- final InputMatcher _sourcesMatcher;
-
- TargetNode(this.target, this.package, {List<String> defaultInclude})
- : _sourcesMatcher =
- InputMatcher(target.sources, defaultInclude: defaultInclude);
-
- bool excludesSource(AssetId id) => _sourcesMatcher.excludes(id);
-
- bool matchesSource(AssetId id) => _sourcesMatcher.matches(id);
-
- @override
- String toString() => target.key;
-}
-
-Future<BuildConfig> _packageBuildConfig(PackageNode package) async {
- final dependencyNames = package.dependencies.map((n) => n.name);
- if (package.path == null) {
- return BuildConfig.useDefault(package.name, dependencyNames);
- }
- try {
- return await BuildConfig.fromBuildConfigDir(
- package.name, dependencyNames, package.path);
- } on ArgumentError catch (e) {
- throw BuildConfigParseException(package.name, e);
- }
-}
-
-class BuildConfigParseException implements Exception {
- final String packageName;
- final dynamic exception;
-
- BuildConfigParseException(this.packageName, this.exception);
-}
diff --git a/build_runner_core/lib/src/performance_tracking/performance_tracking_resolvers.dart b/build_runner_core/lib/src/performance_tracking/performance_tracking_resolvers.dart
deleted file mode 100644
index 0155e55..0000000
--- a/build_runner_core/lib/src/performance_tracking/performance_tracking_resolvers.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 'package:build/build.dart';
-
-import '../generate/performance_tracker.dart';
-
-class PerformanceTrackingResolvers implements Resolvers {
- final Resolvers _delegate;
- final BuilderActionTracker _tracker;
-
- PerformanceTrackingResolvers(this._delegate, this._tracker);
-
- @override
- Future<ReleasableResolver> get(BuildStep buildStep) =>
- _tracker.trackStage('ResolverGet', () => _delegate.get(buildStep));
-
- @override
- void reset() => _delegate.reset();
-}
diff --git a/build_runner_core/lib/src/util/async.dart b/build_runner_core/lib/src/util/async.dart
deleted file mode 100644
index 75d755b..0000000
--- a/build_runner_core/lib/src/util/async.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, 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';
-
-/// Invokes [callback] and returns the result as soon as possible. This will
-/// happen synchronously if [value] is available.
-FutureOr<S> doAfter<T, S>(
- FutureOr<T> value, FutureOr<S> Function(T value) callback) {
- if (value is Future<T>) {
- return value.then(callback);
- } else {
- return callback(value as T);
- }
-}
-
-/// Converts [value] to a [Future] if it is not already.
-Future<T> toFuture<T>(FutureOr<T> value) =>
- value is Future<T> ? value : Future.value(value);
diff --git a/build_runner_core/lib/src/util/build_dirs.dart b/build_runner_core/lib/src/util/build_dirs.dart
deleted file mode 100644
index 1301186..0000000
--- a/build_runner_core/lib/src/util/build_dirs.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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:build/build.dart';
-
-import '../generate/options.dart';
-import '../generate/phase.dart';
-
-/// Returns whether or not [id] should be built based upon [buildDirs],
-/// [phase], and optional [buildFilters].
-///
-/// The logic for this is as follows:
-///
-/// - If any [buildFilters] are supplied, then this only returns `true` if [id]
-/// explicitly matches one of the filters.
-/// - If no [buildFilters] are supplied, then the old behavior applies - all
-/// build to source builders and all files under `lib` of all packages are
-/// always built.
-/// - Regardless of the [buildFilters] setting, if [buildDirs] is supplied then
-/// `id.path` must start with one of the specified directory names.
-bool shouldBuildForDirs(AssetId id, Set<String> buildDirs,
- Set<BuildFilter> buildFilters, BuildPhase phase) {
- buildFilters ??= {};
- if (buildFilters.isEmpty) {
- if (!phase.hideOutput) return true;
-
- if (id.path.startsWith('lib/')) return true;
- } else {
- if (!buildFilters.any((f) => f.matches(id))) {
- return false;
- }
- }
-
- if (buildDirs.isEmpty) return true;
-
- return id.path.startsWith('lib/') || buildDirs.any(id.path.startsWith);
-}
diff --git a/build_runner_core/lib/src/util/clock.dart b/build_runner_core/lib/src/util/clock.dart
deleted file mode 100644
index 5b2db75..0000000
--- a/build_runner_core/lib/src/util/clock.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017, 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';
-
-/// A function that returns the current [DateTime].
-typedef _Clock = DateTime Function();
-DateTime _defaultClock() => DateTime.now();
-
-/// Returns the current [DateTime].
-///
-/// May be overridden for tests using [scopeClock].
-DateTime now() => (Zone.current[_Clock] as _Clock ?? _defaultClock)();
-
-/// Runs [f], with [clock] scoped whenever [now] is called.
-T scopeClock<T>(DateTime Function() clock, T Function() f) =>
- runZoned(f, zoneValues: {_Clock: clock});
diff --git a/build_runner_core/lib/src/util/constants.dart b/build_runner_core/lib/src/util/constants.dart
deleted file mode 100644
index eb1d073..0000000
--- a/build_runner_core/lib/src/util/constants.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-import 'dart:io';
-
-import 'package:crypto/crypto.dart';
-import 'package:path/path.dart' as p;
-
-/// Relative path to the asset graph from the root package dir.
-final String assetGraphPath = assetGraphPathFor(_scriptPath);
-
-/// Relative path to the asset graph for a build script at [path]
-String assetGraphPathFor(String path) =>
- '$cacheDir/${_scriptHashFor(path)}/asset_graph.json';
-
-/// Relative path to the directory which holds serialized versions of errors
-/// reported during previous builds.
-final errorCachePath =
- p.url.join(cacheDir, _scriptHashFor(_scriptPath), 'error_cache');
-
-final String _scriptPath = Platform.script.scheme == 'file'
- ? p.url.joinAll(
- p.split(p.relative(Platform.script.toFilePath(), from: p.current)))
- : Platform.script.path;
-
-/// Directory containing automatically generated build entrypoints.
-///
-/// Files in this directory must be read to do build script invalidation.
-const entryPointDir = '$cacheDir/entrypoint';
-
-/// The directory to which hidden assets will be written.
-String get generatedOutputDirectory => '$cacheDir/$_generatedOutputDirectory';
-
-/// Locks the generated directory name for the duration of this process.
-///
-/// This should be invoked before any builds start.
-void lockGeneratedOutputDirectory() => _generatedOutputDirectoryIsLocked = true;
-
-/// The default generated dir name. Can be modified with
-/// [overrideGeneratedOutputDirectory].
-String _generatedOutputDirectory = 'generated';
-
-/// Whether or not the [generatedOutputDirectory] is locked. This must be `true`
-/// before you can access [generatedOutputDirectory];
-bool _generatedOutputDirectoryIsLocked = false;
-
-/// Overrides the generated directory name.
-///
-/// This is interpreted as a relative path under the [cacheDir].
-void overrideGeneratedOutputDirectory(String path) {
- if (_generatedOutputDirectory != 'generated') {
- throw StateError('You can only override the generated dir once.');
- } else if (_generatedOutputDirectoryIsLocked) {
- throw StateError(
- 'Attempted to override the generated dir after it was locked.');
- } else if (!p.isRelative(path)) {
- throw StateError('Only relative paths are accepted for the generated dir '
- 'but got `$path`.');
- }
- _generatedOutputDirectory = path;
-}
-
-/// Relative path to the cache directory from the root package dir.
-const String cacheDir = '.dart_tool/build';
-
-/// Returns a hash for a given Dart script path.
-///
-/// Normalizes between snapshot and Dart source file paths so they give the same
-/// hash.
-String _scriptHashFor(String path) => md5
- .convert(utf8.encode(
- path.endsWith('.snapshot') ? path.substring(0, path.length - 9) : path))
- .toString();
-
-/// The name of the pub binary on the current platform.
-final pubBinary = p.join(sdkBin, Platform.isWindows ? 'pub.bat' : 'pub');
-
-/// The path to the sdk bin directory on the current platform.
-final sdkBin = p.join(sdkPath, 'bin');
-
-/// The path to the sdk on the current platform.
-final sdkPath = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-/// The maximum number of concurrent actions to run per build phase.
-const buildPhasePoolSize = 16;
diff --git a/build_runner_core/lib/src/util/hash.dart b/build_runner_core/lib/src/util/hash.dart
deleted file mode 100644
index d8539e2..0000000
--- a/build_runner_core/lib/src/util/hash.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2019, 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.
-
-int hashCombine(int hash, int value) {
- hash = 0x1fffffff & (hash + value);
- hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
- return hash ^ (hash >> 6);
-}
-
-int hashComplete(int hash) {
- hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
- hash = hash ^ (hash >> 11);
- return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
-}
diff --git a/build_runner_core/lib/src/util/sdk_version_match.dart b/build_runner_core/lib/src/util/sdk_version_match.dart
deleted file mode 100644
index f584862..0000000
--- a/build_runner_core/lib/src/util/sdk_version_match.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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.
-
-/// Checks whether [thisVersion] and [thatVersion] have the same semver
-/// identifier without extra platform specific information.
-bool isSameSdkVersion(String thisVersion, String thatVersion) =>
- thisVersion?.split(' ')?.first == thatVersion?.split(' ')?.first;
diff --git a/build_runner_core/lib/src/validation/config_validation.dart b/build_runner_core/lib/src/validation/config_validation.dart
deleted file mode 100644
index 2ec9c7e..0000000
--- a/build_runner_core/lib/src/validation/config_validation.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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:build_config/build_config.dart';
-import 'package:logging/logging.dart';
-
-import '../package_graph/apply_builders.dart';
-
-/// Checks that all configuration is for valid builder keys.
-void validateBuilderConfig(
- Iterable<BuilderApplication> builders,
- BuildConfig rootPackageConfig,
- Map<String, Map<String, dynamic>> builderConfigOverrides,
- Logger logger) {
- final builderKeys = builders.map((b) => b.builderKey).toSet();
- for (final key in builderConfigOverrides.keys) {
- if (!builderKeys.contains(key)) {
- logger.warning('Overriding configuration for `$key` but this is not a '
- 'known Builder');
- }
- }
- for (final target in rootPackageConfig.buildTargets.values) {
- for (final key in target.builders.keys) {
- if (!builderKeys.contains(key)) {
- logger.warning('Configuring `$key` in target `${target.key}` but this '
- 'is not a known Builder');
- }
- }
- }
- for (final key in rootPackageConfig.globalOptions.keys) {
- if (!builderKeys.contains(key)) {
- logger.warning('Configuring `$key` in global options but this is not a '
- 'known Builder');
- }
- }
-}
diff --git a/build_runner_core/mono_pkg.yaml b/build_runner_core/mono_pkg.yaml
deleted file mode 100644
index 74ca9f7..0000000
--- a/build_runner_core/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-dart:
- - 2.6.0
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- dart: dev
- - dartanalyzer: --fatal-warnings .
- dart: 2.6.0
- - unit_test:
- - test:
- os:
- - linux
- - windows
diff --git a/build_runner_core/pubspec.yaml b/build_runner_core/pubspec.yaml
deleted file mode 100644
index e87a441..0000000
--- a/build_runner_core/pubspec.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: build_runner_core
-version: 4.4.0
-description: Core tools to write binaries that run builders.
-homepage: https://github.com/dart-lang/build/tree/master/build_runner_core
-
-environment:
- sdk: ">=2.6.0 <3.0.0"
-
-dependencies:
- async: ">=1.13.3 <3.0.0"
- build: ">=1.2.0 <1.3.0"
- build_config: ">=0.4.2 <0.4.3"
- build_resolvers: ^1.0.0
- collection: ^1.14.0
- convert: ^2.0.1
- crypto: ">=0.9.2 <3.0.0"
- glob: ^1.1.0
- graphs: ^0.2.0
- json_annotation: '>=1.0.0 <4.0.0'
- logging: ^0.11.2
- meta: ^1.1.0
- path: ^1.1.0
- pedantic: ^1.0.0
- pool: ^1.0.0
- timing: ^0.1.1
- watcher: ^0.9.7
- yaml: ^2.1.0
-
-dev_dependencies:
- build_test: ^0.10.0
- package_resolver: ^1.0.2
- source_gen: ^0.9.0
- test: ^1.0.0
- test_descriptor: ^1.0.0
- test_process: ^1.0.0
- _test_common:
- path: ../_test_common
diff --git a/build_test/BUILD.gn b/build_test/BUILD.gn
deleted file mode 100644
index f490fa0..0000000
--- a/build_test/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# This file is generated by importer.py for build_test-0.10.12+1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_test") {
- package_name = "build_test"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/pedantic",
- "//third_party/dart-pkg/pub/matcher",
- "//third_party/dart-pkg/pub/glob",
- "//third_party/dart-pkg/pub/watcher",
- "//third_party/dart-pkg/pub/test_core",
- "//third_party/dart-pkg/pub/package_resolver",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/stream_transform",
- "//third_party/dart-pkg/pub/html",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/build_resolvers",
- "//third_party/dart-pkg/pub/test",
- "//third_party/dart-pkg/pub/async",
- "//third_party/dart-pkg/pub/build_config",
- ]
-}
diff --git a/build_test/CHANGELOG.md b/build_test/CHANGELOG.md
deleted file mode 100644
index f0d57ab..0000000
--- a/build_test/CHANGELOG.md
+++ /dev/null
@@ -1,426 +0,0 @@
-## 0.10.12+1
-
-- Allow the latest test_core package (`0.3.x`).
-
-## 0.10.12
-
-- Fix a bug with the `resolve*` apis where they would leak unhandled async
- errors to client code if the provided action callback threw an error.
-
-## 0.10.11
-
-- Add support for the new `$package$` placeholder.
-
-### Potentially Breaking Change
-
-- Only add the non-lib placeholders when a root package is specified
- - Infer the root package when there is only one package in the sources
- - This is being released as a non-breaking change because the only expected
- use cases already would have been broken - `findAssets` calls already
- required a root package.
-
-## 0.10.10
-
-- Allow reading of assets written from the same build step.
- - This mirrors the latest behavior in build_runner_core.
-- Require SDK version `2.6.0` to enable extension methods.
-
-## 0.10.9+1
-
-- Fix the `DebugTestBuilder` on windows.
-- Fix `PackageAssetReader` on windows.
-
-## 0.10.9
-
-- Allow tracking of reported unused assets in `testBuilder` calls with the
- `reportUnusedAssetsForInput(AssetId input, Iterable<AssetId> unused)`
- callback.
-
-## 0.10.8
-
-- Allow a custom AssetReader to be passed to `testBuilder`. This will be used
- as a fallback for any sources that don't exist in the `sourceAssets` map.
-
-## 0.10.7+3
-
-- Handle the case where the root package in a `PackageAssetReader` is a fake
- package.
-
-## 0.10.7+2
-
-- Avoid throwing for missing files from `PackageAssetReader.canRead`.
-
-## 0.10.7+1
-
-- Allow `build_config` `0.4.x`.
-
-## 0.10.7
-
-- Support the latest version of `package:html`.
-- Only generate bootstrap scripts for supported platforms based on `TestOn`
- annotations.
-
-## 0.10.6
-
-- Allow build_resolvers version `1.0.0`.
-
-## 0.10.5
-
-- Improve error messages for unresolvable URIs in the PackageAssetReader.
-
-## 0.10.4
-
-- Allow using `PackageAssetReader` when the current working directory is not the
- root package directory as long as it uses a pub layout.
-
-## 0.10.3+4
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.10.3+3
-
-- Increased the upper bound for `package:analyzer` to '<0.34.0'.
-
-## 0.10.3+2
-
-- Declare support for `package:build` version 1.0.0.
-
-## 0.10.3+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.10.3
-
-- Require test version ^0.12.42 and use `TypeMatcher`.
-- Improve performance of test methods which use a `Resolver` by keeping a cached
- instance of `AnalyzerResolvers`.
-
-## 0.10.2+4
-
-- Allow the latest build_config.
-
-## 0.10.2+3
-
-- Remove package:build_barback dependency, and use public apis from package:test
- to directly do the bootstrapping instead of wrapping the transformer.
-
-## 0.10.2+2
-
-- Avoid looking for files from `Uri.path` paths.
-
-## 0.10.2+1
-
-- Add back an implementation of `findAssets` in `PackageAssetReader`.
-
-## 0.10.2
-
-- Added a `DebugIndexBuilder`, which by default generates a `test/index.html`
- with links to debug tests in your `test/**_test.dart` folder, linking to the
- generated `*_test.debug.html` files. **NOTE**: This only works for web-based
- tests.
-- Fix `PackageAssetReader` when running with a package map pointing to a
- "packages" directory structure, as is generated by `build_runner`. Drop
- support for a broken `findAssets` implementation.
-
-## 0.10.1+1
-
-- Replace `BarbackResolvers` with `AnalyzerResolvers` from `build_resolvers` by
- default.
-
-## 0.10.1
-
-- Allow overriding the `Resolvers` used for `resolve*` utilities.
-- Bug Fix: Don't call the `action` multiple times when there are multiple
- sources passed to `resolve*`.
-
-## 0.10.0
-
-- Added automatic generation of `.debug.html` files for all tests, which can
- be loaded in the browser to directly run tests and debug them without going
- through the package:test runner.
-- Update to package:build version `0.12.0`.
-- Removed `CopyBuilder` in favor of `TestBuilder` which takes closures to
- change behavior rather than adding configuration for every possible
- modification.
-- Added support for the special placeholder `{$lib/$test/$web}` assets
- supported by the `build_runner` and `bazel_codegen` implementations of
- `package:build`. For an example see `test/test_builder_test.dart`. Note that
- this is technically a **BREAKING CHANGE**, as additional inputs will be
- matched for overzealous builders (like `TestBuilder`).
-- Added `resolverFor` as an optional parameter to `resolveSources`. By default
- a `Resolver` is returned for the _first_ asset provided; to modify that the
- name of another asset may be provided. This is a **BREAKING CHANGE**, as
- previously the last asset was used.
-
-## 0.9.4
-
-- Added `InMemoryAssetReader.shareAssetCache` constructor. This is useful for the
- case where the reader should be kept up to date as assets are written through
- a writer.
-- Added `buildInputs` stream to `CopyBuilder` which emits an event for each
- `BuildStep.inputId` at the top of the `build` method.
-- `CopyBuilder` automatically skips the placeholder files (any file ending in
- `$`). This is technically breaking but should not affect any real users and is
- not being released as a breaking change.
-- Changed `TestBootstrapBuilder` to only target `_test.dart` files.
-
-## 0.9.3
-
-- Added `resolveSources`, a way to resolve multiple libraries for testing,
- including any combination of fake files (in-memory, created in the test) and
- real ones (from on-disk packages):
-
-```dart
-test('multiple assets, some mock, some on disk', () async {
- final real = 'build_test|test/_files/example_lib.dart';
- final mock = 'build_test|test/_files/not_really_here.dart';
- final library = await resolveSources(
- {
- real: useAssetReader,
- mock: r'''
- // This is a fake library that we're mocking.
- library example;
-
- // This is a real on-disk library we are using.
- import 'example_lib.dart';
-
- class ExamplePrime extends Example {}
- ''',
- },
- (resolver) => resolver.findLibraryByName('example'),
- );
- final type = library.getType('ExamplePrime');
- expect(type, isNotNull);
- expect(type.supertype.name, 'Example');
-});
-```
-
-## 0.9.2
-
-- Add `inputExtension` argument to `CopyBuilder`. When used the builder with
- throw if any assets are provided that don't match the input extension.
-
-## 0.9.1
-
-- Allow `build_barback` version `0.5.x`. The breaking behavior change should not
- impact test uses that don't already have a version constraint on that package.
-
-## 0.9.0
-
-- Added the `TestBootstrapBuilder` under the `builder.dart` library. This can
- be used to bootstrap tests similar to the `test/pub_serve` Transformer.
- - **Known Issue**: Custom html files are not supported.
-- **Breaking**: All `AssetReader#findAssets` implementations now return a
- `Stream<AssetId>` to match the latest `build` package.
-- **Breaking**: The `DatedValue`, `DatedString`, and `DatedBytes` apis are now
- gone, since timestamps are no longer used by package:build. Instead the
- `InMemoryAssetReader` and other apis take a `Map<AssetId, dynamic>`, and will
- automatically convert any `String` values into `List<int>` values.
-- **Breaking**: The `outputs` map of `testBuilder` works a little bit
- differently due to the removal of `DatedValue` and `DatedString`.
- * If a value provided is a `String`, then the asset is by default decoded
- using UTF8, and matched against the string.
- * If the value is a `matcher`, it will match againt the actual bytes of the
- asset (in `List<int>` form).
- * A new matcher was added, `decodedMatches`, which can be combined with other
- matchers to match against the string contents. For example, to match a
- string containing a substring, you would do
- `decodedMatches(contains('some substring'))`.
-
-## 0.8.0
-
-- `InMemoryAssetReader`, `MultiAssetReader`, `StubAssetReader` and
- `PackageAssetReader` now implement the `MultiPackageAssetReader` interface.
-- `testBuilder` now supports `Builder`s that call `findAssets` in non-root
- packages.
-- Added a `GlobbingBuilder` which globs files in a package.
-- Added the `RecordingAssetReader` interface, which adds the
- `Iterable<AssetId> get assetsRead` getter.
-- `InMemoryAssetReader` now implements `RecordingAssetReader`.
-- **Breaking**: The `MultiAssetReader` now requires all its wrapped readers to
- implement the `MultiPackageAssetReader` interface.
- - This should not affect most users, since all readers provided by this
- package now implement that interface.
-
-## 0.7.1
-
-- Add `mapAssetIds` argument to `checkOutputs` for cases where the logical asset
- location recorded by the builder does not match the written location.
-
-- Add `recordLogs`, a top-level function that invokes `scopeLog` and captures
- the resulting `Stream<LogRecord>` for testing. Can be used with the provided
- `anyLogOf`, `infoLogOf`, `warningLogOf`, `severeLogOf` matchers in order to
- test a build process:
-
-```dart
-test('should log "uh oh!"', () async {
- final logs = recordLogs(() => runBuilder());
- expect(logs, emitsInOrder([
- anyLogOf('uh oh!'),
- ]);
-});
-```
-
-- Add the constructors `forPackages` and `forPackageRoot` to
- `PackageAssetReader` - these are convenience constructors for pointing to a
- small set of packages (fake or real) for testing purposes. For example:
-
-```dart
-test('should resolve multiple libraries', () async {
- reader = new PackageAssetReader.forPackages({
- 'example_a': '_libs/example_a',
- 'example_b': '_libs/example_b',
- });
- expect(await reader.canRead(fileFromExampleLibA), isTrue);
- expect(await reader.canRead(fileFromExampleLibB), isTrue);
- expect(await reader.canRead(fileFromExampleLibC), isFalse);
-});
-```
-
-## 0.7.0+1
-
-- Switch to a typedef from function type syntax for compatibility with older
- SDKs.
-
-## 0.7.0
-
-- **Breaking**: `resolveSource` and `resolveAsset` now take an `action` to
- perform with the Resolver instance.
-
-## 0.6.4+1
-
-- Allow `package:build_barback` v0.4.x
-
-## 0.6.4
-
-- Allow `package:build` v0.10.x
-- `AssetReader` implementations always return `Future` from `canRead`
-
-## 0.6.3
-
-- Added `resolveAsset`, which is similar to `resolveSource` but specifies a
- real asset that lives on the file system. For example, to resolve the main
- library of `package:collection`:
-
-```dart
-var pkgCollection = new AssetId('collection', 'lib/collection.dart');
-var resolver = await resolveAsset(pkgCollection);
-// ...
-```
-
-- Supports `package:build_barback >=0.2.0 <0.4.0`.
-
-## 0.6.2
-
-- Internal version bump.
-
-## 0.6.1
-
-- Declare an output extension in `_ResolveSourceBuilder` so it is not skipped
-
-## 0.6.0
-
-- Support build 0.9.0
- - Rename `hasInput` to `canRead` in `AssetReader` implementations
- - Replace `declareOutputs` with `buildExtensions` in `Builder` implementations
-- **Breaking** `CopyBuilder` no longer has an `outputPackage` field since outputs
- can only ever be in the same package as inputs.
-
-## 0.5.2
-
-- Add `MultiAssetReader` to the public API.
-
-## 0.5.1
-
-- Add `PackageAssetReader`, a standalone asset reader that uses a
- `PackageResolver` to map an `AssetId` to a location on disk.
-- Add `resolveSource`, a top-level function that can resolve arbitrary Dart
- source code. This can be useful in testing your own code that uses a
- `Resolver` to do type checks.
-
-## 0.5.0
-
-- Add `findAssets` implementations to StubAssetReader an InMemoryAssetReader
-- **BREAKING**: InMemoryAssetReader constructor uses named optional parameters
-
-## 0.4.1
-
-- Make `scopeLog` visible so tests can be run with an available `log` without
- going through runBuilder.
-
-## 0.4.0+1
-
-- Bug Fix: Correctly identify missing outputs in testBuilder
-
-## 0.4.0
-
-Updates to work with `build` version 0.7.0.
-
-### New Features
-- The `testBuilder` method now accepts `List<int>` values for both
- `sourceAssets` and `outputs`.
-- The `checkOutputs` method is now public.
-
-### Breaking Changes
-- The `testBuilder` method now requires a `RecordingAssetWriter` instead of
- just an `AssetWriter` for the `writer` parameter.
-- If a `Matcher` is provided as a value in `outputs`, then it will match against
- the same value that was written. For example if your builder uses
- `writeAsString` then it will match against that string. If you use
- `writeAsBytes` then it will match against those bytes. It will not
- automatically convert to/from bytes and strings.
-- Deleted the `makeAsset` and `makeAssets` methods. There is no more `Asset`
- class so these don't really have any value any more.
-- The signature of `addAssets` has changed to
- `void addAssets(Map<AssetId, dynamic> assets, InMemoryAssetWriter writer)`.
- Values of the map may be either `String` or `List<int>`.
-- `InMemoryAssetReader#assets` and `InMemoryAssetWriter#assets` have changed to
- a type of `Map<AssetId, DatedValue>` from a type of
- `Map<AssetId, DatedString>`. `DatedValue` has both a `stringValue` and
- `bytesValue` getter.
-- `InMemoryAssetReader` and `InMemoryAssetWriter` have been updated to implement
- the new `AssetReader` and `AssetWriter` interfaces (see the `build` package
- CHANGELOG for more details).
-- `InMemoryAssetReader#cacheAsset` has been changed to two separate methods,
- `void cacheStringAsset(AssetId id, String contents)` and
- `void cacheBytesAsset(AssetId id, List<int> bytes)`.
-- The `equalsAsset` matcher has been removed, since there is no more `Asset`
- class.
-
-## 0.3.1
-
-- Additional capabilities in testBuilder:
- - Filter sourceAssets to inputs with `isInput`
- - Get log records
- - Ignore output expectations when `outputs` is null
- - Use a custom `writer`
-
-## 0.3.0
-
-- **BREAKING** removed testPhases utility. Tests should be using testBuilder
-- Drop dependency on build_runner package
-
-## 0.2.1
-
-- Support the package split into build/build_runner/build_barback
-- Expose additional test utilities that used to be internal to build
-
-## 0.2.0
-
-- Upgrade build package to 0.4.0
-- Delete now unnecessary `GenericBuilderTransformer` and use
- `BuilderTransformer` in the tests.
-
-## 0.1.2
-
-- Add `logLevel` and `onLog` named args to `testPhases`. These can be used
- to test your log messages, see `test/utils_test.dart` for an example.
-
-## 0.1.1
-
-- Allow String or Matcher for expected output values in `testPhases`.
-
-## 0.1.0
-
-- Initial version, exposes many basic utilities for testing `Builder`s using in
- memory data structures. Most notably, the `testPhases` method.
diff --git a/build_test/LICENSE b/build_test/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/build_test/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_test/README.md b/build_test/README.md
deleted file mode 100644
index 148cb82..0000000
--- a/build_test/README.md
+++ /dev/null
@@ -1,140 +0,0 @@
-<p align="center">
- Testing utilities for users of <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
- <br>
- <a href="https://travis-ci.org/dart-lang/build">
- <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
- </a>
- <a href="https://github.com/dart-lang/build/labels/package%3A%20build_test">
- <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_test.svg" alt="Issues related to build_test" />
- </a>
- <a href="https://pub.dev/packages/build_test">
- <img src="https://img.shields.io/pub/v/build_test.svg" alt="Pub Package Version" />
- </a>
- <a href="https://pub.dev/documentation/build_test/latest">
- <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
- </a>
- <a href="https://gitter.im/dart-lang/build">
- <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
- </a>
-</p>
-
-## Installation
-
-This package is intended to only be as a [development dependency][] for users
-of [`package:build`][], and should not be used in any production code. Simply
-add to your `pubspec.yaml`:
-
-```yaml
-dev_dependencies:
- build_test:
-```
-
-## Running tests
-
-To run tests, you should go through the `pub run build_runner test` command.
-This will compile all your tests to a temp directory and run them using
-`pub run test`. If you would like to see the output directory, you can use the
-`--output=<dir>` option to force the output to go to a specific place.
-
-### Forwarding additional args to `pub run test`
-
-It is very common to need to pass some arguments through to the eventual call
-to `pub run test`. To do this, add all those args after an empty `--` arg.
-
-For example, to run all chrome platform tests you would do
-`pub run build_runner test -- -p chrome`.
-
-## Debugging web tests
-
-This package will automatically create `*.debug.html` files next to all your
-`*_test.dart` files, which can be loaded in a browser from the normal
-development server (`pub run build_runner serve`).
-
-**Note:** In order to run the tests this way, you will need to configure them
-to be compiled (by default we only compile `*.browser_test.dart` files). You
-can do this in your build.yaml file, with something like the following:
-
-```yaml
-targets:
- $default:
- builders:
- build_web_compilers|entrypoint:
- generate_for:
- - test/**_test.dart
- - web/**.dart
-```
-
-You may also view an index of links to every `*.debug.html` file by navigating
-to `http://localhost:8081` (or wherever your `test` folder is being served).
-
-## Writing tests for your custom Builder
-
-In addition to assiting in running normal tests, this package provides some
-utilities for testing your custom `Builder` classes.
-
-_See the `test` folder in the `build` package for more examples_.
-
-### Run a `Builder` within a test environment
-
-Using [`testBuilder`][api:testBuilder], you can run a functional test of a
-`Builder`, including feeding specific assets, and more. It automatically
-creates an in-memory representation of various utility classes.
-
-### Exposing actual package sources to `testBuilder`
-
-You can expose real package sources to the builder in addition to your in
-memory sources, by passing a `PackageAssetReader` to the `reader` parameter:
-
-```dart
-testBuilder(yourBuilder, {}/* test assets here */,
- reader: await PackageAssetReader.currentIsolate());
-```
-
-You can pass any custom AssetReader here, which will be used as a fallback
-for any source not defined in the source assets map.
-
-### Resolve source code for testing
-
-Using [`resolveAsset`][api:resolveAsset] and
-[`resolveSource`][api:resolveSource], you can resolve Dart source code into a
-static element model, suitable for probing and using within tests of code you
-might have written for a `Builder`:
-
-```dart
-test('should resolve a simple dart file', () async {
- var resolver = await resolveSource(r'''
- library example;
-
- class Foo {}
- ''');
- var libExample = resolver.getLibraryByName('example');
- expect(libExample.getType('Foo'), isNotNull);
-});
-```
-
-### Various test implementations of classes
-
-* [`FakeWatcher`][api:FakeWatcher]
-* [`InMemoryAssetReader`][api:InMemoryAssetReader]
-* [`InMemoryAssetWriter`][api:InMemoryAssetWriter]
-* [`MultiAssetReader`][api:MultiAssetReader]
-* [`PackageAssetReader`][api:PackageAssetReader]
-* [`RecordingAssetWriter`][api:RecordingAssetWriter]
-* [`StubAssetReader`][api:StubAssetReader]
-* [`StubAssetWriter`][api:StubAssetWriter]
-
-[development dependency]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[`package:build`]: https://pub.dev/packages/build
-
-[api:FakeWatcher]: https://pub.dev/documentation/build_test/latest/build_test/FakeWatcher-class.html
-[api:InMemoryAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/InMemoryAssetReader-class.html
-[api:InMemoryAssetWriter]: https://pub.dev/documentation/build_test/latest/build_test/InMemoryAssetWriter-class.html
-[api:MultiAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/MultiAssetReader-class.html
-[api:PackageAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/PackageAssetReader-class.html
-[api:RecordingAssetWriter]: https://pub.dev/documentation/build_test/latest/build_test/RecordingAssetWriter-class.html
-[api:StubAssetReader]: https://pub.dev/documentation/build_test/latest/build_test/StubAssetReader-class.html
-[api:StubAssetWriter]: https://pub.dev/documentation/build_test/latest/build_test/StubAssetWriter-class.html
-
-[api:resolveAsset]: https://pub.dev/documentation/build_test/latest/build_test/resolveAsset.html
-[api:resolveSource]: https://pub.dev/documentation/build_test/latest/build_test/resolveSource.html
-[api:testBuilder]: https://pub.dev/documentation/build_test/latest/build_test/testBuilder.html
diff --git a/build_test/build.yaml b/build_test/build.yaml
deleted file mode 100644
index 2283e15..0000000
--- a/build_test/build.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-builders:
- test_bootstrap:
- target: "build_test"
- import: "package:build_test/builder.dart"
- builder_factories:
- - "debugIndexBuilder"
- - "debugTestBuilder"
- - "testBootstrapBuilder"
- build_extensions:
- $test$:
- - index.html
- _test.dart:
- - _test.dart.vm_test.dart
- - _test.dart.browser_test.dart
- - _test.dart.node_test.dart
- - _test.html
- - _test.debug.html
- is_optional: False
- build_to: cache
- auto_apply: root_package
- defaults:
- generate_for: ["test/**"]
diff --git a/build_test/lib/build_test.dart b/build_test/lib/build_test.dart
deleted file mode 100644
index e215514..0000000
--- a/build_test/lib/build_test.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, 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.
-
-export 'package:build/src/builder/logging.dart' show scopeLogAsync;
-
-export 'src/assets.dart';
-export 'src/builder.dart';
-export 'src/fake_watcher.dart';
-export 'src/globbing_builder.dart';
-export 'src/in_memory_reader.dart';
-export 'src/in_memory_writer.dart';
-export 'src/matchers.dart';
-export 'src/multi_asset_reader.dart' show MultiAssetReader;
-export 'src/package_reader.dart' show PackageAssetReader;
-export 'src/record_logs.dart';
-export 'src/resolve_source.dart'
- show useAssetReader, resolveSource, resolveSources, resolveAsset;
-export 'src/stub_reader.dart';
-export 'src/stub_writer.dart';
-export 'src/test_builder.dart';
-export 'src/written_asset_reader.dart';
diff --git a/build_test/lib/builder.dart b/build_test/lib/builder.dart
deleted file mode 100644
index 44d7697..0000000
--- a/build_test/lib/builder.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2017, 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 'src/debug_test_builder.dart';
-import 'src/test_bootstrap_builder.dart';
-
-export 'src/debug_test_builder.dart' show DebugTestBuilder;
-export 'src/test_bootstrap_builder.dart' show TestBootstrapBuilder;
-
-DebugTestBuilder debugTestBuilder(_) => const DebugTestBuilder();
-DebugIndexBuilder debugIndexBuilder(_) => const DebugIndexBuilder();
-TestBootstrapBuilder testBootstrapBuilder(_) => TestBootstrapBuilder();
diff --git a/build_test/lib/src/assets.dart b/build_test/lib/src/assets.dart
deleted file mode 100644
index 53597a8..0000000
--- a/build_test/lib/src/assets.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:build/build.dart';
-
-import 'in_memory_writer.dart';
-
-int _nextId = 0;
-AssetId makeAssetId([String assetIdString]) {
- if (assetIdString == null) {
- assetIdString = 'a|web/asset_$_nextId.txt';
- _nextId++;
- }
- return AssetId.parse(assetIdString);
-}
-
-void addAssets(Map<AssetId, dynamic> assets, InMemoryAssetWriter writer) {
- assets.forEach((id, value) {
- if (value is String) {
- writer.assets[id] = utf8.encode(value);
- } else if (value is List<int>) {
- writer.assets[id] = value;
- } else {
- throw ArgumentError(
- '`assets` values must be of type `String` or `List<int>`, got '
- '${value.runtimeType}.');
- }
- });
-}
diff --git a/build_test/lib/src/builder.dart b/build_test/lib/src/builder.dart
deleted file mode 100644
index f36f6e3..0000000
--- a/build_test/lib/src/builder.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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 'package:build/build.dart';
-
-/// Overridable behavior for a [Builder.build] method.
-typedef BuildBehavior = FutureOr Function(
- BuildStep buildStep, Map<String, List<String>> buildExtensions);
-
-/// Copy the input asset to all possible output assets.
-void _defaultBehavior(
- BuildStep buildStep, Map<String, List<String>> buildExtensions) =>
- _copyToAll(buildStep, buildExtensions);
-
-T _identity<T>(T value) => value;
-Future<String> _readAsset(BuildStep buildStep, AssetId assetId) =>
- buildStep.readAsString(assetId);
-
-/// Pass the input assetId through [readFrom] and duplicate the results of
-/// [read] on that asset into every matching output based on [buildExtensions].
-void _copyToAll(BuildStep buildStep, Map<String, List<String>> buildExtensions,
- {AssetId Function(AssetId assetId) readFrom = _identity,
- Future<String> Function(BuildStep buildStep, AssetId assetId) read =
- _readAsset}) {
- if (!buildExtensions.keys.any((e) => buildStep.inputId.path.endsWith(e))) {
- throw ArgumentError('Only expected inputs with extension in '
- '${buildExtensions.keys.toList()} but got ${buildStep.inputId}');
- }
- for (final inputExtension in buildExtensions.keys) {
- if (!buildStep.inputId.path.endsWith(inputExtension)) continue;
- for (final outputExtension in buildExtensions[inputExtension]) {
- final newPath = _replaceSuffix(
- buildStep.inputId.path, inputExtension, outputExtension);
- final id = AssetId(buildStep.inputId.package, newPath);
- buildStep.writeAsString(id, read(buildStep, readFrom(buildStep.inputId)));
- }
- }
-}
-
-/// A build behavior which reads [assetId] and copies it's content into every
-/// output.
-BuildBehavior copyFrom(AssetId assetId) => (buildStep, buildExtensions) =>
- _copyToAll(buildStep, buildExtensions, readFrom: (_) => assetId);
-
-/// A build behavior which writes either 'true' or 'false' depending on whether
-/// [assetId] can be read.
-BuildBehavior writeCanRead(AssetId assetId) =>
- (BuildStep buildStep, Map<String, List<String>> buildExtensions) =>
- _copyToAll(buildStep, buildExtensions,
- readFrom: (_) => assetId,
- read: (buildStep, assetId) async =>
- '${await buildStep.canRead(assetId)}');
-
-/// A [Builder.buildExtensions] which operats on assets ending in [from] and
-/// creates outputs with [postFix] appended as the extension.
-///
-/// If [numCopies] is greater than 1 the postFix will also get a `.0`, `.1`...
-Map<String, List<String>> appendExtension(String postFix,
- {String from = '', int numCopies = 1}) =>
- {
- from: numCopies == 1
- ? ['$from$postFix']
- : List.generate(numCopies, (i) => '$from$postFix.$i')
- };
-
-Map<String, List<String>> replaceExtension(String from, String to) => {
- from: [to]
- };
-
-/// A [Builder] whose [build] method can be replaced with a closure.
-class TestBuilder implements Builder {
- @override
- final Map<String, List<String>> buildExtensions;
-
- final BuildBehavior _build;
- final BuildBehavior _extraWork;
-
- /// A stream of all the [BuildStep.inputId]s that are seen.
- ///
- /// Events are added at the start of the [build] method.
- final _buildInputsController = StreamController<AssetId>.broadcast();
- Stream<AssetId> get buildInputs => _buildInputsController.stream;
-
- /// A stream of all the [BuildStep.inputId]s that are completed.
- ///
- /// Events are added at the end of the [build] method.
- final _buildsCompletedController = StreamController<AssetId>.broadcast();
- Stream<AssetId> get buildsCompleted => _buildsCompletedController.stream;
-
- TestBuilder({
- Map<String, List<String>> buildExtensions,
- BuildBehavior build,
- BuildBehavior extraWork,
- }) : buildExtensions = buildExtensions ?? appendExtension('.copy'),
- _build = build ?? _defaultBehavior,
- _extraWork = extraWork;
-
- @override
- Future build(BuildStep buildStep) async {
- if (!await buildStep.canRead(buildStep.inputId)) return;
- _buildInputsController.add(buildStep.inputId);
- await _build(buildStep, buildExtensions);
- if (_extraWork != null) await _extraWork(buildStep, buildExtensions);
- _buildsCompletedController.add(buildStep.inputId);
- }
-}
-
-String _replaceSuffix(String path, String old, String replacement) =>
- path.substring(0, path.length - old.length) + replacement;
diff --git a/build_test/lib/src/debug_test_builder.dart b/build_test/lib/src/debug_test_builder.dart
deleted file mode 100644
index 1d97bd9..0000000
--- a/build_test/lib/src/debug_test_builder.dart
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:html/dom.dart';
-import 'package:html/parser.dart';
-import 'package:path/path.dart' as p;
-
-const _inputExtension = '_test.dart';
-const _outputExtension = '_test.debug.html';
-
-/// Returns the (optional) user-provided HTML file to use as an input.
-///
-/// For example, for `test/foo_test.dart`, we look for `test/foo_test.html`.
-AssetId _customHtmlId(AssetId test) => test.changeExtension('.html');
-
-/// Returns the builder-generated HTML file for browsers to navigate to.
-AssetId _debugHtmlId(AssetId test) => test.changeExtension('.debug.html');
-
-/// Returns the JS script path for the browser for [dartTest].
-String _jsScriptPath(AssetId dartTest) => '${p.url.basename(dartTest.path)}.js';
-
-/// Generates a `*.debug.html` for every file in `test/**/*_test.dart`.
-///
-/// This is normally used in order to use Chrome (or another browser's)
-/// debugging tools (such as setting breakpoints) while running a test suite.
-class DebugTestBuilder implements Builder {
- /// Generates a `.debug.html` for the provided `._test.dart` file.
- static Future<void> _generateDebugHtml(
- BuildStep buildStep,
- AssetId dartTest,
- ) async {
- final customHtmlId = _customHtmlId(dartTest);
- final jsScriptPath = _jsScriptPath(buildStep.inputId);
- String debugHtml;
- if (await buildStep.canRead(customHtmlId)) {
- debugHtml = _replaceCustomHtml(
- await buildStep.readAsString(customHtmlId),
- jsScriptPath,
- );
- } else {
- debugHtml = _createDebugHtml(jsScriptPath);
- }
- return buildStep.writeAsString(_debugHtmlId(dartTest), debugHtml);
- }
-
- /// Returns the content of [customHtml] modified to work with this package.
- static String _replaceCustomHtml(String customHtml, String jsScriptPath) {
- final document = parse(customHtml);
-
- // Replace <link rel="x-dart-test"> with <script src="{jsScriptPath}">.
- final linkTag = document.querySelector('link[rel="x-dart-test"]');
- final scriptTag = Element.tag('script');
- scriptTag.attributes['src'] = jsScriptPath;
- linkTag.replaceWith(scriptTag);
-
- // Remove the <script src="packages/test/dart.js"></script> if present.
- document.querySelector('script[src="packages/test/dart.js"]')?.remove();
-
- return document.outerHtml;
- }
-
- static String _createDebugHtml(String jsScriptPath) => ''
- '<html>\n'
- ' <head>\n'
- ' <script src="$jsScriptPath"></script>\n'
- ' </head>\n'
- '</html>\n';
-
- const DebugTestBuilder();
-
- @override
- final buildExtensions = const {
- _inputExtension: [_outputExtension],
- };
-
- @override
- Future<void> build(BuildStep buildStep) {
- return _generateDebugHtml(buildStep, buildStep.inputId);
- }
-}
-
-/// Generates `text/index.html`, useful for navigating and running tests.
-class DebugIndexBuilder implements Builder {
- static final _allTests = Glob(p.url.join('test', '**$_inputExtension'));
-
- static AssetId _outputFor(BuildStep buildStep) {
- return AssetId(buildStep.inputId.package, p.url.join('test', 'index.html'));
- }
-
- static String _generateHtml(Iterable<AssetId> tests) {
- if (tests.isEmpty) {
- return '<strong>No tests found!</strong>';
- }
- final buffer = StringBuffer(' <ul>');
- for (final test in tests) {
- final path =
- p.url.joinAll(p.url.split(_debugHtmlId(test).path)..removeAt(0));
- buffer.writeln(' <li><a href="/$path">${test.path}</a></li>');
- }
- buffer.writeln(' </ul>');
- return buffer.toString();
- }
-
- const DebugIndexBuilder();
-
- @override
- final buildExtensions = const {
- r'$test$': ['index.html'],
- };
-
- @override
- Future<void> build(BuildStep buildStep) async {
- final files = await buildStep.findAssets(_allTests).toList();
- final output = _outputFor(buildStep);
- return buildStep.writeAsString(
- output,
- '<html>\n'
- ' <body>\n'
- ' ${_generateHtml(files)}\n'
- ' </body>\n'
- '</html>');
- }
-}
diff --git a/build_test/lib/src/fake_watcher.dart b/build_test/lib/src/fake_watcher.dart
deleted file mode 100644
index b41ebaa..0000000
--- a/build_test/lib/src/fake_watcher.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2016, 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 'package:watcher/watcher.dart';
-
-/// A fake [DirectoryWatcher].
-///
-/// Use the static [notifyWatchers] method to add simulated events.
-class FakeWatcher implements DirectoryWatcher {
- @override
- String get directory => path;
-
- @override
- final String path;
-
- FakeWatcher(this.path) {
- watchers.add(this);
- }
-
- final _eventsController = StreamController<WatchEvent>();
-
- @override
- Stream<WatchEvent> get events => _eventsController.stream;
-
- @override
- Future get ready => Future(() {});
-
- @override
- bool get isReady => true;
-
- /// All watchers.
- static final List<FakeWatcher> watchers = <FakeWatcher>[];
-
- /// Notify all active watchers of [event] if their [FakeWatcher#path] matches.
- /// The path will also be adjusted to remove the path.
- static void notifyWatchers(WatchEvent event) {
- for (var watcher in watchers) {
- if (event.path.startsWith(watcher.path)) {
- watcher._eventsController.add(WatchEvent(event.type, event.path));
- }
- }
- }
-}
diff --git a/build_test/lib/src/globbing_builder.dart b/build_test/lib/src/globbing_builder.dart
deleted file mode 100644
index 918ec1f..0000000
--- a/build_test/lib/src/globbing_builder.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, 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 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-/// A simple builder which globs files in a package and outputs a file that
-/// lists each matching file in alphabetical order into another file, one
-/// per line.
-class GlobbingBuilder extends Builder {
- @override
- final buildExtensions = {
- '.globPlaceholder': ['.matchingFiles'],
- };
-
- final Glob glob;
-
- GlobbingBuilder(this.glob);
-
- @override
- Future build(BuildStep buildStep) async {
- var allAssets = await buildStep.findAssets(glob).toList();
- allAssets.sort((a, b) => a.path.compareTo(b.path));
- await buildStep.writeAsString(
- buildStep.inputId.changeExtension('.matchingFiles'),
- allAssets.map((id) => id.toString()).join('\n'));
- }
-}
diff --git a/build_test/lib/src/in_memory_reader.dart b/build_test/lib/src/in_memory_reader.dart
deleted file mode 100644
index 9444da1..0000000
--- a/build_test/lib/src/in_memory_reader.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-/// An [AssetReader] that records which assets have been read to [assetsRead].
-abstract class RecordingAssetReader implements AssetReader {
- Iterable<AssetId> get assetsRead;
-}
-
-/// An implementation of [AssetReader] with primed in-memory assets.
-class InMemoryAssetReader extends AssetReader
- implements MultiPackageAssetReader, RecordingAssetReader {
- final Map<AssetId, List<int>> assets;
- final String rootPackage;
-
- @override
- final Set<AssetId> assetsRead = <AssetId>{};
-
- /// Create a new asset reader that contains [sourceAssets].
- ///
- /// Any items in [sourceAssets] which are [String]s will be converted into
- /// a [List<int>] of bytes.
- ///
- /// May optionally define a [rootPackage], which is required for some APIs.
- InMemoryAssetReader({Map<AssetId, dynamic> sourceAssets, this.rootPackage})
- : assets = _assetsAsBytes(sourceAssets) ?? <AssetId, List<int>>{};
-
- /// Create a new asset reader backed by [assets].
- InMemoryAssetReader.shareAssetCache(this.assets, {this.rootPackage});
-
- static Map<AssetId, List<int>> _assetsAsBytes(Map<AssetId, dynamic> assets) {
- if (assets == null || assets.isEmpty) {
- return {};
- }
- final output = <AssetId, List<int>>{};
- assets.forEach((id, stringOrBytes) {
- if (stringOrBytes is List<int>) {
- output[id] = stringOrBytes;
- } else if (stringOrBytes is String) {
- output[id] = utf8.encode(stringOrBytes);
- } else {
- throw UnsupportedError('Invalid asset contents: $stringOrBytes.');
- }
- });
- return output;
- }
-
- @override
- Future<bool> canRead(AssetId id) async {
- assetsRead.add(id);
- return assets.containsKey(id);
- }
-
- @override
- Future<List<int>> readAsBytes(AssetId id) async {
- if (!await canRead(id)) throw AssetNotFoundException(id);
- assetsRead.add(id);
- return assets[id];
- }
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async {
- if (!await canRead(id)) throw AssetNotFoundException(id);
- assetsRead.add(id);
- return utf8.decode(assets[id]);
- }
-
- @override
- Stream<AssetId> findAssets(Glob glob, {String package}) {
- package ??= rootPackage;
- if (package == null) {
- throw UnsupportedError(
- 'Root package is required to use findAssets without providing an '
- 'explicit package.');
- }
- return Stream.fromIterable(assets.keys
- .where((id) => id.package == package && glob.matches(id.path)));
- }
-
- void cacheBytesAsset(AssetId id, List<int> bytes) {
- assets[id] = bytes;
- }
-
- void cacheStringAsset(AssetId id, String contents, {Encoding encoding}) {
- encoding ??= utf8;
- assets[id] = encoding.encode(contents);
- }
-}
diff --git a/build_test/lib/src/in_memory_writer.dart b/build_test/lib/src/in_memory_writer.dart
deleted file mode 100644
index 8bb35cc..0000000
--- a/build_test/lib/src/in_memory_writer.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:build/build.dart';
-
-/// An implementation of [AssetWriter] that records outputs to [assets].
-abstract class RecordingAssetWriter implements AssetWriter {
- Map<AssetId, List<int>> get assets;
-}
-
-/// An implementation of [AssetWriter] that writes outputs to memory.
-class InMemoryAssetWriter implements RecordingAssetWriter {
- @override
- final Map<AssetId, List<int>> assets = {};
-
- InMemoryAssetWriter();
-
- @override
- Future writeAsBytes(AssetId id, List<int> bytes) async {
- assets[id] = bytes;
- }
-
- @override
- Future writeAsString(AssetId id, String contents,
- {Encoding encoding = utf8}) async {
- assets[id] = encoding.encode(contents);
- }
-}
diff --git a/build_test/lib/src/matchers.dart b/build_test/lib/src/matchers.dart
deleted file mode 100644
index 92f3c16..0000000
--- a/build_test/lib/src/matchers.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:test/test.dart';
-
-import 'package:build/build.dart';
-
-/// Matches instance of [AssetNotFoundException].
-final assetNotFoundException = const TypeMatcher<AssetNotFoundException>();
-
-/// Matches instance of [InvalidInputException].
-final invalidInputException = const TypeMatcher<InvalidInputException>();
-
-/// Matches instance of [InvalidOutputException].
-final invalidOutputException = const TypeMatcher<InvalidOutputException>();
-
-/// Matches instance of [PackageNotFoundException].
-final packageNotFoundException = const TypeMatcher<PackageNotFoundException>();
-
-/// Decodes the value using [encoding] and matches it against [expected].
-TypeMatcher<List<int>> decodedMatches(dynamic expected, {Encoding encoding}) {
- encoding ??= utf8;
- return TypeMatcher<List<int>>().having(
- (e) => encoding.decode(e), '${encoding.name} decoded bytes', expected);
-}
diff --git a/build_test/lib/src/multi_asset_reader.dart b/build_test/lib/src/multi_asset_reader.dart
deleted file mode 100644
index a487263..0000000
--- a/build_test/lib/src/multi_asset_reader.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-
-import 'package:async/async.dart';
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-/// A [MultiPackageAssetReader] that delegates to multiple other asset
-/// readers.
-///
-/// [MultiAssetReader] attempts to check every provided
-/// [MultiPackageAssetReader] to see if they are capable of reading an
-/// [AssetId], otherwise checks the next reader.
-class MultiAssetReader extends AssetReader implements MultiPackageAssetReader {
- final List<MultiPackageAssetReader> _readers;
-
- MultiAssetReader(this._readers);
-
- @override
- Future<bool> canRead(AssetId id) async {
- for (var reader in _readers) {
- if (await reader.canRead(id)) {
- return true;
- }
- }
- return false;
- }
-
- @override
- Future<List<int>> readAsBytes(AssetId id) async =>
- (await _readerWith(id)).readAsBytes(id);
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) async =>
- (await _readerWith(id)).readAsString(id, encoding: encoding);
-
- /// Returns all readable assets matching [glob] under [package].
- ///
- /// **NOTE**: This is a combined view of all provided readers. As such it is
- /// possible that an [AssetId] will be iterated over more than once, unlike
- /// other implementations of [AssetReader].
- @override
- Stream<AssetId> findAssets(Glob glob, {String package}) => StreamGroup.merge(
- _readers.map((reader) => reader.findAssets(glob, package: package)));
-
- /// Returns the first [AssetReader] that contains [id].
- ///
- /// Otherwise throws [AssetNotFoundException].
- Future<AssetReader> _readerWith(AssetId id) async {
- for (var reader in _readers) {
- if (await reader.canRead(id)) {
- return reader;
- }
- }
- throw AssetNotFoundException(id);
- }
-}
diff --git a/build_test/lib/src/package_reader.dart b/build_test/lib/src/package_reader.dart
deleted file mode 100644
index b8a7809..0000000
--- a/build_test/lib/src/package_reader.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:io';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-import 'package:package_resolver/package_resolver.dart';
-import 'package:path/path.dart' as p;
-import 'package:stream_transform/stream_transform.dart';
-
-/// Resolves using a [SyncPackageResolver] before reading from the file system.
-///
-/// For a simple implementation that uses the current isolate's package
-/// resolution logic (i.e. whatever you have generated in `.packages` in most
-/// cases), use [currentIsolate]:
-/// ```dart
-/// var assetReader = await PackageAssetReader.currentIsolate();
-/// ```
-class PackageAssetReader extends AssetReader
- implements MultiPackageAssetReader {
- final SyncPackageResolver _packageResolver;
-
- /// What package is the originating build occurring in.
- final String _rootPackage;
-
- /// Wrap a [SyncPackageResolver] to identify where files are located.
- ///
- /// To use a normal [PackageResolver] use `asSync`:
- /// ```
- /// new PackageAssetReader(await packageResolver.asSync);
- /// ```
- PackageAssetReader(this._packageResolver, [this._rootPackage]);
-
- /// A [PackageAssetReader] with a single [packageRoot] configured.
- ///
- /// It is assumed that every _directory_ in [packageRoot] is a package where
- /// the name of the package is the name of the directory. This is similar to
- /// the older "packages" folder paradigm for resolution.
- factory PackageAssetReader.forPackageRoot(String packageRoot,
- [String rootPackage]) {
- // This purposefully doesn't use SyncPackageResolver.root, because that is
- // assuming a symlink collection and not directories, and this factory is
- // more useful for a user-created collection of folders for testing.
- final directory = Directory(packageRoot);
- final packages = <String, String>{};
- for (final entity in directory.listSync()) {
- if (entity is Directory) {
- final name = p.basename(entity.path);
- packages[name] = entity.uri.toFilePath(windows: false);
- }
- }
- return PackageAssetReader.forPackages(packages, rootPackage);
- }
-
- /// Returns a [PackageAssetReader] with a simple [packageToPath] mapping.
- factory PackageAssetReader.forPackages(Map<String, String> packageToPath,
- [String rootPackage]) =>
- PackageAssetReader(
- SyncPackageResolver.config(packageToPath
- .map((k, v) => MapEntry(k, Uri.parse(p.url.absolute(v, 'lib'))))),
- rootPackage);
-
- /// A reader that can resolve files known to the current isolate.
- ///
- /// A [rootPackage] should be provided for full API compatibility.
- static Future<PackageAssetReader> currentIsolate({String rootPackage}) async {
- var resolver = PackageResolver.current;
- return PackageAssetReader(await resolver.asSync, rootPackage);
- }
-
- File _resolve(AssetId id) {
- final uri = id.uri;
- if (uri.isScheme('package')) {
- final uri = _packageResolver.resolveUri(id.uri);
- if (uri != null) {
- return File.fromUri(uri);
- }
- }
- if (id.package == _rootPackage) {
- return File(p.canonicalize(p.join(_rootPackagePath, id.path)));
- }
- return null;
- }
-
- String get _rootPackagePath {
- // If the root package has a pub layout, use `packagePath`.
- final root = _packageResolver.packagePath(_rootPackage);
- if (root != null && Directory(p.join(root, 'lib')).existsSync()) {
- return root;
- }
- // Assume the cwd is the package root.
- return p.current;
- }
-
- @override
- Stream<AssetId> findAssets(Glob glob, {String package}) {
- package ??= _rootPackage;
- if (package == null) {
- throw UnsupportedError(
- 'Root package must be provided to use `findAssets` without an '
- 'explicit `package`.');
- }
- var packageLibDir = _packageResolver.packageConfigMap[package];
- if (packageLibDir == null) {
- throw UnsupportedError('Unable to find package $package');
- }
-
- var packageFiles = Directory.fromUri(packageLibDir)
- .list(recursive: true)
- .whereType<File>()
- .map((f) =>
- p.join('lib', p.relative(f.path, from: p.fromUri(packageLibDir))));
- if (package == _rootPackage) {
- packageFiles = packageFiles.merge(Directory(_rootPackagePath)
- .list(recursive: true)
- .whereType<File>()
- .map((f) => p.relative(f.path, from: _rootPackagePath))
- .where((p) => !(p.startsWith('packages/') || p.startsWith('lib/'))));
- }
- return packageFiles.where(glob.matches).map((p) => AssetId(package, p));
- }
-
- @override
- Future<bool> canRead(AssetId id) =>
- _resolve(id)?.exists() ?? Future.value(false);
-
- @override
- Future<List<int>> readAsBytes(AssetId id) =>
- _resolve(id)?.readAsBytes() ?? (throw AssetNotFoundException(id));
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) =>
- _resolve(id)?.readAsString(encoding: encoding) ??
- (throw AssetNotFoundException(id));
-}
diff --git a/build_test/lib/src/record_logs.dart b/build_test/lib/src/record_logs.dart
deleted file mode 100644
index b45de5b..0000000
--- a/build_test/lib/src/record_logs.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/src/builder/logging.dart';
-import 'package:matcher/matcher.dart';
-import 'package:logging/logging.dart';
-
-/// Executes [run] with a new [Logger], returning the resulting log records.
-///
-/// The returned [Stream] is _closed_ after the [run] function is executed. If
-/// [run] returns a [Future], that future is awaited _before_ the stream is
-/// closed.
-///
-/// ```dart
-/// test('should log "uh oh!"', () async {
-/// final logs = recordLogs(() => runBuilder());
-/// expect(logs, emitsInOrder([
-/// anyLogOf('uh oh!'),
-/// ]);
-/// });
-/// ```
-Stream<LogRecord> recordLogs(dynamic Function() run, {String name = ''}) {
- final logger = Logger(name);
- Timer.run(() async {
- await scopeLogAsync(() => Future.value(run()), logger);
- logger.clearListeners();
- });
- return logger.onRecord;
-}
-
-/// Matches [LogRecord] of any level whose message is [messageOrMatcher].
-///
-/// ```dart
-/// anyLogOf('Hello World)'; // Exactly match 'Hello World'.
-/// anyLogOf(contains('ERROR')); // Contains the sub-string 'ERROR'.
-/// ```
-Matcher anyLogOf(dynamic messageOrMatcher) =>
- _LogRecordMatcher(anything, messageOrMatcher);
-
-/// Matches [LogRecord] of [Level.INFO] where message is [messageOrMatcher].
-Matcher infoLogOf(dynamic messageOrMatcher) =>
- _LogRecordMatcher(Level.INFO, messageOrMatcher);
-
-/// Matches [LogRecord] of [Level.WARNING] where message is [messageOrMatcher].
-Matcher warningLogOf(dynamic messageOrMatcher) =>
- _LogRecordMatcher(Level.WARNING, messageOrMatcher);
-
-/// Matches [LogRecord] of [Level.SEVERE] where message is [messageOrMatcher].
-Matcher severeLogOf(dynamic messageOrMatcher) =>
- _LogRecordMatcher(Level.SEVERE, messageOrMatcher);
-
-class _LogRecordMatcher extends Matcher {
- final Matcher _level;
- final Matcher _message;
-
- factory _LogRecordMatcher(dynamic levelOr, dynamic messageOr) =>
- _LogRecordMatcher._(levelOr is Matcher ? levelOr : equals(levelOr),
- messageOr is Matcher ? messageOr : equals(messageOr));
-
- _LogRecordMatcher._(this._level, this._message);
-
- @override
- Description describe(Description description) {
- description.add('level: ');
- _level.describe(description);
- description.add(', message: ');
- _message.describe(description);
- return description;
- }
-
- @override
- Description describeMismatch(
- covariant LogRecord item, Description description, _, __) {
- if (!_level.matches(item.level, {})) {
- _level.describeMismatch(item.level, description, {}, false);
- }
- if (!_message.matches(item.message, {})) {
- _message.describeMismatch(item.message, description, {}, false);
- }
- return description;
- }
-
- @override
- bool matches(item, _) =>
- item is LogRecord &&
- _level.matches(item.level, {}) &&
- _message.matches(item.message, {});
-}
diff --git a/build_test/lib/src/resolve_source.dart b/build_test/lib/src/resolve_source.dart
deleted file mode 100644
index 6782805..0000000
--- a/build_test/lib/src/resolve_source.dart
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart';
-import 'package:build_resolvers/build_resolvers.dart';
-import 'package:package_resolver/package_resolver.dart';
-import 'package:pedantic/pedantic.dart';
-
-import 'in_memory_reader.dart';
-import 'in_memory_writer.dart';
-import 'multi_asset_reader.dart';
-import 'package_reader.dart';
-
-final defaultResolvers = AnalyzerResolvers();
-
-/// Marker constant that may be used in combination with [resolveSources].
-///
-/// Use of this string means instead of using the contents of the string as the
-/// source of a given asset, instead read the file from the default or provided
-/// [AssetReader].
-const useAssetReader = '__useAssetReader__';
-
-/// A convenience method for using [resolveSources] with a single source file.
-Future<T> resolveSource<T>(
- String inputSource,
- FutureOr<T> Function(Resolver resolver) action, {
- AssetId inputId,
- PackageResolver resolver,
- Future<Null> tearDown,
- Resolvers resolvers,
-}) {
- inputId ??= AssetId('_resolve_source', 'lib/_resolve_source.dart');
- return _resolveAssets(
- {
- '${inputId.package}|${inputId.path}': inputSource,
- },
- inputId.package,
- action,
- resolver: resolver,
- resolverFor: inputId,
- tearDown: tearDown,
- resolvers: resolvers,
- );
-}
-
-/// Resolves and runs [action] using a created resolver for [inputs].
-///
-/// Inputs accepts the pattern of `<package>|<path>.dart`, for example:
-/// ```
-/// {
-/// 'test_lib|lib/test_lib.dart': r'''
-/// // Contents of test_lib.dart go here.
-/// ''',
-/// }
-/// ```
-///
-/// You may provide [useAssetReader] as the value of any input in order to read
-/// it from the file system instead of being forced to provide it inline as a
-/// string. This is useful for mixing real and mocked assets.
-///
-/// Example use:
-/// ```
-/// import 'package:build_test/build_test.dart';
-/// import 'package:test/test.dart';
-///
-/// void main() {
-/// test('should find a Foo type', () async {
-/// var library = await resolveSources({
-/// 'test_lib|lib/test_lib.dart': r'''
-/// library example;
-///
-/// class Foo {}
-/// ''',
-/// }, (resolver) => resolver.findLibraryByName('example'));
-/// expect(library.getType('Foo'), isNotNull);
-/// });
-/// }
-/// ```
-///
-/// By default the [Resolver] is unusable after [action] completes. To keep the
-/// resolver active across multiple tests (for example, use `setUpAll` and
-/// `tearDownAll`, provide a `tearDown` [Future]:
-/// ```
-/// import 'dart:async';
-/// import 'package:build/build.dart';
-/// import 'package:build_test/build_test.dart';
-/// import 'package:test/test.dart';
-///
-/// void main() {
-/// Resolver resolver;
-/// var resolverDone = new Completer<Null>();
-///
-/// setUpAll(() async {
-/// resolver = await resolveSources(
-/// {...},
-/// (resolver) => resolver,
-/// tearDown: resolverDone.future,
-/// );
-/// });
-///
-/// tearDownAll(() => resolverDone.complete());
-///
-/// test('...', () async {
-/// // Use the resolver here, and in other tests.
-/// });
-/// }
-/// ```
-///
-/// May provide [resolverFor] to return the [Resolver] for the asset provided,
-/// otherwise defaults to the first one in [inputs].
-///
-/// **NOTE**: All `package` dependencies are resolved using [PackageAssetReader]
-/// - by default, [PackageAssetReader.currentIsolate]. A custom [resolver] may
-/// be provided to map files not visible to the current package's runtime.
-Future<T> resolveSources<T>(
- Map<String, String> inputs,
- FutureOr<T> Function(Resolver resolver) action, {
- PackageResolver resolver,
- String resolverFor,
- String rootPackage,
- Future<Null> tearDown,
- Resolvers resolvers,
-}) {
- if (inputs == null || inputs.isEmpty) {
- throw ArgumentError.value(inputs, 'inputs', 'Must be a non-empty Map');
- }
- return _resolveAssets(
- inputs,
- rootPackage ?? AssetId.parse(inputs.keys.first).package,
- action,
- resolver: resolver,
- resolverFor: AssetId.parse(resolverFor ?? inputs.keys.first),
- tearDown: tearDown,
- resolvers: resolvers,
- );
-}
-
-/// A convenience for using [resolveSources] with a single [inputId] from disk.
-Future<T> resolveAsset<T>(
- AssetId inputId,
- FutureOr<T> Function(Resolver resolver) action, {
- PackageResolver resolver,
- Future<Null> tearDown,
- Resolvers resolvers,
-}) {
- return _resolveAssets(
- {
- '${inputId.package}|${inputId.path}': useAssetReader,
- },
- inputId.package,
- action,
- resolver: resolver,
- resolverFor: inputId,
- tearDown: tearDown,
- resolvers: resolvers,
- );
-}
-
-/// Internal-only backing implementation of `resolve{Asset|Source(s)}`.
-///
-/// If the value of an entry of [inputs] is [useAssetReader] then the value is
-/// instead read from the file system, otherwise the provided text is used as
-/// the contents of the asset.
-Future<T> _resolveAssets<T>(
- Map<String, String> inputs,
- String rootPackage,
- FutureOr<T> Function(Resolver resolver) action, {
- PackageResolver resolver,
- AssetId resolverFor,
- Future<Null> tearDown,
- Resolvers resolvers,
-}) async {
- final syncResolver = await (resolver ?? PackageResolver.current).asSync;
- final assetReader = PackageAssetReader(syncResolver, rootPackage);
- final resolveBuilder = _ResolveSourceBuilder(
- action,
- resolverFor,
- tearDown,
- );
- final inputAssets = <AssetId, String>{};
- await Future.wait(inputs.keys.map((String rawAssetId) async {
- final assetId = AssetId.parse(rawAssetId);
- var assetValue = inputs[rawAssetId];
- if (assetValue == useAssetReader) {
- assetValue = await assetReader.readAsString(assetId);
- }
- inputAssets[assetId] = assetValue;
- }));
- final inMemory = InMemoryAssetReader(
- sourceAssets: inputAssets,
- rootPackage: rootPackage,
- );
- // We don't care about the results of this build, but we also can't await
- // it because that would block on the `tearDown` of the `resolveBuilder`.
- //
- // We also dont want to leak errors as unhandled async errors so we swallow
- // them here.
- //
- // Errors will still be reported through the resolver itself as well as the
- // `onDone` future that we return.
- unawaited(runBuilder(
- resolveBuilder,
- inputAssets.keys,
- MultiAssetReader([inMemory, assetReader]),
- InMemoryAssetWriter(),
- resolvers ?? defaultResolvers,
- ).catchError((_) {}));
- return resolveBuilder.onDone.future;
-}
-
-/// A [Builder] that is only used to retrieve a [Resolver] instance.
-///
-/// It simulates what a user builder would do in order to resolve a primary
-/// input given a set of dependencies to also use. See `resolveSource`.
-class _ResolveSourceBuilder<T> implements Builder {
- final FutureOr<T> Function(Resolver) _action;
- final Future _tearDown;
- final AssetId _resolverFor;
-
- final onDone = Completer<T>();
-
- _ResolveSourceBuilder(this._action, this._resolverFor, this._tearDown);
-
- @override
- Future<void> build(BuildStep buildStep) async {
- if (_resolverFor != buildStep.inputId) return;
- try {
- onDone.complete(await _action(buildStep.resolver));
- } catch (e, s) {
- onDone.completeError(e, s);
- }
- await _tearDown;
- }
-
- @override
- final buildExtensions = const {
- '': ['.unused']
- };
-}
diff --git a/build_test/lib/src/stub_reader.dart b/build_test/lib/src/stub_reader.dart
deleted file mode 100644
index 6c10e90..0000000
--- a/build_test/lib/src/stub_reader.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-
-/// A no-op implementation of [AssetReader].
-class StubAssetReader extends AssetReader implements MultiPackageAssetReader {
- StubAssetReader();
-
- @override
- Future<bool> canRead(AssetId id) => Future.value(null);
-
- @override
- Future<List<int>> readAsBytes(AssetId id) => Future.value(null);
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding = utf8}) =>
- Future.value(null);
-
- @override
- Stream<AssetId> findAssets(Glob glob, {String package}) => null;
-
- @override
- Future<Digest> digest(AssetId id) => Future.value(Digest([1, 2, 3]));
-}
diff --git a/build_test/lib/src/stub_writer.dart b/build_test/lib/src/stub_writer.dart
deleted file mode 100644
index 8c4b5b2..0000000
--- a/build_test/lib/src/stub_writer.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016, 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:convert';
-
-import 'package:build/build.dart';
-
-/// A no-op implementation of [AssetWriter].
-class StubAssetWriter implements AssetWriter {
- const StubAssetWriter();
-
- @override
- Future writeAsBytes(_, __) => Future.value(null);
-
- @override
- Future writeAsString(_, __, {Encoding encoding = utf8}) => Future.value(null);
-}
diff --git a/build_test/lib/src/test_bootstrap_builder.dart b/build_test/lib/src/test_bootstrap_builder.dart
deleted file mode 100644
index 7c77340..0000000
--- a/build_test/lib/src/test_bootstrap_builder.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-// ignore: deprecated_member_use
-import 'package:test_core/backend.dart';
-
-/// A [Builder] that injects bootstrapping code used by the test runner to run
-/// tests in --precompiled mode.
-///
-/// This doesn't modify existing code at all, it just adds wrapper files that
-/// can be used to load isolates or iframes.
-class TestBootstrapBuilder extends Builder {
- @override
- final buildExtensions = const {
- '_test.dart': [
- '_test.dart.vm_test.dart',
- '_test.dart.browser_test.dart',
- '_test.dart.node_test.dart',
- ]
- };
- TestBootstrapBuilder();
-
- @override
- Future<void> build(BuildStep buildStep) async {
- var id = buildStep.inputId;
- var contents = await buildStep.readAsString(id);
- var assetPath = id.pathSegments.first == 'lib'
- ? p.url.join('packages', id.package, id.path)
- : id.path;
- var metadata = parseMetadata(
- assetPath, contents, Runtime.builtIn.map((r) => r.name).toSet());
-
- if (metadata.testOn.evaluate(SuitePlatform(Runtime.vm))) {
- await buildStep.writeAsString(id.addExtension('.vm_test.dart'), '''
- import "dart:isolate";
-
- import "package:test/bootstrap/vm.dart";
-
- import "${p.url.basename(id.path)}" as test;
-
- void main(_, SendPort message) {
- internalBootstrapVmTest(() => test.main, message);
- }
- ''');
- }
-
- var browserRuntimes = Runtime.builtIn.where((r) => r.isBrowser == true);
- if (browserRuntimes
- .any((r) => metadata.testOn.evaluate(SuitePlatform(r)))) {
- await buildStep.writeAsString(id.addExtension('.browser_test.dart'), '''
- import "package:test/bootstrap/browser.dart";
-
- import "${p.url.basename(id.path)}" as test;
-
- void main() {
- internalBootstrapBrowserTest(() => test.main);
- }
- ''');
- }
-
- if (metadata.testOn.evaluate(SuitePlatform(Runtime.nodeJS))) {
- await buildStep.writeAsString(id.addExtension('.node_test.dart'), '''
- import "package:test/bootstrap/node.dart";
-
- import "${p.url.basename(id.path)}" as test;
-
- void main() {
- internalBootstrapNodeTest(() => test.main);
- }
- ''');
- }
- }
-}
diff --git a/build_test/lib/src/test_builder.dart b/build_test/lib/src/test_builder.dart
deleted file mode 100644
index 31ee456..0000000
--- a/build_test/lib/src/test_builder.dart
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (c) 2014, 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:convert';
-
-import 'package:build/build.dart';
-import 'package:logging/logging.dart';
-import 'package:test/test.dart';
-
-import 'assets.dart';
-import 'in_memory_reader.dart';
-import 'in_memory_writer.dart';
-import 'multi_asset_reader.dart';
-import 'resolve_source.dart';
-import 'written_asset_reader.dart';
-
-AssetId _passThrough(AssetId id) => id;
-
-/// Validates that [actualAssets] matches the expected [outputs].
-///
-/// The keys in [outputs] should be serialized [AssetId]s in the form
-/// `'package|path'`. The values should match the expected content for the
-/// written asset and may be a String (for `writeAsString`), a `List<int>` (for
-/// `writeAsBytes`) or a [Matcher] for a String or bytes.
-///
-/// [actualAssets] are the IDs that were recorded as written during the build.
-///
-/// Assets are checked against those that were written to [writer]. If other
-/// assets were written through the writer, but not as part of the build
-/// process, they will be ignored. Only the IDs in [actualAssets] are checked.
-///
-/// If assets are written to a location that does not match their logical
-/// association to a package pass [mapAssetIds] to translate from the logical
-/// location to the actual written location.
-void checkOutputs(
- Map<String, /*List<int>|String|Matcher<String|List<int>>*/ dynamic> outputs,
- Iterable<AssetId> actualAssets,
- RecordingAssetWriter writer,
- {AssetId Function(AssetId id) mapAssetIds = _passThrough}) {
- var modifiableActualAssets = Set.from(actualAssets);
- if (outputs != null) {
- outputs.forEach((serializedId, contentsMatcher) {
- assert(contentsMatcher is String ||
- contentsMatcher is List<int> ||
- contentsMatcher is Matcher);
-
- var assetId = makeAssetId(serializedId);
-
- // Check that the asset was produced.
- expect(modifiableActualAssets, contains(assetId),
- reason: 'Builder failed to write asset $assetId');
- modifiableActualAssets.remove(assetId);
- var actual = writer.assets[mapAssetIds(assetId)];
- Object expected;
- if (contentsMatcher is String) {
- expected = utf8.decode(actual);
- } else if (contentsMatcher is List<int>) {
- expected = actual;
- } else if (contentsMatcher is Matcher) {
- expected = actual;
- } else {
- throw ArgumentError('Expected values for `outputs` to be of type '
- '`String`, `List<int>`, or `Matcher`, but got `$contentsMatcher`.');
- }
- expect(expected, contentsMatcher,
- reason: 'Unexpected content for $assetId in result.outputs.');
- });
- // Check that no extra assets were produced.
- expect(modifiableActualAssets, isEmpty,
- reason:
- 'Unexpected outputs found `$actualAssets`. Only expected $outputs');
- }
-}
-
-/// Runs [builder] in a test environment.
-///
-/// The test environment supplies in-memory build [sourceAssets] to the builders
-/// under test. [outputs] may be optionally provided to verify that the builders
-/// produce the expected output. If [outputs] is omitted the only validation
-/// this method provides is that the build did not `throw`.
-///
-/// Either [generateFor] or the [isInput] callback can specify which assets
-/// should be given as inputs to the builder. These can be omitted if every
-/// asset in [sourceAssets] should be considered an input. [generateFor] is
-/// ignored if both [isInput] and [generateFor] are provided.
-///
-/// The keys in [sourceAssets] and [outputs] are paths to file assets and the
-/// values are file contents. The paths must use the following format:
-///
-/// PACKAGE_NAME|PATH_WITHIN_PACKAGE
-///
-/// Where `PACKAGE_NAME` is the name of the package, and `PATH_WITHIN_PACKAGE`
-/// is the path to a file relative to the package. `PATH_WITHIN_PACKAGE` must
-/// include `lib`, `web`, `bin` or `test`. Example: "myapp|lib/utils.dart".
-///
-/// If a [reader] is provided, then any asset not in [sourceAssets] will be
-/// read from the provided reader. This allows you to more easily provide
-/// sources of entire packages to the test, instead of mocking them out, for
-/// example, this exposes all assets available to the test itself:
-///
-///
-/// ```dart
-/// testBuilder(yourBuilder, {}/* test assets here */,
-/// reader: await PackageAssetReader.currentIsolate());
-/// ```
-///
-/// Callers may optionally provide a [writer] to stub different behavior or do
-/// more complex validation than what is possible with [outputs].
-///
-/// Callers may optionally provide an [onLog] callback to do validaiton on the
-/// logging output of the builder.
-Future testBuilder(
- Builder builder, Map<String, /*String|List<int>*/ dynamic> sourceAssets,
- {Set<String> generateFor,
- bool Function(String assetId) isInput,
- String rootPackage,
- MultiPackageAssetReader reader,
- RecordingAssetWriter writer,
- Map<String, /*String|List<int>|Matcher<String|List<int>>*/ dynamic> outputs,
- void Function(LogRecord log) onLog,
- void Function(AssetId, Iterable<AssetId>)
- reportUnusedAssetsForInput}) async {
- writer ??= InMemoryAssetWriter();
-
- var inputIds = {
- for (var descriptor in sourceAssets.keys) makeAssetId(descriptor)
- };
- var allPackages = {for (var id in inputIds) id.package};
- if (allPackages.length == 1) rootPackage ??= allPackages.first;
-
- inputIds.addAll([
- for (var package in allPackages) AssetId(package, r'lib/$lib$'),
- if (rootPackage != null) ...[
- AssetId(rootPackage, r'$package$'),
- AssetId(rootPackage, r'test/$test$'),
- AssetId(rootPackage, r'web/$web$'),
- ]
- ]);
-
- final inMemoryReader = InMemoryAssetReader(rootPackage: rootPackage);
-
- sourceAssets.forEach((serializedId, contents) {
- var id = makeAssetId(serializedId);
- if (contents is String) {
- inMemoryReader.cacheStringAsset(id, contents);
- } else if (contents is List<int>) {
- inMemoryReader.cacheBytesAsset(id, contents);
- }
- });
-
- isInput ??= generateFor?.contains ?? (_) => true;
- inputIds.retainWhere((id) => isInput('$id'));
-
- var writerSpy = AssetWriterSpy(writer);
- var logger = Logger('testBuilder');
- var logSubscription = logger.onRecord.listen(onLog);
-
- for (var input in inputIds) {
- // create another writer spy and reader for each input. This prevents writes
- // from a previous input being readable when processing the current input.
- final spyForStep = AssetWriterSpy(writerSpy);
- final readerForStep = MultiAssetReader([
- inMemoryReader,
- if (reader != null) reader,
- WrittenAssetReader(writer, spyForStep),
- ]);
-
- await runBuilder(
- builder, {input}, readerForStep, spyForStep, defaultResolvers,
- logger: logger, reportUnusedAssetsForInput: reportUnusedAssetsForInput);
- }
-
- await logSubscription.cancel();
- var actualOutputs = writerSpy.assetsWritten;
- checkOutputs(outputs, actualOutputs, writer);
-}
diff --git a/build_test/lib/src/written_asset_reader.dart b/build_test/lib/src/written_asset_reader.dart
deleted file mode 100644
index d24dbcb..0000000
--- a/build_test/lib/src/written_asset_reader.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2019, 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:convert';
-
-import 'package:build/build.dart';
-import 'package:glob/glob.dart';
-
-import 'in_memory_writer.dart';
-
-/// A [MultiPackageAssetReader] which supports reads from previous outputs.
-class WrittenAssetReader extends MultiPackageAssetReader {
- final RecordingAssetWriter source;
-
- /// An optional [AssetWriterSpy] to limit what's readable through this reader.
- ///
- /// Only assets reported as written trough this [AssetWriterSpy] can be read
- /// from this reader. When null, all assets from [source] are available.
- final AssetWriterSpy filterSpy;
-
- WrittenAssetReader(this.source, [this.filterSpy]);
-
- @override
- Future<bool> canRead(AssetId id) {
- var canRead = source.assets.containsKey(id);
- if (filterSpy != null) {
- canRead = canRead && filterSpy.assetsWritten.contains(id);
- }
-
- return Future.value(canRead);
- }
-
- @override
- Stream<AssetId> findAssets(Glob glob, {String package}) async* {
- var available = source.assets.keys.toSet();
- if (filterSpy != null) {
- available = available.intersection(filterSpy.assetsWritten.toSet());
- }
-
- for (var asset in available) {
- if (!glob.matches(asset.path)) continue;
- if (package != null && asset.package != package) continue;
-
- yield asset;
- }
- }
-
- @override
- Future<List<int>> readAsBytes(AssetId id) {
- if (!source.assets.containsKey(id)) {
- throw AssetNotFoundException(id);
- }
- return Future.value(source.assets[id]);
- }
-
- @override
- Future<String> readAsString(AssetId id, {Encoding encoding}) async {
- encoding ??= utf8;
- return encoding.decode(await readAsBytes(id));
- }
-}
diff --git a/build_test/mono_pkg.yaml b/build_test/mono_pkg.yaml
deleted file mode 100644
index 912fda7..0000000
--- a/build_test/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.6.0
- - unit_test:
- - command: pub run build_runner test
- os:
- - linux
- - windows
-
-cache:
- directories:
- - .dart_tool/build
diff --git a/build_test/pubspec.yaml b/build_test/pubspec.yaml
deleted file mode 100644
index 5f71f2f..0000000
--- a/build_test/pubspec.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: build_test
-description: Utilities for writing unit tests of Builders.
-version: 0.10.12+1
-homepage: https://github.com/dart-lang/build/tree/master/build_test
-
-environment:
- sdk: ">=2.6.0 <3.0.0"
-
-dependencies:
- async: ">=1.2.0 <3.0.0"
- build: ">=1.2.0 <2.0.0"
- build_config: ">=0.2.0 <0.5.0"
- build_resolvers: ">=0.2.0 <2.0.0"
- crypto: ">=0.9.2 <3.0.0"
- glob: ^1.1.0
- html: ">=0.9.0 <0.15.0"
- logging: ^0.11.2
- matcher: ^0.12.0
- package_resolver: ^1.0.2
- path: ^1.4.1
- pedantic: ^1.0.0
- stream_transform: ">=0.0.20 <2.0.0"
- test: '>=0.12.42 <2.0.0'
- test_core: '>=0.2.4 <0.4.0'
- watcher: ^0.9.7
-
-dev_dependencies:
- analyzer: ">=0.35.4 <0.40.0"
- build_runner: ^1.3.3
- build_vm_compilers: '>=0.1.2 <2.0.0'
- collection: ^1.14.0
diff --git a/build_vm_compilers/BUILD.gn b/build_vm_compilers/BUILD.gn
deleted file mode 100644
index 7861884..0000000
--- a/build_vm_compilers/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# This file is generated by importer.py for build_vm_compilers-1.0.4
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_vm_compilers") {
- package_name = "build_vm_compilers"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/build_config",
- "//third_party/dart-pkg/pub/pool",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/build_modules",
- "//third_party/dart-pkg/pub/analyzer",
- ]
-}
diff --git a/build_vm_compilers/CHANGELOG.md b/build_vm_compilers/CHANGELOG.md
deleted file mode 100644
index cccd852..0000000
--- a/build_vm_compilers/CHANGELOG.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## 1.0.4
-
-- Allow analyzer version `0.39.0`.
-
-## 1.0.3
-
-- Allow analyzer version `0.38.0`.
-
-## 1.0.2
-
-- Fix kernel concat ordering to be topological instead of reverse
- topological.
-
-## 1.0.1
-
-- Allow analyzer version 0.37.0.
-
-## 1.0.0
-
-- Support build_modules 2.0.0
- - Define our own `vm` platform and builders explicitly.
-- Skip trying to compile apps that import known incompatible libraries.
-
-## 0.1.2
-
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-- Require Dart SDK `>=2.1.0`.
-
-## 0.1.1+5
-
-- Increased the upper bound for `package:analyzer` to `<0.36.0`.
-
-## 0.1.1+4
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.1.1+3
-
-- Increased the upper bound for `package:analyzer` to `<0.34.0`.
-
-## 0.1.1+2
-
-Support `package:build_modules` version `1.x.x`.
-
-## 0.1.1+1
-
-Support `package:build` version `1.x.x`.
-
-## 0.1.1
-
-Support the latest build_modules.
-
-## 0.1.0
-
-Initial release, adds the modular kernel compiler for the vm platform, and the
-entrypoint builder which concatenates all the modules into a single kernel file.
diff --git a/build_vm_compilers/LICENSE b/build_vm_compilers/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/build_vm_compilers/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_vm_compilers/README.md b/build_vm_compilers/README.md
deleted file mode 100644
index 971d656..0000000
--- a/build_vm_compilers/README.md
+++ /dev/null
@@ -1,70 +0,0 @@
-<p align="center">
- Vm compilers for users of <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
- <br>
- <a href="https://travis-ci.org/dart-lang/build">
- <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
- </a>
- <a href="https://github.com/dart-lang/build/labels/package%3A%20build_vm_compilers">
- <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_vm_compilers.svg" alt="Issues related to build_vm_compilers" />
- </a>
- <a href="https://pub.dev/packages/build_vm_compilers">
- <img src="https://img.shields.io/pub/v/build_vm_compilers.svg" alt="Pub Package Version" />
- </a>
- <a href="https://pub.dev/documentation/build_vm_compilers/latest">
- <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
- </a>
- <a href="https://gitter.im/dart-lang/build">
- <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
- </a>
-</p>
-
-* [Installation](#installation)
-* [Usage](#usage)
-* [Configuration](#configuration)
-* [Manual Usage](#manual-usage)
-
-## Installation
-
-This package is intended to be used as a [development dependency][] for users
-of [`package:build`][] who want to run code in the Dart vm with precompiled
-kernel files. This allows you to share compilation of dependencies between
-multiple entrypoints, instead of doing a monolithic compile of each entrypoint
-like the Dart VM would normally do on each run.
-
-**Note**: If you want to use this package for running tests with
-`pub run build_runner test` you will also need a `build_test` dev dependency.
-
-## Usage
-
-This package creates a `.vm.app.dill` file corresponding to each `.dart` file
-that contains a `main` function.
-
-These files can be passed directly to the vm, instead of the dart script, and
-the vm will skip its initial parse and compile step.
-
-You can find the output either by using the `-o <dir>` option for build_runner,
-or by finding it in the generated cache directory, which is located at
-`.dart_tool/build/generated/<your-package>`.
-
-## Configuration
-
-There are no configuration options available at this time.
-
-## Custom Build Script Integration
-
-If you are using a custom build script, you will need to add the following
-builder applications to what you already have, sometime after the
-`build_modules` builder applications:
-
-```dart
- apply('build_vm_compilers|entrypoint',
- [vmKernelEntrypointBuilder], toRoot(),
- hideOutput: true,
- // These globs should match your entrypoints only.
- defaultGenerateFor: const InputSet(
- include: const ['bin/**', 'tool/**', 'test/**.vm_test.dart'])),
-]
-```
-
-[development dependency]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[`package:build`]: https://pub.dev/packages/build
diff --git a/build_vm_compilers/build.yaml b/build_vm_compilers/build.yaml
deleted file mode 100644
index 4b13b98..0000000
--- a/build_vm_compilers/build.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-builders:
- modules:
- import: "package:build_vm_compilers/builders.dart"
- builder_factories:
- - metaModuleBuilder
- - metaModuleCleanBuilder
- - moduleBuilder
- build_extensions:
- $lib$:
- - .vm.meta_module.raw
- - .vm.meta_module.clean
- .dart:
- - .vm.module
- is_optional: True
- auto_apply: none
- required_inputs: [".dart", ".module.library"]
- applies_builders: ["build_modules|module_cleanup"]
- vm:
- import: "package:build_vm_compilers/builders.dart"
- builder_factories:
- - vmKernelModuleBuilder
- build_extensions:
- .vm.module:
- - .vm.dill
- is_optional: True
- auto_apply: all_packages
- required_inputs:
- - .dart
- - .vm.module
- applies_builders:
- - build_vm_compilers|modules
- entrypoint:
- import: "package:build_vm_compilers/builders.dart"
- builder_factories:
- - vmKernelEntrypointBuilder
- build_extensions:
- .dart:
- - .vm.app.dill
- required_inputs:
- - .dart
- - .vm.dill
- - .vm.module
- build_to: cache
- auto_apply: root_package
- defaults:
- generate_for:
- include:
- - bin/**
- - tool/**
- - test/**.dart.vm_test.dart
- - example/**
- - benchmark/**
diff --git a/build_vm_compilers/lib/build_vm_compilers.dart b/build_vm_compilers/lib/build_vm_compilers.dart
deleted file mode 100644
index e0ea675..0000000
--- a/build_vm_compilers/lib/build_vm_compilers.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.
-
-export 'src/platform.dart' show vmPlatform;
-export 'src/vm_entrypoint_builder.dart' show VmEntrypointBuilder;
diff --git a/build_vm_compilers/lib/builders.dart b/build_vm_compilers/lib/builders.dart
deleted file mode 100644
index 6848a54..0000000
--- a/build_vm_compilers/lib/builders.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:path/path.dart' as p;
-
-import 'src/platform.dart';
-import 'src/vm_entrypoint_builder.dart';
-
-const vmKernelModuleExtension = '.vm.dill';
-const vmKernelEntrypointExtension = '.vm.app.dill';
-
-Builder metaModuleBuilder(BuilderOptions options) =>
- MetaModuleBuilder.forOptions(vmPlatform, options);
-Builder metaModuleCleanBuilder([_]) => MetaModuleCleanBuilder(vmPlatform);
-Builder moduleBuilder([_]) => ModuleBuilder(vmPlatform);
-
-Builder vmKernelModuleBuilder(_) => KernelBuilder(
- summaryOnly: false,
- sdkKernelPath: p.join('lib', '_internal', 'vm_platform_strong.dill'),
- outputExtension: vmKernelModuleExtension,
- platform: vmPlatform,
- );
-
-Builder vmKernelEntrypointBuilder(_) => VmEntrypointBuilder();
diff --git a/build_vm_compilers/lib/src/platform.dart b/build_vm_compilers/lib/src/platform.dart
deleted file mode 100644
index 85bdf5c..0000000
--- a/build_vm_compilers/lib/src/platform.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2019, 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:build_modules/build_modules.dart';
-
-final vmPlatform = DartPlatform.register('vm', [
- 'async',
- 'cli',
- 'collection',
- 'convert',
- 'core',
- 'developer',
- 'io',
- 'isolate',
- 'math',
- 'mirrors',
- 'nativewrappers',
- 'profiler',
- 'typed_data',
- 'vmservice_io',
- '_internal',
-]);
diff --git a/build_vm_compilers/lib/src/vm_entrypoint_builder.dart b/build_vm_compilers/lib/src/vm_entrypoint_builder.dart
deleted file mode 100644
index 03b520a..0000000
--- a/build_vm_compilers/lib/src/vm_entrypoint_builder.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// 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:convert';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:pool/pool.dart';
-
-import '../builders.dart';
-import 'platform.dart';
-
-/// Because we hold bytes in memory we don't want to compile to many app entry
-/// points at once.
-final _buildPool = Pool(16);
-
-/// A builder which combines several [vmKernelModuleExtension] modules into a
-/// single [vmKernelEntrypointExtension] file, which represents an entire
-/// application.
-class VmEntrypointBuilder implements Builder {
- const VmEntrypointBuilder();
-
- @override
- final buildExtensions = const {
- '.dart': [vmKernelEntrypointExtension],
- };
-
- @override
- Future<void> build(BuildStep buildStep) async {
- await _buildPool.withResource(() async {
- var dartEntrypointId = buildStep.inputId;
- var isAppEntrypoint = await _isAppEntryPoint(dartEntrypointId, buildStep);
- if (!isAppEntrypoint) return;
-
- var moduleId =
- buildStep.inputId.changeExtension(moduleExtension(vmPlatform));
- var module = Module.fromJson(
- json.decode(await buildStep.readAsString(moduleId))
- as Map<String, dynamic>);
-
- List<Module> transitiveModules;
- try {
- transitiveModules = await module
- .computeTransitiveDependencies(buildStep, throwIfUnsupported: true);
- } on UnsupportedModules catch (e) {
- var librariesString = (await e.exactLibraries(buildStep).toList())
- .map((lib) => AssetId(lib.id.package,
- lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
- .join('\n');
- log.warning('''
-Skipping compiling ${buildStep.inputId} for the vm because some of its
-transitive libraries have sdk dependencies that not supported on this platform:
-
-$librariesString
-
-https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
-''');
- return;
- }
-
- var transitiveKernelModules = [
- module.primarySource.changeExtension(vmKernelModuleExtension)
- ].followedBy(transitiveModules.reversed.map(
- (m) => m.primarySource.changeExtension(vmKernelModuleExtension)));
- var appContents = <int>[];
- for (var dependencyId in transitiveKernelModules) {
- appContents.addAll(await buildStep.readAsBytes(dependencyId));
- }
- await buildStep.writeAsBytes(
- buildStep.inputId.changeExtension(vmKernelEntrypointExtension),
- appContents);
- });
- }
-}
-
-/// Returns whether or not [dartId] is an app entrypoint (basically, whether
-/// or not it has a `main` function).
-Future<bool> _isAppEntryPoint(AssetId dartId, AssetReader reader) async {
- assert(dartId.extension == '.dart');
- // Skip reporting errors here, dartdevc will report them later with nicer
- // formatting.
- // ignore: deprecated_member_use
- var parsed = parseCompilationUnit(await reader.readAsString(dartId),
- suppressErrors: true);
- // Allow two or fewer arguments so that entrypoints intended for use with
- // [spawnUri] get counted.
- //
- // TODO: This misses the case where a Dart file doesn't contain main(),
- // but has a part that does, or it exports a `main` from another library.
- return parsed.declarations.any((node) {
- return node is FunctionDeclaration &&
- node.name.name == 'main' &&
- node.functionExpression.parameters.parameters.length <= 2;
- });
-}
diff --git a/build_vm_compilers/mono_pkg.yaml b/build_vm_compilers/mono_pkg.yaml
deleted file mode 100644
index c79ba5d..0000000
--- a/build_vm_compilers/mono_pkg.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.5.0
- - unit_test:
- - test:
- os:
- - linux
- - windows
diff --git a/build_vm_compilers/pubspec.yaml b/build_vm_compilers/pubspec.yaml
deleted file mode 100644
index f9257d2..0000000
--- a/build_vm_compilers/pubspec.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: build_vm_compilers
-version: 1.0.4
-description: Builder implementations wrapping Dart VM compilers.
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/build/tree/master/build_vm_compilers
-
-environment:
- sdk: ">=2.5.0 <3.0.0"
-
-dependencies:
- analyzer: ">=0.35.0 <0.40.0"
- build: ^1.0.0
- build_config: ">=0.3.0 <0.5.0"
- build_modules: ^2.0.0
- path: ^1.6.0
- pool: ^1.3.0
-
-dev_dependencies:
- build_runner: ^1.0.0
- test: ^1.0.0
- test_descriptor: ^1.1.0
- _test_common:
- path: ../_test_common
diff --git a/build_web_compilers/BUILD.gn b/build_web_compilers/BUILD.gn
deleted file mode 100644
index d5652c7..0000000
--- a/build_web_compilers/BUILD.gn
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is generated by importer.py for build_web_compilers-2.9.0
-
-import("//build/dart/dart_library.gni")
-
-dart_library("build_web_compilers") {
- package_name = "build_web_compilers"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/stack_trace",
- "//third_party/dart-pkg/pub/glob",
- "//third_party/dart-pkg/pub/analyzer",
- "//third_party/dart-pkg/pub/js",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/scratch_space",
- "//third_party/dart-pkg/pub/collection",
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/source_span",
- "//third_party/dart-pkg/pub/build_modules",
- "//third_party/dart-pkg/pub/bazel_worker",
- "//third_party/dart-pkg/pub/pool",
- "//third_party/dart-pkg/pub/source_maps",
- "//third_party/dart-pkg/pub/logging",
- "//third_party/dart-pkg/pub/crypto",
- "//third_party/dart-pkg/pub/archive",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/build_config",
- ]
-}
diff --git a/build_web_compilers/CHANGELOG.md b/build_web_compilers/CHANGELOG.md
deleted file mode 100644
index 774e4a0..0000000
--- a/build_web_compilers/CHANGELOG.md
+++ /dev/null
@@ -1,544 +0,0 @@
-## 2.9.0
-
-- Add support for enabling experiments through the `experiments` option on the
- `build_web_compilers|ddc` builder. This must be configured globally.
- - This is a list of experiment names, which translates into
- `--enable-experiment=<name>` arguments.
-
-## 2.8.0
-
-- Enable asserts in dev mode with dart2js by default.
-
-## 2.7.2
-
-- Fix a bug with hot restart,
- [#2586](https://github.com/dart-lang/build/issues/2586).
-
-## 2.7.1
-
-- Allow analyzer version `0.39.x`.
-
-## 2.7.0
-
-- Added an `environment` option to the `DevCompilerBuilder`.
- - This can be configured using the `environment` option of the
- `build_web_compilers|ddc` builder.
- - The expected value is a `Map<String, String>` and is equivalent to
- providing `-D<key>=<value>` command line arguments.
- - This option should only be set globally, and will throw if it ever recieves
- two different values. This is to ensure all modules are compiled with the
- same environment.
-
-## 2.6.4
-
-- Deobfuscate DDC extension method stack traces.
-
-## 2.6.3
-
-- Enforce builder application ordering between the SDK JS copy builder and the
- DDC entrypoint builder.
-
-## 2.6.2
-
-Fix the skipPlatformCheck option which was accidentally doing the opposite
-of what it claimed.
-
-## 2.6.1
-
-- Use the kernel version of `dart_sdk.js` rather than the analyzer version.
-
-## 2.6.0
-
-Add an option to globally skip the platform checks instead of only skipping
-them for a set of whitelisted packages.
-
-## 2.5.2
-
-Republish of `2.5.0` with the proper min sdk contraint.
-
-## 2.5.1
-
-### Bug fix for issue #2464
-
-Ignore the `trackUnusedInputs` option that was added in `2.5.0`.
-
-This option will be respected again in the next release which will have the
-proper minimum sdk constraint.
-
-## 2.5.0
-
-Add support for dependency pruning to the `DevCompilerBuilder`. This should
-greatly improve the invalidation semantics for builds, meaning that less code
-will be recompiled for each edit you make.
-
-This is enabled by default when using build_runner, and can be disabled using
-the `track-unused-inputs: false` option if you run into issues, so in your
-`build.yaml` it would look like this:
-
-```yaml
-targets:
- $default:
- build_web_compilers:ddc:
- options:
- track-unused-inputs: false
-```
-
-When using the builder programatically it is disabled by default and can be
-enabled by passing `trackUnusedInputs: true` to the `DevCompilerBuilder`
-constructor.
-
-## 2.4.1
-
-Make the required assets for DDC applications configurable in the
-`bootstrapDdc` method instead of hard coded. This allows custom integrations
-like flutter web to not require the same assets, or require additional custom
-assets.
-
-## 2.4.0
-
-### New Feature: Better --build-filter support for building a single test.
-
-You can now build a basic app or test in isolation by only requesting the
-`*.dart.js` file using a build filter, for example adding this argument to any
-build_runner command would build the `web/main.dart` app only:
-`--build-filter=web/main.dart.js`.
-
-For tests you will need to specify the bootstrapped test file, so:
-`--build-filter=test/hello_world.dart.browser_test.dart.js`.
-
-Previously you also had to explicitly require the SDK resources like:
-`--build-filter="package:build_web_compilers/**.js"` or similar.
-
-**Note**: If your app relies on any non-Dart generated files you will likely
-have to ask for those explicitly as well with additinal filters.
-
-## 2.3.0
-
-- Add an option to the DDC bootstrap to skip the checks around modules that have
- imports to unsupported SDK libraries like `dart:io` when the module is from a
- specified package. This is not used in the default build, but is available for
- custom DDC integrations.
-
-## 2.2.3
-
-- Allow analyzer version 0.38.0.
-
-## 2.2.2
-
-- Re-publish 2.2.0 with proper minimum sdk constraint of >=2.4.0.
-
-## 2.2.1
-
-- Revert of bad 2.2.0 release (had a bad min sdk).
-
-## 2.2.0
-
-- Make `librariesPath` configurable in `DevCompilerBuilder`.
-
-## 2.1.5
-
-- Add pre-emptive support for an upcoming breaking change in ddc
- around entrypoint naming.
-
-## 2.1.4
-
-- Allow analyzer version 0.37.0.
-
-## 2.1.3
-
-- Improve error message when `dart2js_args` is configured improperly.
-
-## 2.1.2
-
-- Fix hot restart bootstrapping logic for dart scripts that live in a
- different directory than the html file.
-
-## 2.1.1
-
-- Prepare for source map change from dartdevc, don't modify relative paths in
- source maps.
-- Fix hot reload bootstrap logic for app entrypoints under lib.
-
-## 2.1.0
-
-- Make `platformSdk`, `sdkKernelPath`, and `platform` configurable in
- `DevCompilerBuilder`.
-
-## 2.0.2
-
-- Prepare for the next sdk release, which changes what the uris look like for
- non-package sources, and breaks our existing hot restart logic.
-
-## 2.0.1
-
-- Fix issue #2269, which could cause applications to fail to properly bootstrap.
-- Skip compiling modules with ddc when the primary source isn't the primary
- input (only shows up in non-lazy builds - essentially just tests).
-
-## 2.0.0
-
-### Major Update - Switch to use the common front end.
-
-In this release, the Dart front end for the `dev_compiler` is changing from the
-[analyzer] to the common [front end][front_end]. This should unify error
-messages and general consistency across platforms, as this was one of the last
-compilers left still using the analyzer as a front end.
-
-While this is intended to be a transparent change, it is likely that there will
-be unintended differences. Please [file issues][issue tracker] if you experience
-something that seems broken or not working as intended.
-
-### Major Update - Auto-detection of web support for applications
-
-Previously, all files with a `main` that were matched by the input globs would
-attempt to compile for the web. This caused an issue when there were non-web
-applications in the default directories, which specifically happens a lot in the
-`test` directory. Resolving this required custom globs in `build.yaml` files.
-
-Two changes were made to help handle this issue more gracefully, in a way that
-often doesn't require custom `build.yaml` files any more.
-
-- Before compiling any app, build_web_compilers will check that all its
- transitive modules are compatible with the web (based on their `dart:`
- imports).
- - Today we will log a warning message for any app that isn't compatible, as
- ultimately it is most efficient to exclude these using globs in your
- `build.yaml` than waiting for us to detect it. This may change based on
- feedback.
-- Changed the default glob for the `test` directory to only include the
- `test/**.dart.browser_test.dart` files (other dirs remain unchanged).
- - Note that as a result of this, serving the `test` dir and running tests that
- way no longer works, as those entrypoints won't be compiled. You would need
- to configure the `generate_for` to explicitly include `test/**_test.dart`
- to restore that functionality (we will continue pushing on this in the
- future though to restore similar functionality).
- - Also note that the `build_test` package will now output
- `<platform>_test.dart` files based on your [TestOn] annotations, so using
- those where possible will help reduce build platform support warnings as
- well.
-
-### Additional Notes
-
-- Update to run DDC in kernel mode, and consume kernel outlines instead of
- analyzer summaries.
-- Skip trying to compile apps that import known incompatible libraries.
-- Increased the upper bound for `package:analyzer` to `<0.37.0`.
-- Removed support for `build_root_app_summary` configuration option.
-- Combine the `ddc_kernel` and `ddc` workers under a single name (`ddc`).
-- By default only `.dart.browser_test.dart` files will be compiled under the
- `test` directory, instead of all `_test.dart` files.
- - If you used the previous test debugging workflow in the browser you can
- restore the old behavior with something like the following in your
- build.yaml:
-
-```yaml
-targets:
- $default:
- builders:
- build_web_compilers|entrypoint:
- generate_for:
- - test/**_test.dart
- - web/**.dart
-```
-
-- Added the `use-incremental-compiler` option for the `build_web_compilers:ddc`
- builder. This is enabled by default but can be disabled if running into build
- issues by setting it to `false` globally:
-
-```yaml
-global_options:
- build_web_compilers:ddc:
- options:
- use-incremental-compiler: false
-```
-
-- This package now makes its own copy of the `dart_sdk.js` and `require.js`
- files, which it deletes during production builds.
- - In a future build_runner release we will be deleting the entire `$sdk`
- package to resolve some issues with build output bloat.
- - If you are using `dartdevc` as your production compiler, you will need to
- disable the cleanup builder in `build.yaml` (globally) like this:
-
-```yaml
-global_options:
- build_web_compilers|sdk_js_cleanup:
- release_options:
- enabled: false
-```
-
-[analyzer]: https://pub.dev/packages/analyzer
-[front_end]: https://pub.dev/packages/front_end
-[issue tracker]: https://github.com/dart-lang/build/issues/new
-[TestOn]: https://pub.dev/documentation/test/latest/#restricting-tests-to-certain-platforms
-
-## 1.2.2
-
-- Allow build_config 0.4.x.
-
-## 1.2.1
-
-- Allow analyzer version 0.36.x.
-
-## 1.2.0
-
-- Add a marker to inject code before the application main method is called.
-- During a hot restart we will now clear all statics before re-invoking main.
-
-## 1.1.0
-
-- Output a `.digests` file which contains transitive digests for an entrypoint.
-
-## 1.0.2
-
-- Improved the time tracking for ddc actions by not reporting time spent waiting
- for a worker to be available.
-
-## 1.0.1
-
-- Increased the upper bound for `package:analyzer` to `<0.36.0`.
-
-## 1.0.0
-
-- Removed the `enable_sync_async` and `ignore_cast_failures` options for the
- `build_web_compilers|entrypoint` builder. These will no longer have any effect
- and will give a build time warning if you try to use them.
-
-## 0.4.4+3
-
-- Increased the upper bound for `package:analyzer` to `<0.35.0`.
-
-## 0.4.4+2
-
-- Support `package:analyzer` version `0.33.x`.
-
-## 0.4.4+1
-
-- Support `package:build_modules` version `1.x.x`.
-
-## 0.4.4
-
-- Track performance of different builder stages.
-
-## 0.4.3+1
-
-- Removed dependency on cli_util.
-- Fix error in require.js error handling code
-
-## 0.4.3
-
-- Only call `window.postMessage` during initialization if the current context
- is a `Window`.
-- Fixed an error while showing stack traces for DDC generated scripts
- when `<base>` tag is used.
-- Value of `<base href="/.../">` tag should start and end with a `/` to be
- used as the base url for require js.
-- Added more javascript code to dev bootstrap for hot-reloading support
-- Support the latest build_modules.
-
-## 0.4.2+2
-
-- Add magic comment marker for build_runner to know where to inject
- live-reloading client code. This is only present when using the `dartdevc`
- compiler. (reapplied)
-
-## 0.4.2+1
-
-- Restore `new` keyword for a working release on Dart 1 VM.
-
-## 0.4.2
-
-- Add magic comment marker for build_runner to know where to inject
- live-reloading client code. This is only present when using the `dartdevc`
- compiler.
-- Release broken on Dart 1 VM.
-
-## 0.4.1
-
-- Support the latest build_modules, with updated dart2js support so that it can
- do multiple builds concurrently and will restart workers periodically to
- mitigate the effects of dart-lang/sdk#33708.
-- Improvements to reduce the memory usage of the dart2js builder, so that
- transitive dependency information can be garbage collected before the dart2js
- compile is completed.
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.4.0+5
-
-- Fixed an issue where subdirectories with hyphens in the name weren't
- bootstrapped properly in dartdevc.
-
-## 0.4.0+4
-
-- Expand support for `package:build_config` to include version `0.3.x`.
-
-## 0.4.0+3
-
-- Expand support for `package:archive` to include version `2.x.x`.
-
-## 0.4.0+2
-
-- Fix a dart2 error.
-
-## 0.4.0+1
-
-- Support `package:analyzer` `0.32.0`.
-
-## 0.4.0
-
-- Changed the default for `enable_sync_async` to `true` for the
- `build_web_compilers|entrypoint` builder.
-- Changed the default for `ignore_cast_failures` to `false` for the
- `build_web_compilers|entrypoint` builder.
-
-## 0.3.8
-
-- Remove `.dart` sources and `.js.map` files from the output directory in
- release mode.
-- Clean up `.tar.gz` outputs produced by `Dart2Js.`
-- Don't output extra `Dart2Js` outputs other than deferred part files.
-- Fixed a logical error in `dartdevc` compiler to detect correct base url for
- require js.
-- Added a `enable_sync_async` option to the `build_web_compilers|entrypoint`
- builder, which defaults to `false`.
-
-## 0.3.7+3
-
-- The `dartdevc` compiler now respects the `<base href="/....">` tags and will
- set them as the base url for require js.
-
-## 0.3.7+2
-
-- Fix sdk stack trace folding in the browser console and package:test.
-
-## 0.3.7+1
-
-- Add missing dependency on the `pool` package.
-
-## 0.3.7
-
-- Reduce memory usage by requesting (and lazily building) lower level modules
- first when building for an entrypoint.
-
-## 0.3.6
-
-- Add support for compiling with `dart2js` by default in release mode.
-
-## 0.3.5
-
-- Don't ignore cast failures by default. We expect most code to be clean with
- cast failures, and the option can be manually enabled with config.
-
-## 0.3.4+2
-
-- Create `.packages` file and use the new frontend with `dart2js`.
-
-## 0.3.4+1
-
-- Use `--use-old-frontend` with `dart2js` as a stopgap until we can add support
- for `.packages` files.
-
-## 0.3.4
-
-- Added support for dart2js deferred loading.
-- Added support for bootstrapping code in web workers with `dartdevc`.
-
-## 0.3.3
-
-- Added support for `--dump-info` and the `dart2js` compiler. If you pass that
- argument with `dart2js_args` the `.info.json` file will be copied the output.
-
-## 0.3.2
-
-- Dart2JS now has minification (`--minify`) enabled by default, similar to how
- it worked in `pub build`. If you are adding custom `dart2js` options, make
- sure you still keep the `--minify` flag. Here is an example:
-
-```yaml
-targets:
- $default:
- builders:
- build_web_compilers|entrypoint:
- generate_for:
- - web/**.dart
- options:
- compiler: dart2js
- dart2js_args:
- - --fast-startup
- - --minify
- - --trust-type-annotations
- - --trust-primitives
-```
-
-## 0.3.1
-
-- Cast failures will now be ignored in dartdevc by default (these were enabled
- in the latest sdk), and added an `ignore_cast_failures` option to the
- `build_web_compilers|entrypoint` builder which you can set to `true` to enable
- them.
- - At some point in the future it is expected that the default for this will
- flip.
-
-## 0.3.0+1
-
-- Fixed an issue with `dart2js` and the `--no-source-maps` flag.
-
-## 0.3.0
-
-### Breaking changes
-
-- Split `ModuleBuilder`, `UnlinkedSummaryBuilder` and `LinkedSummaryBuilder`
- into a separate `build_modules` package.
-
-## 0.2.1+1
-
-- Support the latest `analyzer` package.
-
-## 0.2.1
-
-- All dart files under `test` are now compiled by default instead of only the
- `_browser_test.dart` files (minus vm/node test bootstrap files). This means
- the original tests can be debugged directly (prior to package:test
- bootstrapping).
-- Updated to `package:build` version `0.12.0`.
-
-## 0.2.0
-
-### New Features
-
-- Added support for `dart2js`. This can be configured using the top level
- `compiler` option for the `build_web_compilers|entrypoint` builder. The
- supported options are `dartdevc` (the default) and `dart2js`. Args can be
- passed to `dart2js` using the `dart2js_args` option. For example:
-
-```yaml
-targets:
- <my_package>:
- builders:
- build_web_compilers|entrypoint:
- options:
- compiler: dart2js
- dart2js_args:
- - --minify
-```
-
-### Breaking Changes
-
-- Renamed `ddc_bootstrap` builder to `entrypoint`, the exposed class also
- changed from `DevCompilerBootstrapBuilder` to `WebEntrypointBuilder`.
-- Renamed `jsBootstrapExtension` to `ddcBootstrapExtension` since it is only
- required when using the dev compiler.
-
-## 0.1.1
-
-- Mark `ddc_bootstrap` builder with `build_to: cache`.
-- Publish as `build_web_compilers`
-
-## 0.1.0
-
-- Add builder factories.
-- Fixed temp dir cleanup bug on windows.
-- Enabled support for running tests in --precompiled mode.
-
-## 0.0.1
-
-- Initial release with support for building analyzer summaries and DDC modules.
diff --git a/build_web_compilers/LICENSE b/build_web_compilers/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/build_web_compilers/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/build_web_compilers/README.md b/build_web_compilers/README.md
deleted file mode 100644
index 4667d45..0000000
--- a/build_web_compilers/README.md
+++ /dev/null
@@ -1,101 +0,0 @@
-<p align="center">
- Web compilers for users of <a href="https://pub.dev/packages/build"><code>package:build</code></a>.
- <br>
- <a href="https://travis-ci.org/dart-lang/build">
- <img src="https://travis-ci.org/dart-lang/build.svg?branch=master" alt="Build Status" />
- </a>
- <a href="https://github.com/dart-lang/build/labels/package%3A%20build_web_compilers">
- <img src="https://img.shields.io/github/issues-raw/dart-lang/build/package%3A%20build_web_compilers.svg" alt="Issues related to build_web_compilers" />
- </a>
- <a href="https://pub.dev/packages/build_web_compilers">
- <img src="https://img.shields.io/pub/v/build_web_compilers.svg" alt="Pub Package Version" />
- </a>
- <a href="https://pub.dev/documentation/build_web_compilers/latest">
- <img src="https://img.shields.io/badge/dartdocs-latest-blue.svg" alt="Latest Dartdocs" />
- </a>
- <a href="https://gitter.im/dart-lang/build">
- <img src="https://badges.gitter.im/dart-lang/build.svg" alt="Join the chat on Gitter" />
- </a>
-</p>
-
-* [Installation](#installation)
-* [Usage](#usage)
-* [Configuration](#configuration)
-* [Manual Usage](#manual-usage)
-
-## Installation
-
-This package is intended to be used as a [development dependency][] for users
-of [`package:build`][] who want to run code in a browser. Simply add the
-following to your `pubspec.yaml`:
-
-```yaml
-dev_dependencies:
- build_web_compilers:
-```
-
-## Usage
-
-If you are using the autogenerated build script (going through
-`pub run build_runner <command>` instead of handwriting a `build.dart` file),
-then all you need is the `dev_dependency` listed above.
-
-## Configuration
-
-By default, the `dartdevc` compiler will be used, which is the Dart Development
-Compiler.
-
-If you would like to opt into `dart2js` you will need to add a `build.yaml`
-file, which should look roughly like the following:
-
-```yaml
-targets:
- $default:
- builders:
- build_web_compilers|entrypoint:
- # These are globs for the entrypoints you want to compile.
- generate_for:
- - test/**.browser_test.dart
- - web/**.dart
- options:
- compiler: dart2js
- # List any dart2js specific args here, or omit it.
- dart2js_args:
- - -O2
-```
-
-## Manual Usage
-
-If you are using a custom build script, you will need to add the following
-builder applications to what you already have, almost certainly at the end of
-the list (unless you need to post-process the js files).
-
-```dart
-[
- apply(
- 'build_web_compilers|ddc',
- [
- (_) => new ModuleBuilder(),
- (_) => new UnlinkedSummaryBuilder(),
- (_) => new LinkedSummaryBuilder(),
- (_) => new DevCompilerBuilder()
- ],
- toAllPackages(),
- // Recommended, but not required. This makes it so only modules that are
- // imported by entrypoints get compiled.
- isOptional: true,
- hideOutput: true),
- apply('build_web_compilers|entrypoint',
- // You can also use `WebCompiler.Dart2Js`. If you don't care about
- // dartdevc at all you may also omit the previous builder application
- // entirely.
- [(_) => new WebEntrypointBuilder(WebCompiler.DartDevc)], toRoot(),
- hideOutput: true,
- // These globs should match your entrypoints only.
- defaultGenerateFor: const InputSet(
- include: const ['web/**', 'test/**.browser_test.dart'])),
-]
-```
-
-[development dependency]: https://dart.dev/tools/pub/dependencies#dev-dependencies
-[`package:build`]: https://pub.dev/packages/build
diff --git a/build_web_compilers/build.yaml b/build_web_compilers/build.yaml
deleted file mode 100644
index c858018..0000000
--- a/build_web_compilers/build.yaml
+++ /dev/null
@@ -1,149 +0,0 @@
-targets:
- $default:
- builders:
- build_web_compilers|entrypoint:
- options:
- compiler: dart2js
- dart2js_args:
- - -O4
- enabled: true
- generate_for:
- - web/stack_trace_mapper.dart
- build_web_compilers|_stack_trace_mapper_copy:
- enabled: true
- build_web_compilers|sdk_js_copy:
- enabled: true
- build_web_compilers|sdk_js_cleanup:
- enabled: true
-builders:
- sdk_js_copy:
- import: "package:build_web_compilers/builders.dart"
- builder_factories:
- - sdkJsCopyBuilder
- build_extensions:
- $lib$:
- - src/dev_compiler/dart_sdk.js
- - src/dev_compiler/require.js
- is_optional: False
- auto_apply: none
- applies_builders: ["build_web_compilers|sdk_js_cleanup"]
- runs_before: ["build_web_compilers|entrypoint"]
- dart2js_modules:
- import: "package:build_web_compilers/builders.dart"
- builder_factories:
- - dart2jsMetaModuleBuilder
- - dart2jsMetaModuleCleanBuilder
- - dart2jsModuleBuilder
- build_extensions:
- $lib$:
- - .dart2js.meta_module.raw
- - .dart2js.meta_module.clean
- .dart:
- - .dart2js.module
- is_optional: True
- auto_apply: none
- required_inputs: [".dart", ".module.library"]
- applies_builders: ["build_modules|module_cleanup"]
- ddc_modules:
- import: "package:build_web_compilers/builders.dart"
- builder_factories:
- - ddcMetaModuleBuilder
- - ddcMetaModuleCleanBuilder
- - ddcModuleBuilder
- build_extensions:
- $lib$:
- - .ddc.meta_module.raw
- - .ddc.meta_module.clean
- .dart:
- - .ddc.module
- is_optional: True
- auto_apply: none
- required_inputs: [".dart", ".module.library"]
- applies_builders: ["build_modules|module_cleanup"]
- ddc:
- import: "package:build_web_compilers/builders.dart"
- builder_factories:
- - ddcKernelBuilder
- - ddcBuilder
- build_extensions:
- .ddc.module:
- - .ddc.dill
- - .ddc.js.errors
- - .ddc.js
- - .ddc.js.map
- is_optional: True
- auto_apply: all_packages
- required_inputs:
- - .ddc.module
- applies_builders:
- - build_web_compilers|ddc_modules
- # This isn't really the best place to apply these, but it is the only
- # place we can (its the only builder which runs on all packages).
- - build_web_compilers|dart2js_modules
- - build_web_compilers|dart_source_cleanup
- entrypoint:
- import: "package:build_web_compilers/builders.dart"
- builder_factories:
- - webEntrypointBuilder
- build_extensions:
- .dart:
- - .dart.bootstrap.js
- - .dart.js
- - .dart.js.map
- - .dart.js.tar.gz
- - .digests
- required_inputs:
- - .dart
- - .ddc.js
- - .ddc.module
- - .dart2js.module
- build_to: cache
- auto_apply: root_package
- defaults:
- generate_for:
- include:
- - web/**
- - test/**.dart.browser_test.dart
- - example/**
- - benchmark/**
- exclude:
- - test/**.node_test.dart
- - test/**.vm_test.dart
- options:
- dart2js_args:
- - --minify
- dev_options:
- dart2js_args:
- - --enable-asserts
- release_options:
- compiler: dart2js
- applies_builders:
- - build_web_compilers|dart2js_archive_extractor
- _stack_trace_mapper_copy:
- import: "tool/copy_builder.dart"
- builder_factories:
- - copyBuilder
- build_extensions:
- web/stack_trace_mapper.dart.js:
- - lib/src/dev_compiler_stack_trace/stack_trace_mapper.dart.js
- auto_apply: none
- build_to: source
-post_process_builders:
- dart2js_archive_extractor:
- import: "package:build_web_compilers/builders.dart"
- builder_factory: dart2jsArchiveExtractor
- defaults:
- release_options:
- filter_outputs: true
- dart_source_cleanup:
- import: "package:build_web_compilers/builders.dart"
- builder_factory: dartSourceCleanup
- defaults:
- release_options:
- enabled: true
- sdk_js_cleanup:
- import: "package:build_web_compilers/builders.dart"
- builder_factory: sdkJsCleanupBuilder
- defaults:
- release_options:
- enabled: true
diff --git a/build_web_compilers/dart_test.yaml b/build_web_compilers/dart_test.yaml
deleted file mode 100644
index f2869e5..0000000
--- a/build_web_compilers/dart_test.yaml
+++ /dev/null
@@ -1 +0,0 @@
-timeout: 2x
diff --git a/build_web_compilers/lib/build_web_compilers.dart b/build_web_compilers/lib/build_web_compilers.dart
deleted file mode 100644
index 95e26a5..0000000
--- a/build_web_compilers/lib/build_web_compilers.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/archive_extractor.dart' show Dart2JsArchiveExtractor;
-export 'src/dev_compiler_builder.dart'
- show
- DevCompilerBuilder,
- jsModuleErrorsExtension,
- jsModuleExtension,
- jsSourceMapExtension;
-export 'src/platforms.dart' show dart2jsPlatform, ddcPlatform;
-export 'src/web_entrypoint_builder.dart'
- show WebCompiler, WebEntrypointBuilder, ddcBootstrapExtension;
diff --git a/build_web_compilers/lib/builders.dart b/build_web_compilers/lib/builders.dart
deleted file mode 100644
index 255fa5d..0000000
--- a/build_web_compilers/lib/builders.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2017, 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:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:collection/collection.dart';
-import 'package:path/path.dart' as p;
-
-import 'build_web_compilers.dart';
-import 'src/common.dart';
-import 'src/platforms.dart';
-import 'src/sdk_js_copy_builder.dart';
-
-// Shared entrypoint builder
-Builder webEntrypointBuilder(BuilderOptions options) =>
- WebEntrypointBuilder.fromOptions(options);
-
-// Ddc related builders
-Builder ddcMetaModuleBuilder(BuilderOptions options) =>
- MetaModuleBuilder.forOptions(ddcPlatform, options);
-Builder ddcMetaModuleCleanBuilder(_) => MetaModuleCleanBuilder(ddcPlatform);
-Builder ddcModuleBuilder([_]) => ModuleBuilder(ddcPlatform);
-Builder ddcBuilder(BuilderOptions options) {
- validateOptions(options.config, _supportedOptions, 'build_web_compilers:ddc');
- _ensureSameDdcOptions(options);
-
- return DevCompilerBuilder(
- useIncrementalCompiler: _readUseIncrementalCompilerOption(options),
- trackUnusedInputs: _readTrackInputsCompilerOption(options),
- platform: ddcPlatform,
- environment: _readEnvironmentOption(options),
- experiments: _readExperimentOption(options),
- );
-}
-
-const ddcKernelExtension = '.ddc.dill';
-Builder ddcKernelBuilder(BuilderOptions options) {
- validateOptions(options.config, _supportedOptions, 'build_web_compilers:ddc');
- _ensureSameDdcOptions(options);
-
- return KernelBuilder(
- summaryOnly: true,
- sdkKernelPath: p.url.join('lib', '_internal', 'ddc_sdk.dill'),
- outputExtension: ddcKernelExtension,
- platform: ddcPlatform,
- useIncrementalCompiler: _readUseIncrementalCompilerOption(options),
- trackUnusedInputs: _readTrackInputsCompilerOption(options),
- experiments: _readExperimentOption(options));
-}
-
-Builder sdkJsCopyBuilder(_) => SdkJsCopyBuilder();
-PostProcessBuilder sdkJsCleanupBuilder(BuilderOptions options) =>
- FileDeletingBuilder(
- ['lib/src/dev_compiler/dart_sdk.js', 'lib/src/dev_compiler/require.js'],
- isEnabled: options.config['enabled'] as bool ?? false);
-
-// Dart2js related builders
-Builder dart2jsMetaModuleBuilder(BuilderOptions options) =>
- MetaModuleBuilder.forOptions(dart2jsPlatform, options);
-Builder dart2jsMetaModuleCleanBuilder(_) =>
- MetaModuleCleanBuilder(dart2jsPlatform);
-Builder dart2jsModuleBuilder([_]) => ModuleBuilder(dart2jsPlatform);
-PostProcessBuilder dart2jsArchiveExtractor(BuilderOptions options) =>
- Dart2JsArchiveExtractor.fromOptions(options);
-
-// General purpose builders
-PostProcessBuilder dartSourceCleanup(BuilderOptions options) =>
- (options.config['enabled'] as bool ?? false)
- ? const FileDeletingBuilder(['.dart', '.js.map'])
- : const FileDeletingBuilder(['.dart', '.js.map'], isEnabled: false);
-
-/// Throws if it is ever given different options.
-void _ensureSameDdcOptions(BuilderOptions options) {
- if (_previousDdcConfig != null) {
- if (!const MapEquality().equals(_previousDdcConfig, options.config)) {
- throw ArgumentError(
- 'The build_web_compilers:ddc builder must have the same '
- 'configuration in all packages. Saw $_previousDdcConfig and '
- '${options.config} which are not equal.\n\n '
- 'Please use the `global_options` section in '
- '`build.yaml` or the `--define` flag to set global options.');
- }
- } else {
- _previousDdcConfig = options.config;
- }
-}
-
-bool _readUseIncrementalCompilerOption(BuilderOptions options) {
- return options.config[_useIncrementalCompilerOption] as bool ?? true;
-}
-
-bool _readTrackInputsCompilerOption(BuilderOptions options) {
- return options.config[_trackUnusedInputsCompilerOption] as bool ?? true;
-}
-
-Map<String, String> _readEnvironmentOption(BuilderOptions options) {
- return Map.from((options.config[_environmentOption] as Map) ?? {});
-}
-
-List<String> _readExperimentOption(BuilderOptions options) {
- return List.from((options.config[_experimentOption] as List) ?? []);
-}
-
-Map<String, dynamic> _previousDdcConfig;
-const _useIncrementalCompilerOption = 'use-incremental-compiler';
-const _trackUnusedInputsCompilerOption = 'track-unused-inputs';
-const _environmentOption = 'environment';
-const _experimentOption = 'experiments';
-const _supportedOptions = [
- _environmentOption,
- _experimentOption,
- _useIncrementalCompilerOption,
- _trackUnusedInputsCompilerOption
-];
diff --git a/build_web_compilers/lib/src/archive_extractor.dart b/build_web_compilers/lib/src/archive_extractor.dart
deleted file mode 100644
index 1506710..0000000
--- a/build_web_compilers/lib/src/archive_extractor.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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 'package:archive/archive.dart';
-import 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-
-import 'web_entrypoint_builder.dart';
-
-class Dart2JsArchiveExtractor implements PostProcessBuilder {
- /// Whether to only output .js files.
- ///
- /// The default in release mode.
- bool filterOutputs;
-
- Dart2JsArchiveExtractor() : filterOutputs = false;
-
- Dart2JsArchiveExtractor.fromOptions(BuilderOptions options)
- : filterOutputs = options.config['filter_outputs'] as bool ?? false;
-
- @override
- final inputExtensions = const [jsEntrypointArchiveExtension];
-
- @override
- Future<void> build(PostProcessBuildStep buildStep) async {
- var bytes = await buildStep.readInputAsBytes();
- var archive = TarDecoder().decodeBytes(bytes);
- for (var file in archive.files) {
- if (filterOutputs && !file.name.endsWith('.js')) continue;
- var inputId = buildStep.inputId;
- var id = AssetId(
- inputId.package, p.url.join(p.url.dirname(inputId.path), file.name));
- await buildStep.writeAsBytes(id, file.content as List<int>);
- }
- buildStep.deletePrimaryInput();
- }
-}
diff --git a/build_web_compilers/lib/src/common.dart b/build_web_compilers/lib/src/common.dart
deleted file mode 100644
index 1916bff..0000000
--- a/build_web_compilers/lib/src/common.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-import 'package:build_modules/build_modules.dart';
-
-final defaultAnalysisOptionsId =
- AssetId('build_modules', 'lib/src/analysis_options.default.yaml');
-
-final sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
-
-String defaultAnalysisOptionsArg(ScratchSpace scratchSpace) =>
- '--options=${scratchSpace.fileFor(defaultAnalysisOptionsId).path}';
-
-// TODO: better solution for a .packages file, today we just create a new one
-// for every kernel build action.
-Future<File> createPackagesFile(Iterable<AssetId> allAssets) async {
- var allPackages = allAssets.map((id) => id.package).toSet();
- var packagesFileDir =
- await Directory.systemTemp.createTemp('kernel_builder_');
- var packagesFile = File(p.join(packagesFileDir.path, '.packages'));
- await packagesFile.create();
- await packagesFile.writeAsString(allPackages
- .map((pkg) => '$pkg:$multiRootScheme:///packages/$pkg')
- .join('\r\n'));
- return packagesFile;
-}
-
-/// Validates that [config] only has the top level keys [supportedOptions].
-///
-/// Throws an [ArgumentError] if not.
-void validateOptions(Map<String, dynamic> config, List<String> supportedOptions,
- String builderKey,
- {List<String> deprecatedOptions}) {
- deprecatedOptions ??= [];
- var unsupported = config.keys.where(
- (o) => !supportedOptions.contains(o) && !deprecatedOptions.contains(o));
- if (unsupported.isNotEmpty) {
- throw ArgumentError.value(unsupported.join(', '), builderKey,
- 'only $supportedOptions are supported options, but got');
- }
- var deprecated = config.keys.where(deprecatedOptions.contains);
- if (deprecated.isNotEmpty) {
- log.warning('Found deprecated options ${deprecated.join(', ')}. These no '
- 'longer have any effect and should be removed.');
- }
-}
diff --git a/build_web_compilers/lib/src/dart2js_bootstrap.dart b/build_web_compilers/lib/src/dart2js_bootstrap.dart
deleted file mode 100644
index 11ba92c..0000000
--- a/build_web_compilers/lib/src/dart2js_bootstrap.dart
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:io';
-
-import 'package:archive/archive.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:crypto/crypto.dart';
-import 'package:glob/glob.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import 'platforms.dart';
-import 'web_entrypoint_builder.dart';
-
-/// Compiles an the primary input of [buildStep] with dart2js.
-///
-/// If [skipPlatformCheck] is `true` then all `dart:` imports will be
-/// allowed in all packages.
-Future<void> bootstrapDart2Js(BuildStep buildStep, List<String> dart2JsArgs,
- {bool skipPlatformCheck}) async {
- skipPlatformCheck ??= false;
- var dartEntrypointId = buildStep.inputId;
- var moduleId =
- dartEntrypointId.changeExtension(moduleExtension(dart2jsPlatform));
- var args = <String>[];
- {
- var module = Module.fromJson(
- json.decode(await buildStep.readAsString(moduleId))
- as Map<String, dynamic>);
- List<Module> allDeps;
- try {
- allDeps = (await module.computeTransitiveDependencies(buildStep,
- throwIfUnsupported: !skipPlatformCheck))
- ..add(module);
- } on UnsupportedModules catch (e) {
- var librariesString = (await e.exactLibraries(buildStep).toList())
- .map((lib) => AssetId(lib.id.package,
- lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
- .join('\n');
- log.warning('''
-Skipping compiling ${buildStep.inputId} with dart2js because some of its
-transitive libraries have sdk dependencies that not supported on this platform:
-
-$librariesString
-
-https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
-''');
- return;
- }
-
- var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
- var allSrcs = allDeps.expand((module) => module.sources);
- await scratchSpace.ensureAssets(allSrcs, buildStep);
- var packageFile =
- await _createPackageFile(allSrcs, buildStep, scratchSpace);
-
- var dartPath = dartEntrypointId.path.startsWith('lib/')
- ? 'package:${dartEntrypointId.package}/'
- '${dartEntrypointId.path.substring('lib/'.length)}'
- : dartEntrypointId.path;
- var jsOutputPath =
- '${p.withoutExtension(dartPath.replaceFirst('package:', 'packages/'))}'
- '$jsEntrypointExtension';
- args = dart2JsArgs.toList()
- ..addAll([
- '--packages=$packageFile',
- '-o$jsOutputPath',
- dartPath,
- ]);
- }
-
- var dart2js = await buildStep.fetchResource(dart2JsWorkerResource);
- var result = await dart2js.compile(args);
- var jsOutputId = dartEntrypointId.changeExtension(jsEntrypointExtension);
- var jsOutputFile = scratchSpace.fileFor(jsOutputId);
- if (result.succeeded && await jsOutputFile.exists()) {
- log.info(result.output);
- var rootDir = p.dirname(jsOutputFile.path);
- var dartFile = p.basename(dartEntrypointId.path);
- var fileGlob = Glob('$dartFile.js*');
- var archive = Archive();
- await for (var jsFile in fileGlob.list(root: rootDir)) {
- if (jsFile.path.endsWith(jsEntrypointExtension) ||
- jsFile.path.endsWith(jsEntrypointSourceMapExtension)) {
- // These are explicitly output, and are not part of the archive.
- continue;
- }
- if (jsFile is File) {
- var fileName = p.relative(jsFile.path, from: rootDir);
- var fileStats = await jsFile.stat();
- archive.addFile(
- ArchiveFile(fileName, fileStats.size, await jsFile.readAsBytes())
- ..mode = fileStats.mode
- ..lastModTime = fileStats.modified.millisecondsSinceEpoch);
- }
- }
- if (archive.isNotEmpty) {
- var archiveId =
- dartEntrypointId.changeExtension(jsEntrypointArchiveExtension);
- await buildStep.writeAsBytes(archiveId, TarEncoder().encode(archive));
- }
-
- // Explicitly write out the original js file and sourcemap - we can't output
- // these as part of the archive because they already have asset nodes.
- await scratchSpace.copyOutput(jsOutputId, buildStep);
- var jsSourceMapId =
- dartEntrypointId.changeExtension(jsEntrypointSourceMapExtension);
- await _copyIfExists(jsSourceMapId, scratchSpace, buildStep);
- } else {
- log.severe(result.output);
- }
-}
-
-Future<void> _copyIfExists(
- AssetId id, ScratchSpace scratchSpace, AssetWriter writer) async {
- var file = scratchSpace.fileFor(id);
- if (await file.exists()) {
- await scratchSpace.copyOutput(id, writer);
- }
-}
-
-/// Creates a `.packages` file unique to this entrypoint at the root of the
-/// scratch space and returns it's filename.
-///
-/// Since mulitple invocations of Dart2Js will share a scratch space and we only
-/// know the set of packages involved the current entrypoint we can't construct
-/// a `.packages` file that will work for all invocations of Dart2Js so a unique
-/// file is created for every entrypoint that is run.
-///
-/// The filename is based off the MD5 hash of the asset path so that files are
-/// unique regarless of situations like `web/foo/bar.dart` vs
-/// `web/foo-bar.dart`.
-Future<String> _createPackageFile(Iterable<AssetId> inputSources,
- BuildStep buildStep, ScratchSpace scratchSpace) async {
- var inputUri = buildStep.inputId.uri;
- var packageFileName =
- '.package-${md5.convert(inputUri.toString().codeUnits)}';
- var packagesFile =
- scratchSpace.fileFor(AssetId(buildStep.inputId.package, packageFileName));
- var packageNames = inputSources.map((s) => s.package).toSet();
- var packagesFileContent =
- packageNames.map((n) => '$n:packages/$n/').join('\n');
- await packagesFile
- .writeAsString('# Generated for $inputUri\n$packagesFileContent');
- return packageFileName;
-}
diff --git a/build_web_compilers/lib/src/ddc_names.dart b/build_web_compilers/lib/src/ddc_names.dart
deleted file mode 100644
index 6a4e987..0000000
--- a/build_web_compilers/lib/src/ddc_names.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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:path/path.dart' as p;
-
-/// Transforms a path to a valid JS identifier.
-///
-/// This logic must be synchronized with [pathToJSIdentifier] in DDC at:
-/// pkg/dev_compiler/lib/src/compiler/module_builder.dart
-///
-/// For backwards compatibility, if this pattern is changed,
-/// dev_compiler_bootstrap.dart must be updated to accept both old and new
-/// patterns.
-String pathToJSIdentifier(String path) {
- path = p.normalize(path);
- if (path.startsWith('/') || path.startsWith('\\')) {
- path = path.substring(1, path.length);
- }
- return toJSIdentifier(path
- .replaceAll('\\', '__')
- .replaceAll('/', '__')
- .replaceAll('..', '__')
- .replaceAll('-', '_'));
-}
-
-/// Escape [name] to make it into a valid identifier.
-String toJSIdentifier(String name) {
- if (name.isEmpty) return r'$';
-
- // Escape any invalid characters
- StringBuffer buffer;
- for (var i = 0; i < name.length; i++) {
- var ch = name[i];
- var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
- if (needsEscape && buffer == null) {
- buffer = StringBuffer(name.substring(0, i));
- }
- if (buffer != null) {
- buffer.write(needsEscape ? '\$${ch.codeUnits.join("")}' : ch);
- }
- }
-
- var result = buffer != null ? '$buffer' : name;
- // Ensure the identifier first character is not numeric and that the whole
- // identifier is not a keyword.
- if (result.startsWith(RegExp('[0-9]')) || invalidVariableName(result)) {
- return '\$$result';
- }
- return result;
-}
-
-/// Returns true for invalid JS variable names, such as keywords.
-/// Also handles invalid variable names in strict mode, like "arguments".
-bool invalidVariableName(String keyword, {bool strictMode = true}) {
- switch (keyword) {
- // http://www.ecma-international.org/ecma-262/6.0/#sec-future-reserved-words
- case 'await':
- case 'break':
- case 'case':
- case 'catch':
- case 'class':
- case 'const':
- case 'continue':
- case 'debugger':
- case 'default':
- case 'delete':
- case 'do':
- case 'else':
- case 'enum':
- case 'export':
- case 'extends':
- case 'finally':
- case 'for':
- case 'function':
- case 'if':
- case 'import':
- case 'in':
- case 'instanceof':
- case 'let':
- case 'new':
- case 'return':
- case 'super':
- case 'switch':
- case 'this':
- case 'throw':
- case 'try':
- case 'typeof':
- case 'var':
- case 'void':
- case 'while':
- case 'with':
- return true;
- case 'arguments':
- case 'eval':
- // http://www.ecma-international.org/ecma-262/6.0/#sec-future-reserved-words
- // http://www.ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
- case 'implements':
- case 'interface':
- case 'package':
- case 'private':
- case 'protected':
- case 'public':
- case 'static':
- case 'yield':
- return strictMode;
- }
- return false;
-}
-
-// Invalid characters for identifiers, which would need to be escaped.
-final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_$0-9]');
diff --git a/build_web_compilers/lib/src/dev_compiler_bootstrap.dart b/build_web_compilers/lib/src/dev_compiler_bootstrap.dart
deleted file mode 100644
index 2845d45..0000000
--- a/build_web_compilers/lib/src/dev_compiler_bootstrap.dart
+++ /dev/null
@@ -1,530 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-import 'dart:convert';
-
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as _p; // ignore: library_prefixes
-import 'package:pool/pool.dart';
-
-import 'ddc_names.dart';
-import 'dev_compiler_builder.dart';
-import 'platforms.dart';
-import 'web_entrypoint_builder.dart';
-
-/// Alias `_p.url` to `p`.
-_p.Context get _context => _p.url;
-
-var _modulePartialExtension = _context.withoutExtension(jsModuleExtension);
-
-/// Bootstraps a ddc application, creating the main entrypoint as well as the
-/// bootstrap and digest entrypoints.
-///
-/// If [skipPlatformCheck] is `true` then all `dart:` imports will be
-/// allowed in all packages.
-///
-/// Deprecated: If [skipPlatformCheckPackages] is provided then any dart:
-/// imports will be allowed in the specified packages.
-///
-/// If [requiredAssets] is provided then this will ensure those assets are
-/// available to the app by making them inputs of this build action.
-Future<void> bootstrapDdc(
- BuildStep buildStep, {
- DartPlatform platform,
- bool skipPlatformCheck = false,
- @deprecated Set<String> skipPlatformCheckPackages = const {},
- Iterable<AssetId> requiredAssets,
-}) async {
- requiredAssets ??= [];
- skipPlatformCheck ??= false;
- // Ensures that the sdk resources are built and available.
- await _ensureResources(buildStep, requiredAssets);
-
- var dartEntrypointId = buildStep.inputId;
- var moduleId = buildStep.inputId
- .changeExtension(moduleExtension(platform ?? ddcPlatform));
- var module = Module.fromJson(json
- .decode(await buildStep.readAsString(moduleId)) as Map<String, dynamic>);
-
- // First, ensure all transitive modules are built.
- List<AssetId> transitiveJsModules;
- try {
- transitiveJsModules = await _ensureTransitiveJsModules(module, buildStep,
- skipPlatformCheck: skipPlatformCheck,
- skipPlatformCheckPackages: skipPlatformCheckPackages);
- } on UnsupportedModules catch (e) {
- var librariesString = (await e.exactLibraries(buildStep).toList())
- .map((lib) => AssetId(lib.id.package,
- lib.id.path.replaceFirst(moduleLibraryExtension, '.dart')))
- .join('\n');
- log.warning('''
-Skipping compiling ${buildStep.inputId} with ddc because some of its
-transitive libraries have sdk dependencies that not supported on this platform:
-
-$librariesString
-
-https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-skipped-compiling-warnings
-''');
- return;
- }
- var jsId = module.primarySource.changeExtension(jsModuleExtension);
- var appModuleName = ddcModuleName(jsId);
- var appDigestsOutput =
- dartEntrypointId.changeExtension(digestsEntrypointExtension);
-
- // The name of the entrypoint dart library within the entrypoint JS module.
- //
- // This is used to invoke `main()` from within the bootstrap script.
- //
- // TODO(jakemac53): Sane module name creation, this only works in the most
- // basic of cases.
- //
- // See https://github.com/dart-lang/sdk/issues/27262 for the root issue
- // which will allow us to not rely on the naming schemes that dartdevc uses
- // internally, but instead specify our own.
- var oldAppModuleScope = toJSIdentifier(
- _context.withoutExtension(_context.basename(buildStep.inputId.path)));
-
- // Like above but with a package-relative entrypoint.
- var appModuleScope =
- pathToJSIdentifier(_context.withoutExtension(buildStep.inputId.path));
-
- // Map from module name to module path for custom modules.
- var modulePaths = SplayTreeMap.of(
- {'dart_sdk': r'packages/build_web_compilers/src/dev_compiler/dart_sdk'});
- for (var jsId in transitiveJsModules) {
- // Strip out the top level dir from the path for any module, and set it to
- // `packages/` for lib modules. We set baseUrl to `/` to simplify things,
- // and we only allow you to serve top level directories.
- var moduleName = ddcModuleName(jsId);
- modulePaths[moduleName] = _context.withoutExtension(
- jsId.path.startsWith('lib')
- ? '$moduleName$jsModuleExtension'
- : _context.joinAll(_context.split(jsId.path).skip(1)));
- }
-
- var bootstrapId = dartEntrypointId.changeExtension(ddcBootstrapExtension);
- var bootstrapModuleName = _context.withoutExtension(_context.relative(
- bootstrapId.path,
- from: _context.dirname(dartEntrypointId.path)));
-
- var dartEntrypointParts = _context.split(dartEntrypointId.path);
- var entrypointLibraryName = _context.joinAll([
- // Convert to a package: uri for files under lib.
- if (dartEntrypointParts.first == 'lib')
- 'package:${module.primarySource.package}',
- // Strip top-level directory from the path.
- ...dartEntrypointParts.skip(1),
- ]);
-
- var bootstrapContent =
- StringBuffer('$_entrypointExtensionMarker\n(function() {\n')
- ..write(_dartLoaderSetup(
- modulePaths,
- _p.url.relative(appDigestsOutput.path,
- from: _p.url.dirname(bootstrapId.path))))
- ..write(_requireJsConfig)
- ..write(_appBootstrap(bootstrapModuleName, appModuleName,
- appModuleScope, entrypointLibraryName,
- oldModuleScope: oldAppModuleScope));
-
- await buildStep.writeAsString(bootstrapId, bootstrapContent.toString());
-
- var entrypointJsContent = _entryPointJs(bootstrapModuleName);
- await buildStep.writeAsString(
- dartEntrypointId.changeExtension(jsEntrypointExtension),
- entrypointJsContent);
-
- // Output the digests for transitive modules.
- // These can be consumed for hot reloads.
- var moduleDigests = <String, String>{
- for (var jsId in transitiveJsModules)
- _moduleDigestKey(jsId): '${await buildStep.digest(jsId)}',
- };
- await buildStep.writeAsString(appDigestsOutput, jsonEncode(moduleDigests));
-}
-
-String _moduleDigestKey(AssetId jsId) =>
- '${ddcModuleName(jsId)}$jsModuleExtension';
-
-final _lazyBuildPool = Pool(16);
-
-/// Ensures that all transitive js modules for [module] are available and built.
-///
-/// Throws an [UnsupportedModules] exception if there are any
-/// unsupported modules.
-Future<List<AssetId>> _ensureTransitiveJsModules(
- Module module, BuildStep buildStep,
- {@required bool skipPlatformCheck,
- @required Set<String> skipPlatformCheckPackages}) async {
- // Collect all the modules this module depends on, plus this module.
- var transitiveDeps = await module.computeTransitiveDependencies(buildStep,
- throwIfUnsupported: !skipPlatformCheck,
- // ignore: deprecated_member_use
- skipPlatformCheckPackages: skipPlatformCheckPackages);
-
- var jsModules = [
- module.primarySource.changeExtension(jsModuleExtension),
- for (var dep in transitiveDeps)
- dep.primarySource.changeExtension(jsModuleExtension),
- ];
- // Check that each module is readable, and warn otherwise.
- await Future.wait(jsModules.map((jsId) async {
- if (await _lazyBuildPool.withResource(() => buildStep.canRead(jsId))) {
- return;
- }
- var errorsId = jsId.addExtension('.errors');
- await buildStep.canRead(errorsId);
- log.warning('Unable to read $jsId, check your console or the '
- '`.dart_tool/build/generated/${errorsId.package}/${errorsId.path}` '
- 'log file.');
- }));
- return jsModules;
-}
-
-/// Code that actually imports the [moduleName] module, and calls the
-/// `[moduleScope].main()` function on it.
-///
-/// Also performs other necessary initialization.
-String _appBootstrap(String bootstrapModuleName, String moduleName,
- String moduleScope, String entrypointLibraryName,
- {String oldModuleScope}) =>
- '''
-define("$bootstrapModuleName", ["$moduleName", "dart_sdk"], function(app, dart_sdk) {
- dart_sdk.dart.setStartAsyncSynchronously(true);
- dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
- $_initializeTools
- $_mainExtensionMarker
- (app.$moduleScope || app.$oldModuleScope).main();
- var bootstrap = {
- hot\$onChildUpdate: function(childName, child) {
- // Special handling for the multi-root scheme uris. We need to strip
- // out the scheme and the top level directory, to match the source path
- // that chrome sees.
- if (childName.startsWith('$multiRootScheme:///')) {
- childName = childName.substring('$multiRootScheme:///'.length);
- var firstSlash = childName.indexOf('/');
- if (firstSlash == -1) return false;
- childName = childName.substring(firstSlash + 1);
- }
- if (childName === "$entrypointLibraryName") {
- // Clear static caches.
- dart_sdk.dart.hotRestart();
- child.main();
- return true;
- }
- }
- }
- dart_sdk.dart.trackLibraries("$bootstrapModuleName", {
- "$bootstrapModuleName": bootstrap
- }, '');
- return {
- bootstrap: bootstrap
- };
-});
-})();
-''';
-
-/// The actual entrypoint JS file which injects all the necessary scripts to
-/// run the app.
-String _entryPointJs(String bootstrapModuleName) => '''
-(function() {
- $_currentDirectoryScript
- $_baseUrlScript
-
- var mapperUri = baseUrl + "packages/build_web_compilers/src/" +
- "dev_compiler_stack_trace/stack_trace_mapper.dart.js";
- var requireUri = baseUrl +
- "packages/build_web_compilers/src/dev_compiler/require.js";
- var mainUri = _currentDirectory + "$bootstrapModuleName";
-
- if (typeof document != 'undefined') {
- var el = document.createElement("script");
- el.defer = true;
- el.async = false;
- el.src = mapperUri;
- document.head.appendChild(el);
-
- el = document.createElement("script");
- el.defer = true;
- el.async = false;
- el.src = requireUri;
- el.setAttribute("data-main", mainUri);
- document.head.appendChild(el);
- } else {
- importScripts(mapperUri, requireUri);
- require.config({
- baseUrl: baseUrl,
- });
- // TODO: update bootstrap code to take argument - dart-lang/build#1115
- window = self;
- require([mainUri + '.js']);
- }
-})();
-''';
-
-/// JavaScript snippet to determine the directory a script was run from.
-final _currentDirectoryScript = r'''
-var _currentDirectory = (function () {
- var _url;
- var lines = new Error().stack.split('\n');
- function lookupUrl() {
- if (lines.length > 2) {
- var match = lines[1].match(/^\s+at (.+):\d+:\d+$/);
- // Chrome.
- if (match) return match[1];
- // Chrome nested eval case.
- match = lines[1].match(/^\s+at eval [(](.+):\d+:\d+[)]$/);
- if (match) return match[1];
- // Edge.
- match = lines[1].match(/^\s+at.+\((.+):\d+:\d+\)$/);
- if (match) return match[1];
- // Firefox.
- match = lines[0].match(/[<][@](.+):\d+:\d+$/)
- if (match) return match[1];
- }
- // Safari.
- return lines[0].match(/(.+):\d+:\d+$/)[1];
- }
- _url = lookupUrl();
- var lastSlash = _url.lastIndexOf('/');
- if (lastSlash == -1) return _url;
- var currentDirectory = _url.substring(0, lastSlash + 1);
- return currentDirectory;
-})();
-''';
-
-/// Sets up `window.$dartLoader` based on [modulePaths].
-String _dartLoaderSetup(Map<String, String> modulePaths, String appDigests) =>
- '''
-$_currentDirectoryScript
-$_baseUrlScript
-let modulePaths = ${const JsonEncoder.withIndent(" ").convert(modulePaths)};
-if(!window.\$dartLoader) {
- window.\$dartLoader = {
- appDigests: _currentDirectory + '$appDigests',
- moduleIdToUrl: new Map(),
- urlToModuleId: new Map(),
- rootDirectories: new Array(),
- // Used in package:build_runner/src/server/build_updates_client/hot_reload_client.dart
- moduleParentsGraph: new Map(),
- moduleLoadingErrorCallbacks: new Map(),
- forceLoadModule: function (moduleName, callback, onError) {
- // dartdevc only strips the final extension when adding modules to source
- // maps, so we need to do the same.
- if (moduleName.endsWith('$_modulePartialExtension')) {
- moduleName = moduleName.substring(0, moduleName.length - ${_modulePartialExtension.length});
- }
- if (typeof onError != 'undefined') {
- var errorCallbacks = \$dartLoader.moduleLoadingErrorCallbacks;
- if (!errorCallbacks.has(moduleName)) {
- errorCallbacks.set(moduleName, new Set());
- }
- errorCallbacks.get(moduleName).add(onError);
- }
- requirejs.undef(moduleName);
- requirejs([moduleName], function() {
- if (typeof onError != 'undefined') {
- errorCallbacks.get(moduleName).delete(onError);
- }
- if (typeof callback != 'undefined') {
- callback();
- }
- });
- },
- getModuleLibraries: null, // set up by _initializeTools
- };
-}
-let customModulePaths = {};
-window.\$dartLoader.rootDirectories.push(window.location.origin + baseUrl);
-for (let moduleName of Object.getOwnPropertyNames(modulePaths)) {
- let modulePath = modulePaths[moduleName];
- if (modulePath != moduleName) {
- customModulePaths[moduleName] = modulePath;
- }
- var src = window.location.origin + '/' + modulePath + '.js';
- if (window.\$dartLoader.moduleIdToUrl.has(moduleName)) {
- continue;
- }
- \$dartLoader.moduleIdToUrl.set(moduleName, src);
- \$dartLoader.urlToModuleId.set(src, moduleName);
-}
-''';
-
-/// Code to initialize the dev tools formatter, stack trace mapper, and any
-/// other tools.
-///
-/// Posts a message to the window when done.
-final _initializeTools = '''
-$_baseUrlScript
- dart_sdk._debugger.registerDevtoolsFormatter();
- \$dartLoader.getModuleLibraries = dart_sdk.dart.getModuleLibraries;
- if (window.\$dartStackTraceUtility && !window.\$dartStackTraceUtility.ready) {
- window.\$dartStackTraceUtility.ready = true;
- let dart = dart_sdk.dart;
- window.\$dartStackTraceUtility.setSourceMapProvider(
- function(url) {
- url = url.replace(baseUrl, '/');
- var module = window.\$dartLoader.urlToModuleId.get(url);
- if (!module) return null;
- return dart.getSourceMap(module);
- });
- }
- if (typeof document != 'undefined') {
- window.postMessage({ type: "DDC_STATE_CHANGE", state: "start" }, "*");
- }
-''';
-
-/// Require JS config for ddc.
-///
-/// Sets the base url to `/` so that all modules can be loaded using absolute
-/// paths which simplifies a lot of scenarios.
-///
-/// Sets the timeout for loading modules to infinity (0).
-///
-/// Sets up the custom module paths.
-///
-/// Adds error handler code for require.js which requests a `.errors` file for
-/// any failed module, and logs it to the console.
-final _requireJsConfig = '''
-// Whenever we fail to load a JS module, try to request the corresponding
-// `.errors` file, and log it to the console.
-(function() {
- var oldOnError = requirejs.onError;
- requirejs.onError = function(e) {
- if (e.requireModules) {
- if (e.message) {
- // If error occurred on loading dependencies, we need to invalidate ancessor too.
- var ancesor = e.message.match(/needed by: (.*)/);
- if (ancesor) {
- e.requireModules.push(ancesor[1]);
- }
- }
- for (const module of e.requireModules) {
- var errorCallbacks = \$dartLoader.moduleLoadingErrorCallbacks.get(module);
- if (errorCallbacks) {
- for (const callback of errorCallbacks) callback(e);
- errorCallbacks.clear();
- }
- }
- }
- if (e.originalError && e.originalError.srcElement) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function() {
- if (this.readyState == 4) {
- var message;
- if (this.status == 200) {
- message = this.responseText;
- } else {
- message = "Unknown error loading " + e.originalError.srcElement.src;
- }
- console.error(message);
- var errorEvent = new CustomEvent(
- 'dartLoadException', { detail: message });
- window.dispatchEvent(errorEvent);
- }
- };
- xhr.open("GET", e.originalError.srcElement.src + ".errors", true);
- xhr.send();
- }
- // Also handle errors the normal way.
- if (oldOnError) oldOnError(e);
- };
-}());
-
-$_baseUrlScript;
-
-require.config({
- baseUrl: baseUrl,
- waitSeconds: 0,
- paths: customModulePaths
-});
-
-const modulesGraph = new Map();
-function getRegisteredModuleName(moduleMap) {
- if (\$dartLoader.moduleIdToUrl.has(moduleMap.name + '$_modulePartialExtension')) {
- return moduleMap.name + '$_modulePartialExtension';
- }
- return moduleMap.name;
-}
-requirejs.onResourceLoad = function (context, map, depArray) {
- const name = getRegisteredModuleName(map);
- const depNameArray = depArray.map(getRegisteredModuleName);
- if (modulesGraph.has(name)) {
- // TODO Move this logic to better place
- var previousDeps = modulesGraph.get(name);
- var changed = previousDeps.length != depNameArray.length;
- changed = changed || depNameArray.some(function(depName) {
- return !previousDeps.includes(depName);
- });
- if (changed) {
- console.warn("Dependencies graph change for module '" + name + "' detected. " +
- "Dependencies was [" + previousDeps + "], now [" + depNameArray.map((depName) => depName) +"]. " +
- "Page can't be hot-reloaded, firing full page reload.");
- window.location.reload();
- }
- } else {
- modulesGraph.set(name, []);
- for (const depName of depNameArray) {
- if (!\$dartLoader.moduleParentsGraph.has(depName)) {
- \$dartLoader.moduleParentsGraph.set(depName, []);
- }
- \$dartLoader.moduleParentsGraph.get(depName).push(name);
- modulesGraph.get(name).push(depName);
- }
- }
-};
-''';
-
-/// Marker comment used by tools to identify the entrypoint file,
-/// to inject custom code.
-final _entrypointExtensionMarker = '/* ENTRYPOINT_EXTENTION_MARKER */';
-
-/// Marker comment used by tools to identify the main function
-/// to inject custom code.
-final _mainExtensionMarker = '/* MAIN_EXTENSION_MARKER */';
-
-final _baseUrlScript = '''
-var baseUrl = (function () {
- // Attempt to detect --precompiled mode for tests, and set the base url
- // appropriately, otherwise set it to '/'.
- var pathParts = location.pathname.split("/");
- if (pathParts[0] == "") {
- pathParts.shift();
- }
- if (pathParts.length > 1 && pathParts[1] == "test") {
- return "/" + pathParts.slice(0, 2).join("/") + "/";
- }
- // Attempt to detect base url using <base href> html tag
- // base href should start and end with "/"
- if (typeof document !== 'undefined') {
- var el = document.getElementsByTagName('base');
- if (el && el[0] && el[0].getAttribute("href") && el[0].getAttribute
- ("href").startsWith("/") && el[0].getAttribute("href").endsWith("/")){
- return el[0].getAttribute("href");
- }
- }
- // return default value
- return "/";
-}());
-''';
-
-/// Ensures that all of [resources] are built successfully, and adds them as
-/// an input dependency to this action.
-///
-/// This also has the effect of ensuring these resources are present whenever
-/// a DDC app is built - reducing the need to explicitly list these files as
-/// build filters.
-Future<void> _ensureResources(
- BuildStep buildStep, Iterable<AssetId> resources) async {
- for (var resource in resources) {
- if (!await buildStep.canRead(resource)) {
- throw StateError('Unable to locate required sdk resource $resource');
- }
- }
-}
diff --git a/build_web_compilers/lib/src/dev_compiler_builder.dart b/build_web_compilers/lib/src/dev_compiler_builder.dart
deleted file mode 100644
index b2809ee..0000000
--- a/build_web_compilers/lib/src/dev_compiler_builder.dart
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2017, 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:convert';
-import 'dart:io';
-
-import 'package:bazel_worker/bazel_worker.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-import 'package:meta/meta.dart';
-import 'package:path/path.dart' as p;
-import 'package:scratch_space/scratch_space.dart';
-
-import '../builders.dart';
-import 'common.dart';
-import 'errors.dart';
-
-const jsModuleErrorsExtension = '.ddc.js.errors';
-const jsModuleExtension = '.ddc.js';
-const jsSourceMapExtension = '.ddc.js.map';
-
-/// A builder which can output ddc modules!
-class DevCompilerBuilder implements Builder {
- final bool useIncrementalCompiler;
-
- final bool trackUnusedInputs;
-
- final DartPlatform platform;
-
- /// The sdk kernel file for the current platform.
- final String sdkKernelPath;
-
- /// The root directory of the platform's dart SDK.
- ///
- /// If not provided, defaults to the directory of
- /// [Platform.resolvedExecutable].
- ///
- /// On flutter this is the path to the root of the flutter_patched_sdk
- /// directory, which contains the platform kernel files.
- final String platformSdk;
-
- /// The absolute path to the libraries file for the current platform.
- ///
- /// If not provided, defaults to "lib/libraries.json" in the sdk directory.
- final String librariesPath;
-
- /// Environment defines to pass to ddc (as -D variables).
- final Map<String, String> environment;
-
- /// Experiments to pass to ddc (as --enable-experiment=<experiment> args).
- final Iterable<String> experiments;
-
- DevCompilerBuilder(
- {bool useIncrementalCompiler,
- bool trackUnusedInputs,
- @required this.platform,
- this.sdkKernelPath,
- String librariesPath,
- String platformSdk,
- Map<String, String> environment,
- Iterable<String> experiments})
- : useIncrementalCompiler = useIncrementalCompiler ?? true,
- platformSdk = platformSdk ?? sdkDir,
- librariesPath = librariesPath ??
- p.join(platformSdk ?? sdkDir, 'lib', 'libraries.json'),
- trackUnusedInputs = trackUnusedInputs ?? false,
- buildExtensions = {
- moduleExtension(platform): [
- jsModuleExtension,
- jsModuleErrorsExtension,
- jsSourceMapExtension
- ],
- },
- environment = environment ?? {},
- experiments = experiments ?? {};
-
- @override
- final Map<String, List<String>> buildExtensions;
-
- @override
- Future build(BuildStep buildStep) async {
- var module = Module.fromJson(
- json.decode(await buildStep.readAsString(buildStep.inputId))
- as Map<String, dynamic>);
- // Entrypoints always have a `.module` file for ease of looking them up,
- // but they might not be the primary source.
- if (module.primarySource.changeExtension(moduleExtension(platform)) !=
- buildStep.inputId) {
- return;
- }
-
- Future<void> handleError(e) async {
- await buildStep.writeAsString(
- module.primarySource.changeExtension(jsModuleErrorsExtension), '$e');
- log.severe('$e');
- }
-
- try {
- await _createDevCompilerModule(
- module,
- buildStep,
- useIncrementalCompiler,
- trackUnusedInputs,
- platformSdk,
- sdkKernelPath,
- librariesPath,
- environment,
- experiments);
- } on DartDevcCompilationException catch (e) {
- await handleError(e);
- } on MissingModulesException catch (e) {
- await handleError(e);
- }
- }
-}
-
-/// Compile [module] with the dev compiler.
-Future<void> _createDevCompilerModule(
- Module module,
- BuildStep buildStep,
- bool useIncrementalCompiler,
- bool trackUnusedInputs,
- String dartSdk,
- String sdkKernelPath,
- String librariesPath,
- Map<String, String> environment,
- Iterable<String> experiments,
- {bool debugMode = true}) async {
- var transitiveDeps = await buildStep.trackStage('CollectTransitiveDeps',
- () => module.computeTransitiveDependencies(buildStep));
- var transitiveKernelDeps = [
- for (var dep in transitiveDeps)
- dep.primarySource.changeExtension(ddcKernelExtension)
- ];
- var scratchSpace = await buildStep.fetchResource(scratchSpaceResource);
-
- var allAssetIds = <AssetId>{...module.sources, ...transitiveKernelDeps};
- await buildStep.trackStage(
- 'EnsureAssets', () => scratchSpace.ensureAssets(allAssetIds, buildStep));
- var jsId = module.primarySource.changeExtension(jsModuleExtension);
- var jsOutputFile = scratchSpace.fileFor(jsId);
- var sdkSummary =
- p.url.join(dartSdk, sdkKernelPath ?? 'lib/_internal/ddc_sdk.dill');
-
- // Maps the inputs paths we provide to the ddc worker to asset ids, if
- // `trackUnusedInputs` is `true`.
- Map<String, AssetId> kernelInputPathToId;
- // If `trackUnusedInputs` is `true`, this is the file we will use to
- // communicate the used inputs with the ddc worker.
- File usedInputsFile;
-
- if (trackUnusedInputs) {
- usedInputsFile = await File(p.join(
- (await Directory.systemTemp.createTemp('ddk_builder_')).path,
- 'used_inputs.txt'))
- .create();
- kernelInputPathToId = {};
- }
-
- var packagesFile = await createPackagesFile(allAssetIds);
- var request = WorkRequest()
- ..arguments.addAll([
- '--dart-sdk-summary=$sdkSummary',
- '--modules=amd',
- '--no-summarize',
- '-o',
- jsOutputFile.path,
- debugMode ? '--source-map' : '--no-source-map',
- for (var dep in transitiveDeps) _summaryArg(dep),
- '--packages=${packagesFile.absolute.uri}',
- '--module-name=${ddcModuleName(jsId)}',
- '--multi-root-scheme=$multiRootScheme',
- '--multi-root=.',
- '--track-widget-creation',
- '--inline-source-map',
- '--libraries-file=${p.toUri(librariesPath)}',
- if (useIncrementalCompiler) ...[
- '--reuse-compiler-result',
- '--use-incremental-compiler',
- ],
- if (usedInputsFile != null)
- '--used-inputs-file=${usedInputsFile.uri.toFilePath()}',
- for (var source in module.sources) _sourceArg(source),
- for (var define in environment.entries) '-D${define.key}=${define.value}',
- for (var experiment in experiments) '--enable-experiment=$experiment',
- ])
- ..inputs.add(Input()
- ..path = sdkSummary
- ..digest = [0])
- ..inputs.addAll(await Future.wait(transitiveKernelDeps.map((dep) async {
- var file = scratchSpace.fileFor(dep);
- if (kernelInputPathToId != null) {
- kernelInputPathToId[file.uri.toString()] = dep;
- }
- return Input()
- ..path = file.path
- ..digest = (await buildStep.digest(dep)).bytes;
- })));
-
- try {
- var driverResource = dartdevkDriverResource;
- var driver = await buildStep.fetchResource(driverResource);
- var response = await driver.doWork(request,
- trackWork: (response) =>
- buildStep.trackStage('Compile', () => response, isExternal: true));
-
- // TODO(jakemac53): Fix the ddc worker mode so it always sends back a bad
- // status code if something failed. Today we just make sure there is an output
- // JS file to verify it was successful.
- var message = response.output
- .replaceAll('${scratchSpace.tempDir.path}/', '')
- .replaceAll('$multiRootScheme:///', '');
- if (response.exitCode != EXIT_CODE_OK ||
- !jsOutputFile.existsSync() ||
- message.contains('Error:')) {
- throw DartDevcCompilationException(jsId, message);
- }
-
- if (message.isNotEmpty) {
- log.info('\n$message');
- }
-
- // Copy the output back using the buildStep.
- await scratchSpace.copyOutput(jsId, buildStep);
- if (debugMode) {
- // We need to modify the sources in the sourcemap to remove the custom
- // `multiRootScheme` that we use.
- var sourceMapId =
- module.primarySource.changeExtension(jsSourceMapExtension);
- var file = scratchSpace.fileFor(sourceMapId);
- var content = await file.readAsString();
- var json = jsonDecode(content);
- json['sources'] = fixSourceMapSources((json['sources'] as List).cast());
- await buildStep.writeAsString(sourceMapId, jsonEncode(json));
- }
-
- // Note that we only want to do this on success, we can't trust the unused
- // inputs if there is a failure.
- if (usedInputsFile != null) {
- await reportUnusedKernelInputs(
- usedInputsFile, transitiveKernelDeps, kernelInputPathToId, buildStep);
- }
- } finally {
- await packagesFile.parent.delete(recursive: true);
- await usedInputsFile?.parent?.delete(recursive: true);
- }
-}
-
-/// Returns the `--summary=` argument for a dependency.
-String _summaryArg(Module module) {
- final kernelAsset = module.primarySource.changeExtension(ddcKernelExtension);
- final moduleName =
- ddcModuleName(module.primarySource.changeExtension(jsModuleExtension));
- return '--summary=${scratchSpace.fileFor(kernelAsset).path}=$moduleName';
-}
-
-/// The url to compile for a source.
-///
-/// Use the package: path for files under lib and the full absolute path for
-/// other files.
-String _sourceArg(AssetId id) {
- var uri = canonicalUriFor(id);
- return uri.startsWith('package:') ? uri : '$multiRootScheme:///${id.path}';
-}
-
-/// Copied to `web/stack_trace_mapper.dart`, these need to be kept in sync.
-///
-/// Given a list of [uris] as [String]s from a sourcemap, fixes them up so that
-/// they make sense in a browser context.
-///
-/// - Strips the scheme from the uri
-/// - Strips the top level directory if its not `packages`
-List<String> fixSourceMapSources(List<String> uris) {
- return uris.map((source) {
- var uri = Uri.parse(source);
- // We only want to rewrite multi-root scheme uris.
- if (uri.scheme.isEmpty) return source;
- var newSegments = uri.pathSegments.first == 'packages'
- ? uri.pathSegments
- : uri.pathSegments.skip(1);
- return Uri(path: p.url.joinAll(['/'].followedBy(newSegments))).toString();
- }).toList();
-}
-
-/// The module name according to ddc for [jsId] which represents the real js
-/// module file.
-String ddcModuleName(AssetId jsId) {
- var jsPath = jsId.path.startsWith('lib/')
- ? jsId.path.replaceFirst('lib/', 'packages/${jsId.package}/')
- : jsId.path;
- return jsPath.substring(0, jsPath.length - jsModuleExtension.length);
-}
diff --git a/build_web_compilers/lib/src/errors.dart b/build_web_compilers/lib/src/errors.dart
deleted file mode 100644
index 9c63746..0000000
--- a/build_web_compilers/lib/src/errors.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2017, 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:build/build.dart';
-
-/// An [Exception] that is thrown when a worker returns an error.
-abstract class _WorkerException implements Exception {
- final AssetId failedAsset;
-
- final String error;
-
- /// A message to prepend to [toString] output.
- String get message;
-
- _WorkerException(this.failedAsset, this.error);
-
- @override
- String toString() => '$message:$failedAsset\n\n$error';
-}
-
-/// An [Exception] that is thrown when dartdevc compilation fails.
-class DartDevcCompilationException extends _WorkerException {
- @override
- final String message = 'Error compiling dartdevc module';
-
- DartDevcCompilationException(AssetId jsId, String error) : super(jsId, error);
-}
diff --git a/build_web_compilers/lib/src/platforms.dart b/build_web_compilers/lib/src/platforms.dart
deleted file mode 100644
index 4722b46..0000000
--- a/build_web_compilers/lib/src/platforms.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2019, 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:build_modules/build_modules.dart';
-
-final ddcPlatform = DartPlatform.register('ddc', [
- 'async',
- 'collection',
- 'convert',
- 'core',
- 'developer',
- 'html',
- 'html_common',
- 'indexed_db',
- 'js',
- 'js_util',
- 'math',
- 'svg',
- 'typed_data',
- 'web_audio',
- 'web_gl',
- 'web_sql',
- '_internal',
-]);
-
-final dart2jsPlatform = DartPlatform.register('dart2js', [
- 'async',
- 'collection',
- 'convert',
- 'core',
- 'developer',
- 'html',
- 'html_common',
- 'indexed_db',
- 'js',
- 'js_util',
- 'math',
- 'svg',
- 'typed_data',
- 'web_audio',
- 'web_gl',
- 'web_sql',
- '_internal',
-]);
diff --git a/build_web_compilers/lib/src/sdk_js_copy_builder.dart b/build_web_compilers/lib/src/sdk_js_copy_builder.dart
deleted file mode 100644
index a2579b1..0000000
--- a/build_web_compilers/lib/src/sdk_js_copy_builder.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2019, 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 'package:build/build.dart';
-import 'package:path/path.dart' as p;
-
-import 'common.dart';
-
-/// Copies the dart_sdk.js and require.js files from the sdk itself, into the
-/// build_web_compilers package at `lib/dart_sdk.js` and `lib/require.js`.
-class SdkJsCopyBuilder implements Builder {
- @override
- final buildExtensions = {
- r'$lib$': ['src/dev_compiler/dart_sdk.js', 'src/dev_compiler/require.js']
- };
-
- /// Path to the dart_sdk.js file that should be used for all ddc web apps.
- final _sdkJsLocation =
- p.join(sdkDir, 'lib', 'dev_compiler', 'kernel', 'amd', 'dart_sdk.js');
-
- /// Path to the require.js file that should be used for all ddc web apps.
- final _sdkRequireJsLocation =
- p.join(sdkDir, 'lib', 'dev_compiler', 'kernel', 'amd', 'require.js');
-
- @override
- FutureOr<void> build(BuildStep buildStep) async {
- if (buildStep.inputId.package != 'build_web_compilers') {
- throw StateError('This builder should only be applied to the '
- 'build_web_compilers package');
- }
- await buildStep.writeAsBytes(
- AssetId('build_web_compilers', 'lib/src/dev_compiler/dart_sdk.js'),
- await File(_sdkJsLocation).readAsBytes());
- await buildStep.writeAsBytes(
- AssetId('build_web_compilers', 'lib/src/dev_compiler/require.js'),
- await File(_sdkRequireJsLocation).readAsBytes());
- }
-}
diff --git a/build_web_compilers/lib/src/web_entrypoint_builder.dart b/build_web_compilers/lib/src/web_entrypoint_builder.dart
deleted file mode 100644
index 5c1c2a3..0000000
--- a/build_web_compilers/lib/src/web_entrypoint_builder.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2017, 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';
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart';
-import 'package:build/build.dart';
-import 'package:build_modules/build_modules.dart';
-
-import 'common.dart';
-import 'dart2js_bootstrap.dart';
-import 'dev_compiler_bootstrap.dart';
-
-const ddcBootstrapExtension = '.dart.bootstrap.js';
-const jsEntrypointExtension = '.dart.js';
-const jsEntrypointSourceMapExtension = '.dart.js.map';
-const jsEntrypointArchiveExtension = '.dart.js.tar.gz';
-const digestsEntrypointExtension = '.digests';
-
-/// Which compiler to use when compiling web entrypoints.
-enum WebCompiler {
- Dart2Js,
- DartDevc,
-}
-
-/// The top level keys supported for the `options` config for the
-/// [WebEntrypointBuilder].
-const _supportedOptions = [
- _compiler,
- _dart2jsArgs,
-];
-
-const _compiler = 'compiler';
-const _dart2jsArgs = 'dart2js_args';
-
-/// The deprecated keys for the `options` config for the [WebEntrypointBuilder].
-const _deprecatedOptions = [
- 'enable_sync_async',
- 'ignore_cast_failures',
-];
-
-/// A builder which compiles entrypoints for the web.
-///
-/// Supports `dart2js` and `dartdevc`.
-class WebEntrypointBuilder implements Builder {
- final WebCompiler webCompiler;
- final List<String> dart2JsArgs;
-
- const WebEntrypointBuilder(this.webCompiler, {this.dart2JsArgs = const []});
-
- factory WebEntrypointBuilder.fromOptions(BuilderOptions options) {
- validateOptions(
- options.config, _supportedOptions, 'build_web_compilers|entrypoint',
- deprecatedOptions: _deprecatedOptions);
- var compilerOption = options.config[_compiler] as String ?? 'dartdevc';
- WebCompiler compiler;
- switch (compilerOption) {
- case 'dartdevc':
- compiler = WebCompiler.DartDevc;
- break;
- case 'dart2js':
- compiler = WebCompiler.Dart2Js;
- break;
- default:
- throw ArgumentError.value(compilerOption, _compiler,
- 'Only `dartdevc` and `dart2js` are supported.');
- }
-
- if (options.config[_dart2jsArgs] is! List) {
- throw ArgumentError.value(options.config[_dart2jsArgs], _dart2jsArgs,
- 'Expected a list for $_dart2jsArgs.');
- }
- var dart2JsArgs = (options.config[_dart2jsArgs] as List)
- ?.map((arg) => '$arg')
- ?.toList() ??
- const <String>[];
-
- return WebEntrypointBuilder(compiler, dart2JsArgs: dart2JsArgs);
- }
-
- @override
- final buildExtensions = const {
- '.dart': [
- ddcBootstrapExtension,
- jsEntrypointExtension,
- jsEntrypointSourceMapExtension,
- jsEntrypointArchiveExtension,
- digestsEntrypointExtension,
- ],
- };
-
- @override
- Future<void> build(BuildStep buildStep) async {
- var dartEntrypointId = buildStep.inputId;
- var isAppEntrypoint = await _isAppEntryPoint(dartEntrypointId, buildStep);
- if (!isAppEntrypoint) return;
- if (webCompiler == WebCompiler.DartDevc) {
- try {
- await bootstrapDdc(buildStep, requiredAssets: _ddcSdkResources);
- } on MissingModulesException catch (e) {
- log.severe('$e');
- }
- } else if (webCompiler == WebCompiler.Dart2Js) {
- await bootstrapDart2Js(buildStep, dart2JsArgs);
- }
- }
-}
-
-/// Returns whether or not [dartId] is an app entrypoint (basically, whether
-/// or not it has a `main` function).
-Future<bool> _isAppEntryPoint(AssetId dartId, AssetReader reader) async {
- assert(dartId.extension == '.dart');
- // Skip reporting errors here, dartdevc will report them later with nicer
- // formatting.
- // ignore: deprecated_member_use
- var parsed = parseCompilationUnit(await reader.readAsString(dartId),
- suppressErrors: true);
- // Allow two or fewer arguments so that entrypoints intended for use with
- // [spawnUri] get counted.
- //
- // TODO: This misses the case where a Dart file doesn't contain main(),
- // but has a part that does, or it exports a `main` from another library.
- return parsed.declarations.any((node) {
- return node is FunctionDeclaration &&
- node.name.name == 'main' &&
- node.functionExpression.parameters.parameters.length <= 2;
- });
-}
-
-/// Files copied from the SDK that are required at runtime to run a DDC
-/// application.
-final _ddcSdkResources = [
- AssetId('build_web_compilers', 'lib/src/dev_compiler/dart_sdk.js'),
- AssetId('build_web_compilers', 'lib/src/dev_compiler/require.js'),
-];
diff --git a/build_web_compilers/mono_pkg.yaml b/build_web_compilers/mono_pkg.yaml
deleted file mode 100644
index bae55f2..0000000
--- a/build_web_compilers/mono_pkg.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.5.0
- - unit_test:
- - group:
- - test:
- os:
- - linux
- - windows
\ No newline at end of file
diff --git a/build_web_compilers/pubspec.yaml b/build_web_compilers/pubspec.yaml
deleted file mode 100644
index 40aa3d6..0000000
--- a/build_web_compilers/pubspec.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: build_web_compilers
-version: 2.9.0
-description: Builder implementations wrapping Dart compilers.
-homepage: https://github.com/dart-lang/build/tree/master/build_web_compilers
-
-environment:
- sdk: ">=2.5.0 <3.0.0"
-
-dependencies:
- analyzer: ">=0.30.0 <0.40.0"
- archive: ^2.0.0
- bazel_worker: ^0.1.18
- build: ">=1.2.0 <2.0.0"
- build_config: ">=0.3.0 <0.5.0"
- build_modules: ^2.8.0
- collection: ^1.0.0
- crypto: ^2.0.0
- glob: ^1.1.0
- js: ^0.6.1
- logging: ^0.11.2
- meta: ^1.1.0
- path: ^1.4.2
- pool: ^1.3.0
- scratch_space: ^0.0.2
- source_maps: ^0.10.4
- source_span: ^1.4.0
- stack_trace: ^1.9.2
-
-dev_dependencies:
- build_runner: ^1.0.0
- build_test: ^0.10.9
- test: ^1.0.0
- a:
- path: test/fixtures/a
- b:
- path: test/fixtures/b
diff --git a/build_web_compilers/tool/copy_builder.dart b/build_web_compilers/tool/copy_builder.dart
deleted file mode 100644
index 1191a9d..0000000
--- a/build_web_compilers/tool/copy_builder.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2019, 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:build/build.dart';
-
-/// Factory for the build script.
-Builder copyBuilder(_) => _CopyBuilder();
-
-/// Copies the [_stackTraceMapperJs] file to [_stackTraceMapperCopyJs].
-class _CopyBuilder extends Builder {
- @override
- final Map<String, List<String>> buildExtensions = {
- _stackTraceMapperJs.path: [_stackTraceMapperCopyJs.path]
- };
-
- @override
- void build(BuildStep buildStep) {
- if (buildStep.inputId != _stackTraceMapperJs) {
- throw StateError(
- 'Unexpected input for `CopyBuilder` expected only $_stackTraceMapperJs');
- }
- buildStep.writeAsString(
- _stackTraceMapperCopyJs, buildStep.readAsString(_stackTraceMapperJs));
- }
-}
-
-final _stackTraceMapperJs =
- AssetId('build_web_compilers', 'web/stack_trace_mapper.dart.js');
-final _stackTraceMapperCopyJs = AssetId('build_web_compilers',
- 'lib/src/dev_compiler_stack_trace/stack_trace_mapper.dart.js');
diff --git a/build_web_compilers/web/source_map_stack_trace.dart b/build_web_compilers/web/source_map_stack_trace.dart
deleted file mode 100644
index b231ef4..0000000
--- a/build_web_compilers/web/source_map_stack_trace.dart
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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.
-
-/// Standalone utility that manages loading source maps for all Dart scripts
-/// on the page compiled with DDC.
-///
-/// This is forked from the equivalent file that ships with the SDK which is
-/// intended for use within bazel only.
-
-import 'package:path/path.dart' as p;
-import 'package:source_maps/source_maps.dart';
-import 'package:stack_trace/stack_trace.dart';
-
-/// TODO(jakemac): Remove after https://github.com/dart-lang/build/issues/2219
-void main() {}
-
-/// Convert [stackTrace], a stack trace generated by DDC-compiled
-/// JavaScript, to a native-looking stack trace using [sourceMap].
-///
-/// [roots] are the paths (usually `http:` URI strings) that DDC applications
-/// are served from. This is used to identify sdk and package URIs.
-StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
- {List<String> roots}) {
- if (stackTrace is Chain) {
- return Chain(stackTrace.traces.map(
- (trace) => Trace.from(mapStackTrace(sourceMap, trace, roots: roots))));
- }
-
- var trace = Trace.from(stackTrace);
- return Trace(trace.frames.map((frame) {
- // If there's no line information, there's no way to translate this frame.
- // We could return it as-is, but these lines are usually not useful anyways.
- if (frame.line == null) return null;
-
- // If there's no column, try using the first column of the line.
- var column = frame.column ?? 0;
-
- // Subtract 1 because stack traces use 1-indexed lines and columns and
- // source maps uses 0-indexed.
- var span = sourceMap.spanFor(frame.line - 1, column - 1,
- uri: frame.uri?.toString());
-
- // If we can't find a source span, ignore the frame. It's probably something
- // internal that the user doesn't care about.
- if (span == null) return null;
-
- var sourceUrl = span.sourceUrl.toString();
- for (var root in roots) {
- if (root != null && p.url.isWithin(root, sourceUrl)) {
- var relative = p.url.relative(sourceUrl, from: root);
- if (relative.contains('dart:')) {
- sourceUrl = relative.substring(relative.indexOf('dart:'));
- break;
- }
- var packageRoot = '$root/packages';
- if (p.url.isWithin(packageRoot, sourceUrl)) {
- sourceUrl = 'package:' + p.url.relative(sourceUrl, from: packageRoot);
- break;
- }
- }
- }
-
- if (!sourceUrl.startsWith('dart:') &&
- sourceUrl ==
- 'package:build_web_compilers/src/dev_compiler/dart_sdk.js') {
- // This compresses the long dart_sdk URLs if SDK source maps are missing.
- // It's no longer linkable, but neither are the properly mapped ones
- // above.
- sourceUrl = 'dart:sdk_internal';
- }
-
- return Frame(Uri.parse(sourceUrl), span.start.line + 1,
- span.start.column + 1, _prettifyMember(frame.member));
- }).where((frame) => frame != null))
- .foldFrames((Frame frame) => frame.uri.scheme.contains('dart'));
-}
-
-final escapedPipe = '\$124';
-final escapedPound = '\$35';
-
-/// Reformats a JS member name to make it look more Dart-like.
-///
-/// TODO(https://github.com/dart-lang/sdk/issues/38869): Remove this logic when
-/// DDC stack trace deobfuscation is overhauled.
-String _prettifyMember(String member) {
- var last = member.lastIndexOf('.');
- if (last < 0) return member;
- var suffix = member.substring(last + 1);
- member = suffix == 'fn' ? member : suffix;
- // We avoid unescaping the entire member here due to DDC's deduping mechanism
- // introducing trailing $N.
- member = member.replaceAll(escapedPipe, '|');
- return member.contains('|') ? _prettifyExtension(member) : member;
-}
-
-/// Reformats a JS member name as an extension method invocation.
-String _prettifyExtension(String member) {
- var isSetter = false;
- var pipeIndex = member.indexOf('|');
- var spaceIndex = member.indexOf(' ');
- var poundIndex = member.indexOf('escapedPound');
- if (spaceIndex >= 0) {
- // Here member is a static field or static getter/setter.
- isSetter = member.substring(0, spaceIndex) == 'set';
- member = member.substring(spaceIndex + 1, member.length);
- } else if (poundIndex >= 0) {
- // Here member is a tearoff or local property getter/setter.
- isSetter = member.substring(pipeIndex + 1, poundIndex) == 'set';
- member = member.replaceRange(pipeIndex + 1, poundIndex + 3, '');
- } else {
- var body = member.substring(pipeIndex + 1, member.length);
- if (body.startsWith('unary') || body.startsWith('\$')) {
- // Here member's an operator, so it's safe to unescape everything lazily.
- member = _unescape(member);
- }
- }
- member = member.replaceAll('|', '.');
- return isSetter ? '$member=' : member;
-}
-
-/// Unescapes a DDC-escaped JS identifier name.
-///
-/// Identifier names that contain illegal JS characters are escaped by DDC to a
-/// decimal representation of the symbol's UTF-16 value.
-/// Warning: this greedily escapes characters, so it can be unsafe in the event
-/// that an escaped sequence precedes a number literal in the JS name.
-String _unescape(String name) {
- return name.replaceAllMapped(
- RegExp(r'\$[0-9]+'),
- (m) =>
- String.fromCharCode(int.parse(name.substring(m.start + 1, m.end))));
-}
diff --git a/build_web_compilers/web/stack_trace_mapper.dart b/build_web_compilers/web/stack_trace_mapper.dart
deleted file mode 100644
index 383fef2..0000000
--- a/build_web_compilers/web/stack_trace_mapper.dart
+++ /dev/null
@@ -1,141 +0,0 @@
-// 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.
-
-/// Standalone utility that manages loading source maps for all Dart scripts
-/// on the page compiled with DDC.
-///
-/// Example JavaScript usage:
-/// $dartStackTraceUtility.addLoadedListener(function() {
-/// // All Dart source maps are now loaded. It is now safe to start your
-/// // Dart application compiled with DDC.
-/// dart_library.start('your_dart_application');
-/// })
-///
-/// If $dartStackTraceUtility is set, the dart:core StackTrace class calls
-/// $dartStackTraceUtility.mapper(someJSStackTrace)
-/// to apply source maps.
-///
-/// This utility can be compiled to JavaScript using Dart2JS while the rest
-/// of the application is compiled with DDC or could be compiled with DDC.
-
-@JS()
-library stack_trace_mapper;
-
-import 'dart:convert';
-
-import 'package:js/js.dart';
-import 'package:path/path.dart' as p;
-import 'package:source_maps/source_maps.dart';
-import 'package:source_span/source_span.dart';
-import 'package:stack_trace/stack_trace.dart';
-
-import 'source_map_stack_trace.dart';
-
-/// Copied from `lib/src/dev_compiler_builder.dart`, these need to be kept in
-/// sync.
-///
-/// Given a list of [uris] as [String]s from a sourcemap, fixes them up so that
-/// they make sense in a browser context.
-///
-/// - Strips the scheme from the uri
-/// - Strips the top level directory if its not `packages`
-List<String> fixSourceMapSources(List<String> uris) {
- return uris.map((source) {
- var uri = Uri.parse(source);
- // We only want to rewrite multi-root scheme uris.
- if (uri.scheme.isEmpty) return source;
- var newSegments = uri.pathSegments.first == 'packages'
- ? uri.pathSegments
- : uri.pathSegments.skip(1);
- return Uri(path: p.url.joinAll(['/'].followedBy(newSegments))).toString();
- }).toList();
-}
-
-typedef ReadyCallback = void Function();
-
-/// Global object DDC uses to see if a stack trace utility has been registered.
-@JS(r'$dartStackTraceUtility')
-external set dartStackTraceUtility(DartStackTraceUtility value);
-
-@JS(r'$dartLoader.rootDirectories')
-external List get rootDirectories;
-
-typedef StackTraceMapper = String Function(String stackTrace);
-typedef SourceMapProvider = dynamic Function(String modulePath);
-typedef SetSourceMapProvider = void Function(SourceMapProvider provider);
-
-@JS()
-@anonymous
-class DartStackTraceUtility {
- external factory DartStackTraceUtility(
- {StackTraceMapper mapper, SetSourceMapProvider setSourceMapProvider});
-}
-
-/// Source mapping that waits to parse source maps until they match the uri
-/// of a requested source map.
-///
-/// This improves startup performance compared to using MappingBundle directly.
-/// The unparsed data for the source maps must still be loaded before
-/// LazyMapping is used.
-class LazyMapping extends Mapping {
- final _bundle = MappingBundle();
- final SourceMapProvider _provider;
-
- LazyMapping(this._provider);
-
- List toJson() => _bundle.toJson();
-
- @override
- SourceMapSpan spanFor(int line, int column,
- {Map<String, SourceFile> files, String uri}) {
- if (uri == null) {
- throw ArgumentError.notNull('uri');
- }
-
- if (!_bundle.containsMapping(uri)) {
- var rawMap = _provider(uri);
- var parsedMap = (rawMap is String ? jsonDecode(rawMap) : rawMap) as Map;
- if (parsedMap != null) {
- parsedMap['sources'] =
- fixSourceMapSources((parsedMap['sources'] as List).cast());
- var mapping = parse(jsonEncode(parsedMap)) as SingleMapping
- ..targetUrl = uri
- ..sourceRoot = '${p.dirname(uri)}/';
- _bundle.addMapping(mapping);
- }
- }
- var span = _bundle.spanFor(line, column, files: files, uri: uri);
- // TODO(jacobr): we shouldn't have to filter out invalid sourceUrl entries
- // here.
- if (span == null || span.start.sourceUrl == null) return null;
- var pathSegments = span.start.sourceUrl.pathSegments;
- if (pathSegments.isNotEmpty && pathSegments.last == 'null') return null;
- return span;
- }
-}
-
-LazyMapping _mapping;
-
-List<String> roots = rootDirectories.map((s) => '$s').toList();
-
-String mapper(String rawStackTrace) {
- if (_mapping == null) {
- // This should not happen if the user has waited for the ReadyCallback
- // to start the application.
- throw StateError('Source maps are not done loading.');
- }
- var trace = Trace.parse(rawStackTrace);
- return mapStackTrace(_mapping, trace, roots: roots).toString();
-}
-
-void setSourceMapProvider(SourceMapProvider provider) {
- _mapping = LazyMapping(provider);
-}
-
-void main() {
- // Register with DDC.
- dartStackTraceUtility = DartStackTraceUtility(
- mapper: allowInterop(mapper),
- setSourceMapProvider: allowInterop(setSourceMapProvider));
-}
diff --git a/code_builder/.gitignore b/code_builder/.gitignore
deleted file mode 100644
index feb089d..0000000
--- a/code_builder/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Files and directories created by pub
-.dart_tool
-.packages
-.pub
-pubspec.lock
diff --git a/code_builder/.travis.yml b/code_builder/.travis.yml
deleted file mode 100644
index e415dd4..0000000
--- a/code_builder/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: dart
-dart:
- - dev
- - 2.1.0
-
-cache:
- directories:
- - $HOME/.pub-cache
-
-dist: trusty
-addons:
- chrome: stable
-
-branches:
- only: [master]
-
-# TODO: Give up the dream of running with dartdevc until...
-# https://github.com/dart-lang/sdk/issues/31280
-
-dart_task:
- - test: --platform vm
- - dartanalyzer
- - dartfmt
diff --git a/code_builder/AUTHORS b/code_builder/AUTHORS
deleted file mode 100644
index 609e0dc..0000000
--- a/code_builder/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Below is a list of people and organizations that have contributed
-# to the project. Names should be added to the list like so:
-#
-# Name/Organization <email address>
-
-Google Inc.
\ No newline at end of file
diff --git a/code_builder/BUILD.gn b/code_builder/BUILD.gn
deleted file mode 100644
index a5f2e0b..0000000
--- a/code_builder/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is generated by importer.py for code_builder-3.2.1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("code_builder") {
- package_name = "code_builder"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/matcher",
- "//third_party/dart-pkg/pub/built_collection",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/built_value",
- "//third_party/dart-pkg/pub/collection",
- ]
-}
diff --git a/code_builder/CHANGELOG.md b/code_builder/CHANGELOG.md
deleted file mode 100644
index 6f2abf0..0000000
--- a/code_builder/CHANGELOG.md
+++ /dev/null
@@ -1,684 +0,0 @@
-## 3.2.1
-
-* Escape newlines in String literals.
-* Introduce `Expression.or` for boolean OR.
-* Introduce `Expression.negate` for boolean NOT.
-* No longer emits redundant `,`s in `FunctionType`s.
-* Added support for `literalSet` and `literalConstSet`.
-* Depend on the latest `package:built_value`.
-
-## 3.2.0
-
-* Emit `=` instead of `:` for named parameter default values.
-* The `new` keyword will not be used in generated code.
-* The `const` keyword will be omitted when it can be inferred.
-* Add an option in `DartEmitter` to order directives.
-* `DartEmitter` added a `startConstCode` function to track the creation of
- constant expression trees.
-* `BinaryExpression` added the `final bool isConst` field.
-
-## 3.1.3
-
-* Bump dependency on built_collection to include v4.0.0.
-
-## 3.1.2
-
-* Set max SDK version to `<3.0.0`.
-
-## 3.1.1
-
-* `Expression.asA` is now wrapped with parenthesis so that further calls may be
- made on it as an expression.
-
-
-## 3.1.0
-
-* Added `Expression.asA` for creating explicit casts:
-
-```dart
-void main() {
- test('should emit an explicit cast', () {
- expect(
- refer('foo').asA(refer('String')),
- equalsDart('foo as String'),
- );
- });
-}
-```
-
-## 3.0.3
-
-* Fix a bug that caused all downstream users of `code_builder` to crash due to
- `build_runner` trying to import our private builder (in `tool/`). Sorry for
- the inconvenience.
-
-## 3.0.2
-
-* Require `source_gen: ^0.7.5`.
-
-## 3.0.1
-
-* Upgrade to `built_value` 5.1.0.
-* Export the `literalNum` function.
-* **BUG FIX**: `literal` supports a `Map`.
-
-## 3.0.0
-
-* Also infer `Constructor.lambda` for `factory` constructors.
-
-## 3.0.0-alpha
-
-* Using `equalsDart` no longer formats automatically with `dartfmt`.
-
-* Removed deprecated `Annotation` and `File` classes.
-
-* `Method.lambda` is inferred based on `Method.body` where possible and now
- defaults to `null`.
-
-## 2.4.0
-
-* Add `equalTo`, `notEqualTo`, `greaterThan`, `lessThan`, `greateOrEqualTo`, and
- `lessOrEqualTo` to `Expression`.
-
-## 2.3.0
-
-* Using `equalsDart` and expecting `dartfmt` by default is *deprecated*. This
- requires this package to have a direct dependency on specific versions of
- `dart_style` (and transitively `analyzer`), which is problematic just for
- testing infrastructure. To future proof, we've exposed the `EqualsDart` class
- with a `format` override:
-
-```dart
-// Copyright (c) 2017, 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:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-final DartFormatter _dartfmt = new DartFormatter();
-String _format(String source) {
- try {
- return _dartfmt.format(source);
- } on FormatException catch (_) {
- return _dartfmt.formatStatement(source);
- }
-}
-
-/// Should be invoked in `main()` of every test in `test/**_test.dart`.
-void useDartfmt() => EqualsDart.format = _format;
-```
-
-* Added `Expression.isA` and `Expression.isNotA`:
-
-```dart
-void main() {
- test('should emit an is check', () {
- expect(
- refer('foo').isA(refer('String')),
- equalsDart('foo is String'),
- );
- });
-}
-```
-
-* Deprecated `Annotation`. It is now legal to simply pass any `Expression` as
- a metadata annotation to `Class`, `Method`, `Field,` and `Parameter`. In
- `3.0.0`, the `Annotation` class will be completely removed:
-
-```dart
-void main() {
- test('should create a class with a annotated constructor', () {
- expect(
- new Class((b) => b
- ..name = 'Foo'
- ..constructors.add(
- new Constructor((b) => b..annotations.add(refer('deprecated'))))),
- equalsDart(r'''
- class Foo {
- @deprecated
- Foo();
- }
- '''),
- );
- });
-}
-```
-
-* Added inference support for `Method.lambda` and `Constructor.lambda`. If not
- explicitly provided and the body of the function originated from an
- `Expression` then `lambda` is inferred to be true. This is not a breaking
- change yet, as it requires an explicit `null` value. In `3.0.0` this will be
- the default:
-
-```dart
-void main() {
- final animal = new Class((b) => b
- ..name = 'Animal'
- ..extend = refer('Organism')
- ..methods.add(new Method.returnsVoid((b) => b
- ..name = 'eat'
- // In 3.0.0, this may be omitted and still is inferred.
- ..lambda = null
- ..body = refer('print').call([literalString('Yum!')]).code)));
- final emitter = new DartEmitter();
- print(new DartFormatter().format('${animal.accept(emitter)}'));
-}
-```
-
-* Added `nullSafeProperty` to `Expression` to access properties with `?.`
-* Added `conditional` to `Expression` to use the ternary operator `? : `
-* Methods taking `positionalArguments` accept `Iterable<Expression>`
-* **BUG FIX**: Parameters can take a `FunctionType` as a `type`.
- `Reference.type` now returns a `Reference`. Note that this change is
- technically breaking but should not impacts most clients.
-
-## 2.2.0
-
-* Imports are prefixed with `_i1` rather than `_1` which satisfies the lint
- `lowercase_with_underscores`. While not a strictly breaking change you may
- have to fix/regenerate golden file-like tests. We added documentation that
- the specific prefix is not considered stable.
-
-* Added `Expression.index` for accessing the `[]` operator:
-
-```dart
-void main() {
- test('should emit an index operator', () {
- expect(
- refer('bar').index(literalTrue).assignVar('foo').statement,
- equalsDart('var foo = bar[true];'),
- );
- });
-
- test('should emit an index operator set', () {
- expect(
- refer('bar')
- .index(literalTrue)
- .assign(literalFalse)
- .assignVar('foo')
- .statement,
- equalsDart('var foo = bar[true] = false;'),
- );
- });
-}
-```
-
-* `literalList` accepts an `Iterable` argument.
-
-* Fixed an NPE when a method had a return type of a `FunctionType`:
-
-```dart
-void main() {
- test('should create a method with a function type return type', () {
- expect(
- new Method((b) => b
- ..name = 'foo'
- ..returns = new FunctionType((b) => b
- ..returnType = refer('String')
- ..requiredParameters.addAll([
- refer('int'),
- ]))),
- equalsDart(r'''
- String Function(int) foo();
- '''),
- );
- });
-}
-```
-
-## 2.1.0
-
-We now require the Dart 2.0-dev branch SDK (`>= 2.0.0-dev`).
-
-* Added support for raw `String` literals.
-* Automatically escapes single quotes in now-raw `String` literals.
-* Deprecated `File`, which is now a redirect to the preferred class, `Library`.
-
-This helps avoid symbol clashes when used with `dart:io`, a popular library. It
-is now safe to do the following and get full access to the `code_builder` API:
-
-```dart
-import 'dart:io';
-
-import 'package:code_builder/code_builder.dart' hide File;
-```
-
-We will remove `File` in `3.0.0`, so use `Library` instead.
-
-## 2.0.0
-
-Re-released without a direct dependency on `package:analyzer`!
-
-For users of the `1.x` branch of `code_builder`, this is a pretty big breaking
-change but ultimately is for the better - it's easier to evolve this library
-now and even add your own builders on top of the library.
-
-```dart
-// Copyright (c) 2017, 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:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-void main() {
- final animal = new Class((b) => b
- ..name = 'Animal'
- ..extend = refer('Organism')
- ..methods.add(new Method.returnsVoid((b) => b
- ..name = 'eat'
- ..lambda = true
- ..body = const Code('print(\'Yum\')'))));
- final emitter = new DartEmitter();
- print(new DartFormatter().format('${animal.accept(emitter)}'));
-}
-```
-
-...outputs...
-
-```dart
-class Animal extends Organism {
- void eat() => print('Yum!');
-}
-```
-
-**Major changes**:
-
-* Builders now use `built_value`, and have a more consistent, friendly API.
-* Builders are now consistent - they don't any work until code is emitted.
-* It's possible to overwrite the built-in code emitting, formatting, etc by
- providing your own visitors. See `DartEmitter` as an example of the built-in
- visitor/emitter.
-* Most of the expression and statement level helpers were removed; in practice
- they were difficult to write and maintain, and many users commonly asked for
- opt-out type APIs. See the `Code` example below:
-
-```dart
-void main() {
- var code = new Code('x + y = z');
- code.expression;
- code.statement;
-}
-```
-
-See the commit log, examples, and tests for full details. While we want to try
-and avoid breaking changes, suggestions, new features, and incremental updates
-are welcome!
-
-## 2.0.0-beta
-
-* Added `lazySpec` and `lazyCode` to lazily create code on visit [#145](https://github.com/dart-lang/code_builder/issues/145).
-
-* **BUG FIX**: `equalsDart` emits the failing source code [#147](https://github.com/dart-lang/code_builder/issues/147).
-* **BUG FIX**: Top-level `lambda` `Method`s no longer emit invalid code [#146](https://github.com/dart-lang/code_builder/issues/146).
-
-## 2.0.0-alpha+3
-
-* Added `Expression.annotation` and `Expression.annotationNamed`.
-* Added `Method.closure` to create an `Expression`.
-* Added `FunctionType`.
-* Added `{new|const}InstanceNamed` to `Expression` [#135](https://github.com/dart-lang/code_builder/issues/135).
- * Also added a `typeArguments` option to all invocations.
-* Added `assign{...}` variants to `Expression` [#137](https://github.com/dart-lang/code_builder/issues/137).
-* Added `.awaited` and `.returned` to `Expression` [#138](https://github.com/dart-lang/code_builder/issues/138).
-
-* **BUG FIX**: `Block` now implements `Code` [#136](https://github.com/dart-lang/code_builder/issues/136).
-* **BUG FIX**: `new DartEmitter.scoped()` applies prefixing [#139](https://github.com/dart-lang/code_builder/issues/139).
-
-* Renamed many of the `.asFoo(...)` and `.toFoo(...)` methods to single getter:
- * `asCode()` to `code`
- * `asStatement()` to `statement`
- * `toExpression()` to `expression`
-
-* Moved `{new|const}Instance{[Named]}` from `Expression` to `Reference`.
-
-## 2.0.0-alpha+2
-
-* Upgraded `build_runner` from `^0.3.0` to `>=0.4.0 <0.6.0`.
-* Upgraded `build_value{_generator}` from `^1.0.0` to `>=2.0.0 <5.0.0`.
-* Upgraded `source_gen` from `>=0.5.0 <0.7.0` to `^0.7.0`.
-
-* Added `MethodModifier` to allow emit a `Method` with `async|async*|sync*`.
-* Added `show|hide` to `Directive`.
-* Added `Directive.importDeferredAs`.
-* Added a new line character after emitting some types (class, method, etc).
-* Added `refer` as a short-hand for `new Reference(...)`.
- * `Reference` now implements `Expression`.
-
-* Added many classes/methods for writing bodies of `Code` fluently:
- * `Expression`
- * `LiteralExpression`
- * `literal`
- * `literalNull`
- * `literalBool`
- * `literalTrue`
- * `literalFalse`
- * `literalNum`
- * `literalString`
- * `literalList` and `literalConstList`
- * `literalMap` and `literalConstMap`
- * `const Code(staticString)`
- * `const Code.scope((allocate) => '')`
-
-* Removed `SimpleSpecVisitor` (it was unused).
-* Removed `implements Reference` from `Method` and `Field`; not a lot of value.
-
-* `SpecVisitor<T>`'s methods all have an optional `[T context]` parameter now.
- * This makes it much easier to avoid allocating extra `StringBuffer`s.
-* `equalsDart` removes insignificant white space before comparing results.
-
-## 2.0.0-alpha+1
-
-* Removed `Reference.localScope`. Just use `Reference(symbol)` now.
-* Allow `Reference` instead of an explicit `TypeReference` in most APIs.
- * `toType()` is performed for you as part the emitter process
-
-```dart
-final animal = new Class((b) => b
- ..name = 'Animal'
- // Used to need a suffix of .toType().
- ..extend = const Reference('Organism')
- ..methods.add(new Method.returnsVoid((b) => b
- ..name = 'eat'
- ..lambda = true
- ..body = new Code((b) => b..code = 'print(\'Yum\')'))));
-```
-
-* We now support the Dart 2.0 pre-release SDKs (`<2.0.0-dev.infinity`)
-* Removed the ability to treat `Class` as a `TypeReference`.
- * Was required for compilation to `dart2js`, which is now tested on travis.
-
-## 2.0.0-alpha
-
-* Complete re-write to not use `package:analyzer`.
-* Code generation now properly uses the _builder_ pattern (via `built_value`).
-* See examples and tests for details.
-
-## 1.0.4
-
-* Added `isInstanceOf` to `ExpressionBuilder`, which performs an `is` check:
-
-```dart
-expect(
- reference('foo').isInstanceOf(_barType),
- equalsSource('foo is Bar'),
-);
-```
-
-## 1.0.3
-
-* Support latest `pkg/analyzer` and `pkg/func`.
-
-## 1.0.2
-
-* Update internals to use newer analyzer API
-
-## 1.0.1
-
-* Support the latest version of `package:dart_style`.
-
-## 1.0.0
-
-First full release. At this point all changes until `2.0.0` will be backwards
-compatible (new features) or bug fixes that are not breaking. This doesn't mean
-that the entire Dart language is buildable with our API, though.
-
-**Contributions are welcome.**
-
-- Exposed `uri` in `ImportBuilder`, `ExportBuilder`, and `Part[Of]Builder`.
-
-## 1.0.0-beta+7
-
-- Added `ExpressionBuilder#ternary`.
-
-## 1.0.0-beta+6
-
-- Added `TypeDefBuilder`.
-- Added `FunctionParameterBuilder`.
-- Added `asAbstract` to various `MethodBuilder` constructors.
-
-## 1.0.0-beta+5
-
-- Re-published the package without merge conflicts.
-
-## 1.0.0-beta+4
-
-- Renamed `PartBuilder` to `PartOfBuilder`.
-- Added a new class, `PartBuilder`, to represent `part '...dart'` directives.
-- Added the `HasAnnotations` interface to all library/part/directive builders.
-- Added `asFactory` and `asConst` to `ConstructorBuilder`.
-- Added `ConstructorBuilder.redirectTo` for a redirecting factory constructor.
-- Added a `name` getter to `ReferenceBuilder`.
-- Supplying an empty constructor name (`''`) is equivalent to `null` (default).
-- Automatically encodes string literals with multiple lines as `'''`.
-- Added `asThrow` to `ExpressionBuilder`.
-- Fixed a bug that prevented `FieldBuilder` from being used at the top-level.
-
-## 1.0.0-beta+3
-
-- Added support for `genericTypes` parameter for `ExpressionBuilder#invoke`:
-
-```dart
-expect(
- explicitThis.invoke('doThing', [literal(true)], genericTypes: [
- lib$core.bool,
- ]),
- equalsSource(r'''
- this.doThing<bool>(true)
- '''),
-);
-```
-
-- Added a `castAs` method to `ExpressionBuilder`:
-
-```dart
-expect(
- literal(1.0).castAs(lib$core.num),
- equalsSource(r'''
- 1.0 as num
- '''),
-);
-```
-
-### BREAKING CHANGES
-
-- Removed `namedNewInstance` and `namedConstInstance`, replaced with `constructor: `:
-
-```dart
-expect(
- reference('Foo').newInstance([], constructor: 'other'),
- equalsSource(r'''
- new Foo.other()
- '''),
-);
-```
-
-- Renamed `named` parameter to `namedArguments`:
-
-```dart
-expect(
- reference('doThing').call(
- [literal(true)],
- namedArguments: {
- 'otherFlag': literal(false),
- },
- ),
- equalsSource(r'''
- doThing(true, otherFlag: false)
- '''),
-);
-```
-
-## 1.0.0-beta+2
-
-### BREAKING CHANGES
-
-Avoid creating symbols that can collide with the Dart language:
-
-- `MethodModifier.async` -> `MethodModifier.asAsync`
-- `MethodModifier.asyncStar` -> `MethodModifier.asAsyncStar`
-- `MethodModifier.syncStar` -> `MethodModifier.asSyncStar`
-
-## 1.0.0-beta+1
-
-- Add support for `switch` statements
-- Add support for a raw expression and statement
- - `new ExpressionBuilder.raw(...)`
- - `new StatemnetBuilder.raw(...)`
-
-This should help cover any cases not covered with builders today.
-
-- Allow referring to a `ClassBuilder` and `TypeBuilder` as an expression
-- Add support for accessing the index `[]` operator on an expression
-
-### BREAKING CHANGES
-
-- Changed `ExpressionBuilder.asAssign` to always take an `ExpressionBuilder` as
- target and removed the `value` property. Most changes are pretty simple, and
- involve just using `reference(...)`. For example:
-
-```dart
-literal(true).asAssign(reference('flag'))
-```
-
-... emits `flag = true`.
-
-## 1.0.0-beta
-
-- Add support for `async`, `sync`, `sync*` functions
-- Add support for expression `asAwait`, `asYield`, `asYieldStar`
-- Add `toExportBuilder` and `toImportBuilder` to types and references
-- Fix an import scoping bug in `return` statements and named constructor invocations.
-- Added constructor initializer support
-- Add `while` and `do {} while` loop support
-- Add `for` and `for-in` support
-- Added a `name` getter for `ParameterBuilder`
-
-## 1.0.0-alpha+7
-
-- Make use of new analyzer API in preparation for analyzer version 0.30.
-
-## 1.0.0-alpha+6
-
-- `MethodBuilder.closure` emits properly as a top-level function
-
-## 1.0.0-alpha+5
-
-- MethodBuilder with no statements will create an empty block instead of
- a semicolon.
-
-```dart
-// main() {}
-method('main')
-```
-
-- Fix lambdas and closures to not include a trailing semicolon when used
- as an expression.
-
-```dart
- // () => false
- new MethodBuilder.closure(returns: literal(false));
-```
-
-## 1.0.0-alpha+4
-
-- Add support for latest `pkg/analyzer`.
-
-## 1.0.0-alpha+3
-
-- BREAKING CHANGE: Added generics support to `TypeBuilder`:
-
-`importFrom` becomes a _named_, not positional argument, and the named
-argument `genericTypes` is added (`Iterable<TypeBuilder>`).
-
-```dart
-// List<String>
-new TypeBuilder('List', genericTypes: [reference('String')])
-```
-
-- Added generic support to `ReferenceBuilder`:
-
-```dart
-// List<String>
-reference('List').toTyped([reference('String')])
-```
-
-- Fixed a bug where `ReferenceBuilder.buildAst` was not implemented
-- Added `and` and `or` methods to `ExpressionBuilder`:
-
-```dart
-// true || false
-literal(true).or(literal(false));
-
-// true && false
-literal(true).and(literal(false));
-```
-
-- Added support for creating closures - `MethodBuilder.closure`:
-
-```dart
-// () => true
-new MethodBuilder.closure(
- returns: literal(true),
- returnType: lib$core.bool,
-)
-```
-
-## 1.0.0-alpha+2
-
-- Added `returnVoid` to well, `return;`
-- Added support for top-level field assignments:
-
-```dart
-new LibraryBuilder()..addMember(literal(false).asConst('foo'))
-```
-
-- Added support for specifying a `target` when using `asAssign`:
-
-```dart
-// Outputs bank.bar = goldBar
-reference('goldBar').asAssign('bar', target: reference('bank'))
-```
-
-- Added support for the cascade operator:
-
-```dart
-// Outputs foo..doThis()..doThat()
-reference('foo').cascade((c) => <ExpressionBuilder> [
- c.invoke('doThis', []),
- c.invoke('doThat', []),
-]);
-```
-
-- Added support for accessing a property
-
-```dart
-// foo.bar
-reference('foo').property('bar');
-```
-
-## 1.0.0-alpha+1
-
-- Slight updates to confusing documentation.
-- Added support for null-aware assignments.
-- Added `show` and `hide` support to `ImportBuilder`
-- Added `deferred` support to `ImportBuilder`
-- Added `ExportBuilder`
-- Added `list` and `map` literals that support generic types
-
-## 1.0.0-alpha
-
-- Large refactor that makes the library more feature complete.
-
-## 0.1.1
-
-- Add concept of `Scope` and change `toAst` to support it
-
-Now your entire AST tree can be scoped and import directives
-automatically added to a `LibraryBuilder` for you if you use
-`LibraryBuilder.scope`.
-
-## 0.1.0
-
-- Initial version
diff --git a/code_builder/CONTRIBUTING.md b/code_builder/CONTRIBUTING.md
deleted file mode 100644
index 0dfd0f7..0000000
--- a/code_builder/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
- // Copyright (c) 2017, 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.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
\ No newline at end of file
diff --git a/code_builder/LICENSE b/code_builder/LICENSE
deleted file mode 100644
index 82e9b52..0000000
--- a/code_builder/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2016, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/code_builder/README.md b/code_builder/README.md
deleted file mode 100644
index 9d9f394..0000000
--- a/code_builder/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-[![Pub package](https://img.shields.io/pub/v/code_builder.svg)](https://pub.dartlang.org/packages/code_builder)
-[![Build status](https://travis-ci.org/dart-lang/code_builder.svg)](https://travis-ci.org/dart-lang/code_builder)
-[![Latest docs](https://img.shields.io/badge/dartdocs-latest-blue.svg)](https://www.dartdocs.org/documentation/code_builder/latest)
-[![Gitter chat](https://badges.gitter.im/dart-lang/build.svg)](https://gitter.im/dart-lang/build)
-
-A fluent, builder-based library for generating valid Dart code.
-
-## Usage
-
-`code_builder` has a narrow and user-friendly API.
-
-See the `example` and `test` folders for additional examples.
-
-For example creating a class with a method:
-
-```dart
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-void main() {
- final animal = Class((b) => b
- ..name = 'Animal'
- ..extend = refer('Organism')
- ..methods.add(Method.returnsVoid((b) => b
- ..name = 'eat'
- ..body = const Code("print('Yum');"))));
- final emitter = DartEmitter();
- print(DartFormatter().format('${animal.accept(emitter)}'));
-}
-```
-
-Outputs:
-```dart
-class Animal extends Organism {
- void eat() => print('Yum!');
-}
-```
-
-Have a complicated set of dependencies for your generated code?
-`code_builder` supports automatic scoping of your ASTs to automatically
-use prefixes to avoid symbol conflicts:
-
-```dart
-import 'package:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-void main() {
- final library = Library((b) => b.body.addAll([
- Method((b) => b
- ..body = const Code('')
- ..name = 'doThing'
- ..returns = refer('Thing', 'package:a/a.dart')),
- Method((b) => b
- ..body = const Code('')
- ..name = 'doOther'
- ..returns = refer('Other', 'package:b/b.dart')),
- ]));
- final emitter = DartEmitter(Allocator.simplePrefixing());
- print(DartFormatter().format('${library.accept(emitter)}'));
-}
-```
-
-Outputs:
-```dart
-import 'package:a/a.dart' as _i1;
-import 'package:b/b.dart' as _i2;
-
-_i1.Thing doThing() {}
-_i2.Other doOther() {}
-```
-
-## Contributing
-
-* Read and help us document common patterns over [at the wiki][wiki].
-* Is there a *bug* in the code? [File an issue][issue].
-
-If a feature is missing (the Dart language is always evolving) or you'd like an
-easier or better way to do something, consider [opening a pull request][pull].
-You can always [file an issue][issue], but generally speaking feature requests
-will be on a best-effort basis.
-
-> **NOTE**: Due to the evolving Dart SDK the local `dartfmt` must be used to
-> format this repository. You can run it simply from the command-line:
->
-> ```sh
-> $ pub run dart_style:format -w .
-> ```
-
-[wiki]: https://github.com/dart-lang/code_builder/wiki
-[issue]: https://github.com/dart-lang/code_builder/issues
-[pull]: https://github.com/dart-lang/code_builder/pulls
-
-### Updating generated (`.g.dart`) files
-
-> **NOTE**: There is currently a limitation in `build_runner` that requires
-> a workaround for developing this package. We expect this to be unnecessary
-> in the future.
-
-Use [`build_runner`][build_runner]:
-
-```bash
-$ mv build.disabled.yaml build.yaml
-$ pub run build_runner build --delete-conflicting-outputs
-$ mv build.yaml build.disabled.yaml
-```
-
-[build_runner]: https://pub.dartlang.org/packages/build_runner
diff --git a/code_builder/analysis_options.yaml b/code_builder/analysis_options.yaml
deleted file mode 100644
index b4b37b4..0000000
--- a/code_builder/analysis_options.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-analyzer:
- strong-mode:
- implicit-casts: false
- implicit-dynamic: false
-
-linter:
- rules:
- # Error Rules
- - avoid_empty_else
- - comment_references
- - control_flow_in_finally
- - empty_statements
- - hash_and_equals
- - invariant_booleans
- - iterable_contains_unrelated_type
- - list_remove_unrelated_type
- - no_adjacent_strings_in_list
- - no_duplicate_case_values
- - test_types_in_equals
- - throw_in_finally
- - unrelated_type_equality_checks
- - valid_regexps
-
- # Style Rules
- - annotate_overrides
- - avoid_init_to_null
- - avoid_return_types_on_setters
- - camel_case_types
- - cascade_invocations
- - constant_identifier_names
- - directives_ordering
- - empty_catches
- - empty_constructor_bodies
- - implementation_imports
- - library_names
- - library_prefixes
- - non_constant_identifier_names
- - omit_local_variable_types
- - only_throw_errors
- - prefer_adjacent_string_concatenation
- - prefer_collection_literals
- - prefer_const_constructors
- - prefer_contains
- - prefer_equal_for_default_values
- - prefer_final_fields
- - prefer_final_locals
- - prefer_initializing_formals
- - prefer_interpolation_to_compose_strings
- - prefer_is_empty
- - prefer_is_not_empty
- - recursive_getters
- - slash_for_doc_comments
- - type_init_formals
- - unnecessary_brace_in_string_interps
- - unnecessary_this
diff --git a/code_builder/build.disabled.yaml b/code_builder/build.disabled.yaml
deleted file mode 100644
index 2eed503..0000000
--- a/code_builder/build.disabled.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-targets:
- $default:
- builders:
- "|_built_value":
-
-builders:
- _built_value:
- target: ":code_builder"
- import: "../../../tool/src/builder.dart"
- builder_factories:
- - "builtValueBuilder"
- build_extensions:
- ".dart": [".g.dart"]
- build_to: "source"
diff --git a/code_builder/example/example.dart b/code_builder/example/example.dart
deleted file mode 100644
index 577752b..0000000
--- a/code_builder/example/example.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2017, 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:code_builder/code_builder.dart';
-import 'package:dart_style/dart_style.dart';
-
-final _dartfmt = DartFormatter();
-
-void main() {
- print('animalClass():\n${'=' * 40}\n${animalClass()}');
- print('scopedLibrary():\n${'=' * 40}\n${scopedLibrary()}');
-}
-
-/// Outputs:
-///
-/// ```dart
-/// class Animal extends Organism {
-/// void eat() => print('Yum!');
-/// }
-/// ```
-String animalClass() {
- final animal = Class((b) => b
- ..name = 'Animal'
- ..extend = refer('Organism')
- ..methods.add(Method.returnsVoid((b) => b
- ..name = 'eat'
- ..body = refer('print').call([literalString('Yum!')]).code)));
- return _dartfmt.format('${animal.accept(DartEmitter())}');
-}
-
-/// Outputs:
-///
-/// ```dart
-/// import 'package:a/a.dart' as _i1;
-/// import 'package:b/b.dart' as _i2;
-///
-/// _i1.Thing doThing() {}
-/// _i2.Other doOther() {}
-/// ```
-String scopedLibrary() {
- final methods = [
- Method((b) => b
- ..body = const Code('')
- ..name = 'doThing'
- ..returns = refer('Thing', 'package:a/a.dart')),
- Method((b) => b
- ..body = const Code('')
- ..name = 'doOther'
- ..returns = refer('Other', 'package:b/b.dart')),
- ];
- final library = Library((b) => b.body.addAll(methods));
- return _dartfmt.format('${library.accept(DartEmitter.scoped())}');
-}
diff --git a/code_builder/lib/code_builder.dart b/code_builder/lib/code_builder.dart
deleted file mode 100644
index 2be4733..0000000
--- a/code_builder/lib/code_builder.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/allocator.dart' show Allocator;
-export 'src/base.dart' show lazySpec, Spec;
-export 'src/emitter.dart' show DartEmitter;
-export 'src/matchers.dart' show equalsDart, EqualsDart;
-export 'src/specs/class.dart' show Class, ClassBuilder;
-export 'src/specs/code.dart'
- show lazyCode, Block, BlockBuilder, Code, StaticCode, ScopedCode;
-export 'src/specs/constructor.dart' show Constructor, ConstructorBuilder;
-export 'src/specs/directive.dart'
- show Directive, DirectiveType, DirectiveBuilder;
-export 'src/specs/expression.dart'
- show
- ToCodeExpression,
- BinaryExpression,
- CodeExpression,
- Expression,
- ExpressionEmitter,
- ExpressionVisitor,
- InvokeExpression,
- InvokeExpressionType,
- LiteralExpression,
- LiteralListExpression,
- literal,
- literalNull,
- literalNum,
- literalBool,
- literalList,
- literalConstList,
- literalSet,
- literalConstSet,
- literalMap,
- literalConstMap,
- literalString,
- literalTrue,
- literalFalse;
-export 'src/specs/field.dart' show Field, FieldBuilder, FieldModifier;
-export 'src/specs/library.dart' show Library, LibraryBuilder;
-export 'src/specs/method.dart'
- show
- Method,
- MethodBuilder,
- MethodModifier,
- MethodType,
- Parameter,
- ParameterBuilder;
-export 'src/specs/reference.dart' show refer, Reference;
-export 'src/specs/type_function.dart' show FunctionType, FunctionTypeBuilder;
-export 'src/specs/type_reference.dart' show TypeReference, TypeReferenceBuilder;
diff --git a/code_builder/lib/src/allocator.dart b/code_builder/lib/src/allocator.dart
deleted file mode 100644
index 87315d5..0000000
--- a/code_builder/lib/src/allocator.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2017, 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 'specs/directive.dart';
-import 'specs/reference.dart';
-
-/// Collects references and automatically allocates prefixes and imports.
-///
-/// `Allocator` takes out the manual work of deciding whether a symbol will
-/// clash with other imports in your generated code, or what imports are needed
-/// to resolve all symbols in your generated code.
-abstract class Allocator {
- /// An allocator that does not prefix symbols nor collects imports.
- static const Allocator none = _NullAllocator();
-
- /// Creates a new default allocator that applies no prefixing.
- factory Allocator() = _Allocator;
-
- /// Creates a new allocator that applies naive prefixing to avoid conflicts.
- ///
- /// This implementation is not optimized for any particular code generation
- /// style and instead takes a conservative approach of prefixing _every_
- /// import except references to `dart:core` (which are considered always
- /// imported).
- ///
- /// The prefixes are not guaranteed to be stable and cannot be expected to
- /// have any particular value.
- factory Allocator.simplePrefixing() = _PrefixedAllocator;
-
- /// Returns a reference string given a [reference] object.
- ///
- /// For example, a no-op implementation:
- /// ```dart
- /// allocate(const Reference('List', 'dart:core')); // Returns 'List'.
- /// ```
- ///
- /// Where-as an implementation that prefixes imports might output:
- /// ```dart
- /// allocate(const Reference('Foo', 'package:foo')); // Returns '_i1.Foo'.
- /// ```
- String allocate(Reference reference);
-
- /// All imports that have so far been added implicitly via [allocate].
- Iterable<Directive> get imports;
-}
-
-class _Allocator implements Allocator {
- final _imports = Set<String>();
-
- @override
- String allocate(Reference reference) {
- if (reference.url != null) {
- _imports.add(reference.url);
- }
- return reference.symbol;
- }
-
- @override
- Iterable<Directive> get imports {
- return _imports.map((u) => Directive.import(u));
- }
-}
-
-class _NullAllocator implements Allocator {
- const _NullAllocator();
-
- @override
- String allocate(Reference reference) => reference.symbol;
-
- @override
- Iterable<Directive> get imports => const [];
-}
-
-class _PrefixedAllocator implements Allocator {
- static const _doNotPrefix = ['dart:core'];
-
- final _imports = <String, int>{};
- var _keys = 1;
-
- @override
- String allocate(Reference reference) {
- final symbol = reference.symbol;
- if (reference.url == null || _doNotPrefix.contains(reference.url)) {
- return symbol;
- }
- return '_i${_imports.putIfAbsent(reference.url, _nextKey)}.$symbol';
- }
-
- int _nextKey() => _keys++;
-
- @override
- Iterable<Directive> get imports {
- return _imports.keys.map(
- (u) => Directive.import(u, as: '_i${_imports[u]}'),
- );
- }
-}
diff --git a/code_builder/lib/src/base.dart b/code_builder/lib/src/base.dart
deleted file mode 100644
index 529dd5b..0000000
--- a/code_builder/lib/src/base.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2017, 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 'visitors.dart';
-
-abstract class Spec {
- R accept<R>(SpecVisitor<R> visitor, [R context]);
-}
-
-/// Returns a generic [Spec] that is lazily generated when visited.
-Spec lazySpec(Spec Function() generate) => _LazySpec(generate);
-
-class _LazySpec implements Spec {
- final Spec Function() generate;
-
- const _LazySpec(this.generate);
-
- @override
- R accept<R>(SpecVisitor<R> visitor, [R context]) {
- return generate().accept(visitor, context);
- }
-}
diff --git a/code_builder/lib/src/emitter.dart b/code_builder/lib/src/emitter.dart
deleted file mode 100644
index d7a688f..0000000
--- a/code_builder/lib/src/emitter.dart
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright (c) 2017, 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 'allocator.dart';
-import 'base.dart';
-import 'specs/class.dart';
-import 'specs/code.dart';
-import 'specs/constructor.dart';
-import 'specs/directive.dart';
-import 'specs/expression.dart';
-import 'specs/field.dart';
-import 'specs/library.dart';
-import 'specs/method.dart';
-import 'specs/reference.dart';
-import 'specs/type_function.dart';
-import 'specs/type_reference.dart';
-import 'visitors.dart';
-
-/// Helper method improving on [StringSink.writeAll].
-///
-/// For every `Spec` in [elements], executing [visit].
-///
-/// If [elements] is at least 2 elements, inserts [separator] delimiting them.
-StringSink visitAll<T>(
- Iterable<T> elements,
- StringSink output,
- void visit(T element), [
- String separator = ', ',
-]) {
- // Basically, this whole method is an improvement on
- // output.writeAll(specs.map((s) => s.accept(visitor));
- //
- // ... which would allocate more StringBuffer(s) for a one-time use.
- if (elements.isEmpty) {
- return output;
- }
- final iterator = elements.iterator..moveNext();
- visit(iterator.current);
- while (iterator.moveNext()) {
- output.write(separator);
- visit(iterator.current);
- }
- return output;
-}
-
-class DartEmitter extends Object
- with CodeEmitter, ExpressionEmitter
- implements SpecVisitor<StringSink> {
- @override
- final Allocator allocator;
-
- /// If directives should be ordered while emitting.
- ///
- /// Ordering rules follow the guidance in
- /// [Effective Dart](https://www.dartlang.org/guides/language/effective-dart/style#ordering)
- /// and the
- /// [directives_ordering](http://dart-lang.github.io/linter/lints/directives_ordering.html)
- /// lint.
- final bool orderDirectives;
-
- /// Creates a new instance of [DartEmitter].
- ///
- /// May specify an [Allocator] to use for symbols, otherwise uses a no-op.
- DartEmitter([this.allocator = Allocator.none, bool orderDirectives = false])
- : orderDirectives = orderDirectives ?? false;
-
- /// Creates a new instance of [DartEmitter] with simple automatic imports.
- factory DartEmitter.scoped({bool orderDirectives = false}) {
- return DartEmitter(Allocator.simplePrefixing(), orderDirectives);
- }
-
- static bool _isLambdaBody(Code code) =>
- code is ToCodeExpression && !code.isStatement;
-
- /// Whether the provided [method] is considered a lambda method.
- static bool _isLambdaMethod(Method method) =>
- method.lambda ?? _isLambdaBody(method.body);
-
- /// Whether the provided [constructor] is considered a lambda method.
- static bool _isLambdaConstructor(Constructor constructor) =>
- constructor.lambda ??
- constructor.factory && _isLambdaBody(constructor.body);
-
- @override
- visitAnnotation(Expression spec, [StringSink output]) {
- (output ??= StringBuffer()).write('@');
- spec.accept(this, output);
- output.write(' ');
- return output;
- }
-
- @override
- visitClass(Class spec, [StringSink output]) {
- output ??= StringBuffer();
- spec.docs.forEach(output.writeln);
- spec.annotations.forEach((a) => visitAnnotation(a, output));
- if (spec.abstract) {
- output.write('abstract ');
- }
- output.write('class ${spec.name}');
- visitTypeParameters(spec.types.map((r) => r.type), output);
- if (spec.extend != null) {
- output.write(' extends ');
- spec.extend.type.accept(this, output);
- }
- if (spec.mixins.isNotEmpty) {
- output
- ..write(' with ')
- ..writeAll(
- spec.mixins.map<StringSink>((m) => m.type.accept(this)), ',');
- }
- if (spec.implements.isNotEmpty) {
- output
- ..write(' implements ')
- ..writeAll(
- spec.implements.map<StringSink>((m) => m.type.accept(this)), ',');
- }
- output.write(' {');
- spec.constructors.forEach((c) {
- visitConstructor(c, spec.name, output);
- output.writeln();
- });
- spec.fields.forEach((f) {
- visitField(f, output);
- output.writeln();
- });
- spec.methods.forEach((m) {
- visitMethod(m, output);
- if (_isLambdaMethod(m)) {
- output.write(';');
- }
- output.writeln();
- });
- output.writeln(' }');
- return output;
- }
-
- @override
- visitConstructor(Constructor spec, String clazz, [StringSink output]) {
- output ??= StringBuffer();
- spec.docs.forEach(output.writeln);
- spec.annotations.forEach((a) => visitAnnotation(a, output));
- if (spec.external) {
- output.write('external ');
- }
- if (spec.factory) {
- output.write('factory ');
- }
- if (spec.constant) {
- output.write('const ');
- }
- output.write(clazz);
- if (spec.name != null) {
- output..write('.')..write(spec.name);
- }
- output.write('(');
- if (spec.requiredParameters.isNotEmpty) {
- var count = 0;
- for (final p in spec.requiredParameters) {
- count++;
- _visitParameter(p, output);
- if (spec.requiredParameters.length != count ||
- spec.optionalParameters.isNotEmpty) {
- output.write(', ');
- }
- }
- }
- if (spec.optionalParameters.isNotEmpty) {
- final named = spec.optionalParameters.any((p) => p.named);
- if (named) {
- output.write('{');
- } else {
- output.write('[');
- }
- var count = 0;
- for (final p in spec.optionalParameters) {
- count++;
- _visitParameter(p, output, optional: true, named: named);
- if (spec.optionalParameters.length != count) {
- output.write(', ');
- }
- }
- if (named) {
- output.write('}');
- } else {
- output.write(']');
- }
- }
- output.write(')');
- if (spec.initializers.isNotEmpty) {
- output.write(' : ');
- var count = 0;
- for (final initializer in spec.initializers) {
- count++;
- initializer.accept(this, output);
- if (count != spec.initializers.length) {
- output.write(', ');
- }
- }
- }
- if (spec.redirect != null) {
- output.write(' = ');
- spec.redirect.type.accept(this, output);
- output.write(';');
- } else if (spec.body != null) {
- if (_isLambdaConstructor(spec)) {
- output.write(' => ');
- spec.body.accept(this, output);
- output.write(';');
- } else {
- output.write(' { ');
- spec.body.accept(this, output);
- output.write(' }');
- }
- } else {
- output.write(';');
- }
- output.writeln();
- return output;
- }
-
- @override
- visitDirective(Directive spec, [StringSink output]) {
- output ??= StringBuffer();
- if (spec.type == DirectiveType.import) {
- output.write('import ');
- } else {
- output.write('export ');
- }
- output.write("'${spec.url}'");
- if (spec.as != null) {
- if (spec.deferred) {
- output.write(' deferred ');
- }
- output.write(' as ${spec.as}');
- }
- if (spec.show.isNotEmpty) {
- output
- ..write(' show ')
- ..writeAll(spec.show, ', ');
- } else if (spec.hide.isNotEmpty) {
- output
- ..write(' hide ')
- ..writeAll(spec.hide, ', ');
- }
- output.write(';');
- return output;
- }
-
- @override
- visitField(Field spec, [StringSink output]) {
- output ??= StringBuffer();
- spec.docs.forEach(output.writeln);
- spec.annotations.forEach((a) => visitAnnotation(a, output));
- if (spec.static) {
- output.write('static ');
- }
- switch (spec.modifier) {
- case FieldModifier.var$:
- if (spec.type == null) {
- output.write('var ');
- }
- break;
- case FieldModifier.final$:
- output.write('final ');
- break;
- case FieldModifier.constant:
- output.write('const ');
- break;
- }
- if (spec.type != null) {
- spec.type.type.accept(this, output);
- output.write(' ');
- }
- output.write(spec.name);
- if (spec.assignment != null) {
- output.write(' = ');
- startConstCode(spec.modifier == FieldModifier.constant, () {
- spec.assignment.accept(this, output);
- });
- }
- output.writeln(';');
- return output;
- }
-
- @override
- visitLibrary(Library spec, [StringSink output]) {
- output ??= StringBuffer();
- // Process the body first in order to prime the allocators.
- final body = StringBuffer();
- for (final spec in spec.body) {
- spec.accept(this, body);
- if (spec is Method && _isLambdaMethod(spec)) {
- body.write(';');
- }
- }
-
- final directives = <Directive>[]
- ..addAll(spec.directives)
- ..addAll(allocator.imports);
-
- if (orderDirectives) {
- directives.sort();
- }
-
- Directive previous;
- for (final directive in directives) {
- if (_newLineBetween(orderDirectives, previous, directive)) {
- // Note: dartfmt handles creating new lines between directives.
- // 2 lines are written here. The first one comes after the previous
- // directive `;`, the second is the empty line.
- output..writeln()..writeln();
- }
- directive.accept(this, output);
- previous = directive;
- }
- output.write(body);
- return output;
- }
-
- @override
- visitFunctionType(FunctionType spec, [StringSink output]) {
- output ??= StringBuffer();
- if (spec.returnType != null) {
- spec.returnType.accept(this, output);
- output.write(' ');
- }
- output.write('Function');
- if (spec.types.isNotEmpty) {
- output.write('<');
- visitAll<Reference>(spec.types, output, (spec) {
- spec.accept(this, output);
- });
- output.write('>');
- }
- output.write('(');
- visitAll<Reference>(spec.requiredParameters, output, (spec) {
- spec.accept(this, output);
- });
- if (spec.requiredParameters.isNotEmpty &&
- (spec.optionalParameters.isNotEmpty ||
- spec.namedParameters.isNotEmpty)) {
- output.write(', ');
- }
- if (spec.optionalParameters.isNotEmpty) {
- output.write('[');
- visitAll<Reference>(spec.optionalParameters, output, (spec) {
- spec.accept(this, output);
- });
- output.write(']');
- } else if (spec.namedParameters.isNotEmpty) {
- output.write('{');
- visitAll<String>(spec.namedParameters.keys, output, (name) {
- spec.namedParameters[name].accept(this, output);
- output..write(' ')..write(name);
- });
- output.write('}');
- }
- return output..write(')');
- }
-
- @override
- visitMethod(Method spec, [StringSink output]) {
- output ??= StringBuffer();
- spec.docs.forEach(output.writeln);
- spec.annotations.forEach((a) => visitAnnotation(a, output));
- if (spec.external) {
- output.write('external ');
- }
- if (spec.static) {
- output.write('static ');
- }
- if (spec.returns != null) {
- spec.returns.accept(this, output);
- output.write(' ');
- }
- if (spec.type == MethodType.getter) {
- output..write('get ')..write(spec.name);
- } else {
- if (spec.type == MethodType.setter) {
- output.write('set ');
- }
- if (spec.name != null) {
- output.write(spec.name);
- }
- visitTypeParameters(spec.types.map((r) => r.type), output);
- output.write('(');
- if (spec.requiredParameters.isNotEmpty) {
- var count = 0;
- for (final p in spec.requiredParameters) {
- count++;
- _visitParameter(p, output);
- if (spec.requiredParameters.length != count ||
- spec.optionalParameters.isNotEmpty) {
- output.write(', ');
- }
- }
- }
- if (spec.optionalParameters.isNotEmpty) {
- final named = spec.optionalParameters.any((p) => p.named);
- if (named) {
- output.write('{');
- } else {
- output.write('[');
- }
- var count = 0;
- for (final p in spec.optionalParameters) {
- count++;
- _visitParameter(p, output, optional: true, named: named);
- if (spec.optionalParameters.length != count) {
- output.write(', ');
- }
- }
- if (named) {
- output.write('}');
- } else {
- output.write(']');
- }
- }
- output.write(')');
- }
- if (spec.body != null) {
- if (spec.modifier != null) {
- switch (spec.modifier) {
- case MethodModifier.async:
- output.write(' async ');
- break;
- case MethodModifier.asyncStar:
- output.write(' async* ');
- break;
- case MethodModifier.syncStar:
- output.write(' sync* ');
- break;
- }
- }
- if (_isLambdaMethod(spec)) {
- output.write(' => ');
- } else {
- output.write(' { ');
- }
- spec.body.accept(this, output);
- if (!_isLambdaMethod(spec)) {
- output.write(' } ');
- }
- } else {
- output.write(';');
- }
- return output;
- }
-
- // Expose as a first-class visit function only if needed.
- void _visitParameter(
- Parameter spec,
- StringSink output, {
- bool optional = false,
- bool named = false,
- }) {
- spec.docs.forEach(output.writeln);
- spec.annotations.forEach((a) => visitAnnotation(a, output));
- if (spec.type != null) {
- spec.type.type.accept(this, output);
- output.write(' ');
- }
- if (spec.toThis) {
- output.write('this.');
- }
- output.write(spec.name);
- if (optional && spec.defaultTo != null) {
- output.write(' = ');
- spec.defaultTo.accept(this, output);
- }
- }
-
- @override
- visitReference(Reference spec, [StringSink output]) {
- return (output ??= StringBuffer())..write(allocator.allocate(spec));
- }
-
- @override
- visitSpec(Spec spec, [StringSink output]) => spec.accept(this, output);
-
- @override
- visitType(TypeReference spec, [StringSink output]) {
- output ??= StringBuffer();
- // Intentionally not .accept to avoid stack overflow.
- visitReference(spec, output);
- if (spec.bound != null) {
- output.write(' extends ');
- spec.bound.type.accept(this, output);
- }
- visitTypeParameters(spec.types.map((r) => r.type), output);
- return output;
- }
-
- @override
- visitTypeParameters(Iterable<Reference> specs, [StringSink output]) {
- output ??= StringBuffer();
- if (specs.isNotEmpty) {
- output
- ..write('<')
- ..writeAll(specs.map<StringSink>((s) => s.accept(this)), ',')
- ..write('>');
- }
- return output;
- }
-}
-
-/// Returns `true` if:
-///
-/// * [ordered] is `true`
-/// * [a] is non-`null`
-/// * If there should be an empty line before [b] if it's emitted after [a].
-bool _newLineBetween(bool ordered, Directive a, Directive b) {
- if (!ordered) return false;
- if (a == null) return false;
-
- assert(b != null);
-
- // Put a line between imports and exports
- if (a.type != b.type) return true;
-
- // Within exports, don't put in extra blank lines
- if (a.type == DirectiveType.export) {
- assert(b.type == DirectiveType.export);
- return false;
- }
-
- // Return `true` if the schemes for [a] and [b] are different
- return !Uri.parse(a.url).isScheme(Uri.parse(b.url).scheme);
-}
diff --git a/code_builder/lib/src/matchers.dart b/code_builder/lib/src/matchers.dart
deleted file mode 100644
index dda8ac8..0000000
--- a/code_builder/lib/src/matchers.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2017, 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:matcher/matcher.dart';
-
-import 'base.dart';
-import 'emitter.dart';
-
-/// Encodes [spec] as Dart source code.
-String _dart(Spec spec, DartEmitter emitter) =>
- EqualsDart._format(spec.accept<StringSink>(emitter).toString());
-
-/// Returns a matcher for Dart source code.
-Matcher equalsDart(
- String source, [
- DartEmitter emitter,
-]) =>
- EqualsDart._(EqualsDart._format(source), emitter ?? DartEmitter());
-
-/// Implementation detail of using the [equalsDart] matcher.
-///
-/// See [EqualsDart.format] to specify the default source code formatter.
-class EqualsDart extends Matcher {
- /// May override to provide a function to format Dart on [equalsDart].
- ///
- /// By default, uses [collapseWhitespace], but it is recommended to instead
- /// use `dart_style` (dartfmt) where possible. See `test/common.dart` for an
- /// example.
- static String Function(String) format = (String source) {
- return collapseWhitespace(source);
- };
-
- static String _format(String source) {
- try {
- return format(source).trim();
- } catch (_) {
- // Ignored on purpose, probably not exactly valid Dart code.
- return collapseWhitespace(source).trim();
- }
- }
-
- final DartEmitter _emitter;
- final String _source;
-
- const EqualsDart._(this._source, this._emitter);
-
- @override
- Description describe(Description description) => description.add(_source);
-
- @override
- Description describeMismatch(
- covariant Spec item,
- Description mismatchDescription,
- state,
- verbose,
- ) {
- final result = _dart(item, _emitter);
- return equals(result).describeMismatch(
- _source,
- mismatchDescription.add(result),
- state,
- verbose,
- );
- }
-
- @override
- bool matches(covariant Spec item, _) => _dart(item, _emitter) == _source;
-}
diff --git a/code_builder/lib/src/mixins/annotations.dart b/code_builder/lib/src/mixins/annotations.dart
deleted file mode 100644
index f8bc948..0000000
--- a/code_builder/lib/src/mixins/annotations.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, 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:built_collection/built_collection.dart';
-
-import '../specs/expression.dart';
-
-/// A type of AST node that can have metadata [annotations].
-abstract class HasAnnotations {
- /// Annotations as metadata on the node.
- BuiltList<Expression> get annotations;
-}
-
-/// Compliment to the [HasAnnotations] mixin for metadata [annotations].
-abstract class HasAnnotationsBuilder {
- /// Annotations as metadata on the node.
- ListBuilder<Expression> annotations;
-}
diff --git a/code_builder/lib/src/mixins/dartdoc.dart b/code_builder/lib/src/mixins/dartdoc.dart
deleted file mode 100644
index ae44bd1..0000000
--- a/code_builder/lib/src/mixins/dartdoc.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2017, 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:built_collection/built_collection.dart';
-
-abstract class HasDartDocs {
- /// Dart docs.
- BuiltList<String> get docs;
-}
-
-abstract class HasDartDocsBuilder {
- /// Dart docs.
- ListBuilder<String> docs;
-}
diff --git a/code_builder/lib/src/mixins/generics.dart b/code_builder/lib/src/mixins/generics.dart
deleted file mode 100644
index 04a049e..0000000
--- a/code_builder/lib/src/mixins/generics.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2017, 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:built_collection/built_collection.dart';
-
-import '../specs/reference.dart';
-
-abstract class HasGenerics {
- /// Generic type parameters.
- BuiltList<Reference> get types;
-}
-
-abstract class HasGenericsBuilder {
- /// Generic type parameters.
- ListBuilder<Reference> types;
-}
diff --git a/code_builder/lib/src/specs/class.dart b/code_builder/lib/src/specs/class.dart
deleted file mode 100644
index 3e596a6..0000000
--- a/code_builder/lib/src/specs/class.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'constructor.dart';
-import 'expression.dart';
-import 'field.dart';
-import 'method.dart';
-import 'reference.dart';
-
-part 'class.g.dart';
-
-@immutable
-abstract class Class extends Object
- with HasAnnotations, HasDartDocs, HasGenerics
- implements Built<Class, ClassBuilder>, Spec {
- factory Class([void updates(ClassBuilder b)]) = _$Class;
-
- Class._();
-
- /// Whether the class is `abstract`.
- bool get abstract;
-
- @override
- BuiltList<Expression> get annotations;
-
- @override
- BuiltList<String> get docs;
-
- @nullable
- Reference get extend;
-
- BuiltList<Reference> get implements;
-
- BuiltList<Reference> get mixins;
-
- @override
- BuiltList<Reference> get types;
-
- BuiltList<Constructor> get constructors;
- BuiltList<Method> get methods;
- BuiltList<Field> get fields;
-
- /// Name of the class.
- String get name;
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitClass(this, context);
-}
-
-abstract class ClassBuilder extends Object
- with HasAnnotationsBuilder, HasDartDocsBuilder, HasGenericsBuilder
- implements Builder<Class, ClassBuilder> {
- factory ClassBuilder() = _$ClassBuilder;
-
- ClassBuilder._();
-
- /// Whether the class is `abstract`.
- bool abstract = false;
-
- @override
- ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
- @override
- ListBuilder<String> docs = ListBuilder<String>();
-
- Reference extend;
-
- ListBuilder<Reference> implements = ListBuilder<Reference>();
- ListBuilder<Reference> mixins = ListBuilder<Reference>();
-
- @override
- ListBuilder<Reference> types = ListBuilder<Reference>();
-
- ListBuilder<Constructor> constructors = ListBuilder<Constructor>();
- ListBuilder<Method> methods = ListBuilder<Method>();
- ListBuilder<Field> fields = ListBuilder<Field>();
-
- /// Name of the class.
- String name;
-}
diff --git a/code_builder/lib/src/specs/class.g.dart b/code_builder/lib/src/specs/class.g.dart
deleted file mode 100644
index 68cff19..0000000
--- a/code_builder/lib/src/specs/class.g.dart
+++ /dev/null
@@ -1,353 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'class.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Class extends Class {
- @override
- final bool abstract;
- @override
- final BuiltList<Expression> annotations;
- @override
- final BuiltList<String> docs;
- @override
- final Reference extend;
- @override
- final BuiltList<Reference> implements;
- @override
- final BuiltList<Reference> mixins;
- @override
- final BuiltList<Reference> types;
- @override
- final BuiltList<Constructor> constructors;
- @override
- final BuiltList<Method> methods;
- @override
- final BuiltList<Field> fields;
- @override
- final String name;
-
- factory _$Class([void updates(ClassBuilder b)]) =>
- (new ClassBuilder()..update(updates)).build() as _$Class;
-
- _$Class._(
- {this.abstract,
- this.annotations,
- this.docs,
- this.extend,
- this.implements,
- this.mixins,
- this.types,
- this.constructors,
- this.methods,
- this.fields,
- this.name})
- : super._() {
- if (abstract == null)
- throw new BuiltValueNullFieldError('Class', 'abstract');
- if (annotations == null)
- throw new BuiltValueNullFieldError('Class', 'annotations');
- if (docs == null) throw new BuiltValueNullFieldError('Class', 'docs');
- if (implements == null)
- throw new BuiltValueNullFieldError('Class', 'implements');
- if (mixins == null) throw new BuiltValueNullFieldError('Class', 'mixins');
- if (types == null) throw new BuiltValueNullFieldError('Class', 'types');
- if (constructors == null)
- throw new BuiltValueNullFieldError('Class', 'constructors');
- if (methods == null) throw new BuiltValueNullFieldError('Class', 'methods');
- if (fields == null) throw new BuiltValueNullFieldError('Class', 'fields');
- if (name == null) throw new BuiltValueNullFieldError('Class', 'name');
- }
-
- @override
- Class rebuild(void updates(ClassBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$ClassBuilder toBuilder() => new _$ClassBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Class) return false;
- return abstract == other.abstract &&
- annotations == other.annotations &&
- docs == other.docs &&
- extend == other.extend &&
- implements == other.implements &&
- mixins == other.mixins &&
- types == other.types &&
- constructors == other.constructors &&
- methods == other.methods &&
- fields == other.fields &&
- name == other.name;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc($jc(0, abstract.hashCode),
- annotations.hashCode),
- docs.hashCode),
- extend.hashCode),
- implements.hashCode),
- mixins.hashCode),
- types.hashCode),
- constructors.hashCode),
- methods.hashCode),
- fields.hashCode),
- name.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Class')
- ..add('abstract', abstract)
- ..add('annotations', annotations)
- ..add('docs', docs)
- ..add('extend', extend)
- ..add('implements', implements)
- ..add('mixins', mixins)
- ..add('types', types)
- ..add('constructors', constructors)
- ..add('methods', methods)
- ..add('fields', fields)
- ..add('name', name))
- .toString();
- }
-}
-
-class _$ClassBuilder extends ClassBuilder {
- _$Class _$v;
-
- @override
- bool get abstract {
- _$this;
- return super.abstract;
- }
-
- @override
- set abstract(bool abstract) {
- _$this;
- super.abstract = abstract;
- }
-
- @override
- ListBuilder<Expression> get annotations {
- _$this;
- return super.annotations ??= new ListBuilder<Expression>();
- }
-
- @override
- set annotations(ListBuilder<Expression> annotations) {
- _$this;
- super.annotations = annotations;
- }
-
- @override
- ListBuilder<String> get docs {
- _$this;
- return super.docs ??= new ListBuilder<String>();
- }
-
- @override
- set docs(ListBuilder<String> docs) {
- _$this;
- super.docs = docs;
- }
-
- @override
- Reference get extend {
- _$this;
- return super.extend;
- }
-
- @override
- set extend(Reference extend) {
- _$this;
- super.extend = extend;
- }
-
- @override
- ListBuilder<Reference> get implements {
- _$this;
- return super.implements ??= new ListBuilder<Reference>();
- }
-
- @override
- set implements(ListBuilder<Reference> implements) {
- _$this;
- super.implements = implements;
- }
-
- @override
- ListBuilder<Reference> get mixins {
- _$this;
- return super.mixins ??= new ListBuilder<Reference>();
- }
-
- @override
- set mixins(ListBuilder<Reference> mixins) {
- _$this;
- super.mixins = mixins;
- }
-
- @override
- ListBuilder<Reference> get types {
- _$this;
- return super.types ??= new ListBuilder<Reference>();
- }
-
- @override
- set types(ListBuilder<Reference> types) {
- _$this;
- super.types = types;
- }
-
- @override
- ListBuilder<Constructor> get constructors {
- _$this;
- return super.constructors ??= new ListBuilder<Constructor>();
- }
-
- @override
- set constructors(ListBuilder<Constructor> constructors) {
- _$this;
- super.constructors = constructors;
- }
-
- @override
- ListBuilder<Method> get methods {
- _$this;
- return super.methods ??= new ListBuilder<Method>();
- }
-
- @override
- set methods(ListBuilder<Method> methods) {
- _$this;
- super.methods = methods;
- }
-
- @override
- ListBuilder<Field> get fields {
- _$this;
- return super.fields ??= new ListBuilder<Field>();
- }
-
- @override
- set fields(ListBuilder<Field> fields) {
- _$this;
- super.fields = fields;
- }
-
- @override
- String get name {
- _$this;
- return super.name;
- }
-
- @override
- set name(String name) {
- _$this;
- super.name = name;
- }
-
- _$ClassBuilder() : super._();
-
- ClassBuilder get _$this {
- if (_$v != null) {
- super.abstract = _$v.abstract;
- super.annotations = _$v.annotations?.toBuilder();
- super.docs = _$v.docs?.toBuilder();
- super.extend = _$v.extend;
- super.implements = _$v.implements?.toBuilder();
- super.mixins = _$v.mixins?.toBuilder();
- super.types = _$v.types?.toBuilder();
- super.constructors = _$v.constructors?.toBuilder();
- super.methods = _$v.methods?.toBuilder();
- super.fields = _$v.fields?.toBuilder();
- super.name = _$v.name;
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Class other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Class;
- }
-
- @override
- void update(void updates(ClassBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Class build() {
- _$Class _$result;
- try {
- _$result = _$v ??
- new _$Class._(
- abstract: abstract,
- annotations: annotations.build(),
- docs: docs.build(),
- extend: extend,
- implements: implements.build(),
- mixins: mixins.build(),
- types: types.build(),
- constructors: constructors.build(),
- methods: methods.build(),
- fields: fields.build(),
- name: name);
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'annotations';
- annotations.build();
- _$failedField = 'docs';
- docs.build();
-
- _$failedField = 'implements';
- implements.build();
- _$failedField = 'mixins';
- mixins.build();
- _$failedField = 'types';
- types.build();
- _$failedField = 'constructors';
- constructors.build();
- _$failedField = 'methods';
- methods.build();
- _$failedField = 'fields';
- fields.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Class', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/code.dart b/code_builder/lib/src/specs/code.dart
deleted file mode 100644
index e14c102..0000000
--- a/code_builder/lib/src/specs/code.dart
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../allocator.dart';
-import '../base.dart';
-import '../emitter.dart';
-import '../visitors.dart';
-
-import 'expression.dart';
-import 'reference.dart';
-
-part 'code.g.dart';
-
-/// Returns a scoped symbol to [Reference], with an import prefix if needed.
-///
-/// This is short-hand for [Allocator.allocate] in most implementations.
-typedef String Allocate(Reference reference);
-
-/// Represents arbitrary Dart code (either expressions or statements).
-///
-/// See the various constructors for details.
-abstract class Code implements Spec {
- /// Create a simple code body based on a static string.
- const factory Code(String code) = StaticCode._;
-
- /// Create a code based that may use a provided [Allocator] for scoping:
- ///
- /// ```dart
- /// // Emits `_i123.FooType()`, where `_i123` is the import prefix.
- ///
- /// Code.scope((a) {
- /// return '${a.allocate(fooType)}()'
- /// });
- /// ```
- const factory Code.scope(
- String Function(Allocate allocate) scope,
- ) = ScopedCode._;
-
- @override
- R accept<R>(covariant CodeVisitor<R> visitor, [R context]);
-}
-
-/// Represents blocks of statements of Dart code.
-abstract class Block implements Built<Block, BlockBuilder>, Code, Spec {
- factory Block([void updates(BlockBuilder b)]) = _$Block;
-
- factory Block.of(Iterable<Code> statements) {
- return Block((b) => b..statements.addAll(statements));
- }
-
- Block._();
-
- @override
- R accept<R>(covariant CodeVisitor<R> visitor, [R context]) {
- return visitor.visitBlock(this, context);
- }
-
- BuiltList<Code> get statements;
-}
-
-abstract class BlockBuilder implements Builder<Block, BlockBuilder> {
- factory BlockBuilder() = _$BlockBuilder;
-
- BlockBuilder._();
-
- /// Adds an [expression] to [statements].
- ///
- /// **NOTE**: Not all expressions are _useful_ statements.
- void addExpression(Expression expression) {
- statements.add(expression.statement);
- }
-
- ListBuilder<Code> statements = ListBuilder<Code>();
-}
-
-/// Knowledge of different types of blocks of code in Dart.
-///
-/// **INTERNAL ONLY**.
-abstract class CodeVisitor<T> implements SpecVisitor<T> {
- T visitBlock(Block code, [T context]);
- T visitStaticCode(StaticCode code, [T context]);
- T visitScopedCode(ScopedCode code, [T context]);
-}
-
-/// Knowledge of how to write valid Dart code from [CodeVisitor].
-abstract class CodeEmitter implements CodeVisitor<StringSink> {
- @protected
- Allocator get allocator;
-
- @override
- visitBlock(Block block, [StringSink output]) {
- output ??= StringBuffer();
- return visitAll<Code>(block.statements, output, (statement) {
- statement.accept(this, output);
- }, '\n');
- }
-
- @override
- visitStaticCode(StaticCode code, [StringSink output]) {
- output ??= StringBuffer();
- return output..write(code.code);
- }
-
- @override
- visitScopedCode(ScopedCode code, [StringSink output]) {
- output ??= StringBuffer();
- return output..write(code.code(allocator.allocate));
- }
-}
-
-/// Represents a code block that requires lazy visiting.
-class LazyCode implements Code {
- final Spec Function(SpecVisitor) generate;
-
- const LazyCode._(this.generate);
-
- @override
- R accept<R>(CodeVisitor<R> visitor, [R context]) {
- return generate(visitor).accept(visitor, context);
- }
-}
-
-/// Returns a generic [Code] that is lazily generated when visited.
-Code lazyCode(Code Function() generate) => _LazyCode(generate);
-
-class _LazyCode implements Code {
- final Code Function() generate;
-
- const _LazyCode(this.generate);
-
- @override
- R accept<R>(CodeVisitor<R> visitor, [R context]) {
- return generate().accept(visitor, context);
- }
-}
-
-/// Represents a simple, literal code block to be inserted as-is.
-class StaticCode implements Code {
- final String code;
-
- const StaticCode._(this.code);
-
- @override
- R accept<R>(CodeVisitor<R> visitor, [R context]) {
- return visitor.visitStaticCode(this, context);
- }
-
- @override
- String toString() => code;
-}
-
-/// Represents a code block that may require scoping.
-class ScopedCode implements Code {
- final String Function(Allocate) code;
-
- const ScopedCode._(this.code);
-
- @override
- R accept<R>(CodeVisitor<R> visitor, [R context]) {
- return visitor.visitScopedCode(this, context);
- }
-
- @override
- String toString() => code((ref) => ref.symbol);
-}
diff --git a/code_builder/lib/src/specs/code.g.dart b/code_builder/lib/src/specs/code.g.dart
deleted file mode 100644
index 5243ec8..0000000
--- a/code_builder/lib/src/specs/code.g.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'code.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Block extends Block {
- @override
- final BuiltList<Code> statements;
-
- factory _$Block([void updates(BlockBuilder b)]) =>
- (new BlockBuilder()..update(updates)).build() as _$Block;
-
- _$Block._({this.statements}) : super._() {
- if (statements == null)
- throw new BuiltValueNullFieldError('Block', 'statements');
- }
-
- @override
- Block rebuild(void updates(BlockBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$BlockBuilder toBuilder() => new _$BlockBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Block) return false;
- return statements == other.statements;
- }
-
- @override
- int get hashCode {
- return $jf($jc(0, statements.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Block')..add('statements', statements))
- .toString();
- }
-}
-
-class _$BlockBuilder extends BlockBuilder {
- _$Block _$v;
-
- @override
- ListBuilder<Code> get statements {
- _$this;
- return super.statements ??= new ListBuilder<Code>();
- }
-
- @override
- set statements(ListBuilder<Code> statements) {
- _$this;
- super.statements = statements;
- }
-
- _$BlockBuilder() : super._();
-
- BlockBuilder get _$this {
- if (_$v != null) {
- super.statements = _$v.statements?.toBuilder();
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Block other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Block;
- }
-
- @override
- void update(void updates(BlockBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Block build() {
- _$Block _$result;
- try {
- _$result = _$v ?? new _$Block._(statements: statements.build());
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'statements';
- statements.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Block', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/constructor.dart b/code_builder/lib/src/specs/constructor.dart
deleted file mode 100644
index 04fcc70..0000000
--- a/code_builder/lib/src/specs/constructor.dart
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'method.dart';
-import 'reference.dart';
-
-part 'constructor.g.dart';
-
-@immutable
-abstract class Constructor extends Object
- with HasAnnotations, HasDartDocs
- implements Built<Constructor, ConstructorBuilder> {
- factory Constructor([void updates(ConstructorBuilder b)]) = _$Constructor;
-
- Constructor._();
-
- @override
- BuiltList<Expression> get annotations;
-
- @override
- BuiltList<String> get docs;
-
- /// Optional parameters.
- BuiltList<Parameter> get optionalParameters;
-
- /// Required parameters.
- BuiltList<Parameter> get requiredParameters;
-
- /// Constructor initializer statements.
- BuiltList<Code> get initializers;
-
- /// Body of the method.
- @nullable
- Code get body;
-
- /// Whether the constructor should be prefixed with `external`.
- bool get external;
-
- /// Whether the constructor should be prefixed with `const`.
- bool get constant;
-
- /// Whether this constructor should be prefixed with `factory`.
- bool get factory;
-
- /// Whether this constructor is a simple lambda expression.
- @nullable
- bool get lambda;
-
- /// Name of the constructor - optional.
- @nullable
- String get name;
-
- /// If non-null, redirect to this constructor.
- @nullable
- Reference get redirect;
-}
-
-abstract class ConstructorBuilder extends Object
- with HasAnnotationsBuilder, HasDartDocsBuilder
- implements Builder<Constructor, ConstructorBuilder> {
- factory ConstructorBuilder() = _$ConstructorBuilder;
-
- ConstructorBuilder._();
-
- @override
- ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
- @override
- ListBuilder<String> docs = ListBuilder<String>();
-
- /// Optional parameters.
- ListBuilder<Parameter> optionalParameters = ListBuilder<Parameter>();
-
- /// Required parameters.
- ListBuilder<Parameter> requiredParameters = ListBuilder<Parameter>();
-
- /// Constructor initializer statements.
- ListBuilder<Code> initializers = ListBuilder<Code>();
-
- /// Body of the constructor.
- Code body;
-
- /// Whether the constructor should be prefixed with `const`.
- bool constant = false;
-
- /// Whether the constructor should be prefixed with `external`.
- bool external = false;
-
- /// Whether this constructor should be prefixed with `factory`.
- bool factory = false;
-
- /// Whether this constructor is a simple lambda expression.
- bool lambda;
-
- /// Name of the constructor - optional.
- String name;
-
- /// If non-null, redirect to this constructor.
- @nullable
- Reference redirect;
-}
diff --git a/code_builder/lib/src/specs/constructor.g.dart b/code_builder/lib/src/specs/constructor.g.dart
deleted file mode 100644
index efc08f2..0000000
--- a/code_builder/lib/src/specs/constructor.g.dart
+++ /dev/null
@@ -1,368 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'constructor.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Constructor extends Constructor {
- @override
- final BuiltList<Expression> annotations;
- @override
- final BuiltList<String> docs;
- @override
- final BuiltList<Parameter> optionalParameters;
- @override
- final BuiltList<Parameter> requiredParameters;
- @override
- final BuiltList<Code> initializers;
- @override
- final Code body;
- @override
- final bool external;
- @override
- final bool constant;
- @override
- final bool factory;
- @override
- final bool lambda;
- @override
- final String name;
- @override
- final Reference redirect;
-
- factory _$Constructor([void updates(ConstructorBuilder b)]) =>
- (new ConstructorBuilder()..update(updates)).build() as _$Constructor;
-
- _$Constructor._(
- {this.annotations,
- this.docs,
- this.optionalParameters,
- this.requiredParameters,
- this.initializers,
- this.body,
- this.external,
- this.constant,
- this.factory,
- this.lambda,
- this.name,
- this.redirect})
- : super._() {
- if (annotations == null)
- throw new BuiltValueNullFieldError('Constructor', 'annotations');
- if (docs == null) throw new BuiltValueNullFieldError('Constructor', 'docs');
- if (optionalParameters == null)
- throw new BuiltValueNullFieldError('Constructor', 'optionalParameters');
- if (requiredParameters == null)
- throw new BuiltValueNullFieldError('Constructor', 'requiredParameters');
- if (initializers == null)
- throw new BuiltValueNullFieldError('Constructor', 'initializers');
- if (external == null)
- throw new BuiltValueNullFieldError('Constructor', 'external');
- if (constant == null)
- throw new BuiltValueNullFieldError('Constructor', 'constant');
- if (factory == null)
- throw new BuiltValueNullFieldError('Constructor', 'factory');
- }
-
- @override
- Constructor rebuild(void updates(ConstructorBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$ConstructorBuilder toBuilder() => new _$ConstructorBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Constructor) return false;
- return annotations == other.annotations &&
- docs == other.docs &&
- optionalParameters == other.optionalParameters &&
- requiredParameters == other.requiredParameters &&
- initializers == other.initializers &&
- body == other.body &&
- external == other.external &&
- constant == other.constant &&
- factory == other.factory &&
- lambda == other.lambda &&
- name == other.name &&
- redirect == other.redirect;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc($jc(0, annotations.hashCode),
- docs.hashCode),
- optionalParameters.hashCode),
- requiredParameters.hashCode),
- initializers.hashCode),
- body.hashCode),
- external.hashCode),
- constant.hashCode),
- factory.hashCode),
- lambda.hashCode),
- name.hashCode),
- redirect.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Constructor')
- ..add('annotations', annotations)
- ..add('docs', docs)
- ..add('optionalParameters', optionalParameters)
- ..add('requiredParameters', requiredParameters)
- ..add('initializers', initializers)
- ..add('body', body)
- ..add('external', external)
- ..add('constant', constant)
- ..add('factory', factory)
- ..add('lambda', lambda)
- ..add('name', name)
- ..add('redirect', redirect))
- .toString();
- }
-}
-
-class _$ConstructorBuilder extends ConstructorBuilder {
- _$Constructor _$v;
-
- @override
- ListBuilder<Expression> get annotations {
- _$this;
- return super.annotations ??= new ListBuilder<Expression>();
- }
-
- @override
- set annotations(ListBuilder<Expression> annotations) {
- _$this;
- super.annotations = annotations;
- }
-
- @override
- ListBuilder<String> get docs {
- _$this;
- return super.docs ??= new ListBuilder<String>();
- }
-
- @override
- set docs(ListBuilder<String> docs) {
- _$this;
- super.docs = docs;
- }
-
- @override
- ListBuilder<Parameter> get optionalParameters {
- _$this;
- return super.optionalParameters ??= new ListBuilder<Parameter>();
- }
-
- @override
- set optionalParameters(ListBuilder<Parameter> optionalParameters) {
- _$this;
- super.optionalParameters = optionalParameters;
- }
-
- @override
- ListBuilder<Parameter> get requiredParameters {
- _$this;
- return super.requiredParameters ??= new ListBuilder<Parameter>();
- }
-
- @override
- set requiredParameters(ListBuilder<Parameter> requiredParameters) {
- _$this;
- super.requiredParameters = requiredParameters;
- }
-
- @override
- ListBuilder<Code> get initializers {
- _$this;
- return super.initializers ??= new ListBuilder<Code>();
- }
-
- @override
- set initializers(ListBuilder<Code> initializers) {
- _$this;
- super.initializers = initializers;
- }
-
- @override
- Code get body {
- _$this;
- return super.body;
- }
-
- @override
- set body(Code body) {
- _$this;
- super.body = body;
- }
-
- @override
- bool get external {
- _$this;
- return super.external;
- }
-
- @override
- set external(bool external) {
- _$this;
- super.external = external;
- }
-
- @override
- bool get constant {
- _$this;
- return super.constant;
- }
-
- @override
- set constant(bool constant) {
- _$this;
- super.constant = constant;
- }
-
- @override
- bool get factory {
- _$this;
- return super.factory;
- }
-
- @override
- set factory(bool factory) {
- _$this;
- super.factory = factory;
- }
-
- @override
- bool get lambda {
- _$this;
- return super.lambda;
- }
-
- @override
- set lambda(bool lambda) {
- _$this;
- super.lambda = lambda;
- }
-
- @override
- String get name {
- _$this;
- return super.name;
- }
-
- @override
- set name(String name) {
- _$this;
- super.name = name;
- }
-
- @override
- Reference get redirect {
- _$this;
- return super.redirect;
- }
-
- @override
- set redirect(Reference redirect) {
- _$this;
- super.redirect = redirect;
- }
-
- _$ConstructorBuilder() : super._();
-
- ConstructorBuilder get _$this {
- if (_$v != null) {
- super.annotations = _$v.annotations?.toBuilder();
- super.docs = _$v.docs?.toBuilder();
- super.optionalParameters = _$v.optionalParameters?.toBuilder();
- super.requiredParameters = _$v.requiredParameters?.toBuilder();
- super.initializers = _$v.initializers?.toBuilder();
- super.body = _$v.body;
- super.external = _$v.external;
- super.constant = _$v.constant;
- super.factory = _$v.factory;
- super.lambda = _$v.lambda;
- super.name = _$v.name;
- super.redirect = _$v.redirect;
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Constructor other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Constructor;
- }
-
- @override
- void update(void updates(ConstructorBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Constructor build() {
- _$Constructor _$result;
- try {
- _$result = _$v ??
- new _$Constructor._(
- annotations: annotations.build(),
- docs: docs.build(),
- optionalParameters: optionalParameters.build(),
- requiredParameters: requiredParameters.build(),
- initializers: initializers.build(),
- body: body,
- external: external,
- constant: constant,
- factory: factory,
- lambda: lambda,
- name: name,
- redirect: redirect);
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'annotations';
- annotations.build();
- _$failedField = 'docs';
- docs.build();
- _$failedField = 'optionalParameters';
- optionalParameters.build();
- _$failedField = 'requiredParameters';
- requiredParameters.build();
- _$failedField = 'initializers';
- initializers.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Constructor', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/directive.dart b/code_builder/lib/src/specs/directive.dart
deleted file mode 100644
index 69e93ff..0000000
--- a/code_builder/lib/src/specs/directive.dart
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:collection/collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../visitors.dart';
-
-part 'directive.g.dart';
-
-@immutable
-abstract class Directive
- implements Built<Directive, DirectiveBuilder>, Spec, Comparable<Directive> {
- factory Directive([void updates(DirectiveBuilder b)]) = _$Directive;
-
- factory Directive.import(
- String url, {
- String as,
- List<String> show = const [],
- List<String> hide = const [],
- }) =>
- Directive((builder) => builder
- ..as = as
- ..type = DirectiveType.import
- ..url = url
- ..show.addAll(show)
- ..hide.addAll(hide));
-
- factory Directive.importDeferredAs(
- String url,
- String as, {
- List<String> show = const [],
- List<String> hide = const [],
- }) =>
- Directive((builder) => builder
- ..as = as
- ..type = DirectiveType.import
- ..url = url
- ..deferred = true
- ..show.addAll(show)
- ..hide.addAll(hide));
-
- factory Directive.export(
- String url, {
- List<String> show = const [],
- List<String> hide = const [],
- }) =>
- Directive((builder) => builder
- ..type = DirectiveType.export
- ..url = url
- ..show.addAll(show)
- ..hide.addAll(hide));
-
- Directive._();
-
- @nullable
- String get as;
-
- String get url;
-
- DirectiveType get type;
-
- List<String> get show;
-
- List<String> get hide;
-
- bool get deferred;
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitDirective(this, context);
-
- @override
- int compareTo(Directive other) => _compareDirectives(this, other);
-}
-
-abstract class DirectiveBuilder
- implements Builder<Directive, DirectiveBuilder> {
- factory DirectiveBuilder() = _$DirectiveBuilder;
-
- DirectiveBuilder._();
-
- bool deferred = false;
-
- String as;
-
- String url;
-
- List<String> show = <String>[];
-
- List<String> hide = <String>[];
-
- DirectiveType type;
-}
-
-enum DirectiveType {
- import,
- export,
-}
-
-/// Sort import URIs represented by [a] and [b] to honor the
-/// "Effective Dart" ordering rules which are enforced by the
-/// `directives_ordering` lint.
-///
-/// 1. `import`s before `export`s
-/// 2. `dart:`
-/// 3. `package:`
-/// 4. relative
-int _compareDirectives(Directive a, Directive b) {
- // NOTE: using the fact that `import` is before `export` in the
- // `DirectiveType` enum – which allows us to compare using `indexOf`.
- var value = DirectiveType.values
- .indexOf(a.type)
- .compareTo(DirectiveType.values.indexOf(b.type));
-
- if (value == 0) {
- final uriA = Uri.parse(a.url);
- final uriB = Uri.parse(b.url);
-
- if (uriA.hasScheme) {
- if (uriB.hasScheme) {
- // If both import URIs have schemes, compare them based on scheme
- // `dart` will sort before `package` which is what we want
- // schemes are case-insensitive, so compare accordingly
- value = compareAsciiLowerCase(uriA.scheme, uriB.scheme);
- } else {
- value = -1;
- }
- } else if (uriB.hasScheme) {
- value = 1;
- }
-
- // If both schemes are the same, compare based on path
- if (value == 0) {
- value = compareAsciiLowerCase(uriA.path, uriB.path);
- }
-
- assert((value == 0) == (a.url == b.url));
- }
-
- return value;
-}
diff --git a/code_builder/lib/src/specs/directive.g.dart b/code_builder/lib/src/specs/directive.g.dart
deleted file mode 100644
index a1717b2..0000000
--- a/code_builder/lib/src/specs/directive.g.dart
+++ /dev/null
@@ -1,203 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'directive.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Directive extends Directive {
- @override
- final String as;
- @override
- final String url;
- @override
- final DirectiveType type;
- @override
- final List<String> show;
- @override
- final List<String> hide;
- @override
- final bool deferred;
-
- factory _$Directive([void updates(DirectiveBuilder b)]) =>
- (new DirectiveBuilder()..update(updates)).build() as _$Directive;
-
- _$Directive._(
- {this.as, this.url, this.type, this.show, this.hide, this.deferred})
- : super._() {
- if (url == null) throw new BuiltValueNullFieldError('Directive', 'url');
- if (type == null) throw new BuiltValueNullFieldError('Directive', 'type');
- if (show == null) throw new BuiltValueNullFieldError('Directive', 'show');
- if (hide == null) throw new BuiltValueNullFieldError('Directive', 'hide');
- if (deferred == null)
- throw new BuiltValueNullFieldError('Directive', 'deferred');
- }
-
- @override
- Directive rebuild(void updates(DirectiveBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$DirectiveBuilder toBuilder() => new _$DirectiveBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Directive) return false;
- return as == other.as &&
- url == other.url &&
- type == other.type &&
- show == other.show &&
- hide == other.hide &&
- deferred == other.deferred;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc($jc($jc($jc(0, as.hashCode), url.hashCode), type.hashCode),
- show.hashCode),
- hide.hashCode),
- deferred.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Directive')
- ..add('as', as)
- ..add('url', url)
- ..add('type', type)
- ..add('show', show)
- ..add('hide', hide)
- ..add('deferred', deferred))
- .toString();
- }
-}
-
-class _$DirectiveBuilder extends DirectiveBuilder {
- _$Directive _$v;
-
- @override
- String get as {
- _$this;
- return super.as;
- }
-
- @override
- set as(String as) {
- _$this;
- super.as = as;
- }
-
- @override
- String get url {
- _$this;
- return super.url;
- }
-
- @override
- set url(String url) {
- _$this;
- super.url = url;
- }
-
- @override
- DirectiveType get type {
- _$this;
- return super.type;
- }
-
- @override
- set type(DirectiveType type) {
- _$this;
- super.type = type;
- }
-
- @override
- List<String> get show {
- _$this;
- return super.show;
- }
-
- @override
- set show(List<String> show) {
- _$this;
- super.show = show;
- }
-
- @override
- List<String> get hide {
- _$this;
- return super.hide;
- }
-
- @override
- set hide(List<String> hide) {
- _$this;
- super.hide = hide;
- }
-
- @override
- bool get deferred {
- _$this;
- return super.deferred;
- }
-
- @override
- set deferred(bool deferred) {
- _$this;
- super.deferred = deferred;
- }
-
- _$DirectiveBuilder() : super._();
-
- DirectiveBuilder get _$this {
- if (_$v != null) {
- super.as = _$v.as;
- super.url = _$v.url;
- super.type = _$v.type;
- super.show = _$v.show;
- super.hide = _$v.hide;
- super.deferred = _$v.deferred;
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Directive other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Directive;
- }
-
- @override
- void update(void updates(DirectiveBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Directive build() {
- final _$result = _$v ??
- new _$Directive._(
- as: as,
- url: url,
- type: type,
- show: show,
- hide: hide,
- deferred: deferred);
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/expression.dart b/code_builder/lib/src/specs/expression.dart
deleted file mode 100644
index cbbf6d4..0000000
--- a/code_builder/lib/src/specs/expression.dart
+++ /dev/null
@@ -1,573 +0,0 @@
-// Copyright (c) 2017, 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.
-
-library code_builder.src.specs.expression;
-
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../emitter.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'method.dart';
-import 'reference.dart';
-import 'type_function.dart';
-
-part 'expression/binary.dart';
-part 'expression/closure.dart';
-part 'expression/code.dart';
-part 'expression/invoke.dart';
-part 'expression/literal.dart';
-
-/// Represents a [code] block that wraps an [Expression].
-
-/// Represents a Dart expression.
-///
-/// See various concrete implementations for details.
-abstract class Expression implements Spec {
- const Expression();
-
- /// An empty expression.
- static const _empty = CodeExpression(Code(''));
-
- @override
- R accept<R>(covariant ExpressionVisitor<R> visitor, [R context]);
-
- /// The expression as a valid [Code] block.
- ///
- /// Also see [statement].
- Code get code => ToCodeExpression(this, false);
-
- /// The expression as a valid [Code] block with a trailing `;`.
- Code get statement => ToCodeExpression(this, true);
-
- /// Returns the result of `this` `&&` [other].
- Expression and(Expression other) {
- return BinaryExpression._(expression, other, '&&');
- }
-
- /// Returns the result of `this` `||` [other].
- Expression or(Expression other) {
- return BinaryExpression._(expression, other, '||');
- }
-
- /// Returns the result of `!this`.
- Expression negate() {
- return BinaryExpression._(_empty, expression, '!', addSpace: false);
- }
-
- /// Returns the result of `this` `as` [other].
- Expression asA(Expression other) {
- return CodeExpression(Block.of([
- const Code('('),
- BinaryExpression._(
- expression,
- other,
- 'as',
- ).code,
- const Code(')')
- ]));
- }
-
- /// Returns accessing the index operator (`[]`) on `this`.
- Expression index(Expression index) {
- return BinaryExpression._(
- expression,
- CodeExpression(Block.of([
- const Code('['),
- index.code,
- const Code(']'),
- ])),
- '',
- );
- }
-
- /// Returns the result of `this` `is` [other].
- Expression isA(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- 'is',
- );
- }
-
- /// Returns the result of `this` `is!` [other].
- Expression isNotA(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- 'is!',
- );
- }
-
- /// Returns the result of `this` `==` [other].
- Expression equalTo(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '==',
- );
- }
-
- /// Returns the result of `this` `!=` [other].
- Expression notEqualTo(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '!=',
- );
- }
-
- /// Returns the result of `this` `>` [other].
- Expression greaterThan(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '>',
- );
- }
-
- /// Returns the result of `this` `<` [other].
- Expression lessThan(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '<',
- );
- }
-
- /// Returns the result of `this` `>=` [other].
- Expression greaterOrEqualTo(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '>=',
- );
- }
-
- /// Returns the result of `this` `<=` [other].
- Expression lessOrEqualTo(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '<=',
- );
- }
-
- /// Returns the result of `this` `+` [other].
- Expression operatorAdd(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '+',
- );
- }
-
- /// Returns the result of `this` `-` [other].
- Expression operatorSubstract(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '-',
- );
- }
-
- /// Returns the result of `this` `/` [other].
- Expression operatorDivide(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '/',
- );
- }
-
- /// Returns the result of `this` `*` [other].
- Expression operatorMultiply(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '*',
- );
- }
-
- /// Returns the result of `this` `%` [other].
- Expression operatorEuclideanModulo(Expression other) {
- return BinaryExpression._(
- expression,
- other,
- '%',
- );
- }
-
- Expression conditional(Expression whenTrue, Expression whenFalse) {
- return BinaryExpression._(
- expression,
- BinaryExpression._(whenTrue, whenFalse, ':'),
- '?',
- );
- }
-
- /// This expression preceded by `await`.
- Expression get awaited {
- return BinaryExpression._(
- _empty,
- this,
- 'await',
- );
- }
-
- /// Return `{other} = {this}`.
- Expression assign(Expression other) {
- return BinaryExpression._(
- this,
- other,
- '=',
- );
- }
-
- /// Return `{other} ??= {this}`.
- Expression assignNullAware(Expression other) {
- return BinaryExpression._(
- this,
- other,
- '??=',
- );
- }
-
- /// Return `var {name} = {this}`.
- Expression assignVar(String name, [Reference type]) {
- return BinaryExpression._(
- type == null
- ? LiteralExpression._('var $name')
- : BinaryExpression._(
- type.expression,
- LiteralExpression._(name),
- '',
- ),
- this,
- '=',
- );
- }
-
- /// Return `final {name} = {this}`.
- Expression assignFinal(String name, [Reference type]) {
- return BinaryExpression._(
- type == null
- ? const LiteralExpression._('final')
- : BinaryExpression._(
- const LiteralExpression._('final'),
- type.expression,
- '',
- ),
- this,
- '$name =',
- );
- }
-
- /// Return `const {name} = {this}`.
- Expression assignConst(String name, [Reference type]) {
- return BinaryExpression._(
- type == null
- ? const LiteralExpression._('const')
- : BinaryExpression._(
- const LiteralExpression._('const'),
- type.expression,
- '',
- ),
- this,
- '$name =',
- isConst: true,
- );
- }
-
- /// Call this expression as a method.
- Expression call(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression._(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- );
- }
-
- /// Returns an expression accessing `.<name>` on this expression.
- Expression property(String name) {
- return BinaryExpression._(
- this,
- LiteralExpression._(name),
- '.',
- addSpace: false,
- );
- }
-
- /// Returns an expression accessing `?.<name>` on this expression.
- Expression nullSafeProperty(String name) {
- return BinaryExpression._(
- this,
- LiteralExpression._(name),
- '?.',
- addSpace: false,
- );
- }
-
- /// This expression preceded by `return`.
- Expression get returned {
- return BinaryExpression._(
- const LiteralExpression._('return'),
- this,
- '',
- );
- }
-
- /// May be overridden to support other types implementing [Expression].
- @visibleForOverriding
- Expression get expression => this;
-}
-
-/// Creates `typedef {name} =`.
-Code createTypeDef(String name, FunctionType type) => BinaryExpression._(
- LiteralExpression._('typedef $name'), type.expression, '=')
- .statement;
-
-class ToCodeExpression implements Code {
- final Expression code;
-
- /// Whether this code should be considered a _statement_.
- final bool isStatement;
-
- @visibleForTesting
- const ToCodeExpression(this.code, [this.isStatement = false]);
-
- @override
- R accept<R>(CodeVisitor<R> visitor, [R context]) {
- return (visitor as ExpressionVisitor<R>)
- .visitToCodeExpression(this, context);
- }
-
- @override
- String toString() => code.toString();
-}
-
-/// Knowledge of different types of expressions in Dart.
-///
-/// **INTERNAL ONLY**.
-abstract class ExpressionVisitor<T> implements SpecVisitor<T> {
- T visitToCodeExpression(ToCodeExpression code, [T context]);
- T visitBinaryExpression(BinaryExpression expression, [T context]);
- T visitClosureExpression(ClosureExpression expression, [T context]);
- T visitCodeExpression(CodeExpression expression, [T context]);
- T visitInvokeExpression(InvokeExpression expression, [T context]);
- T visitLiteralExpression(LiteralExpression expression, [T context]);
- T visitLiteralListExpression(LiteralListExpression expression, [T context]);
- T visitLiteralSetExpression(LiteralSetExpression expression, [T context]);
- T visitLiteralMapExpression(LiteralMapExpression expression, [T context]);
-}
-
-/// Knowledge of how to write valid Dart code from [ExpressionVisitor].
-///
-/// **INTERNAL ONLY**.
-abstract class ExpressionEmitter implements ExpressionVisitor<StringSink> {
- @override
- visitToCodeExpression(ToCodeExpression expression, [StringSink output]) {
- output ??= StringBuffer();
- expression.code.accept(this, output);
- if (expression.isStatement) {
- output.write(';');
- }
- return output;
- }
-
- @override
- visitBinaryExpression(BinaryExpression expression, [StringSink output]) {
- output ??= StringBuffer();
- expression.left.accept(this, output);
- if (expression.addSpace) {
- output.write(' ');
- }
- output.write(expression.operator);
- if (expression.addSpace) {
- output.write(' ');
- }
- startConstCode(expression.isConst, () {
- expression.right.accept(this, output);
- });
- return output;
- }
-
- @override
- visitClosureExpression(ClosureExpression expression, [StringSink output]) {
- output ??= StringBuffer();
- return expression.method.accept(this, output);
- }
-
- @override
- visitCodeExpression(CodeExpression expression, [StringSink output]) {
- output ??= StringBuffer();
- final visitor = this as CodeVisitor<StringSink>;
- return expression.code.accept(visitor, output);
- }
-
- @override
- visitInvokeExpression(InvokeExpression expression, [StringSink output]) {
- output ??= StringBuffer();
- return _writeConstExpression(
- output, expression.type == InvokeExpressionType.constInstance, () {
- expression.target.accept(this, output);
- if (expression.name != null) {
- output..write('.')..write(expression.name);
- }
- if (expression.typeArguments.isNotEmpty) {
- output.write('<');
- visitAll<Reference>(expression.typeArguments, output, (type) {
- type.accept(this, output);
- });
- output.write('>');
- }
- output.write('(');
- visitAll<Spec>(expression.positionalArguments, output, (spec) {
- spec.accept(this, output);
- });
- if (expression.positionalArguments.isNotEmpty &&
- expression.namedArguments.isNotEmpty) {
- output.write(', ');
- }
- visitAll<String>(expression.namedArguments.keys, output, (name) {
- output..write(name)..write(': ');
- expression.namedArguments[name].accept(this, output);
- });
- return output..write(')');
- });
- }
-
- @override
- visitLiteralExpression(LiteralExpression expression, [StringSink output]) {
- output ??= StringBuffer();
- return output..write(expression.literal);
- }
-
- void _acceptLiteral(Object literalOrSpec, StringSink output) {
- if (literalOrSpec is Spec) {
- literalOrSpec.accept(this, output);
- return;
- }
- literal(literalOrSpec).accept(this, output);
- }
-
- bool _withInConstExpression = false;
-
- @override
- visitLiteralListExpression(
- LiteralListExpression expression, [
- StringSink output,
- ]) {
- output ??= StringBuffer();
-
- return _writeConstExpression(output, expression.isConst, () {
- if (expression.type != null) {
- output.write('<');
- expression.type.accept(this, output);
- output.write('>');
- }
- output.write('[');
- visitAll<Object>(expression.values, output, (value) {
- _acceptLiteral(value, output);
- });
- return output..write(']');
- });
- }
-
- @override
- visitLiteralSetExpression(
- LiteralSetExpression expression, [
- StringSink output,
- ]) {
- output ??= StringBuffer();
-
- return _writeConstExpression(output, expression.isConst, () {
- if (expression.type != null) {
- output.write('<');
- expression.type.accept(this, output);
- output.write('>');
- }
- output.write('{');
- visitAll<Object>(expression.values, output, (value) {
- _acceptLiteral(value, output);
- });
- return output..write('}');
- });
- }
-
- @override
- visitLiteralMapExpression(
- LiteralMapExpression expression, [
- StringSink output,
- ]) {
- output ??= StringBuffer();
- return _writeConstExpression(output, expression.isConst, () {
- if (expression.keyType != null) {
- output.write('<');
- expression.keyType.accept(this, output);
- output.write(', ');
- if (expression.valueType == null) {
- const Reference('dynamic', 'dart:core').accept(this, output);
- } else {
- expression.valueType.accept(this, output);
- }
- output.write('>');
- }
- output.write('{');
- visitAll<Object>(expression.values.keys, output, (key) {
- final value = expression.values[key];
- _acceptLiteral(key, output);
- output.write(': ');
- _acceptLiteral(value, output);
- });
- return output..write('}');
- });
- }
-
- /// Executes [visit] within a context which may alter the output if [isConst]
- /// is `true`.
- ///
- /// This allows constant expressions to omit the `const` keyword if they
- /// are already within a constant expression.
- void startConstCode(
- bool isConst,
- Null Function() visit,
- ) {
- final previousConstContext = _withInConstExpression;
- if (isConst) {
- _withInConstExpression = true;
- }
-
- visit();
- _withInConstExpression = previousConstContext;
- }
-
- /// Similar to [startConstCode], but handles writing `"const "` if [isConst]
- /// is `true` and the invocation is not nested under other invocations where
- /// [isConst] is true.
- StringSink _writeConstExpression(
- StringSink sink,
- bool isConst,
- StringSink Function() visitExpression,
- ) {
- final previousConstContext = _withInConstExpression;
- if (isConst) {
- if (!_withInConstExpression) {
- sink.write('const ');
- }
- _withInConstExpression = true;
- }
-
- final returnedSink = visitExpression();
- assert(identical(returnedSink, sink));
- _withInConstExpression = previousConstContext;
- return sink;
- }
-}
diff --git a/code_builder/lib/src/specs/expression/binary.dart b/code_builder/lib/src/specs/expression/binary.dart
deleted file mode 100644
index 1f7e76e..0000000
--- a/code_builder/lib/src/specs/expression/binary.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2017, 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.
-
-part of code_builder.src.specs.expression;
-
-/// Represents two expressions ([left] and [right]) and an [operator].
-class BinaryExpression extends Expression {
- final Expression left;
- final Expression right;
- final String operator;
- final bool addSpace;
- final bool isConst;
-
- const BinaryExpression._(
- this.left,
- this.right,
- this.operator, {
- this.addSpace = true,
- this.isConst = false,
- });
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitBinaryExpression(this, context);
- }
-}
diff --git a/code_builder/lib/src/specs/expression/closure.dart b/code_builder/lib/src/specs/expression/closure.dart
deleted file mode 100644
index 1af2760..0000000
--- a/code_builder/lib/src/specs/expression/closure.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2017, 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.
-
-part of code_builder.src.specs.expression;
-
-Expression toClosure(Method method) {
- final withoutTypes = method.rebuild((b) {
- b.returns = null;
- b.types.clear();
- });
- return ClosureExpression._(withoutTypes);
-}
-
-class ClosureExpression extends Expression {
- final Method method;
-
- const ClosureExpression._(this.method);
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitClosureExpression(this, context);
- }
-}
diff --git a/code_builder/lib/src/specs/expression/code.dart b/code_builder/lib/src/specs/expression/code.dart
deleted file mode 100644
index 7465448..0000000
--- a/code_builder/lib/src/specs/expression/code.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, 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.
-
-part of code_builder.src.specs.expression;
-
-/// Represents a [Code] block as an [Expression].
-class CodeExpression extends Expression {
- @override
- final Code code;
-
- /// **INTERNAL ONLY**: Used to wrap [Code] as an [Expression].
- const CodeExpression(this.code);
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitCodeExpression(this, context);
- }
-}
diff --git a/code_builder/lib/src/specs/expression/invoke.dart b/code_builder/lib/src/specs/expression/invoke.dart
deleted file mode 100644
index 3ac586f..0000000
--- a/code_builder/lib/src/specs/expression/invoke.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2017, 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.
-
-part of code_builder.src.specs.expression;
-
-/// Represents invoking [target] as a method with arguments.
-class InvokeExpression extends Expression {
- /// Target of the method invocation.
- final Expression target;
-
- /// Optional; type of invocation.
- final InvokeExpressionType type;
-
- final List<Expression> positionalArguments;
- final Map<String, Expression> namedArguments;
- final List<Reference> typeArguments;
- final String name;
-
- const InvokeExpression._(
- this.target,
- this.positionalArguments, [
- this.namedArguments = const {},
- this.typeArguments,
- this.name,
- ]) : type = null;
-
- const InvokeExpression.newOf(
- this.target,
- this.positionalArguments, [
- this.namedArguments = const {},
- this.typeArguments,
- this.name,
- ]) : type = InvokeExpressionType.newInstance;
-
- const InvokeExpression.constOf(
- this.target,
- this.positionalArguments, [
- this.namedArguments = const {},
- this.typeArguments,
- this.name,
- ]) : type = InvokeExpressionType.constInstance;
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitInvokeExpression(this, context);
- }
-
- @override
- String toString() =>
- '${type ?? ''} $target($positionalArguments, $namedArguments)';
-}
-
-enum InvokeExpressionType {
- newInstance,
- constInstance,
-}
diff --git a/code_builder/lib/src/specs/expression/literal.dart b/code_builder/lib/src/specs/expression/literal.dart
deleted file mode 100644
index 3021fa1..0000000
--- a/code_builder/lib/src/specs/expression/literal.dart
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2017, 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.
-
-part of code_builder.src.specs.expression;
-
-/// Converts a runtime Dart [literal] value into an [Expression].
-///
-/// Unsupported inputs invoke the [onError] callback.
-Expression literal(Object literal, {Expression onError(Object value)}) {
- if (literal is bool) {
- return literalBool(literal);
- }
- if (literal is num) {
- return literalNum(literal);
- }
- if (literal is String) {
- return literalString(literal);
- }
- if (literal is List) {
- return literalList(literal);
- }
- if (literal is Set) {
- return literalSet(literal);
- }
- if (literal is Map) {
- return literalMap(literal);
- }
- if (literal == null) {
- return literalNull;
- }
- if (onError != null) {
- return onError(literal);
- }
- throw UnsupportedError('Not a supported literal type: $literal.');
-}
-
-/// Represents the literal value `true`.
-const Expression literalTrue = LiteralExpression._('true');
-
-/// Represents the literal value `false`.
-const Expression literalFalse = LiteralExpression._('false');
-
-/// Create a literal expression from a boolean [value].
-Expression literalBool(bool value) => value ? literalTrue : literalFalse;
-
-/// Represents the literal value `null`.
-const Expression literalNull = LiteralExpression._('null');
-
-/// Create a literal expression from a number [value].
-Expression literalNum(num value) => LiteralExpression._('$value');
-
-/// Create a literal expression from a string [value].
-///
-/// **NOTE**: The string is always formatted `'<value>'`.
-///
-/// If [raw] is `true`, creates a raw String formatted `r'<value>'` and the
-/// value may not contain a single quote.
-/// Escapes single quotes and newlines in the value.
-Expression literalString(String value, {bool raw = false}) {
- if (raw && value.contains('\'')) {
- throw ArgumentError('Cannot include a single quote in a raw string');
- }
- final escaped = value.replaceAll('\'', '\\\'').replaceAll('\n', '\\n');
- return LiteralExpression._("${raw ? 'r' : ''}'$escaped'");
-}
-
-/// Creates a literal list expression from [values].
-LiteralListExpression literalList(Iterable<Object> values, [Reference type]) {
- return LiteralListExpression._(false, values.toList(), type);
-}
-
-/// Creates a literal `const` list expression from [values].
-LiteralListExpression literalConstList(List<Object> values, [Reference type]) {
- return LiteralListExpression._(true, values, type);
-}
-
-/// Creates a literal set expression from [values].
-LiteralSetExpression literalSet(Iterable<Object> values, [Reference type]) {
- return LiteralSetExpression._(false, values.toSet(), type);
-}
-
-/// Creates a literal `const` set expression from [values].
-LiteralSetExpression literalConstSet(Set<Object> values, [Reference type]) {
- return LiteralSetExpression._(true, values, type);
-}
-
-/// Create a literal map expression from [values].
-LiteralMapExpression literalMap(
- Map<Object, Object> values, [
- Reference keyType,
- Reference valueType,
-]) {
- return LiteralMapExpression._(false, values, keyType, valueType);
-}
-
-/// Create a literal `const` map expression from [values].
-LiteralMapExpression literalConstMap(
- Map<Object, Object> values, [
- Reference keyType,
- Reference valueType,
-]) {
- return LiteralMapExpression._(true, values, keyType, valueType);
-}
-
-/// Represents a literal value in Dart source code.
-///
-/// For example, `LiteralExpression('null')` should emit `null`.
-///
-/// Some common literals and helpers are available as methods/fields:
-/// * [literal]
-/// * [literalBool] and [literalTrue], [literalFalse]
-/// * [literalNull]
-/// * [literalList] and [literalConstList]
-/// * [literalSet] and [literalConstSet]
-class LiteralExpression extends Expression {
- final String literal;
-
- const LiteralExpression._(this.literal);
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitLiteralExpression(this, context);
- }
-
- @override
- String toString() => literal;
-}
-
-class LiteralListExpression extends Expression {
- final bool isConst;
- final List<Object> values;
- final Reference type;
-
- const LiteralListExpression._(this.isConst, this.values, this.type);
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitLiteralListExpression(this, context);
- }
-
- @override
- String toString() => '[${values.map(literal).join(', ')}]';
-}
-
-class LiteralSetExpression extends Expression {
- final bool isConst;
- final Set<Object> values;
- final Reference type;
-
- const LiteralSetExpression._(this.isConst, this.values, this.type);
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitLiteralSetExpression(this, context);
- }
-
- @override
- String toString() => '{${values.map(literal).join(', ')}}';
-}
-
-class LiteralMapExpression extends Expression {
- final bool isConst;
- final Map<Object, Object> values;
- final Reference keyType;
- final Reference valueType;
-
- const LiteralMapExpression._(
- this.isConst,
- this.values,
- this.keyType,
- this.valueType,
- );
-
- @override
- R accept<R>(ExpressionVisitor<R> visitor, [R context]) {
- return visitor.visitLiteralMapExpression(this, context);
- }
-
- @override
- String toString() => '{$values}';
-}
diff --git a/code_builder/lib/src/specs/field.dart b/code_builder/lib/src/specs/field.dart
deleted file mode 100644
index 81c5640..0000000
--- a/code_builder/lib/src/specs/field.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2017, 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:built_collection/built_collection.dart';
-import 'package:built_value/built_value.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'field.g.dart';
-
-@immutable
-abstract class Field extends Object
- with HasAnnotations, HasDartDocs
- implements Built<Field, FieldBuilder>, Spec {
- factory Field([void updates(FieldBuilder b)]) = _$Field;
-
- Field._();
-
- @override
- BuiltList<Expression> get annotations;
-
- @override
- BuiltList<String> get docs;
-
- /// Field assignment, if any.
- @nullable
- Code get assignment;
-
- /// Whether this field should be prefixed with `static`.
- ///
- /// This is only valid within classes.
- bool get static;
-
- /// Name of the field.
- String get name;
-
- @nullable
- Reference get type;
-
- FieldModifier get modifier;
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitField(this, context);
-}
-
-enum FieldModifier {
- var$,
- final$,
- constant,
-}
-
-abstract class FieldBuilder extends Object
- with HasAnnotationsBuilder, HasDartDocsBuilder
- implements Builder<Field, FieldBuilder> {
- factory FieldBuilder() = _$FieldBuilder;
-
- FieldBuilder._();
-
- @override
- ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
- @override
- ListBuilder<String> docs = ListBuilder<String>();
-
- /// Field assignment, if any.
- Code assignment;
-
- /// Whether this field should be prefixed with `static`.
- ///
- /// This is only valid within classes.
- bool static = false;
-
- /// Name of the field.
- String name;
-
- Reference type;
-
- FieldModifier modifier = FieldModifier.var$;
-}
diff --git a/code_builder/lib/src/specs/field.g.dart b/code_builder/lib/src/specs/field.g.dart
deleted file mode 100644
index 3bef453..0000000
--- a/code_builder/lib/src/specs/field.g.dart
+++ /dev/null
@@ -1,247 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'field.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Field extends Field {
- @override
- final BuiltList<Expression> annotations;
- @override
- final BuiltList<String> docs;
- @override
- final Code assignment;
- @override
- final bool static;
- @override
- final String name;
- @override
- final Reference type;
- @override
- final FieldModifier modifier;
-
- factory _$Field([void updates(FieldBuilder b)]) =>
- (new FieldBuilder()..update(updates)).build() as _$Field;
-
- _$Field._(
- {this.annotations,
- this.docs,
- this.assignment,
- this.static,
- this.name,
- this.type,
- this.modifier})
- : super._() {
- if (annotations == null)
- throw new BuiltValueNullFieldError('Field', 'annotations');
- if (docs == null) throw new BuiltValueNullFieldError('Field', 'docs');
- if (static == null) throw new BuiltValueNullFieldError('Field', 'static');
- if (name == null) throw new BuiltValueNullFieldError('Field', 'name');
- if (modifier == null)
- throw new BuiltValueNullFieldError('Field', 'modifier');
- }
-
- @override
- Field rebuild(void updates(FieldBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$FieldBuilder toBuilder() => new _$FieldBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Field) return false;
- return annotations == other.annotations &&
- docs == other.docs &&
- assignment == other.assignment &&
- static == other.static &&
- name == other.name &&
- type == other.type &&
- modifier == other.modifier;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc(
- $jc(
- $jc($jc($jc(0, annotations.hashCode), docs.hashCode),
- assignment.hashCode),
- static.hashCode),
- name.hashCode),
- type.hashCode),
- modifier.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Field')
- ..add('annotations', annotations)
- ..add('docs', docs)
- ..add('assignment', assignment)
- ..add('static', static)
- ..add('name', name)
- ..add('type', type)
- ..add('modifier', modifier))
- .toString();
- }
-}
-
-class _$FieldBuilder extends FieldBuilder {
- _$Field _$v;
-
- @override
- ListBuilder<Expression> get annotations {
- _$this;
- return super.annotations ??= new ListBuilder<Expression>();
- }
-
- @override
- set annotations(ListBuilder<Expression> annotations) {
- _$this;
- super.annotations = annotations;
- }
-
- @override
- ListBuilder<String> get docs {
- _$this;
- return super.docs ??= new ListBuilder<String>();
- }
-
- @override
- set docs(ListBuilder<String> docs) {
- _$this;
- super.docs = docs;
- }
-
- @override
- Code get assignment {
- _$this;
- return super.assignment;
- }
-
- @override
- set assignment(Code assignment) {
- _$this;
- super.assignment = assignment;
- }
-
- @override
- bool get static {
- _$this;
- return super.static;
- }
-
- @override
- set static(bool static) {
- _$this;
- super.static = static;
- }
-
- @override
- String get name {
- _$this;
- return super.name;
- }
-
- @override
- set name(String name) {
- _$this;
- super.name = name;
- }
-
- @override
- Reference get type {
- _$this;
- return super.type;
- }
-
- @override
- set type(Reference type) {
- _$this;
- super.type = type;
- }
-
- @override
- FieldModifier get modifier {
- _$this;
- return super.modifier;
- }
-
- @override
- set modifier(FieldModifier modifier) {
- _$this;
- super.modifier = modifier;
- }
-
- _$FieldBuilder() : super._();
-
- FieldBuilder get _$this {
- if (_$v != null) {
- super.annotations = _$v.annotations?.toBuilder();
- super.docs = _$v.docs?.toBuilder();
- super.assignment = _$v.assignment;
- super.static = _$v.static;
- super.name = _$v.name;
- super.type = _$v.type;
- super.modifier = _$v.modifier;
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Field other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Field;
- }
-
- @override
- void update(void updates(FieldBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Field build() {
- _$Field _$result;
- try {
- _$result = _$v ??
- new _$Field._(
- annotations: annotations.build(),
- docs: docs.build(),
- assignment: assignment,
- static: static,
- name: name,
- type: type,
- modifier: modifier);
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'annotations';
- annotations.build();
- _$failedField = 'docs';
- docs.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Field', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/library.dart b/code_builder/lib/src/specs/library.dart
deleted file mode 100644
index f476828..0000000
--- a/code_builder/lib/src/specs/library.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2017, 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:built_collection/built_collection.dart';
-import 'package:built_value/built_value.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../visitors.dart';
-import 'directive.dart';
-
-part 'library.g.dart';
-
-@immutable
-abstract class Library implements Built<Library, LibraryBuilder>, Spec {
- factory Library([void updates(LibraryBuilder b)]) = _$Library;
- Library._();
-
- BuiltList<Directive> get directives;
- BuiltList<Spec> get body;
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitLibrary(this, context);
-}
-
-abstract class LibraryBuilder implements Builder<Library, LibraryBuilder> {
- factory LibraryBuilder() = _$LibraryBuilder;
- LibraryBuilder._();
-
- ListBuilder<Spec> body = ListBuilder<Spec>();
- ListBuilder<Directive> directives = ListBuilder<Directive>();
-}
diff --git a/code_builder/lib/src/specs/library.g.dart b/code_builder/lib/src/specs/library.g.dart
deleted file mode 100644
index 9935040..0000000
--- a/code_builder/lib/src/specs/library.g.dart
+++ /dev/null
@@ -1,133 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'library.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Library extends Library {
- @override
- final BuiltList<Directive> directives;
- @override
- final BuiltList<Spec> body;
-
- factory _$Library([void updates(LibraryBuilder b)]) =>
- (new LibraryBuilder()..update(updates)).build() as _$Library;
-
- _$Library._({this.directives, this.body}) : super._() {
- if (directives == null)
- throw new BuiltValueNullFieldError('Library', 'directives');
- if (body == null) throw new BuiltValueNullFieldError('Library', 'body');
- }
-
- @override
- Library rebuild(void updates(LibraryBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$LibraryBuilder toBuilder() => new _$LibraryBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Library) return false;
- return directives == other.directives && body == other.body;
- }
-
- @override
- int get hashCode {
- return $jf($jc($jc(0, directives.hashCode), body.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Library')
- ..add('directives', directives)
- ..add('body', body))
- .toString();
- }
-}
-
-class _$LibraryBuilder extends LibraryBuilder {
- _$Library _$v;
-
- @override
- ListBuilder<Directive> get directives {
- _$this;
- return super.directives ??= new ListBuilder<Directive>();
- }
-
- @override
- set directives(ListBuilder<Directive> directives) {
- _$this;
- super.directives = directives;
- }
-
- @override
- ListBuilder<Spec> get body {
- _$this;
- return super.body ??= new ListBuilder<Spec>();
- }
-
- @override
- set body(ListBuilder<Spec> body) {
- _$this;
- super.body = body;
- }
-
- _$LibraryBuilder() : super._();
-
- LibraryBuilder get _$this {
- if (_$v != null) {
- super.directives = _$v.directives?.toBuilder();
- super.body = _$v.body?.toBuilder();
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Library other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Library;
- }
-
- @override
- void update(void updates(LibraryBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Library build() {
- _$Library _$result;
- try {
- _$result = _$v ??
- new _$Library._(directives: directives.build(), body: body.build());
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'directives';
- directives.build();
- _$failedField = 'body';
- body.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Library', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/method.dart b/code_builder/lib/src/specs/method.dart
deleted file mode 100644
index 5fecfe3..0000000
--- a/code_builder/lib/src/specs/method.dart
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/annotations.dart';
-import '../mixins/dartdoc.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'method.g.dart';
-
-final Reference _$void = const Reference('void');
-
-@immutable
-abstract class Method extends Object
- with HasAnnotations, HasGenerics, HasDartDocs
- implements Built<Method, MethodBuilder>, Spec {
- factory Method([void updates(MethodBuilder b)]) = _$Method;
-
- factory Method.returnsVoid([void updates(MethodBuilder b)]) {
- return Method((b) {
- if (updates != null) {
- updates(b);
- }
- b.returns = _$void;
- });
- }
-
- Method._();
-
- @override
- BuiltList<Expression> get annotations;
-
- @override
- BuiltList<String> get docs;
-
- @override
- BuiltList<Reference> get types;
-
- /// Optional parameters.
- BuiltList<Parameter> get optionalParameters;
-
- /// Required parameters.
- BuiltList<Parameter> get requiredParameters;
-
- /// Body of the method.
- @nullable
- Code get body;
-
- /// Whether the method should be prefixed with `external`.
- bool get external;
-
- /// Whether this method is a simple lambda expression.
- ///
- /// May be `null` to be inferred based on the value of [body].
- @nullable
- bool get lambda;
-
- /// Whether this method should be prefixed with `static`.
- ///
- /// This is only valid within classes.
- bool get static;
-
- /// Name of the method or function.
- ///
- /// May be `null` when being used as a [closure].
- @nullable
- String get name;
-
- /// Whether this is a getter or setter.
- @nullable
- MethodType get type;
-
- /// Whether this method is `async`, `async*`, or `sync*`.
- @nullable
- MethodModifier get modifier;
-
- @nullable
- Reference get returns;
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitMethod(this, context);
-
- /// This method as a closure.
- Expression get closure => toClosure(this);
-}
-
-abstract class MethodBuilder extends Object
- with HasAnnotationsBuilder, HasGenericsBuilder, HasDartDocsBuilder
- implements Builder<Method, MethodBuilder> {
- factory MethodBuilder() = _$MethodBuilder;
-
- MethodBuilder._();
-
- @override
- ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
- @override
- ListBuilder<String> docs = ListBuilder<String>();
-
- @override
- ListBuilder<Reference> types = ListBuilder<Reference>();
-
- /// Optional parameters.
- ListBuilder<Parameter> optionalParameters = ListBuilder<Parameter>();
-
- /// Required parameters.
- ListBuilder<Parameter> requiredParameters = ListBuilder<Parameter>();
-
- /// Body of the method.
- Code body;
-
- /// Whether the method should be prefixed with `external`.
- bool external = false;
-
- /// Whether this method is a simple lambda expression.
- ///
- /// If not specified this is inferred from the [body].
- bool lambda;
-
- /// Whether this method should be prefixed with `static`.
- ///
- /// This is only valid within classes.
- bool static = false;
-
- /// Name of the method or function.
- String name;
-
- /// Whether this is a getter or setter.
- MethodType type;
-
- /// Whether this method is `async`, `async*`, or `sync*`.
- MethodModifier modifier;
-
- Reference returns;
-}
-
-enum MethodType {
- getter,
- setter,
-}
-
-enum MethodModifier {
- async,
- asyncStar,
- syncStar,
-}
-
-abstract class Parameter extends Object
- with HasAnnotations, HasGenerics, HasDartDocs
- implements Built<Parameter, ParameterBuilder> {
- factory Parameter([void updates(ParameterBuilder b)]) = _$Parameter;
-
- Parameter._();
-
- /// If not `null`, a default assignment if the parameter is optional.
- @nullable
- Code get defaultTo;
-
- /// Name of the parameter.
- String get name;
-
- /// Whether this parameter should be named, if optional.
- bool get named;
-
- /// Whether this parameter should be field formal (i.e. `this.`).
- ///
- /// This is only valid on constructors;
- bool get toThis;
-
- @override
- BuiltList<Expression> get annotations;
-
- @override
- BuiltList<String> get docs;
-
- @override
- BuiltList<Reference> get types;
-
- /// Type of the parameter;
- @nullable
- Reference get type;
-}
-
-abstract class ParameterBuilder extends Object
- with HasAnnotationsBuilder, HasGenericsBuilder, HasDartDocsBuilder
- implements Builder<Parameter, ParameterBuilder> {
- factory ParameterBuilder() = _$ParameterBuilder;
-
- ParameterBuilder._();
-
- /// If not `null`, a default assignment if the parameter is optional.
- Code defaultTo;
-
- /// Name of the parameter.
- String name;
-
- /// Whether this parameter should be named, if optional.
- bool named = false;
-
- /// Whether this parameter should be field formal (i.e. `this.`).
- ///
- /// This is only valid on constructors;
- bool toThis = false;
-
- @override
- ListBuilder<Expression> annotations = ListBuilder<Expression>();
-
- @override
- ListBuilder<String> docs = ListBuilder<String>();
-
- @override
- ListBuilder<Reference> types = ListBuilder<Reference>();
-
- /// Type of the parameter;
- Reference type;
-}
diff --git a/code_builder/lib/src/specs/method.g.dart b/code_builder/lib/src/specs/method.g.dart
deleted file mode 100644
index b6b862a..0000000
--- a/code_builder/lib/src/specs/method.g.dart
+++ /dev/null
@@ -1,641 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'method.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$Method extends Method {
- @override
- final BuiltList<Expression> annotations;
- @override
- final BuiltList<String> docs;
- @override
- final BuiltList<Reference> types;
- @override
- final BuiltList<Parameter> optionalParameters;
- @override
- final BuiltList<Parameter> requiredParameters;
- @override
- final Code body;
- @override
- final bool external;
- @override
- final bool lambda;
- @override
- final bool static;
- @override
- final String name;
- @override
- final MethodType type;
- @override
- final MethodModifier modifier;
- @override
- final Reference returns;
-
- factory _$Method([void updates(MethodBuilder b)]) =>
- (new MethodBuilder()..update(updates)).build() as _$Method;
-
- _$Method._(
- {this.annotations,
- this.docs,
- this.types,
- this.optionalParameters,
- this.requiredParameters,
- this.body,
- this.external,
- this.lambda,
- this.static,
- this.name,
- this.type,
- this.modifier,
- this.returns})
- : super._() {
- if (annotations == null)
- throw new BuiltValueNullFieldError('Method', 'annotations');
- if (docs == null) throw new BuiltValueNullFieldError('Method', 'docs');
- if (types == null) throw new BuiltValueNullFieldError('Method', 'types');
- if (optionalParameters == null)
- throw new BuiltValueNullFieldError('Method', 'optionalParameters');
- if (requiredParameters == null)
- throw new BuiltValueNullFieldError('Method', 'requiredParameters');
- if (external == null)
- throw new BuiltValueNullFieldError('Method', 'external');
- if (static == null) throw new BuiltValueNullFieldError('Method', 'static');
- }
-
- @override
- Method rebuild(void updates(MethodBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$MethodBuilder toBuilder() => new _$MethodBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Method) return false;
- return annotations == other.annotations &&
- docs == other.docs &&
- types == other.types &&
- optionalParameters == other.optionalParameters &&
- requiredParameters == other.requiredParameters &&
- body == other.body &&
- external == other.external &&
- lambda == other.lambda &&
- static == other.static &&
- name == other.name &&
- type == other.type &&
- modifier == other.modifier &&
- returns == other.returns;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc(0,
- annotations.hashCode),
- docs.hashCode),
- types.hashCode),
- optionalParameters.hashCode),
- requiredParameters.hashCode),
- body.hashCode),
- external.hashCode),
- lambda.hashCode),
- static.hashCode),
- name.hashCode),
- type.hashCode),
- modifier.hashCode),
- returns.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Method')
- ..add('annotations', annotations)
- ..add('docs', docs)
- ..add('types', types)
- ..add('optionalParameters', optionalParameters)
- ..add('requiredParameters', requiredParameters)
- ..add('body', body)
- ..add('external', external)
- ..add('lambda', lambda)
- ..add('static', static)
- ..add('name', name)
- ..add('type', type)
- ..add('modifier', modifier)
- ..add('returns', returns))
- .toString();
- }
-}
-
-class _$MethodBuilder extends MethodBuilder {
- _$Method _$v;
-
- @override
- ListBuilder<Expression> get annotations {
- _$this;
- return super.annotations ??= new ListBuilder<Expression>();
- }
-
- @override
- set annotations(ListBuilder<Expression> annotations) {
- _$this;
- super.annotations = annotations;
- }
-
- @override
- ListBuilder<String> get docs {
- _$this;
- return super.docs ??= new ListBuilder<String>();
- }
-
- @override
- set docs(ListBuilder<String> docs) {
- _$this;
- super.docs = docs;
- }
-
- @override
- ListBuilder<Reference> get types {
- _$this;
- return super.types ??= new ListBuilder<Reference>();
- }
-
- @override
- set types(ListBuilder<Reference> types) {
- _$this;
- super.types = types;
- }
-
- @override
- ListBuilder<Parameter> get optionalParameters {
- _$this;
- return super.optionalParameters ??= new ListBuilder<Parameter>();
- }
-
- @override
- set optionalParameters(ListBuilder<Parameter> optionalParameters) {
- _$this;
- super.optionalParameters = optionalParameters;
- }
-
- @override
- ListBuilder<Parameter> get requiredParameters {
- _$this;
- return super.requiredParameters ??= new ListBuilder<Parameter>();
- }
-
- @override
- set requiredParameters(ListBuilder<Parameter> requiredParameters) {
- _$this;
- super.requiredParameters = requiredParameters;
- }
-
- @override
- Code get body {
- _$this;
- return super.body;
- }
-
- @override
- set body(Code body) {
- _$this;
- super.body = body;
- }
-
- @override
- bool get external {
- _$this;
- return super.external;
- }
-
- @override
- set external(bool external) {
- _$this;
- super.external = external;
- }
-
- @override
- bool get lambda {
- _$this;
- return super.lambda;
- }
-
- @override
- set lambda(bool lambda) {
- _$this;
- super.lambda = lambda;
- }
-
- @override
- bool get static {
- _$this;
- return super.static;
- }
-
- @override
- set static(bool static) {
- _$this;
- super.static = static;
- }
-
- @override
- String get name {
- _$this;
- return super.name;
- }
-
- @override
- set name(String name) {
- _$this;
- super.name = name;
- }
-
- @override
- MethodType get type {
- _$this;
- return super.type;
- }
-
- @override
- set type(MethodType type) {
- _$this;
- super.type = type;
- }
-
- @override
- MethodModifier get modifier {
- _$this;
- return super.modifier;
- }
-
- @override
- set modifier(MethodModifier modifier) {
- _$this;
- super.modifier = modifier;
- }
-
- @override
- Reference get returns {
- _$this;
- return super.returns;
- }
-
- @override
- set returns(Reference returns) {
- _$this;
- super.returns = returns;
- }
-
- _$MethodBuilder() : super._();
-
- MethodBuilder get _$this {
- if (_$v != null) {
- super.annotations = _$v.annotations?.toBuilder();
- super.docs = _$v.docs?.toBuilder();
- super.types = _$v.types?.toBuilder();
- super.optionalParameters = _$v.optionalParameters?.toBuilder();
- super.requiredParameters = _$v.requiredParameters?.toBuilder();
- super.body = _$v.body;
- super.external = _$v.external;
- super.lambda = _$v.lambda;
- super.static = _$v.static;
- super.name = _$v.name;
- super.type = _$v.type;
- super.modifier = _$v.modifier;
- super.returns = _$v.returns;
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Method other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Method;
- }
-
- @override
- void update(void updates(MethodBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Method build() {
- _$Method _$result;
- try {
- _$result = _$v ??
- new _$Method._(
- annotations: annotations.build(),
- docs: docs.build(),
- types: types.build(),
- optionalParameters: optionalParameters.build(),
- requiredParameters: requiredParameters.build(),
- body: body,
- external: external,
- lambda: lambda,
- static: static,
- name: name,
- type: type,
- modifier: modifier,
- returns: returns);
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'annotations';
- annotations.build();
- _$failedField = 'docs';
- docs.build();
- _$failedField = 'types';
- types.build();
- _$failedField = 'optionalParameters';
- optionalParameters.build();
- _$failedField = 'requiredParameters';
- requiredParameters.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Method', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
-
-class _$Parameter extends Parameter {
- @override
- final Code defaultTo;
- @override
- final String name;
- @override
- final bool named;
- @override
- final bool toThis;
- @override
- final BuiltList<Expression> annotations;
- @override
- final BuiltList<String> docs;
- @override
- final BuiltList<Reference> types;
- @override
- final Reference type;
-
- factory _$Parameter([void updates(ParameterBuilder b)]) =>
- (new ParameterBuilder()..update(updates)).build() as _$Parameter;
-
- _$Parameter._(
- {this.defaultTo,
- this.name,
- this.named,
- this.toThis,
- this.annotations,
- this.docs,
- this.types,
- this.type})
- : super._() {
- if (name == null) throw new BuiltValueNullFieldError('Parameter', 'name');
- if (named == null) throw new BuiltValueNullFieldError('Parameter', 'named');
- if (toThis == null)
- throw new BuiltValueNullFieldError('Parameter', 'toThis');
- if (annotations == null)
- throw new BuiltValueNullFieldError('Parameter', 'annotations');
- if (docs == null) throw new BuiltValueNullFieldError('Parameter', 'docs');
- if (types == null) throw new BuiltValueNullFieldError('Parameter', 'types');
- }
-
- @override
- Parameter rebuild(void updates(ParameterBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$ParameterBuilder toBuilder() => new _$ParameterBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! Parameter) return false;
- return defaultTo == other.defaultTo &&
- name == other.name &&
- named == other.named &&
- toThis == other.toThis &&
- annotations == other.annotations &&
- docs == other.docs &&
- types == other.types &&
- type == other.type;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc(
- $jc(
- $jc(
- $jc($jc($jc(0, defaultTo.hashCode), name.hashCode),
- named.hashCode),
- toThis.hashCode),
- annotations.hashCode),
- docs.hashCode),
- types.hashCode),
- type.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('Parameter')
- ..add('defaultTo', defaultTo)
- ..add('name', name)
- ..add('named', named)
- ..add('toThis', toThis)
- ..add('annotations', annotations)
- ..add('docs', docs)
- ..add('types', types)
- ..add('type', type))
- .toString();
- }
-}
-
-class _$ParameterBuilder extends ParameterBuilder {
- _$Parameter _$v;
-
- @override
- Code get defaultTo {
- _$this;
- return super.defaultTo;
- }
-
- @override
- set defaultTo(Code defaultTo) {
- _$this;
- super.defaultTo = defaultTo;
- }
-
- @override
- String get name {
- _$this;
- return super.name;
- }
-
- @override
- set name(String name) {
- _$this;
- super.name = name;
- }
-
- @override
- bool get named {
- _$this;
- return super.named;
- }
-
- @override
- set named(bool named) {
- _$this;
- super.named = named;
- }
-
- @override
- bool get toThis {
- _$this;
- return super.toThis;
- }
-
- @override
- set toThis(bool toThis) {
- _$this;
- super.toThis = toThis;
- }
-
- @override
- ListBuilder<Expression> get annotations {
- _$this;
- return super.annotations ??= new ListBuilder<Expression>();
- }
-
- @override
- set annotations(ListBuilder<Expression> annotations) {
- _$this;
- super.annotations = annotations;
- }
-
- @override
- ListBuilder<String> get docs {
- _$this;
- return super.docs ??= new ListBuilder<String>();
- }
-
- @override
- set docs(ListBuilder<String> docs) {
- _$this;
- super.docs = docs;
- }
-
- @override
- ListBuilder<Reference> get types {
- _$this;
- return super.types ??= new ListBuilder<Reference>();
- }
-
- @override
- set types(ListBuilder<Reference> types) {
- _$this;
- super.types = types;
- }
-
- @override
- Reference get type {
- _$this;
- return super.type;
- }
-
- @override
- set type(Reference type) {
- _$this;
- super.type = type;
- }
-
- _$ParameterBuilder() : super._();
-
- ParameterBuilder get _$this {
- if (_$v != null) {
- super.defaultTo = _$v.defaultTo;
- super.name = _$v.name;
- super.named = _$v.named;
- super.toThis = _$v.toThis;
- super.annotations = _$v.annotations?.toBuilder();
- super.docs = _$v.docs?.toBuilder();
- super.types = _$v.types?.toBuilder();
- super.type = _$v.type;
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(Parameter other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$Parameter;
- }
-
- @override
- void update(void updates(ParameterBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$Parameter build() {
- _$Parameter _$result;
- try {
- _$result = _$v ??
- new _$Parameter._(
- defaultTo: defaultTo,
- name: name,
- named: named,
- toThis: toThis,
- annotations: annotations.build(),
- docs: docs.build(),
- types: types.build(),
- type: type);
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'annotations';
- annotations.build();
- _$failedField = 'docs';
- docs.build();
- _$failedField = 'types';
- types.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'Parameter', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/reference.dart b/code_builder/lib/src/specs/reference.dart
deleted file mode 100644
index 102d330..0000000
--- a/code_builder/lib/src/specs/reference.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2017, 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.
-
-library code_builder.src.specs.reference;
-
-import 'package:built_value/built_value.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'type_reference.dart';
-
-/// Short-hand for `Reference(symbol, url)`.
-Reference refer(String symbol, [String url]) {
- return Reference(symbol, url);
-}
-
-/// A reference to [symbol], such as a class, or top-level method or field.
-///
-/// References can be collected and collated in order to automatically generate
-/// `import` statements for all used symbols.
-@immutable
-class Reference extends Expression implements Spec {
- /// Relative, `package:` or `dart:` URL of the library.
- ///
- /// May be omitted (`null`) in order to express "same library".
- final String url;
-
- /// Name of the class, method, or field.
- final String symbol;
-
- /// Create a reference to [symbol] in [url].
- const Reference(this.symbol, [this.url]);
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitReference(this, context);
-
- @override
- int get hashCode => '$url#$symbol'.hashCode;
-
- @override
- bool operator ==(Object o) =>
- o is Reference && o.url == url && o.symbol == symbol;
-
- /// Returns a new instance of this expression.
- Expression newInstance(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.newOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- null,
- );
- }
-
- /// Returns a new instance of this expression with a named constructor.
- Expression newInstanceNamed(
- String name,
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.newOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- name,
- );
- }
-
- /// Returns a const instance of this expression.
- Expression constInstance(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.constOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- null,
- );
- }
-
- /// Returns a const instance of this expression with a named constructor.
- Expression constInstanceNamed(
- String name,
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.constOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- name,
- );
- }
-
- @override
- Expression get expression {
- return CodeExpression(Code.scope((a) => a(this)));
- }
-
- @override
- String toString() => (newBuiltValueToStringHelper('Reference')
- ..add('url', url)
- ..add('symbol', symbol))
- .toString();
-
- /// Returns as a [TypeReference], which allows adding generic type parameters.
- Reference get type => TypeReference((b) => b
- ..url = url
- ..symbol = symbol);
-}
diff --git a/code_builder/lib/src/specs/type_function.dart b/code_builder/lib/src/specs/type_function.dart
deleted file mode 100644
index b7b9014..0000000
--- a/code_builder/lib/src/specs/type_function.dart
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'type_function.g.dart';
-
-@immutable
-abstract class FunctionType extends Expression
- with HasGenerics
- implements Built<FunctionType, FunctionTypeBuilder>, Reference, Spec {
- factory FunctionType([
- void updates(FunctionTypeBuilder b),
- ]) = _$FunctionType;
-
- FunctionType._();
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitFunctionType(this, context);
-
- /// Return type.
- @nullable
- Reference get returnType;
-
- @override
- BuiltList<Reference> get types;
-
- /// Required positional arguments to this function type.
- BuiltList<Reference> get requiredParameters;
-
- /// Optional positional arguments to this function type.
- BuiltList<Reference> get optionalParameters;
-
- /// Named optional arguments to this function type.
- BuiltMap<String, Reference> get namedParameters;
-
- @override
- String get url => null;
-
- @override
- String get symbol => null;
-
- @override
- Reference get type => this;
-
- @override
- Expression newInstance(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) =>
- throw UnsupportedError('Cannot instantiate a function type.');
-
- @override
- Expression newInstanceNamed(
- String name,
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) =>
- throw UnsupportedError('Cannot instantiate a function type.');
-
- @override
- Expression constInstance(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) =>
- throw UnsupportedError('Cannot "const" a function type.');
-
- @override
- Expression constInstanceNamed(
- String name,
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) =>
- throw UnsupportedError('Cannot "const" a function type.');
-
- /// A typedef assignment to this type.
- Code toTypeDef(String name) => createTypeDef(name, this);
-}
-
-abstract class FunctionTypeBuilder extends Object
- with HasGenericsBuilder
- implements Builder<FunctionType, FunctionTypeBuilder> {
- factory FunctionTypeBuilder() = _$FunctionTypeBuilder;
-
- FunctionTypeBuilder._();
-
- Reference returnType;
-
- @override
- ListBuilder<Reference> types = ListBuilder<Reference>();
-
- ListBuilder<Reference> requiredParameters = ListBuilder<Reference>();
-
- ListBuilder<Reference> optionalParameters = ListBuilder<Reference>();
-
- MapBuilder<String, Reference> namedParameters =
- MapBuilder<String, Reference>();
-}
diff --git a/code_builder/lib/src/specs/type_function.g.dart b/code_builder/lib/src/specs/type_function.g.dart
deleted file mode 100644
index b89237f..0000000
--- a/code_builder/lib/src/specs/type_function.g.dart
+++ /dev/null
@@ -1,211 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'type_function.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$FunctionType extends FunctionType {
- @override
- final Reference returnType;
- @override
- final BuiltList<Reference> types;
- @override
- final BuiltList<Reference> requiredParameters;
- @override
- final BuiltList<Reference> optionalParameters;
- @override
- final BuiltMap<String, Reference> namedParameters;
-
- factory _$FunctionType([void updates(FunctionTypeBuilder b)]) =>
- (new FunctionTypeBuilder()..update(updates)).build() as _$FunctionType;
-
- _$FunctionType._(
- {this.returnType,
- this.types,
- this.requiredParameters,
- this.optionalParameters,
- this.namedParameters})
- : super._() {
- if (types == null)
- throw new BuiltValueNullFieldError('FunctionType', 'types');
- if (requiredParameters == null)
- throw new BuiltValueNullFieldError('FunctionType', 'requiredParameters');
- if (optionalParameters == null)
- throw new BuiltValueNullFieldError('FunctionType', 'optionalParameters');
- if (namedParameters == null)
- throw new BuiltValueNullFieldError('FunctionType', 'namedParameters');
- }
-
- @override
- FunctionType rebuild(void updates(FunctionTypeBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$FunctionTypeBuilder toBuilder() =>
- new _$FunctionTypeBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! FunctionType) return false;
- return returnType == other.returnType &&
- types == other.types &&
- requiredParameters == other.requiredParameters &&
- optionalParameters == other.optionalParameters &&
- namedParameters == other.namedParameters;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc(
- $jc($jc($jc(0, returnType.hashCode), types.hashCode),
- requiredParameters.hashCode),
- optionalParameters.hashCode),
- namedParameters.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('FunctionType')
- ..add('returnType', returnType)
- ..add('types', types)
- ..add('requiredParameters', requiredParameters)
- ..add('optionalParameters', optionalParameters)
- ..add('namedParameters', namedParameters))
- .toString();
- }
-}
-
-class _$FunctionTypeBuilder extends FunctionTypeBuilder {
- _$FunctionType _$v;
-
- @override
- Reference get returnType {
- _$this;
- return super.returnType;
- }
-
- @override
- set returnType(Reference returnType) {
- _$this;
- super.returnType = returnType;
- }
-
- @override
- ListBuilder<Reference> get types {
- _$this;
- return super.types ??= new ListBuilder<Reference>();
- }
-
- @override
- set types(ListBuilder<Reference> types) {
- _$this;
- super.types = types;
- }
-
- @override
- ListBuilder<Reference> get requiredParameters {
- _$this;
- return super.requiredParameters ??= new ListBuilder<Reference>();
- }
-
- @override
- set requiredParameters(ListBuilder<Reference> requiredParameters) {
- _$this;
- super.requiredParameters = requiredParameters;
- }
-
- @override
- ListBuilder<Reference> get optionalParameters {
- _$this;
- return super.optionalParameters ??= new ListBuilder<Reference>();
- }
-
- @override
- set optionalParameters(ListBuilder<Reference> optionalParameters) {
- _$this;
- super.optionalParameters = optionalParameters;
- }
-
- @override
- MapBuilder<String, Reference> get namedParameters {
- _$this;
- return super.namedParameters ??= new MapBuilder<String, Reference>();
- }
-
- @override
- set namedParameters(MapBuilder<String, Reference> namedParameters) {
- _$this;
- super.namedParameters = namedParameters;
- }
-
- _$FunctionTypeBuilder() : super._();
-
- FunctionTypeBuilder get _$this {
- if (_$v != null) {
- super.returnType = _$v.returnType;
- super.types = _$v.types?.toBuilder();
- super.requiredParameters = _$v.requiredParameters?.toBuilder();
- super.optionalParameters = _$v.optionalParameters?.toBuilder();
- super.namedParameters = _$v.namedParameters?.toBuilder();
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(FunctionType other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$FunctionType;
- }
-
- @override
- void update(void updates(FunctionTypeBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$FunctionType build() {
- _$FunctionType _$result;
- try {
- _$result = _$v ??
- new _$FunctionType._(
- returnType: returnType,
- types: types.build(),
- requiredParameters: requiredParameters.build(),
- optionalParameters: optionalParameters.build(),
- namedParameters: namedParameters.build());
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'types';
- types.build();
- _$failedField = 'requiredParameters';
- requiredParameters.build();
- _$failedField = 'optionalParameters';
- optionalParameters.build();
- _$failedField = 'namedParameters';
- namedParameters.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'FunctionType', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/specs/type_reference.dart b/code_builder/lib/src/specs/type_reference.dart
deleted file mode 100644
index 1f864f9..0000000
--- a/code_builder/lib/src/specs/type_reference.dart
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2017, 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:built_value/built_value.dart';
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-
-import '../base.dart';
-import '../mixins/generics.dart';
-import '../visitors.dart';
-import 'code.dart';
-import 'expression.dart';
-import 'reference.dart';
-
-part 'type_reference.g.dart';
-
-@immutable
-abstract class TypeReference extends Expression
- with HasGenerics
- implements Built<TypeReference, TypeReferenceBuilder>, Reference, Spec {
- factory TypeReference([
- void updates(TypeReferenceBuilder b),
- ]) = _$TypeReference;
-
- TypeReference._();
-
- @override
- String get symbol;
-
- @override
- @nullable
- String get url;
-
- /// Optional bound generic.
- @nullable
- Reference get bound;
-
- @override
- BuiltList<Reference> get types;
-
- @override
- R accept<R>(
- SpecVisitor<R> visitor, [
- R context,
- ]) =>
- visitor.visitType(this, context);
-
- @override
- Expression get expression {
- return CodeExpression(Code.scope((a) => a(this)));
- }
-
- @override
- TypeReference get type => this;
-
- @override
- Expression newInstance(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.newOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- null,
- );
- }
-
- @override
- Expression newInstanceNamed(
- String name,
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.newOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- name,
- );
- }
-
- @override
- Expression constInstance(
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.constOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- null,
- );
- }
-
- @override
- Expression constInstanceNamed(
- String name,
- Iterable<Expression> positionalArguments, [
- Map<String, Expression> namedArguments = const {},
- List<Reference> typeArguments = const [],
- ]) {
- return InvokeExpression.constOf(
- this,
- positionalArguments.toList(),
- namedArguments,
- typeArguments,
- name,
- );
- }
-}
-
-abstract class TypeReferenceBuilder extends Object
- with HasGenericsBuilder
- implements Builder<TypeReference, TypeReferenceBuilder> {
- factory TypeReferenceBuilder() = _$TypeReferenceBuilder;
-
- TypeReferenceBuilder._();
-
- String symbol;
-
- String url;
-
- /// Optional bound generic.
- Reference bound;
-
- @override
- ListBuilder<Reference> types = ListBuilder<Reference>();
-}
diff --git a/code_builder/lib/src/specs/type_reference.g.dart b/code_builder/lib/src/specs/type_reference.g.dart
deleted file mode 100644
index bcd362f..0000000
--- a/code_builder/lib/src/specs/type_reference.g.dart
+++ /dev/null
@@ -1,172 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'type_reference.dart';
-
-// **************************************************************************
-// BuiltValueGenerator
-// **************************************************************************
-
-// ignore_for_file: always_put_control_body_on_new_line
-// ignore_for_file: annotate_overrides
-// ignore_for_file: avoid_annotating_with_dynamic
-// ignore_for_file: avoid_catches_without_on_clauses
-// ignore_for_file: avoid_returning_this
-// ignore_for_file: lines_longer_than_80_chars
-// ignore_for_file: omit_local_variable_types
-// ignore_for_file: prefer_expression_function_bodies
-// ignore_for_file: sort_constructors_first
-
-class _$TypeReference extends TypeReference {
- @override
- final String symbol;
- @override
- final String url;
- @override
- final Reference bound;
- @override
- final BuiltList<Reference> types;
-
- factory _$TypeReference([void updates(TypeReferenceBuilder b)]) =>
- (new TypeReferenceBuilder()..update(updates)).build() as _$TypeReference;
-
- _$TypeReference._({this.symbol, this.url, this.bound, this.types})
- : super._() {
- if (symbol == null)
- throw new BuiltValueNullFieldError('TypeReference', 'symbol');
- if (types == null)
- throw new BuiltValueNullFieldError('TypeReference', 'types');
- }
-
- @override
- TypeReference rebuild(void updates(TypeReferenceBuilder b)) =>
- (toBuilder()..update(updates)).build();
-
- @override
- _$TypeReferenceBuilder toBuilder() =>
- new _$TypeReferenceBuilder()..replace(this);
-
- @override
- bool operator ==(dynamic other) {
- if (identical(other, this)) return true;
- if (other is! TypeReference) return false;
- return symbol == other.symbol &&
- url == other.url &&
- bound == other.bound &&
- types == other.types;
- }
-
- @override
- int get hashCode {
- return $jf($jc(
- $jc($jc($jc(0, symbol.hashCode), url.hashCode), bound.hashCode),
- types.hashCode));
- }
-
- @override
- String toString() {
- return (newBuiltValueToStringHelper('TypeReference')
- ..add('symbol', symbol)
- ..add('url', url)
- ..add('bound', bound)
- ..add('types', types))
- .toString();
- }
-}
-
-class _$TypeReferenceBuilder extends TypeReferenceBuilder {
- _$TypeReference _$v;
-
- @override
- String get symbol {
- _$this;
- return super.symbol;
- }
-
- @override
- set symbol(String symbol) {
- _$this;
- super.symbol = symbol;
- }
-
- @override
- String get url {
- _$this;
- return super.url;
- }
-
- @override
- set url(String url) {
- _$this;
- super.url = url;
- }
-
- @override
- Reference get bound {
- _$this;
- return super.bound;
- }
-
- @override
- set bound(Reference bound) {
- _$this;
- super.bound = bound;
- }
-
- @override
- ListBuilder<Reference> get types {
- _$this;
- return super.types ??= new ListBuilder<Reference>();
- }
-
- @override
- set types(ListBuilder<Reference> types) {
- _$this;
- super.types = types;
- }
-
- _$TypeReferenceBuilder() : super._();
-
- TypeReferenceBuilder get _$this {
- if (_$v != null) {
- super.symbol = _$v.symbol;
- super.url = _$v.url;
- super.bound = _$v.bound;
- super.types = _$v.types?.toBuilder();
- _$v = null;
- }
- return this;
- }
-
- @override
- void replace(TypeReference other) {
- if (other == null) throw new ArgumentError.notNull('other');
- _$v = other as _$TypeReference;
- }
-
- @override
- void update(void updates(TypeReferenceBuilder b)) {
- if (updates != null) updates(this);
- }
-
- @override
- _$TypeReference build() {
- _$TypeReference _$result;
- try {
- _$result = _$v ??
- new _$TypeReference._(
- symbol: symbol, url: url, bound: bound, types: types.build());
- } catch (_) {
- String _$failedField;
- try {
- _$failedField = 'types';
- types.build();
- } catch (e) {
- throw new BuiltValueNestedFieldError(
- 'TypeReference', _$failedField, e.toString());
- }
- rethrow;
- }
- replace(_$result);
- return _$result;
- }
-}
diff --git a/code_builder/lib/src/visitors.dart b/code_builder/lib/src/visitors.dart
deleted file mode 100644
index 62b47bc..0000000
--- a/code_builder/lib/src/visitors.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2017, 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:meta/meta.dart';
-
-import 'base.dart';
-import 'specs/class.dart';
-import 'specs/constructor.dart';
-import 'specs/directive.dart';
-import 'specs/expression.dart';
-import 'specs/field.dart';
-import 'specs/library.dart';
-import 'specs/method.dart';
-import 'specs/reference.dart';
-import 'specs/type_function.dart';
-import 'specs/type_reference.dart';
-
-@optionalTypeArgs
-abstract class SpecVisitor<T> {
- const SpecVisitor._();
-
- T visitAnnotation(Expression spec, [T context]);
-
- T visitClass(Class spec, [T context]);
-
- T visitConstructor(Constructor spec, String clazz, [T context]);
-
- T visitDirective(Directive spec, [T context]);
-
- T visitField(Field spec, [T context]);
-
- T visitLibrary(Library spec, [T context]);
-
- T visitFunctionType(FunctionType spec, [T context]);
-
- T visitMethod(Method spec, [T context]);
-
- T visitReference(Reference spec, [T context]);
-
- T visitSpec(Spec spec, [T context]);
-
- T visitType(TypeReference spec, [T context]);
-
- T visitTypeParameters(Iterable<Reference> specs, [T context]);
-}
diff --git a/code_builder/pubspec.yaml b/code_builder/pubspec.yaml
deleted file mode 100644
index 60bcd09..0000000
--- a/code_builder/pubspec.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: code_builder
-version: 3.2.1
-
-description: >-
- A fluent, builder-based library for generating valid Dart code
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/code_builder
-
-environment:
- sdk: '>=2.1.0 <3.0.0'
-
-dependencies:
- built_collection: '>=3.0.0 <5.0.0'
- built_value: ^7.0.0
- collection: ^1.14.0
- matcher: ^0.12.0
- meta: ^1.0.5
-
-dev_dependencies:
- build: ^1.0.0
- build_runner: ^1.1.0
- built_value_generator: ^7.0.0
- dart_style: ^1.0.0
- source_gen: ^0.9.0
- test: ^1.3.0
-
-#dependency_overrides:
-# built_value: ^7.0.0
diff --git a/code_builder/tool/src/builder.dart b/code_builder/tool/src/builder.dart
deleted file mode 100644
index ff95814..0000000
--- a/code_builder/tool/src/builder.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2017, 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:build/build.dart';
-import 'package:built_value_generator/built_value_generator.dart';
-import 'package:source_gen/source_gen.dart';
-
-/// Returns a [Builder] to generate `.g.dart` files for `built_value`.
-Builder builtValueBuilder(BuilderOptions _) {
- return PartBuilder([
- const BuiltValueGenerator(),
- ], '.g.dart');
-}
diff --git a/completion/.travis.yml b/completion/.travis.yml
index 7e4cc44..f8a21dd 100644
--- a/completion/.travis.yml
+++ b/completion/.travis.yml
@@ -2,11 +2,17 @@
dart:
- dev
+ - 2.3.0
dart_task:
- test
- - dartfmt
- - dartanalyzer
+ - dartanalyzer: --fatal-infos --fatal-warnings .
+
+matrix:
+ include:
+ # Only validate formatting using the dev release
+ - dart: dev
+ dart_task: dartfmt
# Only building master means that we don't run two builds for each pull request.
branches:
diff --git a/completion/BUILD.gn b/completion/BUILD.gn
index f1d8965..c6d945e 100644
--- a/completion/BUILD.gn
+++ b/completion/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for completion-0.2.1+1
+# This file is generated by importer.py for completion-0.2.2
import("//build/dart/dart_library.gni")
diff --git a/completion/CHANGELOG.md b/completion/CHANGELOG.md
index 7fa074d..0f8ca1c 100644
--- a/completion/CHANGELOG.md
+++ b/completion/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.2.2
+
+* Increase minimum Dart SDK to `2.3.0`.
+
## 0.2.1+1
* Small fix to error handler.
diff --git a/completion/analysis_options.yaml b/completion/analysis_options.yaml
index 47f9b74..c1d96c4 100644
--- a/completion/analysis_options.yaml
+++ b/completion/analysis_options.yaml
@@ -1,63 +1,70 @@
+include: package:pedantic/analysis_options.yaml
+
analyzer:
strong-mode:
implicit-casts: false
- errors:
- unused_element: error
- unused_import: error
- unused_local_variable: error
- dead_code: error
- override_on_non_overriding_method: error
+
linter:
rules:
- - annotate_overrides
- - avoid_empty_else
+ - avoid_catching_errors
- avoid_function_literals_in_foreach_calls
- - avoid_init_to_null
- - avoid_null_checks_in_equality_operators
- - avoid_return_types_on_setters
+ - avoid_private_typedef_functions
+ - avoid_redundant_argument_values
+ - avoid_renaming_method_parameters
- avoid_returning_null
+ - avoid_returning_null_for_void
- avoid_unused_constructor_parameters
+ - avoid_void_async
- await_only_futures
- camel_case_types
- cancel_subscriptions
+ - cascade_invocations
- comment_references
- constant_identifier_names
- control_flow_in_finally
- directives_ordering
- - empty_catches
- - empty_constructor_bodies
- empty_statements
+ - file_names
- hash_and_equals
- implementation_imports
+ - invariant_booleans
- iterable_contains_unrelated_type
- - library_names
- - library_prefixes
+ - join_return_with_assignment
+ - lines_longer_than_80_chars
- list_remove_unrelated_type
- - no_duplicate_case_values
+ - literal_only_boolean_expressions
+ - missing_whitespace_between_adjacent_strings
+ - no_adjacent_strings_in_list
+ - no_runtimeType_toString
- non_constant_identifier_names
- only_throw_errors
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
- - prefer_conditional_assignment
- - prefer_final_fields
- - prefer_is_empty
- - prefer_is_not_empty
- - prefer_single_quotes
+ - prefer_asserts_in_initializer_lists
+ - prefer_const_constructors
+ - prefer_const_declarations
+ - prefer_expression_function_bodies
+ - prefer_final_locals
+ - prefer_function_declarations_over_variables
+ - prefer_initializing_formals
+ - prefer_inlined_adds
+ - prefer_interpolation_to_compose_strings
+ - prefer_is_not_operator
+ - prefer_null_aware_operators
+ - prefer_relative_imports
- prefer_typing_uninitialized_variables
- - recursive_getters
- - slash_for_doc_comments
- - super_goes_last
+ - prefer_void_to_null
+ - sort_pub_dependencies
- test_types_in_equals
- throw_in_finally
- - type_init_formals
- - unawaited_futures
- unnecessary_brace_in_string_interps
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_null_aware_assignments
+ - unnecessary_overrides
+ - unnecessary_parenthesis
- unnecessary_statements
- - unused_catch_clause
- - unrelated_type_equality_checks
- - valid_regexps
+ - unnecessary_string_interpolations
+ - void_checks
diff --git a/completion/example/hello-completion.sh b/completion/example/example-completion.sh
similarity index 69%
rename from completion/example/hello-completion.sh
rename to completion/example/example-completion.sh
index 91e272f..3dee89a 100644
--- a/completion/example/hello-completion.sh
+++ b/completion/example/example-completion.sh
@@ -11,32 +11,32 @@
#
# /usr/local/etc/bash_completion.d/
-###-begin-hello.dart-completion-###
+###-begin-example.dart-completion-###
if type complete &>/dev/null; then
- __hello_dart_completion() {
+ __example_dart_completion() {
local si="$IFS"
IFS=$'\n' COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
COMP_LINE="$COMP_LINE" \
COMP_POINT="$COMP_POINT" \
- hello.dart completion -- "${COMP_WORDS[@]}" \
+ example.dart completion -- "${COMP_WORDS[@]}" \
2>/dev/null)) || return $?
IFS="$si"
}
- complete -F __hello_dart_completion hello.dart
+ complete -F __example_dart_completion example.dart
elif type compdef &>/dev/null; then
- __hello_dart_completion() {
+ __example_dart_completion() {
si=$IFS
compadd -- $(COMP_CWORD=$((CURRENT-1)) \
COMP_LINE=$BUFFER \
COMP_POINT=0 \
- hello.dart completion -- "${words[@]}" \
+ example.dart completion -- "${words[@]}" \
2>/dev/null)
IFS=$si
}
- compdef __hello_dart_completion hello.dart
+ compdef __example_dart_completion example.dart
elif type compctl &>/dev/null; then
- __hello_dart_completion() {
+ __example_dart_completion() {
local cword line point words si
read -Ac words
read -cn cword
@@ -47,14 +47,14 @@
IFS=$'\n' reply=($(COMP_CWORD="$cword" \
COMP_LINE="$line" \
COMP_POINT="$point" \
- hello.dart completion -- "${words[@]}" \
+ example.dart completion -- "${words[@]}" \
2>/dev/null)) || return $?
IFS="$si"
}
- compctl -K __hello_dart_completion hello.dart
+ compctl -K __example_dart_completion example.dart
fi
-###-end-hello.dart-completion-###
+###-end-example.dart-completion-###
-## Generated 2018-04-24 15:45:52.542816Z
+## Generated 2018-12-06 13:41:53.261614Z
## By /Users/kevmoo/source/github/completion.dart/bin/shell_completion_generator.dart
diff --git a/completion/example/hello.dart b/completion/example/example.dart
similarity index 94%
rename from completion/example/hello.dart
rename to completion/example/example.dart
index 81ce1de..c20909a 100755
--- a/completion/example/hello.dart
+++ b/completion/example/example.dart
@@ -1,11 +1,12 @@
#!/usr/bin/env dart
import 'dart:io';
+
import 'package:args/args.dart';
import 'package:completion/completion.dart';
import '../test/completion_tests_args.dart';
-main(List<String> args) {
+void main(List<String> args) {
final argParser = getHelloSampleParser();
ArgResults argResult;
@@ -45,7 +46,7 @@
print(subCommandParser.usage);
return;
} else {
- throw new StateError(
+ throw StateError(
'no clue what that subCammand is: ${subSubCommand.name}');
}
}
@@ -67,7 +68,7 @@
final greeting = argResult['friendly'] as bool ? 'Hiya' : 'Hello';
- final String salutationVal = argResult['salutation'];
+ final salutationVal = argResult['salutation'] as String;
final salutation = salutationVal == null ? '' : '$salutationVal ';
var message = '$greeting, $salutation$name';
diff --git a/completion/example/hello_completion_init.sh b/completion/example/example_completion_init.sh
similarity index 73%
rename from completion/example/hello_completion_init.sh
rename to completion/example/example_completion_init.sh
index 1bb2642..873f19c 100644
--- a/completion/example/hello_completion_init.sh
+++ b/completion/example/example_completion_init.sh
@@ -5,8 +5,8 @@
# source hello_completion_init.sh
#
-APP_NAME=hello.dart
-COMPETION_NAME=hello-completion.sh
+APP_NAME=example.dart
+COMPLETION_NAME=example-completion.sh
APP_DIR=$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd )
@@ -18,15 +18,15 @@
if [ ! -f $APP_DIR/$COMPETION_NAME ]
then
- echo $COMPETION_NAME does not exist in the expected directory
+ echo $COMPLETION_NAME does not exist in the expected directory
exit 1
fi
echo Initializing your environment to run the $APP_NAME completion sample
echo
-echo 'sourcing' $COMPETION_NAME to enable command completion
-source $APP_DIR/$COMPETION_NAME
+echo 'sourcing' $COMPLETION_NAME to enable command completion
+source $APP_DIR/$COMPLETION_NAME
echo
echo Adding $APP_NAME directory \($APP_DIR\) to PATH environment
diff --git a/completion/lib/completion.dart b/completion/lib/completion.dart
index 55c627a..4ebc244 100644
--- a/completion/lib/completion.dart
+++ b/completion/lib/completion.dart
@@ -13,10 +13,9 @@
logFile}) {
tryCompletion(
mainArgs,
- (List<String> args, String compLine, int compPoint) {
- return getArgsCompletions(parser, args, compLine, compPoint);
- },
- // ignore: deprecated_member_use
+ (List<String> args, String compLine, int compPoint) =>
+ getArgsCompletions(parser, args, compLine, compPoint),
+ // ignore: deprecated_member_use_from_same_package,deprecated_member_use
logFile: logFile,
);
return parser.parse(mainArgs);
diff --git a/completion/lib/src/bot.dart b/completion/lib/src/bot.dart
deleted file mode 100644
index c77a072..0000000
--- a/completion/lib/src/bot.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-class Tuple<T1, T2> {
- final T1 item1;
- final T2 item2;
-
- const Tuple(this.item1, this.item2);
-
- @override
- bool operator ==(other) {
- return other is Tuple && item1 == other.item1 && item2 == other.item2;
- }
-
- @override
- String toString() => '{item1: $item1, item2: $item2}';
-
- @override
- int get hashCode => Util.getHashCode([item1, item2]);
-
- dynamic toJson() => {'item1': item1, 'item2': item2};
-}
-
-class Util {
- static int getHashCode(Iterable source) {
- requireArgumentNotNull(source, 'source');
-
- int hash = 0;
- for (final h in source) {
- int next = h == null ? 0 : h.hashCode;
- hash = 0x1fffffff & (hash + next);
- hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
- hash ^= hash >> 6;
- }
- hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
- hash ^= hash >> 11;
- return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
- }
-}
-
-void require(bool truth, [String message]) {
- if (!truth) {
- throw new Exception(message);
- }
-}
-
-void requireArgumentNotNull(argument, String argName) {
- _metaRequireArgumentNotNullOrEmpty(argName);
- if (argument == null) {
- throw new ArgumentError.notNull(argName);
- }
-}
-
-void _metaRequireArgumentNotNullOrEmpty(String argName) {
- if (argName == null || argName.isEmpty) {
- throw new UnsupportedError("That's just sad. Give me a good argName");
- }
-}
diff --git a/completion/lib/src/generate.dart b/completion/lib/src/generate.dart
index e371b2b..7fb0304 100644
--- a/completion/lib/src/generate.dart
+++ b/completion/lib/src/generate.dart
@@ -12,7 +12,7 @@
* Can contain letters, numbers, '_', '-', '.'
* Must end with letter or number
*/
-final _binNameMatch = new RegExp(r'^[a-zA-Z0-9]((\w|-|\.)*[a-zA-Z0-9])?$');
+final _binNameMatch = RegExp(r'^[a-zA-Z0-9]((\w|-|\.)*[a-zA-Z0-9])?$');
/*
* Format for unified bash and zsh completion script:
@@ -26,32 +26,32 @@
String generateCompletionScript(List<String> binaryNames) {
if (binaryNames.isEmpty) {
- throw new ArgumentError('Provide the name of at least of one command');
+ throw ArgumentError('Provide the name of at least of one command');
}
for (final binName in binaryNames) {
if (!_binNameMatch.hasMatch(binName)) {
final msg = 'The provided name - "$binName" - is invalid\n'
'It must match regex: ${_binNameMatch.pattern}';
- throw new StateError(msg);
+ throw StateError(msg);
}
}
- var buffer = new StringBuffer();
+ final buffer = StringBuffer();
final prefix =
LineSplitter.split(_prefix).map((l) => '# $l'.trim()).join('\n');
- buffer.writeln(prefix);
-
- // empty line
- buffer.writeln('');
+ buffer
+ ..writeln(prefix)
+ // empty line
+ ..writeln('');
for (final binName in binaryNames) {
buffer.writeln(_printBinName(binName));
}
final detailLines = [
- 'Generated ${new DateTime.now().toUtc()}',
+ 'Generated ${DateTime.now().toUtc()}',
];
if (Platform.script.scheme == 'file') {
@@ -68,14 +68,11 @@
}
String _printBinName(String binName) {
- var templateContents = _template.replaceAll(_binNameReplacement, binName);
+ final templateContents = _template.replaceAll(_binNameReplacement, binName);
var funcName = binName.replaceAll('.', '_');
funcName = '__${funcName}_completion';
- templateContents =
- templateContents.replaceAll(_funcNameReplacement, funcName);
-
- return templateContents;
+ return templateContents.replaceAll(_funcNameReplacement, funcName);
}
const _prefix = '''
diff --git a/completion/lib/src/get_args_completions.dart b/completion/lib/src/get_args_completions.dart
index d593e88..4f00923 100644
--- a/completion/lib/src/get_args_completions.dart
+++ b/completion/lib/src/get_args_completions.dart
@@ -1,6 +1,5 @@
import 'package:args/args.dart';
-import 'bot.dart';
import 'util.dart';
/*
@@ -8,20 +7,24 @@
* then tabbing into an app just completes to that one command. Weird?
*/
-List<String> getArgsCompletions(ArgParser parser, List<String> providedArgs,
- String compLine, int compPoint) {
+List<String> getArgsCompletions(
+ ArgParser parser,
+ List<String> providedArgs,
+ String compLine,
+ int compPoint,
+) {
assert(parser != null);
assert(providedArgs != null);
// all arg entries: no empty items, no null items, all pre-trimmed
- for (int i = 0; i < providedArgs.length; i++) {
+ for (var i = 0; i < providedArgs.length; i++) {
final arg = providedArgs[i];
final msg = 'Arg at index $i with value "$arg" ';
- requireArgumentNotNull(arg, '$msg is null');
- require(arg.trim() == arg, '$msg has whitespace');
+ if (arg.trim() != arg) throw StateError('$msg has whitespace');
if (i < (providedArgs.length - 1)) {
- require(
- arg.isNotEmpty, '$msg – Only the last arg can be an empty string');
+ if (arg.isEmpty) {
+ throw StateError('$msg – Only the last arg can be an empty string');
+ }
}
}
@@ -60,14 +63,14 @@
// a set of options in use (minus, potentially, the last one)
// all non-null, all unique
- var optionsDefinedInArgs = alignedArgsOptions
+ final optionsDefinedInArgs = alignedArgsOptions
.take(alignedArgsOptions.length - 1)
.where((o) => o != null)
.toSet();
sublog('defined options: ${optionsDefinedInArgs.map((o) => o.name).toSet()}');
- var parserOptionCompletions = new List<String>.unmodifiable(
- _getParserOptionCompletions(parser, optionsDefinedInArgs));
+ final parserOptionCompletions = List<String>.unmodifiable(
+ _parserOptionCompletions(parser, optionsDefinedInArgs));
/*
* KNOWN: at least one item in providedArgs last and first are now safe
@@ -79,9 +82,9 @@
* If it does, we can use the result to determine what we should do next
*/
- final subsetTuple = _getValidSubset(parser, providedArgs);
- final validSubSet = subsetTuple.item1;
- final subsetResult = subsetTuple.item2;
+ final subsetTuple = _validSubset(parser, providedArgs);
+ final validSubSet = subsetTuple.subset;
+ final subsetResult = subsetTuple.result;
sublog('valid subset: ${helpfulToString(validSubSet)}');
@@ -160,7 +163,7 @@
assert(!option.isFlag);
sublog('completing option "${option.name}"');
- final String optionValue = providedArgs[providedArgs.length - 1];
+ final optionValue = providedArgs[providedArgs.length - 1];
return option.allowed
.where((String v) => v.startsWith(optionValue))
@@ -248,7 +251,7 @@
return null;
}
-Iterable<String> _getParserOptionCompletions(
+Iterable<String> _parserOptionCompletions(
ArgParser parser, Set<Option> existingOptions) {
assert(
existingOptions.every((option) => parser.options.containsValue(option)));
@@ -256,11 +259,10 @@
return parser.options.values
.where((opt) =>
!existingOptions.contains(opt) || opt.type == OptionType.multiple)
- .expand(_getArgsOptionCompletions);
+ .expand(_argsOptionCompletions);
}
-Tuple<List<String>, ArgResults> _getValidSubset(
- ArgParser parser, List<String> providedArgs) {
+_Tuple _validSubset(ArgParser parser, List<String> providedArgs) {
/* start with all of the args, loop through parsing them,
* removing one every time
*
@@ -285,19 +287,17 @@
validSubSet.removeLast();
}
- return new Tuple(validSubSet, subsetResult);
+ return _Tuple(validSubSet, subsetResult);
}
-List<String> _getArgsOptionCompletions(Option option) {
- final items = new List<String>();
+List<String> _argsOptionCompletions(Option option) => <String>[
+ '--${option.name}',
+ if (option.negatable) '--no-${option.name}',
+ ]..sort();
- items.add('--${option.name}');
+class _Tuple {
+ final List<String> subset;
+ final ArgResults result;
- if (option.negatable) {
- items.add('--no-${option.name}');
- }
-
- items.sort();
-
- return items;
+ const _Tuple(this.subset, this.result);
}
diff --git a/completion/lib/src/try_completion.dart b/completion/lib/src/try_completion.dart
index 0c3449c..8db4cca 100644
--- a/completion/lib/src/try_completion.dart
+++ b/completion/lib/src/try_completion.dart
@@ -3,7 +3,6 @@
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
-import 'bot.dart';
import 'util.dart';
/// The string 'completion' used to denote that arguments provided to an app are
@@ -17,11 +16,12 @@
void tryCompletion(
List<String> args,
- List<String> completer(List<String> args, String compLine, int compPoint),
+ List<String> Function(List<String> args, String compLine, int compPoint)
+ completer,
{@Deprecated('Useful for testing, but do not release with this set.')
logFile}) {
if (logFile != null) {
- var logFile = new File('_completion.log');
+ final logFile = File('_completion.log');
void logLine(String content) {
logFile.writeAsStringSync('$content\n', mode: FileMode.writeOnlyAppend);
@@ -30,12 +30,14 @@
logLine(' *' * 50);
Logger.root.onRecord.listen((e) {
- var loggerName = e.loggerName.split('.');
+ final loggerName = e.loggerName.split('.');
if (loggerName.isNotEmpty && loggerName.first == 'completion') {
loggerName.removeAt(0);
assert(e.level == Level.INFO);
logLine(
- '${loggerName.join('.').padLeft(Tag.longestTagLength)} ${e.message}');
+ '${loggerName.join('.').padLeft(Tag.longestTagLength)} '
+ '${e.message}',
+ );
}
});
}
@@ -43,7 +45,8 @@
String scriptName;
try {
scriptName = p.basename(Platform.script.toFilePath());
- } on UnsupportedError {
+ } on UnsupportedError // ignore: avoid_catching_errors
+ {
scriptName = '<unknown>';
}
@@ -56,20 +59,24 @@
final env = Platform.environment;
- // There are 3 interesting env paramaters passed by the completion logic
+ // There are 3 interesting env parameters passed by the completion logic
// COMP_LINE: the full contents of the completion
final compLine = env['COMP_LINE'];
- require(compLine != null, 'Environment variable COMP_LINE must be set');
+ if (compLine == null) {
+ throw StateError('Environment variable COMP_LINE must be set');
+ }
// COMP_CWORD: number of words. Also might be nice
// COMP_POINT: where the cursor is on the completion line
final compPointValue = env[_compPointVar];
- require(compPointValue != null && compPointValue.isNotEmpty,
- 'Environment variable $_compPointVar must be set and non-empty');
+ if (compPointValue == null || compPointValue.isEmpty) {
+ throw StateError(
+ 'Environment variable $_compPointVar must be set and non-empty');
+ }
final compPoint = int.tryParse(compPointValue);
if (compPoint == null) {
- throw new FormatException('Could not parse $_compPointVar value '
+ throw FormatException('Could not parse $_compPointVar value '
'"$compPointValue" into an integer');
}
diff --git a/completion/lib/src/util.dart b/completion/lib/src/util.dart
index 4512df1..98b5209 100644
--- a/completion/lib/src/util.dart
+++ b/completion/lib/src/util.dart
@@ -1,7 +1,7 @@
import 'package:logging/logging.dart' as logging;
class Tag {
- static const getArgsCompletions = const Tag._('getArgsCompletions');
+ static const getArgsCompletions = Tag._('getArgsCompletions');
final String name;
@@ -27,9 +27,7 @@
final loggerName = startArgs.join('.');
- final logger = new logging.Logger(loggerName);
-
- logger.info(safe);
+ logging.Logger(loggerName)..info(safe);
}
String helpfulToString(Object input) {
diff --git a/completion/pubspec.yaml b/completion/pubspec.yaml
index f70ef9e..3599f7b 100644
--- a/completion/pubspec.yaml
+++ b/completion/pubspec.yaml
@@ -1,11 +1,10 @@
name: completion
-version: 0.2.1+1
-author: Kevin Moore <github@j832.com>
+version: 0.2.2
description: A packaged to add shell command completion to your Dart application
homepage: https://github.com/kevmoo/completion.dart
environment:
- sdk: '>=2.0.0-dev.54.0 <3.0.0'
+ sdk: '>=2.3.0 <3.0.0'
dependencies:
args: ^1.4.0
@@ -13,6 +12,7 @@
path: ^1.0.0
dev_dependencies:
+ pedantic: ^1.0.0
test: ^1.2.0
test_process: ^1.0.1
diff --git a/connectivity/BUILD.gn b/connectivity/BUILD.gn
index 567cd56..559c427 100644
--- a/connectivity/BUILD.gn
+++ b/connectivity/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for connectivity-0.4.6+2
+# This file is generated by importer.py for connectivity-0.4.8+1
import("//build/dart/dart_library.gni")
@@ -12,7 +12,9 @@
disable_analysis = true
deps = [
+ "//third_party/dart-pkg/pub/connectivity_platform_interface",
"//third_party/dart-pkg/pub/meta",
"//third_party/dart-pkg/git/flutter/packages/flutter",
+ "//third_party/dart-pkg/pub/connectivity_macos",
]
}
diff --git a/connectivity/CHANGELOG.md b/connectivity/CHANGELOG.md
index 57741ee..b297f38 100644
--- a/connectivity/CHANGELOG.md
+++ b/connectivity/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 0.4.8+1
+
+* Make the pedantic dev_dependency explicit.
+
+## 0.4.8
+
+* Adds macOS as an endorsed platform.
+
+## 0.4.7
+
+* Migrate the plugin to use the ConnectivityPlatform.instance defined in the connectivity_platform_interface package.
+
## 0.4.6+2
* Migrate deprecated BinaryMessages to ServicesBinding.instance.defaultBinaryMessenger.
diff --git a/connectivity/connectivity_macos/CHANGELOG.md b/connectivity/connectivity_macos/CHANGELOG.md
deleted file mode 100644
index c34dc60..0000000
--- a/connectivity/connectivity_macos/CHANGELOG.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## 0.0.2+1
-
-* Add CHANGELOG.
-
-## 0.0.1
-
-* Initial open source release.
\ No newline at end of file
diff --git a/connectivity/connectivity_macos/README.md b/connectivity/connectivity_macos/README.md
deleted file mode 100644
index ee34d1d..0000000
--- a/connectivity/connectivity_macos/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# connectivity_macos
-
-The macos implementation of [`connectivity`].
-
-## Usage
-
-### Import the package
-
-To use this plugin in your Flutter Web app, simply add it as a dependency in
-your `pubspec.yaml` alongside the base `connectivity` plugin.
-
-_(This is only temporary: in the future we hope to make this package an
-"endorsed" implementation of `connectivity`, so that it is automatically
-included in your Flutter macos app when you depend on `package:connectivity_macos`.)_
-
-This is what the above means to your `pubspec.yaml`:
-
-```yaml
-...
-dependencies:
- ...
- connectivity: ^0.4.6
- connectivity_macos: ^0.0.1
- ...
-```
-
-### Use the plugin
-
-Once you have the `connectivity_macos` dependency in your pubspec, you should
-be able to use `package:connectivity` as normal.
diff --git a/connectivity/example/lib/main.dart b/connectivity/example/lib/main.dart
index 0d9c282..4ad3097 100644
--- a/connectivity/example/lib/main.dart
+++ b/connectivity/example/lib/main.dart
@@ -15,7 +15,7 @@
// Sets a platform override for desktop to avoid exceptions. See
// https://flutter.dev/desktop#target-platform-override for more info.
void _enablePlatformOverrideForDesktop() {
- if (!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux)) {
+ if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) {
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
}
}
diff --git a/connectivity/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/connectivity/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/connectivity/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "group:Runner.xcodeproj">
+ </FileRef>
+ <FileRef
+ location = "group:Pods/Pods.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/connectivity/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/connectivity/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/connectivity/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IDEDidComputeMac32BitWarning</key>
+ <true/>
+</dict>
+</plist>
diff --git a/connectivity/example/pubspec.yaml b/connectivity/example/pubspec.yaml
index c4c58a1..a16e604 100644
--- a/connectivity/example/pubspec.yaml
+++ b/connectivity/example/pubspec.yaml
@@ -6,14 +6,13 @@
sdk: flutter
connectivity:
path: ../
- connectivity_macos:
- path: ../connectivity_macos
dev_dependencies:
flutter_driver:
sdk: flutter
test: any
e2e: ^0.2.0
+ pedantic: ^1.8.0
flutter:
uses-material-design: true
diff --git a/connectivity/example/test_driver/test/connectivity_e2e.dart b/connectivity/example/test_driver/test/connectivity_e2e.dart
new file mode 100644
index 0000000..10c4bda
--- /dev/null
+++ b/connectivity/example/test_driver/test/connectivity_e2e.dart
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. 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:io';
+import 'package:e2e/e2e.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:connectivity/connectivity.dart';
+
+void main() {
+ E2EWidgetsFlutterBinding.ensureInitialized();
+
+ group('Connectivity test driver', () {
+ Connectivity _connectivity;
+
+ setUpAll(() async {
+ _connectivity = Connectivity();
+ });
+
+ testWidgets('test connectivity result', (WidgetTester tester) async {
+ final ConnectivityResult result = await _connectivity.checkConnectivity();
+ expect(result, isNotNull);
+ switch (result) {
+ case ConnectivityResult.wifi:
+ expect(_connectivity.getWifiName(), completes);
+ expect(_connectivity.getWifiBSSID(), completes);
+ expect((await _connectivity.getWifiIP()), isNotNull);
+ break;
+ default:
+ break;
+ }
+ });
+
+ testWidgets('test location methods, iOS only', (WidgetTester tester) async {
+ if (Platform.isIOS) {
+ expect((await _connectivity.getLocationServiceAuthorization()),
+ LocationAuthorizationStatus.notDetermined);
+ }
+ });
+ });
+}
diff --git a/connectivity/lib/connectivity.dart b/connectivity/lib/connectivity.dart
index ad9fae3..a5d9f25 100644
--- a/connectivity/lib/connectivity.dart
+++ b/connectivity/lib/connectivity.dart
@@ -3,22 +3,13 @@
// found in the LICENSE file.
import 'dart:async';
-import 'dart:io';
import 'package:flutter/services.dart';
-import 'package:meta/meta.dart';
+import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
-/// Connection status check result.
-enum ConnectivityResult {
- /// WiFi: Device connected via Wi-Fi
- wifi,
-
- /// Mobile: Device connected to cellular network
- mobile,
-
- /// None: Device not connected to any network
- none
-}
+// Export enums from the platform_interface so plugin users can use them directly.
+export 'package:connectivity_platform_interface/connectivity_platform_interface.dart'
+ show ConnectivityResult, LocationAuthorizationStatus;
/// Discover network connectivity configurations: Distinguish between WI-FI and cellular, check WI-FI status and more.
class Connectivity {
@@ -27,7 +18,7 @@
/// [Connectivity] is designed to work as a singleton.
// When a second instance is created, the first instance will not be able to listen to the
// EventChannel because it is overridden. Forcing the class to be a singleton class can prevent
- // misusage of creating a second instance from a programmer.
+ // misuse of creating a second instance from a programmer.
factory Connectivity() {
if (_singleton == null) {
_singleton = Connectivity._();
@@ -39,28 +30,11 @@
static Connectivity _singleton;
- Stream<ConnectivityResult> _onConnectivityChanged;
-
- /// Exposed for testing purposes and should not be used by users of the plugin.
- @visibleForTesting
- static const MethodChannel methodChannel = MethodChannel(
- 'plugins.flutter.io/connectivity',
- );
-
- /// Exposed for testing purposes and should not be used by users of the plugin.
- @visibleForTesting
- static const EventChannel eventChannel = EventChannel(
- 'plugins.flutter.io/connectivity_status',
- );
+ static ConnectivityPlatform get _platform => ConnectivityPlatform.instance;
/// Fires whenever the connectivity state changes.
Stream<ConnectivityResult> get onConnectivityChanged {
- if (_onConnectivityChanged == null) {
- _onConnectivityChanged = eventChannel
- .receiveBroadcastStream()
- .map((dynamic event) => _parseConnectivityResult(event));
- }
- return _onConnectivityChanged;
+ return _platform.onConnectivityChanged;
}
/// Checks the connection status of the device.
@@ -69,9 +43,8 @@
/// make a network request. It only gives you the radio status.
///
/// Instead listen for connectivity changes via [onConnectivityChanged] stream.
- Future<ConnectivityResult> checkConnectivity() async {
- final String result = await methodChannel.invokeMethod<String>('check');
- return _parseConnectivityResult(result);
+ Future<ConnectivityResult> checkConnectivity() {
+ return _platform.checkConnectivity();
}
/// Obtains the wifi name (SSID) of the connected network
@@ -80,12 +53,8 @@
///
/// From android 8.0 onwards the GPS must be ON (high accuracy)
/// in order to be able to obtain the SSID.
- Future<String> getWifiName() async {
- String wifiName = await methodChannel.invokeMethod<String>('wifiName');
- // as Android might return <unknown ssid>, uniforming result
- // our iOS implementation will return null
- if (wifiName == '<unknown ssid>') wifiName = null;
- return wifiName;
+ Future<String> getWifiName() {
+ return _platform.getWifiName();
}
/// Obtains the wifi BSSID of the connected network.
@@ -94,13 +63,13 @@
///
/// From Android 8.0 onwards the GPS must be ON (high accuracy)
/// in order to be able to obtain the BSSID.
- Future<String> getWifiBSSID() async {
- return await methodChannel.invokeMethod<String>('wifiBSSID');
+ Future<String> getWifiBSSID() {
+ return _platform.getWifiBSSID();
}
/// Obtains the IP address of the connected wifi network
- Future<String> getWifiIP() async {
- return await methodChannel.invokeMethod<String>('wifiIPAddress');
+ Future<String> getWifiIP() {
+ return _platform.getWifiIP();
}
/// Request to authorize the location service (Only on iOS).
@@ -151,14 +120,12 @@
/// Ideally, a location service authorization should only be requested if the current authorization status is not determined.
///
/// See also [getLocationServiceAuthorization] to obtain current location service status.
- Future<LocationAuthorizationStatus> requestLocationServiceAuthorization(
- {bool requestAlwaysLocationUsage = false}) async {
- //Just `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
- assert(!Platform.isAndroid);
- final String result = await methodChannel.invokeMethod<String>(
- 'requestLocationServiceAuthorization',
- <bool>[requestAlwaysLocationUsage]);
- return _convertLocationStatusString(result);
+ Future<LocationAuthorizationStatus> requestLocationServiceAuthorization({
+ bool requestAlwaysLocationUsage = false,
+ }) {
+ return _platform.requestLocationServiceAuthorization(
+ requestAlwaysLocationUsage: requestAlwaysLocationUsage,
+ );
}
/// Get the current location service authorization (Only on iOS).
@@ -197,61 +164,7 @@
/// ```
///
/// See also [requestLocationServiceAuthorization] for requesting a location service authorization.
- Future<LocationAuthorizationStatus> getLocationServiceAuthorization() async {
- //Just `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
- assert(!Platform.isAndroid);
- final String result = await methodChannel
- .invokeMethod<String>('getLocationServiceAuthorization');
- return _convertLocationStatusString(result);
+ Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
+ return _platform.getLocationServiceAuthorization();
}
-
- LocationAuthorizationStatus _convertLocationStatusString(String result) {
- switch (result) {
- case 'notDetermined':
- return LocationAuthorizationStatus.notDetermined;
- case 'restricted':
- return LocationAuthorizationStatus.restricted;
- case 'denied':
- return LocationAuthorizationStatus.denied;
- case 'authorizedAlways':
- return LocationAuthorizationStatus.authorizedAlways;
- case 'authorizedWhenInUse':
- return LocationAuthorizationStatus.authorizedWhenInUse;
- default:
- return LocationAuthorizationStatus.unknown;
- }
- }
-}
-
-ConnectivityResult _parseConnectivityResult(String state) {
- switch (state) {
- case 'wifi':
- return ConnectivityResult.wifi;
- case 'mobile':
- return ConnectivityResult.mobile;
- case 'none':
- default:
- return ConnectivityResult.none;
- }
-}
-
-/// The status of the location service authorization.
-enum LocationAuthorizationStatus {
- /// The authorization of the location service is not determined.
- notDetermined,
-
- /// This app is not authorized to use location.
- restricted,
-
- /// User explicitly denied the location service.
- denied,
-
- /// User authorized the app to access the location at any time.
- authorizedAlways,
-
- /// User authorized the app to access the location when the app is visible to them.
- authorizedWhenInUse,
-
- /// Status unknown.
- unknown
}
diff --git a/connectivity/macos/connectivity.podspec b/connectivity/macos/connectivity.podspec
new file mode 100644
index 0000000..ea544df
--- /dev/null
+++ b/connectivity/macos/connectivity.podspec
@@ -0,0 +1,22 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
+#
+Pod::Spec.new do |s|
+ s.name = 'connectivity'
+ s.version = '0.0.1'
+ s.summary = 'No-op implementation of the macos connectivity to avoid build issues on macos'
+ s.description = <<-DESC
+ No-op implementation of the connectivity plugin to avoid build issues on macos.
+ https://github.com/flutter/flutter/issues/46618
+ DESC
+ s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/connectivity'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' }
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*'
+ s.public_header_files = 'Classes/**/*.h'
+
+ s.platform = :osx
+ s.osx.deployment_target = '10.11'
+end
+
diff --git a/connectivity/pubspec.yaml b/connectivity/pubspec.yaml
index 91ba068..ce90f75 100644
--- a/connectivity/pubspec.yaml
+++ b/connectivity/pubspec.yaml
@@ -1,8 +1,8 @@
name: connectivity
description: Flutter plugin for discovering the state of the network (WiFi &
mobile/cellular) connectivity on Android and iOS.
-homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity
-version: 0.4.6+2
+homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity
+version: 0.4.8+1
flutter:
plugin:
@@ -12,11 +12,15 @@
pluginClass: ConnectivityPlugin
ios:
pluginClass: FLTConnectivityPlugin
+ macos:
+ default_package: connectivity_macos
dependencies:
flutter:
sdk: flutter
meta: "^1.0.5"
+ connectivity_platform_interface: ^1.0.2
+ connectivity_macos: ^0.1.0
dev_dependencies:
flutter_test:
@@ -25,6 +29,9 @@
sdk: flutter
test: any
e2e: ^0.2.0
+ mockito: ^4.1.1
+ plugin_platform_interface: ^1.0.0
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/connectivity_macos/BUILD.gn b/connectivity_macos/BUILD.gn
new file mode 100644
index 0000000..07cb715
--- /dev/null
+++ b/connectivity_macos/BUILD.gn
@@ -0,0 +1,17 @@
+# This file is generated by importer.py for connectivity_macos-0.1.0+1
+
+import("//build/dart/dart_library.gni")
+
+dart_library("connectivity_macos") {
+ package_name = "connectivity_macos"
+
+ # This parameter is left empty as we don't care about analysis or exporting
+ # these sources outside of the tree.
+ sources = []
+
+ disable_analysis = true
+
+ deps = [
+ "//third_party/dart-pkg/git/flutter/packages/flutter",
+ ]
+}
diff --git a/connectivity_macos/CHANGELOG.md b/connectivity_macos/CHANGELOG.md
new file mode 100644
index 0000000..43db2ff
--- /dev/null
+++ b/connectivity_macos/CHANGELOG.md
@@ -0,0 +1,16 @@
+## 0.1.0+1
+
+* Make the pedantic dev_dependency explicit.
+
+## 0.1.0
+
+* Adds an example app to trigger CI tests. Bumped the MINOR version to
+avoid compatibility issues once this packages is endorsed.
+
+## 0.0.2+1
+
+* Add CHANGELOG.
+
+## 0.0.1
+
+* Initial open source release.
\ No newline at end of file
diff --git a/connectivity/connectivity_macos/LICENSE b/connectivity_macos/LICENSE
similarity index 100%
rename from connectivity/connectivity_macos/LICENSE
rename to connectivity_macos/LICENSE
diff --git a/connectivity_macos/README.md b/connectivity_macos/README.md
new file mode 100644
index 0000000..d63803a
--- /dev/null
+++ b/connectivity_macos/README.md
@@ -0,0 +1,25 @@
+# connectivity_macos
+
+The macos implementation of [`connectivity`].
+
+## Usage
+
+### Import the package
+
+
+This package has been endorsed, meaning that you only need to add `connectivity`
+as a dependency in your `pubspec.yaml`. It will be automatically included in your app
+when you depend on `package:connectivity`.
+
+This is what the above means to your `pubspec.yaml`:
+
+```yaml
+...
+dependencies:
+ ...
+ connectivity: ^0.4.8
+ ...
+```
+
+Refer to the `connectivity` [documentation](https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity) for more details.
+
diff --git a/connectivity/connectivity_macos/android/README.md b/connectivity_macos/android/README.md
similarity index 100%
rename from connectivity/connectivity_macos/android/README.md
rename to connectivity_macos/android/README.md
diff --git a/connectivity/connectivity_macos/android/build.gradle b/connectivity_macos/android/build.gradle
similarity index 100%
rename from connectivity/connectivity_macos/android/build.gradle
rename to connectivity_macos/android/build.gradle
diff --git a/connectivity/connectivity_macos/android/gradle.properties b/connectivity_macos/android/gradle.properties
similarity index 100%
rename from connectivity/connectivity_macos/android/gradle.properties
rename to connectivity_macos/android/gradle.properties
diff --git a/connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties b/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
rename to connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/connectivity/connectivity_macos/android/settings.gradle b/connectivity_macos/android/settings.gradle
similarity index 100%
rename from connectivity/connectivity_macos/android/settings.gradle
rename to connectivity_macos/android/settings.gradle
diff --git a/connectivity/connectivity_macos/android/src/main/AndroidManifest.xml b/connectivity_macos/android/src/main/AndroidManifest.xml
similarity index 100%
rename from connectivity/connectivity_macos/android/src/main/AndroidManifest.xml
rename to connectivity_macos/android/src/main/AndroidManifest.xml
diff --git a/connectivity/connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java b/connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java
similarity index 100%
rename from connectivity/connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java
rename to connectivity_macos/android/src/main/java/com/example/connectivity/ConnectivityPlugin.java
diff --git a/connectivity_macos/example/android/app/build.gradle b/connectivity_macos/example/android/app/build.gradle
new file mode 100644
index 0000000..5d1f138
--- /dev/null
+++ b/connectivity_macos/example/android/app/build.gradle
@@ -0,0 +1,58 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 28
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ applicationId "io.flutter.plugins.connectivityexample"
+ minSdkVersion 16
+ targetSdkVersion 28
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
diff --git a/connectivity_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties b/connectivity_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9a4163a
--- /dev/null
+++ b/connectivity_macos/example/android/app/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/connectivity_macos/example/android/app/src/main/AndroidManifest.xml b/connectivity_macos/example/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..3bf2ca0
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="io.flutter.plugins.connectivityexample">
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <application android:name="io.flutter.app.FlutterApplication" android:label="connectivity_example" android:icon="@mipmap/ic_launcher">
+ <activity android:name=".EmbeddingV1Activity"
+ android:launchMode="singleTop"
+ android:theme="@android:style/Theme.Black.NoTitleBar"
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+ android:hardwareAccelerated="true"
+ android:exported="true"
+ android:windowSoftInputMode="adjustResize">
+ </activity>
+ <activity android:name=".MainActivity"
+ android:theme="@android:style/Theme.Black.NoTitleBar"
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+ android:hardwareAccelerated="true"
+ android:windowSoftInputMode="adjustResize">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java
new file mode 100644
index 0000000..587b623
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1Activity.java
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import android.os.Bundle;
+import io.flutter.app.FlutterActivity;
+import io.flutter.plugins.GeneratedPluginRegistrant;
+
+public class EmbeddingV1Activity extends FlutterActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GeneratedPluginRegistrant.registerWith(this);
+ }
+}
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java
new file mode 100644
index 0000000..a347553
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/EmbeddingV1ActivityTest.java
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import androidx.test.rule.ActivityTestRule;
+import dev.flutter.plugins.e2e.FlutterRunner;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(FlutterRunner.class)
+public class EmbeddingV1ActivityTest {
+ @Rule
+ public ActivityTestRule<EmbeddingV1Activity> rule =
+ new ActivityTestRule<>(EmbeddingV1Activity.class);
+}
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivity.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivity.java
new file mode 100644
index 0000000..b0deb61
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivity.java
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.plugins.connectivity.ConnectivityPlugin;
+
+public class MainActivity extends FlutterActivity {
+
+ @Override
+ public void configureFlutterEngine(FlutterEngine flutterEngine) {
+ super.configureFlutterEngine(flutterEngine);
+ flutterEngine.getPlugins().add(new ConnectivityPlugin());
+ }
+}
diff --git a/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivityTest.java b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivityTest.java
new file mode 100644
index 0000000..0c33d6a
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/java/io/flutter/plugins/connectivityexample/MainActivityTest.java
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.connectivityexample;
+
+import androidx.test.rule.ActivityTestRule;
+import dev.flutter.plugins.e2e.FlutterRunner;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(FlutterRunner.class)
+public class MainActivityTest {
+ @Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class);
+}
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..db77bb4
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..17987b7
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..09d4391
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d5f1c8d
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/connectivity_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4d6372e
--- /dev/null
+++ b/connectivity_macos/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/connectivity_macos/example/android/build.gradle b/connectivity_macos/example/android/build.gradle
new file mode 100644
index 0000000..541636c
--- /dev/null
+++ b/connectivity_macos/example/android/build.gradle
@@ -0,0 +1,29 @@
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.3.0'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/connectivity_macos/example/android/gradle.properties b/connectivity_macos/example/android/gradle.properties
new file mode 100644
index 0000000..a673820
--- /dev/null
+++ b/connectivity_macos/example/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+android.enableR8=true
diff --git a/connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties b/connectivity_macos/example/android/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
copy from connectivity/connectivity_macos/android/gradle/wrapper/gradle-wrapper.properties
copy to connectivity_macos/example/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/connectivity_macos/example/android/settings.gradle b/connectivity_macos/example/android/settings.gradle
new file mode 100644
index 0000000..a159ea7
--- /dev/null
+++ b/connectivity_macos/example/android/settings.gradle
@@ -0,0 +1,15 @@
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+ pluginsFile.withInputStream { stream -> plugins.load(stream) }
+}
+
+plugins.each { name, path ->
+ def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+}
diff --git a/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist b/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..6c2de80
--- /dev/null
+++ b/connectivity_macos/example/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>App</string>
+ <key>CFBundleIdentifier</key>
+ <string>io.flutter.flutter.app</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>App</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>arm64</string>
+ </array>
+ <key>MinimumOSVersion</key>
+ <string>8.0</string>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Flutter/Debug.xcconfig b/connectivity_macos/example/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..e8efba1
--- /dev/null
+++ b/connectivity_macos/example/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/connectivity_macos/example/ios/Flutter/Release.xcconfig b/connectivity_macos/example/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..399e934
--- /dev/null
+++ b/connectivity_macos/example/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj b/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..e497d09
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,490 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
+ 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+ EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C80D49AFD183103034E444C2 /* libPods-Runner.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+ 3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
+ 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
+ 69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
+ 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ C80D49AFD183103034E444C2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
+ EB0BA966000B5C35B13186D7 /* libPods-Runner.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 89F516DEFCBF79E39D2885C2 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ C80D49AFD183103034E444C2 /* libPods-Runner.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 8ECC1C323F60D5498EEC2315 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 69D903F0A9A7C636EE803AF8 /* Pods-Runner.debug.xcconfig */,
+ 3173C764DD180BE02EB51E47 /* Pods-Runner.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B80C3931E831B6300D905FE /* App.framework */,
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEBA1CF902C7004384FC /* Flutter.framework */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "<group>";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ 8ECC1C323F60D5498EEC2315 /* Pods */,
+ 89F516DEFCBF79E39D2885C2 /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
+ 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 97C146F11CF9000F007C117D /* Supporting Files */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ );
+ path = Runner;
+ sourceTree = "<group>";
+ };
+ 97C146F11CF9000F007C117D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146F21CF9000F007C117D /* main.m */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */,
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ 6A2F146AD353BE7A0C3E797E /* [CP] Embed Pods Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1100;
+ ORGANIZATIONNAME = "The Chromium Authors";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
+ };
+ 3BAF367E8BACBC7576CEE653 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 6A2F146AD353BE7A0C3E797E /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
+ 97C146F31CF9000F007C117D /* main.m in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ENABLE_BITCODE = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "group:Runner.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..3bb3697
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "1100"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+ BuildableName = "Runner.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+ BuildableName = "Runner.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <Testables>
+ </Testables>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+ BuildableName = "Runner.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "97C146ED1CF9000F007C117D"
+ BuildableName = "Runner.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "group:Runner.xcodeproj">
+ </FileRef>
+ <FileRef
+ location = "group:Pods/Pods.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..949b678
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>BuildSystemType</key>
+ <string>Original</string>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Runner/AppDelegate.h b/connectivity_macos/example/ios/Runner/AppDelegate.h
new file mode 100644
index 0000000..d9e18e9
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/AppDelegate.h
@@ -0,0 +1,10 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Flutter/Flutter.h>
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : FlutterAppDelegate
+
+@end
diff --git a/connectivity_macos/example/ios/Runner/AppDelegate.m b/connectivity_macos/example/ios/Runner/AppDelegate.m
new file mode 100644
index 0000000..f086757
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/AppDelegate.m
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "AppDelegate.h"
+#include "GeneratedPluginRegistrant.h"
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application
+ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ [GeneratedPluginRegistrant registerWithRegistry:self];
+ // Override point for customization after application launch.
+ return [super application:application didFinishLaunchingWithOptions:launchOptions];
+}
+
+@end
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d22f10b
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,116 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..28c6bf0
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..2ccbfd9
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..f091b6b
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..4cde121
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..d0ef06e
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..dcdc230
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..2ccbfd9
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..c8f9ed8
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..a6d6b86
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..a6d6b86
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..75b2d16
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..c4df70d
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..6a84f41
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000..d0e1f58
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
Binary files differ
diff --git a/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..ebf48f6
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+ <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard b/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..f3c2851
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+ </dependencies>
+ <scenes>
+ <!--Flutter View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+ <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/connectivity_macos/example/ios/Runner/Info.plist b/connectivity_macos/example/ios/Runner/Info.plist
new file mode 100644
index 0000000..babbd80
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Info.plist
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>connectivity_example</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+ <string>This app requires accessing your location information all the time to get wi-fi information.</string>
+ <key>NSLocationWhenInUseUsageDescription</key>
+ <string>This app requires accessing your location information when the app is in foreground to get wi-fi information.</string>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>arm64</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UIViewControllerBasedStatusBarAppearance</key>
+ <false/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Runner/Runner.entitlements b/connectivity_macos/example/ios/Runner/Runner.entitlements
new file mode 100644
index 0000000..ba21fbd
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/Runner.entitlements
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.developer.networking.wifi-info</key>
+ <true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/ios/Runner/main.m b/connectivity_macos/example/ios/Runner/main.m
new file mode 100644
index 0000000..bec320c
--- /dev/null
+++ b/connectivity_macos/example/ios/Runner/main.m
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Flutter/Flutter.h>
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char* argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/connectivity_macos/example/lib/main.dart b/connectivity_macos/example/lib/main.dart
new file mode 100644
index 0000000..4ad3097
--- /dev/null
+++ b/connectivity_macos/example/lib/main.dart
@@ -0,0 +1,172 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ignore_for_file: public_member_api_docs
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:connectivity/connectivity.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+// Sets a platform override for desktop to avoid exceptions. See
+// https://flutter.dev/desktop#target-platform-override for more info.
+void _enablePlatformOverrideForDesktop() {
+ if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) {
+ debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
+ }
+}
+
+void main() {
+ _enablePlatformOverrideForDesktop();
+ runApp(MyApp());
+}
+
+class MyApp extends StatelessWidget {
+ // This widget is the root of your application.
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
+ ),
+ home: MyHomePage(title: 'Flutter Demo Home Page'),
+ );
+ }
+}
+
+class MyHomePage extends StatefulWidget {
+ MyHomePage({Key key, this.title}) : super(key: key);
+
+ final String title;
+
+ @override
+ _MyHomePageState createState() => _MyHomePageState();
+}
+
+class _MyHomePageState extends State<MyHomePage> {
+ String _connectionStatus = 'Unknown';
+ final Connectivity _connectivity = Connectivity();
+ StreamSubscription<ConnectivityResult> _connectivitySubscription;
+
+ @override
+ void initState() {
+ super.initState();
+ initConnectivity();
+ _connectivitySubscription =
+ _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
+ }
+
+ @override
+ void dispose() {
+ _connectivitySubscription.cancel();
+ super.dispose();
+ }
+
+ // Platform messages are asynchronous, so we initialize in an async method.
+ Future<void> initConnectivity() async {
+ ConnectivityResult result;
+ // Platform messages may fail, so we use a try/catch PlatformException.
+ try {
+ result = await _connectivity.checkConnectivity();
+ } on PlatformException catch (e) {
+ print(e.toString());
+ }
+
+ // If the widget was removed from the tree while the asynchronous platform
+ // message was in flight, we want to discard the reply rather than calling
+ // setState to update our non-existent appearance.
+ if (!mounted) {
+ return Future.value(null);
+ }
+
+ return _updateConnectionStatus(result);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text('Plugin example app'),
+ ),
+ body: Center(child: Text('Connection Status: $_connectionStatus')),
+ );
+ }
+
+ Future<void> _updateConnectionStatus(ConnectivityResult result) async {
+ switch (result) {
+ case ConnectivityResult.wifi:
+ String wifiName, wifiBSSID, wifiIP;
+
+ try {
+ if (Platform.isIOS) {
+ LocationAuthorizationStatus status =
+ await _connectivity.getLocationServiceAuthorization();
+ if (status == LocationAuthorizationStatus.notDetermined) {
+ status =
+ await _connectivity.requestLocationServiceAuthorization();
+ }
+ if (status == LocationAuthorizationStatus.authorizedAlways ||
+ status == LocationAuthorizationStatus.authorizedWhenInUse) {
+ wifiName = await _connectivity.getWifiName();
+ } else {
+ wifiName = await _connectivity.getWifiName();
+ }
+ } else {
+ wifiName = await _connectivity.getWifiName();
+ }
+ } on PlatformException catch (e) {
+ print(e.toString());
+ wifiName = "Failed to get Wifi Name";
+ }
+
+ try {
+ if (Platform.isIOS) {
+ LocationAuthorizationStatus status =
+ await _connectivity.getLocationServiceAuthorization();
+ if (status == LocationAuthorizationStatus.notDetermined) {
+ status =
+ await _connectivity.requestLocationServiceAuthorization();
+ }
+ if (status == LocationAuthorizationStatus.authorizedAlways ||
+ status == LocationAuthorizationStatus.authorizedWhenInUse) {
+ wifiBSSID = await _connectivity.getWifiBSSID();
+ } else {
+ wifiBSSID = await _connectivity.getWifiBSSID();
+ }
+ } else {
+ wifiBSSID = await _connectivity.getWifiBSSID();
+ }
+ } on PlatformException catch (e) {
+ print(e.toString());
+ wifiBSSID = "Failed to get Wifi BSSID";
+ }
+
+ try {
+ wifiIP = await _connectivity.getWifiIP();
+ } on PlatformException catch (e) {
+ print(e.toString());
+ wifiIP = "Failed to get Wifi IP";
+ }
+
+ setState(() {
+ _connectionStatus = '$result\n'
+ 'Wifi Name: $wifiName\n'
+ 'Wifi BSSID: $wifiBSSID\n'
+ 'Wifi IP: $wifiIP\n';
+ });
+ break;
+ case ConnectivityResult.mobile:
+ case ConnectivityResult.none:
+ setState(() => _connectionStatus = result.toString());
+ break;
+ default:
+ setState(() => _connectionStatus = 'Failed to get connectivity.');
+ break;
+ }
+ }
+}
diff --git a/connectivity_macos/example/macos/Flutter/Flutter-Debug.xcconfig b/connectivity_macos/example/macos/Flutter/Flutter-Debug.xcconfig
new file mode 100644
index 0000000..785633d
--- /dev/null
+++ b/connectivity_macos/example/macos/Flutter/Flutter-Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/connectivity_macos/example/macos/Flutter/Flutter-Release.xcconfig b/connectivity_macos/example/macos/Flutter/Flutter-Release.xcconfig
new file mode 100644
index 0000000..5fba960
--- /dev/null
+++ b/connectivity_macos/example/macos/Flutter/Flutter-Release.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/connectivity_macos/example/macos/Runner.xcodeproj/project.pbxproj b/connectivity_macos/example/macos/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..0e24134
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,654 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 51;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
+ buildPhases = (
+ 33CC111E2044C6BF0003C045 /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = "Flutter Assemble";
+ productName = FLX;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
+ 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
+ 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
+ D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 748ADDF1719804343BB18004 /* Pods_Runner.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 33CC111A2044C6BA0003C045;
+ remoteInfo = FLX;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 33CC110E2044A8840003C045 /* Bundle Framework */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */,
+ 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */,
+ );
+ name = "Bundle Framework";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
+ 33CC10ED2044A3C60003C045 /* connectivity_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = connectivity_example.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
+ 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
+ 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
+ 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; };
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
+ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
+ 748ADDF1719804343BB18004 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
+ 80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
+ AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
+ D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
+ E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 33CC10EA2044A3C60003C045 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
+ 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
+ EA473EC5F2038B17A2FE4D78 /* Pods_Runner.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 33BA886A226E78AF003329D5 /* Configs */ = {
+ isa = PBXGroup;
+ children = (
+ 33E5194F232828860026EE4D /* AppInfo.xcconfig */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
+ );
+ path = Configs;
+ sourceTree = "<group>";
+ };
+ 33CC10E42044A3C60003C045 = {
+ isa = PBXGroup;
+ children = (
+ 33FAB671232836740065AC1E /* Runner */,
+ 33CEB47122A05771004F2AC0 /* Flutter */,
+ 33CC10EE2044A3C60003C045 /* Products */,
+ D73912EC22F37F3D000D13A0 /* Frameworks */,
+ D42EAEE5849744148CC78D83 /* Pods */,
+ );
+ sourceTree = "<group>";
+ };
+ 33CC10EE2044A3C60003C045 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10ED2044A3C60003C045 /* connectivity_example.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 33CC11242044D66E0003C045 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10F22044A3C60003C045 /* Assets.xcassets */,
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */,
+ 33CC10F72044A3C60003C045 /* Info.plist */,
+ );
+ name = Resources;
+ path = ..;
+ sourceTree = "<group>";
+ };
+ 33CEB47122A05771004F2AC0 /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
+ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
+ 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
+ 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
+ D73912EF22F37F9E000D13A0 /* App.framework */,
+ 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */,
+ );
+ path = Flutter;
+ sourceTree = "<group>";
+ };
+ 33FAB671232836740065AC1E /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 33CC10F02044A3C60003C045 /* AppDelegate.swift */,
+ 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
+ 33E51913231747F40026EE4D /* DebugProfile.entitlements */,
+ 33E51914231749380026EE4D /* Release.entitlements */,
+ 33CC11242044D66E0003C045 /* Resources */,
+ 33BA886A226E78AF003329D5 /* Configs */,
+ );
+ path = Runner;
+ sourceTree = "<group>";
+ };
+ D42EAEE5849744148CC78D83 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 80418F0A2F74D683C63A4D0A /* Pods-Runner.debug.xcconfig */,
+ E960ED3977AF6DF197F74FFA /* Pods-Runner.release.xcconfig */,
+ AA19B00394637215A825CF5E /* Pods-Runner.profile.xcconfig */,
+ );
+ name = Pods;
+ path = Pods;
+ sourceTree = "<group>";
+ };
+ D73912EC22F37F3D000D13A0 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 748ADDF1719804343BB18004 /* Pods_Runner.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 33CC10EC2044A3C60003C045 /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */,
+ 33CC10E92044A3C60003C045 /* Sources */,
+ 33CC10EA2044A3C60003C045 /* Frameworks */,
+ 33CC10EB2044A3C60003C045 /* Resources */,
+ 33CC110E2044A8840003C045 /* Bundle Framework */,
+ 3399D490228B24CF009A79C7 /* ShellScript */,
+ 84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */,
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 33CC10ED2044A3C60003C045 /* connectivity_example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 33CC10E52044A3C60003C045 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0920;
+ LastUpgradeCheck = 0930;
+ ORGANIZATIONNAME = "Google LLC";
+ TargetAttributes = {
+ 33CC10EC2044A3C60003C045 = {
+ CreatedOnToolsVersion = 9.2;
+ LastSwiftMigration = 1100;
+ ProvisioningStyle = Automatic;
+ SystemCapabilities = {
+ com.apple.Sandbox = {
+ enabled = 1;
+ };
+ };
+ };
+ 33CC111A2044C6BA0003C045 = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Manual;
+ };
+ };
+ };
+ buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 8.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 33CC10E42044A3C60003C045;
+ productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 33CC10EC2044A3C60003C045 /* Runner */,
+ 33CC111A2044C6BA0003C045 /* Flutter Assemble */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 33CC10EB2044A3C60003C045 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
+ 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3399D490228B24CF009A79C7 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n";
+ };
+ 33CC111E2044C6BF0003C045 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ Flutter/ephemeral/FlutterInputs.xcfilelist,
+ );
+ inputPaths = (
+ Flutter/ephemeral/tripwire,
+ );
+ outputFileListPaths = (
+ Flutter/ephemeral/FlutterOutputs.xcfilelist,
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n";
+ };
+ 84A8D21305B2F01D093A8F9C /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ B24477CAB9D5BDFC8F3553DA /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 33CC10E92044A3C60003C045 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
+ 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
+ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
+ targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 33CC10F52044A3C60003C045 /* Base */,
+ );
+ name = MainMenu.xib;
+ path = Runner;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 338D0CE9231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Profile;
+ };
+ 338D0CEA231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter/ephemeral",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Profile;
+ };
+ 338D0CEB231458BD00FA5F75 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Manual;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Profile;
+ };
+ 33CC10F92044A3C60003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 33CC10FA2044A3C60003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ };
+ name = Release;
+ };
+ 33CC10FC2044A3C60003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter/ephemeral",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 33CC10FD2044A3C60003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PROJECT_DIR)/Flutter/ephemeral",
+ );
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 33CC111C2044C6BA0003C045 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Manual;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 33CC111D2044C6BA0003C045 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC10F92044A3C60003C045 /* Debug */,
+ 33CC10FA2044A3C60003C045 /* Release */,
+ 338D0CE9231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC10FC2044A3C60003C045 /* Debug */,
+ 33CC10FD2044A3C60003C045 /* Release */,
+ 338D0CEA231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 33CC111C2044C6BA0003C045 /* Debug */,
+ 33CC111D2044C6BA0003C045 /* Release */,
+ 338D0CEB231458BD00FA5F75 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 33CC10E52044A3C60003C045 /* Project object */;
+}
diff --git a/connectivity_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/connectivity_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..2a7d3e7
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "1000"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+ BuildableName = "connectivity_example.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "00380F9121DF178D00097171"
+ BuildableName = "RunnerUITests.xctest"
+ BlueprintName = "RunnerUITests"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+ BuildableName = "connectivity_example.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+ BuildableName = "connectivity_example.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "33CC10EC2044A3C60003C045"
+ BuildableName = "connectivity_example.app"
+ BlueprintName = "Runner"
+ ReferencedContainer = "container:Runner.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/connectivity_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/connectivity_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..21a3cc1
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "group:Runner.xcodeproj">
+ </FileRef>
+ <FileRef
+ location = "group:Pods/Pods.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/connectivity_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/connectivity_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IDEDidComputeMac32BitWarning</key>
+ <true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/macos/Runner/AppDelegate.swift b/connectivity_macos/example/macos/Runner/AppDelegate.swift
new file mode 100644
index 0000000..d53ef64
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/AppDelegate.swift
@@ -0,0 +1,9 @@
+import Cocoa
+import FlutterMacOS
+
+@NSApplicationMain
+class AppDelegate: FlutterAppDelegate {
+ override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
+ return true
+ }
+}
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..a2ec33f
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+ "images" : [
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "app_icon_16.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "16x16",
+ "idiom" : "mac",
+ "filename" : "app_icon_32.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "app_icon_32.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "32x32",
+ "idiom" : "mac",
+ "filename" : "app_icon_64.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "app_icon_128.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "128x128",
+ "idiom" : "mac",
+ "filename" : "app_icon_256.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "app_icon_256.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "256x256",
+ "idiom" : "mac",
+ "filename" : "app_icon_512.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "app_icon_512.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "512x512",
+ "idiom" : "mac",
+ "filename" : "app_icon_1024.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000..3c4935a
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
new file mode 100644
index 0000000..ed4cc16
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
new file mode 100644
index 0000000..483be61
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
new file mode 100644
index 0000000..bcbf36d
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
new file mode 100644
index 0000000..9c0a652
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
new file mode 100644
index 0000000..e71a726
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
new file mode 100644
index 0000000..8a31fe2
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
Binary files differ
diff --git a/connectivity_macos/example/macos/Runner/Base.lproj/MainMenu.xib b/connectivity_macos/example/macos/Runner/Base.lproj/MainMenu.xib
new file mode 100644
index 0000000..537341a
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Base.lproj/MainMenu.xib
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+ <dependencies>
+ <deployment identifier="macosx"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+ <connections>
+ <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
+ </connections>
+ </customObject>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+ <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Runner" customModuleProvider="target">
+ <connections>
+ <outlet property="applicationMenu" destination="uQy-DD-JDr" id="XBo-yE-nKs"/>
+ <outlet property="mainFlutterWindow" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
+ </connections>
+ </customObject>
+ <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+ <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+ <items>
+ <menuItem title="APP_NAME" id="1Xt-HY-uBw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="APP_NAME" systemMenu="apple" id="uQy-DD-JDr">
+ <items>
+ <menuItem title="About APP_NAME" id="5kV-Vb-QxS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+ <menuItem title="Services" id="NMo-om-nkz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+ <menuItem title="Hide APP_NAME" keyEquivalent="h" id="Olw-nP-bQN">
+ <connections>
+ <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Show All" id="Kd2-mp-pUS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+ <menuItem title="Quit APP_NAME" keyEquivalent="q" id="4sb-4s-VLi">
+ <connections>
+ <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Edit" id="5QF-Oa-p0T">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+ <items>
+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+ <connections>
+ <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+ <connections>
+ <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+ <connections>
+ <action selector="cut:" target="-1" id="YJe-68-I9s"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+ <connections>
+ <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+ <connections>
+ <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Delete" id="pa3-QI-u2k">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+ <connections>
+ <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+ <menuItem title="Find" id="4EN-yA-p0u">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Find" id="1b7-l0-nxx">
+ <items>
+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+ <connections>
+ <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+ <items>
+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+ <connections>
+ <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+ <connections>
+ <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Substitutions" id="9ic-FL-obx">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+ <items>
+ <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Links" id="cwL-P1-jid">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Data Detectors" id="tRr-pd-1PS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Transformations" id="2oI-Rn-ZJC">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+ <items>
+ <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Speech" id="xrE-MZ-jX0">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+ <items>
+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="View" id="H8h-7b-M4v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="View" id="HyV-fh-RgO">
+ <items>
+ <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Window" id="aUF-d1-5bR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+ <items>
+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+ <connections>
+ <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Zoom" id="R4o-n2-Eq4">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ <point key="canvasLocation" x="142" y="-258"/>
+ </menu>
+ <window title="APP_NAME" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MainFlutterWindow" customModule="Runner" customModuleProvider="target">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+ <rect key="contentRect" x="335" y="390" width="800" height="600"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1577"/>
+ <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
+ <rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </view>
+ </window>
+ </objects>
+</document>
diff --git a/connectivity_macos/example/macos/Runner/Configs/AppInfo.xcconfig b/connectivity_macos/example/macos/Runner/Configs/AppInfo.xcconfig
new file mode 100644
index 0000000..a951488
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/AppInfo.xcconfig
@@ -0,0 +1,14 @@
+// Application-level settings for the Runner target.
+//
+// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
+// future. If not, the values below would default to using the project name when this becomes a
+// 'flutter create' template.
+
+// The application's name. By default this is also the title of the Flutter window.
+PRODUCT_NAME = connectivity_example
+
+// The application's bundle identifier
+PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.connectivityExample
+
+// The copyright displayed in application information
+PRODUCT_COPYRIGHT = Copyright © 2019 io.flutter.plugins. All rights reserved.
diff --git a/connectivity_macos/example/macos/Runner/Configs/Debug.xcconfig b/connectivity_macos/example/macos/Runner/Configs/Debug.xcconfig
new file mode 100644
index 0000000..36b0fd9
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Debug.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/connectivity_macos/example/macos/Runner/Configs/Release.xcconfig b/connectivity_macos/example/macos/Runner/Configs/Release.xcconfig
new file mode 100644
index 0000000..dff4f49
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "../../Flutter/Flutter-Release.xcconfig"
+#include "Warnings.xcconfig"
diff --git a/connectivity_macos/example/macos/Runner/Configs/Warnings.xcconfig b/connectivity_macos/example/macos/Runner/Configs/Warnings.xcconfig
new file mode 100644
index 0000000..42bcbf4
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Configs/Warnings.xcconfig
@@ -0,0 +1,13 @@
+WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
+GCC_WARN_UNDECLARED_SELECTOR = YES
+CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
+CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
+CLANG_WARN_PRAGMA_PACK = YES
+CLANG_WARN_STRICT_PROTOTYPES = YES
+CLANG_WARN_COMMA = YES
+GCC_WARN_STRICT_SELECTOR_MATCH = YES
+CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
+CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
+GCC_WARN_SHADOW = YES
+CLANG_WARN_UNREACHABLE_CODE = YES
diff --git a/connectivity_macos/example/macos/Runner/DebugProfile.entitlements b/connectivity_macos/example/macos/Runner/DebugProfile.entitlements
new file mode 100644
index 0000000..dddb8a3
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/DebugProfile.entitlements
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.app-sandbox</key>
+ <true/>
+ <key>com.apple.security.cs.allow-jit</key>
+ <true/>
+ <key>com.apple.security.network.server</key>
+ <true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/macos/Runner/Info.plist b/connectivity_macos/example/macos/Runner/Info.plist
new file mode 100644
index 0000000..4789daa
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>$(FLUTTER_BUILD_NAME)</string>
+ <key>CFBundleVersion</key>
+ <string>$(FLUTTER_BUILD_NUMBER)</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>$(PRODUCT_COPYRIGHT)</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift b/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift
new file mode 100644
index 0000000..2722837
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/MainFlutterWindow.swift
@@ -0,0 +1,15 @@
+import Cocoa
+import FlutterMacOS
+
+class MainFlutterWindow: NSWindow {
+ override func awakeFromNib() {
+ let flutterViewController = FlutterViewController.init()
+ let windowFrame = self.frame
+ self.contentViewController = flutterViewController
+ self.setFrame(windowFrame, display: true)
+
+ RegisterGeneratedPlugins(registry: flutterViewController)
+
+ super.awakeFromNib()
+ }
+}
diff --git a/connectivity_macos/example/macos/Runner/Release.entitlements b/connectivity_macos/example/macos/Runner/Release.entitlements
new file mode 100644
index 0000000..852fa1a
--- /dev/null
+++ b/connectivity_macos/example/macos/Runner/Release.entitlements
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.app-sandbox</key>
+ <true/>
+</dict>
+</plist>
diff --git a/connectivity_macos/example/pubspec.yaml b/connectivity_macos/example/pubspec.yaml
new file mode 100644
index 0000000..8772500
--- /dev/null
+++ b/connectivity_macos/example/pubspec.yaml
@@ -0,0 +1,19 @@
+name: connectivity_example
+description: Demonstrates how to use the connectivity plugin.
+
+dependencies:
+ flutter:
+ sdk: flutter
+ connectivity: any
+ connectivity_macos:
+ path: ../
+
+dev_dependencies:
+ flutter_driver:
+ sdk: flutter
+ test: any
+ e2e: ^0.2.0
+ pedantic: ^1.8.0
+
+flutter:
+ uses-material-design: true
diff --git a/connectivity_macos/example/test_driver/test/connectivity_e2e.dart b/connectivity_macos/example/test_driver/test/connectivity_e2e.dart
new file mode 100644
index 0000000..10c4bda
--- /dev/null
+++ b/connectivity_macos/example/test_driver/test/connectivity_e2e.dart
@@ -0,0 +1,41 @@
+// Copyright 2019 The Chromium Authors. 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:io';
+import 'package:e2e/e2e.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:connectivity/connectivity.dart';
+
+void main() {
+ E2EWidgetsFlutterBinding.ensureInitialized();
+
+ group('Connectivity test driver', () {
+ Connectivity _connectivity;
+
+ setUpAll(() async {
+ _connectivity = Connectivity();
+ });
+
+ testWidgets('test connectivity result', (WidgetTester tester) async {
+ final ConnectivityResult result = await _connectivity.checkConnectivity();
+ expect(result, isNotNull);
+ switch (result) {
+ case ConnectivityResult.wifi:
+ expect(_connectivity.getWifiName(), completes);
+ expect(_connectivity.getWifiBSSID(), completes);
+ expect((await _connectivity.getWifiIP()), isNotNull);
+ break;
+ default:
+ break;
+ }
+ });
+
+ testWidgets('test location methods, iOS only', (WidgetTester tester) async {
+ if (Platform.isIOS) {
+ expect((await _connectivity.getLocationServiceAuthorization()),
+ LocationAuthorizationStatus.notDetermined);
+ }
+ });
+ });
+}
diff --git a/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart b/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart
new file mode 100644
index 0000000..84b7ae6
--- /dev/null
+++ b/connectivity_macos/example/test_driver/test/connectivity_e2e_test.dart
@@ -0,0 +1,14 @@
+// Copyright 2019 The Chromium Authors. 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:io';
+import 'package:flutter_driver/flutter_driver.dart';
+
+Future<void> main() async {
+ final FlutterDriver driver = await FlutterDriver.connect();
+ final String result =
+ await driver.requestData(null, timeout: const Duration(minutes: 1));
+ await driver.close();
+ exit(result == 'pass' ? 0 : 1);
+}
diff --git a/connectivity/connectivity_macos/ios/connectivity_macos.podspec b/connectivity_macos/ios/connectivity_macos.podspec
similarity index 100%
rename from connectivity/connectivity_macos/ios/connectivity_macos.podspec
rename to connectivity_macos/ios/connectivity_macos.podspec
diff --git a/connectivity_macos/lib/connectivity_macos.dart b/connectivity_macos/lib/connectivity_macos.dart
new file mode 100644
index 0000000..7be7b14
--- /dev/null
+++ b/connectivity_macos/lib/connectivity_macos.dart
@@ -0,0 +1,3 @@
+// Analyze will fail if there is no main.dart file. This file should
+// be removed once an example app has been added to connectivity_macos.
+// https://github.com/flutter/flutter/issues/51007
diff --git a/connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift b/connectivity_macos/macos/Classes/ConnectivityPlugin.swift
similarity index 100%
rename from connectivity/connectivity_macos/macos/Classes/ConnectivityPlugin.swift
rename to connectivity_macos/macos/Classes/ConnectivityPlugin.swift
diff --git a/connectivity/connectivity_macos/macos/Classes/IPHelper.h b/connectivity_macos/macos/Classes/IPHelper.h
similarity index 100%
rename from connectivity/connectivity_macos/macos/Classes/IPHelper.h
rename to connectivity_macos/macos/Classes/IPHelper.h
diff --git a/connectivity/connectivity_macos/macos/connectivity_macos.podspec b/connectivity_macos/macos/connectivity_macos.podspec
similarity index 100%
rename from connectivity/connectivity_macos/macos/connectivity_macos.podspec
rename to connectivity_macos/macos/connectivity_macos.podspec
diff --git a/connectivity/connectivity_macos/pubspec.yaml b/connectivity_macos/pubspec.yaml
similarity index 87%
rename from connectivity/connectivity_macos/pubspec.yaml
rename to connectivity_macos/pubspec.yaml
index f82189f..70ba247 100644
--- a/connectivity/connectivity_macos/pubspec.yaml
+++ b/connectivity_macos/pubspec.yaml
@@ -1,6 +1,6 @@
name: connectivity_macos
description: macOS implementation of the connectivity plugin.
-version: 0.0.2+1
+version: 0.1.0+1
homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_macos
flutter:
@@ -16,3 +16,6 @@
dependencies:
flutter:
sdk: flutter
+
+dev_dependencies:
+ pedantic: ^1.8.0
diff --git a/connectivity_platform_interface/BUILD.gn b/connectivity_platform_interface/BUILD.gn
new file mode 100644
index 0000000..5541f94
--- /dev/null
+++ b/connectivity_platform_interface/BUILD.gn
@@ -0,0 +1,19 @@
+# This file is generated by importer.py for connectivity_platform_interface-1.0.3
+
+import("//build/dart/dart_library.gni")
+
+dart_library("connectivity_platform_interface") {
+ package_name = "connectivity_platform_interface"
+
+ # This parameter is left empty as we don't care about analysis or exporting
+ # these sources outside of the tree.
+ sources = []
+
+ disable_analysis = true
+
+ deps = [
+ "//third_party/dart-pkg/pub/plugin_platform_interface",
+ "//third_party/dart-pkg/pub/meta",
+ "//third_party/dart-pkg/git/flutter/packages/flutter",
+ ]
+}
diff --git a/connectivity_platform_interface/CHANGELOG.md b/connectivity_platform_interface/CHANGELOG.md
new file mode 100644
index 0000000..d249985
--- /dev/null
+++ b/connectivity_platform_interface/CHANGELOG.md
@@ -0,0 +1,19 @@
+## 1.0.3
+
+* Make the pedantic dev_dependency explicit.
+
+## 1.0.2
+
+* Bring ConnectivityResult and LocationAuthorizationStatus enums from the core package.
+* Use the above Enums as return values for ConnectivityPlatformInterface methods.
+* Modify the MethodChannel implementation so it returns the right types.
+* Bring all utility methods, asserts and other logic that is only needed on the MethodChannel implementation from the core package.
+* Bring MethodChannel unit tests from core package.
+
+## 1.0.1
+
+* Fix README.md link.
+
+## 1.0.0
+
+* Initial release.
diff --git a/connectivity_platform_interface/LICENSE b/connectivity_platform_interface/LICENSE
new file mode 100644
index 0000000..0c91662
--- /dev/null
+++ b/connectivity_platform_interface/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/connectivity_platform_interface/README.md b/connectivity_platform_interface/README.md
new file mode 100644
index 0000000..76b3931
--- /dev/null
+++ b/connectivity_platform_interface/README.md
@@ -0,0 +1,26 @@
+# connectivity_platform_interface
+
+A common platform interface for the [`connectivity`][1] plugin.
+
+This interface allows platform-specific implementations of the `connectivity`
+plugin, as well as the plugin itself, to ensure they are supporting the
+same interface.
+
+# Usage
+
+To implement a new platform-specific implementation of `connectivity`, extend
+[`ConnectivityPlatform`][2] with an implementation that performs the
+platform-specific behavior, and when you register your plugin, set the default
+`ConnectivityPlatform` by calling
+`ConnectivityPlatform.instance = MyPlatformConnectivity()`.
+
+# Note on breaking changes
+
+Strongly prefer non-breaking changes (such as adding a method to the interface)
+over breaking changes for this package.
+
+See https://flutter.dev/go/platform-interface-breaking-changes for a discussion
+on why a less-clean interface is preferable to a breaking change.
+
+[1]: ../
+[2]: lib/connectivity_platform_interface.dart
diff --git a/connectivity_platform_interface/lib/connectivity_platform_interface.dart b/connectivity_platform_interface/lib/connectivity_platform_interface.dart
new file mode 100644
index 0000000..cfd9cf6
--- /dev/null
+++ b/connectivity_platform_interface/lib/connectivity_platform_interface.dart
@@ -0,0 +1,79 @@
+// Copyright 2020 The Chromium Authors. 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 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'src/enums.dart';
+import 'src/method_channel_connectivity.dart';
+
+export 'src/enums.dart';
+
+/// The interface that implementations of connectivity must implement.
+///
+/// Platform implementations should extend this class rather than implement it as `Connectivity`
+/// does not consider newly added methods to be breaking changes. Extending this class
+/// (using `extends`) ensures that the subclass will get the default implementation, while
+/// platform implementations that `implements` this interface will be broken by newly added
+/// [ConnectivityPlatform] methods.
+abstract class ConnectivityPlatform extends PlatformInterface {
+ /// Constructs a ConnectivityPlatform.
+ ConnectivityPlatform() : super(token: _token);
+
+ static final Object _token = Object();
+
+ static ConnectivityPlatform _instance = MethodChannelConnectivity();
+
+ /// The default instance of [ConnectivityPlatform] to use.
+ ///
+ /// Defaults to [MethodChannelConnectivity].
+ static ConnectivityPlatform get instance => _instance;
+
+ /// Platform-specific plugins should set this with their own platform-specific
+ /// class that extends [ConnectivityPlatform] when they register themselves.
+ static set instance(ConnectivityPlatform instance) {
+ PlatformInterface.verifyToken(instance, _token);
+ _instance = instance;
+ }
+
+ /// Checks the connection status of the device.
+ Future<ConnectivityResult> checkConnectivity() {
+ throw UnimplementedError('checkConnectivity() has not been implemented.');
+ }
+
+ /// Returns a Stream of ConnectivityResults changes.
+ Stream<ConnectivityResult> get onConnectivityChanged {
+ throw UnimplementedError(
+ 'get onConnectivityChanged has not been implemented.');
+ }
+
+ /// Obtains the wifi name (SSID) of the connected network
+ Future<String> getWifiName() {
+ throw UnimplementedError('getWifiName() has not been implemented.');
+ }
+
+ /// Obtains the wifi BSSID of the connected network.
+ Future<String> getWifiBSSID() {
+ throw UnimplementedError('getWifiBSSID() has not been implemented.');
+ }
+
+ /// Obtains the IP address of the connected wifi network
+ Future<String> getWifiIP() {
+ throw UnimplementedError('getWifiIP() has not been implemented.');
+ }
+
+ /// Request to authorize the location service (Only on iOS).
+ Future<LocationAuthorizationStatus> requestLocationServiceAuthorization(
+ {bool requestAlwaysLocationUsage = false}) {
+ throw UnimplementedError(
+ 'requestLocationServiceAuthorization() has not been implemented.');
+ }
+
+ /// Get the current location service authorization (Only on iOS).
+ Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
+ throw UnimplementedError(
+ 'getLocationServiceAuthorization() has not been implemented.');
+ }
+}
diff --git a/connectivity_platform_interface/lib/src/enums.dart b/connectivity_platform_interface/lib/src/enums.dart
new file mode 100644
index 0000000..9d8cef9
--- /dev/null
+++ b/connectivity_platform_interface/lib/src/enums.dart
@@ -0,0 +1,32 @@
+/// Connection status check result.
+enum ConnectivityResult {
+ /// WiFi: Device connected via Wi-Fi
+ wifi,
+
+ /// Mobile: Device connected to cellular network
+ mobile,
+
+ /// None: Device not connected to any network
+ none
+}
+
+/// The status of the location service authorization.
+enum LocationAuthorizationStatus {
+ /// The authorization of the location service is not determined.
+ notDetermined,
+
+ /// This app is not authorized to use location.
+ restricted,
+
+ /// User explicitly denied the location service.
+ denied,
+
+ /// User authorized the app to access the location at any time.
+ authorizedAlways,
+
+ /// User authorized the app to access the location when the app is visible to them.
+ authorizedWhenInUse,
+
+ /// Status unknown.
+ unknown
+}
diff --git a/connectivity_platform_interface/lib/src/method_channel_connectivity.dart b/connectivity_platform_interface/lib/src/method_channel_connectivity.dart
new file mode 100644
index 0000000..7a64115
--- /dev/null
+++ b/connectivity_platform_interface/lib/src/method_channel_connectivity.dart
@@ -0,0 +1,88 @@
+// Copyright 2020 The Chromium Authors. 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' show Platform;
+
+import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
+import 'package:flutter/services.dart';
+import 'package:meta/meta.dart';
+
+import 'utils.dart';
+
+/// An implementation of [ConnectivityPlatform] that uses method channels.
+class MethodChannelConnectivity extends ConnectivityPlatform {
+ /// The method channel used to interact with the native platform.
+ @visibleForTesting
+ MethodChannel methodChannel =
+ MethodChannel('plugins.flutter.io/connectivity');
+
+ /// The event channel used to receive ConnectivityResult changes from the native platform.
+ @visibleForTesting
+ EventChannel eventChannel =
+ EventChannel('plugins.flutter.io/connectivity_status');
+
+ Stream<ConnectivityResult> _onConnectivityChanged;
+
+ /// Fires whenever the connectivity state changes.
+ Stream<ConnectivityResult> get onConnectivityChanged {
+ if (_onConnectivityChanged == null) {
+ _onConnectivityChanged = eventChannel
+ .receiveBroadcastStream()
+ .map((dynamic result) => result.toString())
+ .map(parseConnectivityResult);
+ }
+ return _onConnectivityChanged;
+ }
+
+ @override
+ Future<ConnectivityResult> checkConnectivity() {
+ return methodChannel
+ .invokeMethod<String>('check')
+ .then(parseConnectivityResult);
+ }
+
+ @override
+ Future<String> getWifiName() async {
+ String wifiName = await methodChannel.invokeMethod<String>('wifiName');
+ // as Android might return <unknown ssid>, uniforming result
+ // our iOS implementation will return null
+ if (wifiName == '<unknown ssid>') {
+ wifiName = null;
+ }
+ return wifiName;
+ }
+
+ @override
+ Future<String> getWifiBSSID() {
+ return methodChannel.invokeMethod<String>('wifiBSSID');
+ }
+
+ @override
+ Future<String> getWifiIP() {
+ return methodChannel.invokeMethod<String>('wifiIPAddress');
+ }
+
+ @override
+ Future<LocationAuthorizationStatus> requestLocationServiceAuthorization({
+ bool requestAlwaysLocationUsage = false,
+ }) {
+ // `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
+ // TODO: These should noop for non-Android, instead of throwing, so people don't need to rely on dart:io for this.
+ assert(!Platform.isAndroid);
+ return methodChannel.invokeMethod<String>(
+ 'requestLocationServiceAuthorization', <bool>[
+ requestAlwaysLocationUsage
+ ]).then(parseLocationAuthorizationStatus);
+ }
+
+ @override
+ Future<LocationAuthorizationStatus> getLocationServiceAuthorization() {
+ // `assert(Platform.isIOS)` will prevent us from doing dart side unit testing.
+ assert(!Platform.isAndroid);
+ return methodChannel
+ .invokeMethod<String>('getLocationServiceAuthorization')
+ .then(parseLocationAuthorizationStatus);
+ }
+}
diff --git a/connectivity_platform_interface/lib/src/utils.dart b/connectivity_platform_interface/lib/src/utils.dart
new file mode 100644
index 0000000..2ae22e1
--- /dev/null
+++ b/connectivity_platform_interface/lib/src/utils.dart
@@ -0,0 +1,32 @@
+import 'package:connectivity_platform_interface/connectivity_platform_interface.dart';
+
+/// Convert a String to a ConnectivityResult value.
+ConnectivityResult parseConnectivityResult(String state) {
+ switch (state) {
+ case 'wifi':
+ return ConnectivityResult.wifi;
+ case 'mobile':
+ return ConnectivityResult.mobile;
+ case 'none':
+ default:
+ return ConnectivityResult.none;
+ }
+}
+
+/// Convert a String to a LocationAuthorizationStatus value.
+LocationAuthorizationStatus parseLocationAuthorizationStatus(String result) {
+ switch (result) {
+ case 'notDetermined':
+ return LocationAuthorizationStatus.notDetermined;
+ case 'restricted':
+ return LocationAuthorizationStatus.restricted;
+ case 'denied':
+ return LocationAuthorizationStatus.denied;
+ case 'authorizedAlways':
+ return LocationAuthorizationStatus.authorizedAlways;
+ case 'authorizedWhenInUse':
+ return LocationAuthorizationStatus.authorizedWhenInUse;
+ default:
+ return LocationAuthorizationStatus.unknown;
+ }
+}
diff --git a/connectivity_platform_interface/pubspec.yaml b/connectivity_platform_interface/pubspec.yaml
new file mode 100644
index 0000000..78f9473
--- /dev/null
+++ b/connectivity_platform_interface/pubspec.yaml
@@ -0,0 +1,21 @@
+name: connectivity_platform_interface
+description: A common platform interface for the connectivity plugin.
+homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_platform_interface
+# NOTE: We strongly prefer non-breaking changes, even at the expense of a
+# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
+version: 1.0.3
+
+dependencies:
+ flutter:
+ sdk: flutter
+ meta: ^1.0.5
+ plugin_platform_interface: ^1.0.1
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ pedantic: ^1.8.0
+
+environment:
+ sdk: ">=2.0.0-dev.28.0 <3.0.0"
+ flutter: ">=1.10.0 <2.0.0"
diff --git a/coverage/.travis.yml b/coverage/.travis.yml
index 9ce0790..5cccfe5 100644
--- a/coverage/.travis.yml
+++ b/coverage/.travis.yml
@@ -1,7 +1,7 @@
language: dart
dart:
- - 2.6.0
+ - 2.7.0
- dev
install:
diff --git a/coverage/BUILD.gn b/coverage/BUILD.gn
index e7f6d83..9b05ac8 100644
--- a/coverage/BUILD.gn
+++ b/coverage/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for coverage-0.13.6
+# This file is generated by importer.py for coverage-0.13.8
import("//build/dart/dart_library.gni")
diff --git a/coverage/CHANGELOG.md b/coverage/CHANGELOG.md
index b97c52b..c3d28d2 100644
--- a/coverage/CHANGELOG.md
+++ b/coverage/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.13.8 - 2020-03-02
+
+* Update to package_config `1.9.0` which supports package_config.json
+ files and should be forwards compatible with `2.0.0`.
+* Deprecate the `packageRoot` argument on `Resolver`.
+
+## 0.13.7 - 2020-02-28
+
+* Loosen the dependency on the `vm_service` package from `>=1.0.0 <3.0.0` to
+`>=1.0.0 <4.0.0`.
+
## 0.13.6 - 2020-02-10
* Now consider all `.json` files for the `format_coverage` command.
diff --git a/coverage/bin/format_coverage.dart b/coverage/bin/format_coverage.dart
index 0b15899..3e2b659 100644
--- a/coverage/bin/format_coverage.dart
+++ b/coverage/bin/format_coverage.dart
@@ -54,6 +54,7 @@
? BazelResolver(workspacePath: env.bazelWorkspace)
: Resolver(
packagesPath: env.packagesPath,
+ // ignore_for_file: deprecated_member_use_from_same_package
packageRoot: env.pkgRoot,
sdkRoot: env.sdkRoot);
final loader = Loader();
diff --git a/coverage/lib/src/collect.dart b/coverage/lib/src/collect.dart
index f44b030..768e2f8 100644
--- a/coverage/lib/src/collect.dart
+++ b/coverage/lib/src/collect.dart
@@ -51,7 +51,10 @@
final options = const CompressionOptions(enabled: false);
final socket = await WebSocket.connect('$uri', compression: options);
final controller = StreamController<String>();
- socket.listen((data) => controller.add(data as String));
+ socket.listen((data) => controller.add(data as String), onDone: () {
+ controller.close();
+ service.dispose();
+ });
service = VmService(
controller.stream, (String message) => socket.add(message),
log: StdoutLog(), disposeHandler: () => socket.close());
@@ -86,7 +89,7 @@
if (isolateIds != null && !isolateIds.contains(isolateRef.id)) continue;
if (scopedOutput.isNotEmpty) {
final scripts = await service.getScripts(isolateRef.id);
- for (var script in scripts.scripts) {
+ for (ScriptRef script in scripts.scripts) {
final uri = Uri.parse(script.uri);
if (uri.scheme != 'package') continue;
final scope = uri.path.split('/').first;
@@ -94,7 +97,7 @@
if (!scopedOutput.contains(scope)) continue;
final scriptReport = await service.getSourceReport(
isolateRef.id, <String>[SourceReportKind.kCoverage],
- forceCompile: true, scriptId: script.id);
+ forceCompile: true, scriptId: script.id) as SourceReport;
final coverage = await _getCoverageJson(
service, isolateRef, scriptReport, includeDart);
allCoverage.addAll(coverage);
@@ -104,7 +107,7 @@
isolateRef.id,
<String>[SourceReportKind.kCoverage],
forceCompile: true,
- );
+ ) as SourceReport;
final coverage = await _getCoverageJson(
service, isolateRef, isolateReport, includeDart);
allCoverage.addAll(coverage);
@@ -115,11 +118,22 @@
Future _resumeIsolates(VmService service) async {
final vm = await service.getVM();
+ final futures = <Future>[];
for (var isolateRef in vm.isolates) {
- final isolate = await service.getIsolate(isolateRef.id) as Isolate;
- if (isolate.pauseEvent.kind != EventKind.kResume) {
- await service.resume(isolateRef.id);
- }
+ // Guard against sync as well as async errors: sync - when we are writing
+ // message to the socket, the socket might be closed; async - when we are
+ // waiting for the response, the socket again closes.
+ futures.add(Future.sync(() async {
+ final isolate = await service.getIsolate(isolateRef.id) as Isolate;
+ if (isolate.pauseEvent.kind != EventKind.kResume) {
+ await service.resume(isolateRef.id);
+ }
+ }));
+ }
+ try {
+ await Future.wait(futures);
+ } catch (_) {
+ // Ignore resume isolate failures
}
}
diff --git a/coverage/lib/src/resolver.dart b/coverage/lib/src/resolver.dart
index 316c66d..03ae6ef 100644
--- a/coverage/lib/src/resolver.dart
+++ b/coverage/lib/src/resolver.dart
@@ -3,14 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
import 'dart:io';
-import 'package:package_config/packages_file.dart' as packages_file;
+import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;
/// [Resolver] resolves imports with respect to a given environment.
class Resolver {
- Resolver({String packagesPath, this.packageRoot, this.sdkRoot})
+ // ignore_for_file: deprecated_member_use_from_same_package
+ Resolver({String packagesPath, @deprecated this.packageRoot, this.sdkRoot})
: packagesPath = packagesPath,
_packages = packagesPath != null ? _parsePackages(packagesPath) : null;
@@ -89,8 +91,32 @@
}
static Map<String, Uri> _parsePackages(String packagesPath) {
- final source = File(packagesPath).readAsBytesSync();
- return packages_file.parse(source, Uri.file(packagesPath));
+ final content = File(packagesPath).readAsStringSync();
+ try {
+ final parsed =
+ PackageConfig.parseString(content, Uri.base.resolve(packagesPath));
+ return {
+ for (var package in parsed.packages)
+ package.name: package.packageUriRoot
+ };
+ } on FormatException catch (_) {
+ // It was probably an old style .packages file
+ final lines = LineSplitter.split(content);
+ final packageMap = <String, Uri>{};
+ for (var line in lines) {
+ if (line.startsWith('#')) continue;
+ final firstColon = line.indexOf(':');
+ if (firstColon == -1) {
+ throw FormatException(
+ 'Unexpected package config format, expected an old style '
+ '.packages file or new style package_config.json file.',
+ content);
+ }
+ packageMap[line.substring(0, firstColon)] =
+ Uri.parse(line.substring(firstColon + 1, line.length));
+ }
+ return packageMap;
+ }
}
}
diff --git a/coverage/pubspec.yaml b/coverage/pubspec.yaml
index 6757599..5401403 100644
--- a/coverage/pubspec.yaml
+++ b/coverage/pubspec.yaml
@@ -1,23 +1,24 @@
name: coverage
-version: 0.13.6
+version: 0.13.8
description: Coverage data manipulation and formatting
homepage: https://github.com/dart-lang/coverage
environment:
- sdk: '>=2.6.0 <3.0.0'
+ sdk: '>=2.7.0 <3.0.0'
dependencies:
- args: '>=1.4.0 <2.0.0'
+ args: ^1.4.0
logging: '>=0.9.0 <0.12.0'
- package_config: '>=0.1.5 <2.0.0'
+ package_config: ^1.9.0
path: '>=0.9.0 <2.0.0'
source_maps: ^0.10.8
stack_trace: ^1.3.0
- vm_service: '>=1.0.0 <3.0.0'
+ vm_service: '>=1.0.0 <4.0.0'
dev_dependencies:
pedantic: ^1.0.0
test: ^1.0.0
+ test_descriptor: ^1.2.0
executables:
collect_coverage:
diff --git a/device_info/BUILD.gn b/device_info/BUILD.gn
index f5a595b..ff67c9a 100644
--- a/device_info/BUILD.gn
+++ b/device_info/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for device_info-0.4.1+4
+# This file is generated by importer.py for device_info-0.4.1+5
import("//build/dart/dart_library.gni")
diff --git a/device_info/CHANGELOG.md b/device_info/CHANGELOG.md
index 13e0bae..00dcd29 100644
--- a/device_info/CHANGELOG.md
+++ b/device_info/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.4.1+5
+
+* Make the pedantic dev_dependency explicit.
+
## 0.4.1+4
* Remove the deprecated `author:` field from pubspec.yaml
diff --git a/device_info/example/pubspec.yaml b/device_info/example/pubspec.yaml
index 148b7b9..89bf430 100644
--- a/device_info/example/pubspec.yaml
+++ b/device_info/example/pubspec.yaml
@@ -11,6 +11,7 @@
flutter_driver:
sdk: flutter
e2e: ^0.2.0
+ pedantic: ^1.8.0
flutter:
uses-material-design: true
diff --git a/device_info/pubspec.yaml b/device_info/pubspec.yaml
index 452d690..b862a7d 100644
--- a/device_info/pubspec.yaml
+++ b/device_info/pubspec.yaml
@@ -2,7 +2,7 @@
description: Flutter plugin providing detailed information about the device
(make, model, etc.), and Android or iOS version the app is running on.
homepage: https://github.com/flutter/plugins/tree/master/packages/device_info
-version: 0.4.1+4
+version: 0.4.1+5
flutter:
plugin:
@@ -22,6 +22,7 @@
flutter_test:
sdk: flutter
e2e: ^0.2.0
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/graphs/.gitignore b/graphs/.gitignore
deleted file mode 100644
index ddfdca1..0000000
--- a/graphs/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.dart_tool/
-.packages
-.pub/
-build/
-pubspec.lock
diff --git a/graphs/.travis.yml b/graphs/.travis.yml
deleted file mode 100644
index 3c0743f..0000000
--- a/graphs/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: dart
-
-dart:
- - dev
- - stable
-
-dart_task:
- - test
- - test -p chrome,firefox
- - dartfmt
- - dartanalyzer: --fatal-infos --fatal-warnings .
-
-matrix:
- exclude:
- - dart: stable
- dart_task: dartfmt
-
-branches:
- only: [master]
-
-cache:
- directories:
- - $HOME/.pub-cache
diff --git a/graphs/CHANGELOG.md b/graphs/CHANGELOG.md
deleted file mode 100644
index 78722c4..0000000
--- a/graphs/CHANGELOG.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# 0.2.0-dev
-
-- **BREAKING** `shortestPath`, `shortestPaths` and `stronglyConnectedComponents`
- now have one generic parameter and have replaced the `key` parameter with
- optional params: `{bool equals(T key1, T key2), int hashCode(T key)}`.
- This follows the pattern used in `dart:collection` classes `HashMap` and
- `LinkedHashMap`. It improves the usability and performance of the case where
- the source values are directly usable in a hash data structure.
-
-# 0.1.3+1
-
-- Fixed a bug with non-identity `key` in `shortestPath` and `shortestPaths`.
-
-# 0.1.3
-
-- Added `shortestPath` and `shortestPaths` functions.
-- Use `HashMap` and `HashSet` from `dart:collection` for
- `stronglyConnectedComponents`. Improves runtime performance.
-
-# 0.1.2+1
-
-- Allow using non-dev Dart 2 SDK.
-
-# 0.1.2
-
-- `crawlAsync` surfaces exceptions while crawling through the result stream
- rather than as uncaught asynchronous errors.
-
-# 0.1.1
-
-- `crawlAsync` will now ignore nodes that are resolved to `null`.
-
-# 0.1.0
-
-- Initial release with an implementation of `stronglyConnectedComponents` and
- `crawlAsync`.
diff --git a/graphs/CONTRIBUTING.md b/graphs/CONTRIBUTING.md
deleted file mode 100644
index 286d61c..0000000
--- a/graphs/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
- // Copyright (c) 2017, 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.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
diff --git a/graphs/LICENSE b/graphs/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/graphs/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/graphs/README.md b/graphs/README.md
deleted file mode 100644
index 0edaf92..0000000
--- a/graphs/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# [![Build Status](https://travis-ci.org/dart-lang/graphs.svg?branch=master)](https://travis-ci.org/dart-lang/graphs)
-
-Graph algorithms which do not specify a particular approach for representing a
-Graph.
-
-Functions in this package will take arguments that provide the mechanism for
-traversing the graph. For example two common approaches for representing a
-graph:
-
-```dart
-class Graph {
- Map<Node, List<Node>> nodes;
-}
-class Node {
- // Interesting data
-}
-```
-
-```dart
-class Graph {
- Node root;
-}
-class Node {
- List<Node> edges;
- // Interesting data
-}
-```
-
-Any representation can be adapted to the needs of the algorithm:
-
-- Some algorithms need to associate data with each node in the graph. If the
- node type `T` does not correctly or efficiently implement `hashCode` or `==`,
- you may provide optional `equals` and/or `hashCode` functions are parameters.
-- Algorithms which need to traverse the graph take a `edges` function which
- provides the reachable nodes.
- - `(node) => graph[node]`
- - `(node) => node.edges`
-
-
-Graphs which are resolved asynchronously will have similar functions which
-return `FutureOr`.
diff --git a/graphs/analysis_options.yaml b/graphs/analysis_options.yaml
deleted file mode 100644
index 6e159f3..0000000
--- a/graphs/analysis_options.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-include: package:pedantic/analysis_options.yaml
-analyzer:
- strong-mode:
- implicit-casts: false
- errors:
- unused_element: error
- unused_import: error
- unused_local_variable: error
- dead_code: error
-linter:
- rules:
- - annotate_overrides
- - avoid_function_literals_in_foreach_calls
- - avoid_init_to_null
- - avoid_null_checks_in_equality_operators
- - avoid_relative_lib_imports
- - avoid_returning_null
- - avoid_unused_constructor_parameters
- - await_only_futures
- - camel_case_types
- - cancel_subscriptions
- - comment_references
- - constant_identifier_names
- - control_flow_in_finally
- - directives_ordering
- - empty_catches
- - empty_constructor_bodies
- - empty_statements
- - hash_and_equals
- - implementation_imports
- - invariant_booleans
- - iterable_contains_unrelated_type
- - library_names
- - library_prefixes
- - list_remove_unrelated_type
- - no_adjacent_strings_in_list
- - non_constant_identifier_names
- - omit_local_variable_types
- - only_throw_errors
- - overridden_fields
- - package_api_docs
- - package_names
- - package_prefixed_library_names
- - prefer_adjacent_string_concatenation
- - prefer_collection_literals
- - prefer_conditional_assignment
- - prefer_const_constructors
- - prefer_final_fields
- - prefer_initializing_formals
- - prefer_interpolation_to_compose_strings
- - prefer_single_quotes
- - prefer_typing_uninitialized_variables
- - slash_for_doc_comments
- - test_types_in_equals
- - super_goes_last
- - test_types_in_equals
- - throw_in_finally
- - type_init_formals
- - unnecessary_brace_in_string_interps
- - unnecessary_const
- - unnecessary_getters_setters
- - unnecessary_lambdas
- - unnecessary_new
- - unnecessary_null_aware_assignments
- - unnecessary_statements
- - unnecessary_this
diff --git a/graphs/benchmark/connected_components_benchmark.dart b/graphs/benchmark/connected_components_benchmark.dart
deleted file mode 100644
index c1c83d7..0000000
--- a/graphs/benchmark/connected_components_benchmark.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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:collection';
-import 'dart:math' show Random;
-
-import 'package:graphs/graphs.dart';
-
-void main() {
- final _rnd = Random(0);
- final size = 2000;
- final graph = HashMap<int, List<int>>();
-
- for (var i = 0; i < size * 3; i++) {
- final toList = graph.putIfAbsent(_rnd.nextInt(size), () => <int>[]);
-
- final toValue = _rnd.nextInt(size);
- if (!toList.contains(toValue)) {
- toList.add(toValue);
- }
- }
-
- var maxCount = 0;
- var maxIteration = 0;
-
- final duration = const Duration(milliseconds: 100);
-
- for (var i = 1;; i++) {
- var count = 0;
- final watch = Stopwatch()..start();
- while (watch.elapsed < duration) {
- count++;
- final length =
- stronglyConnectedComponents(graph.keys, (e) => graph[e] ?? []).length;
- assert(length == 244, '$length');
- }
-
- if (count > maxCount) {
- maxCount = count;
- maxIteration = i;
- }
-
- if (maxIteration == i || (i - maxIteration) % 20 == 0) {
- print('max iterations in ${duration.inMilliseconds}ms: $maxCount\t'
- 'after $maxIteration of $i iterations');
- }
- }
-}
diff --git a/graphs/benchmark/shortest_path_benchmark.dart b/graphs/benchmark/shortest_path_benchmark.dart
deleted file mode 100644
index 813c18b..0000000
--- a/graphs/benchmark/shortest_path_benchmark.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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:collection';
-import 'dart:math' show Random;
-
-import 'package:graphs/graphs.dart';
-
-void main() {
- final _rnd = Random(1);
- final size = 1000;
- final graph = HashMap<int, List<int>>();
-
- for (var i = 0; i < size * 5; i++) {
- final toList = graph.putIfAbsent(_rnd.nextInt(size), () => <int>[]);
-
- final toValue = _rnd.nextInt(size);
- if (!toList.contains(toValue)) {
- toList.add(toValue);
- }
- }
-
- int minTicks;
- var maxIteration = 0;
-
- final testOutput =
- shortestPath(0, size - 1, (e) => graph[e] ?? []).toString();
- print(testOutput);
- assert(testOutput == '[258, 252, 819, 999]');
-
- final watch = Stopwatch();
- for (var i = 1;; i++) {
- watch
- ..reset()
- ..start();
- final length = shortestPath(0, size - 1, (e) => graph[e] ?? []).length;
- watch.stop();
- assert(length == 4, '$length');
-
- if (minTicks == null || watch.elapsedTicks < minTicks) {
- minTicks = watch.elapsedTicks;
- maxIteration = i;
- }
-
- if (maxIteration == i || (i - maxIteration) % 100000 == 0) {
- print('min ticks for one run: $minTicks\t'
- 'after $maxIteration of $i iterations');
- }
- }
-}
diff --git a/graphs/example/crawl_async_example.dart b/graphs/example/crawl_async_example.dart
deleted file mode 100644
index 959b894..0000000
--- a/graphs/example/crawl_async_example.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2017, 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 'package:analyzer/dart/analysis/analysis_context.dart';
-import 'package:analyzer/dart/analysis/context_builder.dart';
-import 'package:analyzer/dart/analysis/context_locator.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:graphs/graphs.dart';
-import 'package:path/path.dart' as p;
-
-/// Print a transitive set of imported URIs where libraries are read
-/// asynchronously.
-Future<Null> main() async {
- var allImports = await crawlAsync(
- [Uri.parse('package:graphs/graphs.dart')], read, findImports)
- .toList();
- print(allImports.map((s) => s.uri).toList());
-}
-
-AnalysisContext _analysisContext;
-
-Future<AnalysisContext> get analysisContext async {
- if (_analysisContext == null) {
- var libUri = Uri.parse('package:graphs/');
- var libPath = await pathForUri(libUri);
- var packagePath = p.dirname(libPath);
-
- var roots = ContextLocator().locateRoots(includedPaths: [packagePath]);
- if (roots.length != 1) {
- throw StateError('Expected to find exactly one context root, got $roots');
- }
-
- _analysisContext = ContextBuilder().createContext(contextRoot: roots[0]);
- }
-
- return _analysisContext;
-}
-
-Future<Iterable<Uri>> findImports(Uri from, Source source) async {
- return source.unit.directives
- .whereType<UriBasedDirective>()
- .map((d) => d.uri.stringValue)
- .where((uri) => !uri.startsWith('dart:'))
- .map((import) => resolveImport(import, from));
-}
-
-Future<CompilationUnit> parseUri(Uri uri) async {
- var path = await pathForUri(uri);
- var analysisSession = (await analysisContext).currentSession;
- var parseResult = analysisSession.getParsedUnit(path);
- return parseResult.unit;
-}
-
-Future<String> pathForUri(Uri uri) async {
- var fileUri = await Isolate.resolvePackageUri(uri);
- if (fileUri == null || !fileUri.isScheme('file')) {
- throw StateError('Expected to resolve $uri to a file URI, got $fileUri');
- }
- return p.fromUri(fileUri);
-}
-
-Future<Source> read(Uri uri) async => Source(uri, await parseUri(uri));
-
-Uri resolveImport(String import, Uri from) {
- if (import.startsWith('package:')) return Uri.parse(import);
- assert(from.scheme == 'package');
- final package = from.pathSegments.first;
- final fromPath = p.joinAll(from.pathSegments.skip(1));
- final path = p.normalize(p.join(p.dirname(fromPath), import));
- return Uri.parse('package:${p.join(package, path)}');
-}
-
-class Source {
- final Uri uri;
- final CompilationUnit unit;
-
- Source(this.uri, this.unit);
-}
diff --git a/graphs/example/example.dart b/graphs/example/example.dart
deleted file mode 100644
index 47aca61..0000000
--- a/graphs/example/example.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2017, 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:graphs/graphs.dart';
-
-/// A representation of a directed graph.
-///
-/// Data is stored on the [Node] class.
-class Graph {
- final Map<Node, List<Node>> nodes;
-
- Graph(this.nodes);
-}
-
-class Node {
- final String id;
- final int data;
-
- Node(this.id, this.data);
-
- @override
- bool operator ==(Object other) => other is Node && other.id == id;
-
- @override
- int get hashCode => id.hashCode;
-
- @override
- String toString() => '<$id -> $data>';
-}
-
-void main() {
- var nodeA = Node('A', 1);
- var nodeB = Node('B', 2);
- var nodeC = Node('C', 3);
- var nodeD = Node('D', 4);
- var graph = Graph({
- nodeA: [nodeB, nodeC],
- nodeB: [nodeC, nodeD],
- nodeC: [nodeB, nodeD]
- });
-
- var components = stronglyConnectedComponents<Node>(
- graph.nodes.keys, (node) => graph.nodes[node]);
-
- print(components);
-}
diff --git a/graphs/lib/graphs.dart b/graphs/lib/graphs.dart
deleted file mode 100644
index a5de89c..0000000
--- a/graphs/lib/graphs.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/crawl_async.dart' show crawlAsync;
-export 'src/shortest_path.dart' show shortestPath, shortestPaths;
-export 'src/strongly_connected_components.dart'
- show stronglyConnectedComponents;
diff --git a/graphs/lib/src/crawl_async.dart b/graphs/lib/src/crawl_async.dart
deleted file mode 100644
index 319a61e..0000000
--- a/graphs/lib/src/crawl_async.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-
-final _empty = Future<Null>.value(null);
-
-/// Finds and returns every node in a graph who's nodes and edges are
-/// asynchronously resolved.
-///
-/// Cycles are allowed. If this is an undirected graph the [edges] function
-/// may be symmetric. In this case the [roots] may be any node in each connected
-/// graph.
-///
-/// [V] is the type of values in the graph nodes. [K] must be a type suitable
-/// for using as a Map or Set key. [edges] should return the next reachable
-/// nodes.
-///
-/// There are no ordering guarantees. This is useful for ensuring some work is
-/// performed at every node in an asynchronous graph, but does not give
-/// guarantees that the work is done in topological order.
-///
-/// If [readNode] returns null for any key it will be ignored from the rest of
-/// the graph. If missing nodes are important they should be tracked within the
-/// [readNode] callback.
-///
-/// If either [readNode] or [edges] throws the error will be forwarded
-/// through the result stream and no further nodes will be crawled, though some
-/// work may have already been started.
-Stream<V> crawlAsync<K, V>(Iterable<K> roots, FutureOr<V> Function(K) readNode,
- FutureOr<Iterable<K>> Function(K, V) edges) {
- final crawl = _CrawlAsync(roots, readNode, edges)..run();
- return crawl.result.stream;
-}
-
-class _CrawlAsync<K, V> {
- final result = StreamController<V>();
-
- final FutureOr<V> Function(K) readNode;
- final FutureOr<Iterable<K>> Function(K, V) edges;
- final Iterable<K> roots;
-
- final _seen = HashSet<K>();
-
- _CrawlAsync(this.roots, this.readNode, this.edges);
-
- /// Add all nodes in the graph to [result] and return a Future which fires
- /// after all nodes have been seen.
- Future<Null> run() async {
- try {
- await Future.wait(roots.map(_visit), eagerError: true);
- await result.close();
- } catch (e, st) {
- result.addError(e, st);
- await result.close();
- }
- }
-
- /// Resolve the node at [key] and output it, then start crawling all of it's
- /// edges.
- Future<Null> _crawlFrom(K key) async {
- var value = await readNode(key);
- if (value == null) return;
- if (result.isClosed) return;
- result.add(value);
- var next = await edges(key, value) ?? const [];
- await Future.wait(next.map(_visit), eagerError: true);
- }
-
- /// Synchronously record that [key] is being handled then start work on the
- /// node for [key].
- ///
- /// The returned Future will complete only after the work for [key] and all
- /// transitively reachable nodes has either been finished, or will be finished
- /// by some other Future in [_seen].
- Future<Null> _visit(K key) {
- if (_seen.contains(key)) return _empty;
- _seen.add(key);
- return _crawlFrom(key);
- }
-}
diff --git a/graphs/lib/src/shortest_path.dart b/graphs/lib/src/shortest_path.dart
deleted file mode 100644
index f295e5d..0000000
--- a/graphs/lib/src/shortest_path.dart
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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:collection';
-
-/// Returns the shortest path from [start] to [target] given the directed
-/// edges of a graph provided by [edges].
-///
-/// If [start] `==` [target], an empty [List] is returned and [edges] is never
-/// called.
-///
-/// [start], [target] and all values returned by [edges] must not be `null`.
-/// If asserts are enabled, an [AssertionError] is raised if these conditions
-/// are not met. If asserts are not enabled, violations result in undefined
-/// behavior.
-///
-/// If [equals] is provided, it is used to compare nodes in the graph. If
-/// [equals] is omitted, the node's own [Object.==] is used instead.
-///
-/// Similarly, if [hashCode] is provided, it is used to produce a hash value
-/// for nodes to efficiently calculate the return value. If it is omitted, the
-/// key's own [Object.hashCode] is used.
-///
-/// If you supply one of [equals] or [hashCode], you should generally also to
-/// supply the other.
-List<T> shortestPath<T>(
- T start,
- T target,
- Iterable<T> Function(T) edges, {
- bool equals(T key1, T key2),
- int hashCode(T key),
-}) =>
- _shortestPaths<T>(
- start,
- edges,
- target: target,
- equals: equals,
- hashCode: hashCode,
- )[target];
-
-/// Returns a [Map] of the shortest paths from [start] to all of the nodes in
-/// the directed graph defined by [edges].
-///
-/// All return values will contain the key [start] with an empty [List] value.
-///
-/// [start] and all values returned by [edges] must not be `null`.
-/// If asserts are enabled, an [AssertionError] is raised if these conditions
-/// are not met. If asserts are not enabled, violations result in undefined
-/// behavior.
-///
-/// If [equals] is provided, it is used to compare nodes in the graph. If
-/// [equals] is omitted, the node's own [Object.==] is used instead.
-///
-/// Similarly, if [hashCode] is provided, it is used to produce a hash value
-/// for nodes to efficiently calculate the return value. If it is omitted, the
-/// key's own [Object.hashCode] is used.
-///
-/// If you supply one of [equals] or [hashCode], you should generally also to
-/// supply the other.
-Map<T, List<T>> shortestPaths<T>(
- T start,
- Iterable<T> Function(T) edges, {
- bool equals(T key1, T key2),
- int hashCode(T key),
-}) =>
- _shortestPaths<T>(
- start,
- edges,
- equals: equals,
- hashCode: hashCode,
- );
-
-Map<T, List<T>> _shortestPaths<T>(
- T start,
- Iterable<T> Function(T) edges, {
- T target,
- bool equals(T key1, T key2),
- int hashCode(T key),
-}) {
- assert(start != null, '`start` cannot be null');
- assert(edges != null, '`edges` cannot be null');
-
- final distances = HashMap<T, List<T>>(equals: equals, hashCode: hashCode);
- distances[start] = List(0);
-
- equals ??= _defaultEquals;
- if (equals(start, target)) {
- return distances;
- }
-
- final toVisit = ListQueue<T>()..add(start);
-
- List<T> bestOption;
-
- while (toVisit.isNotEmpty) {
- final current = toVisit.removeFirst();
- final currentPath = distances[current];
- final currentPathLength = currentPath.length;
-
- if (bestOption != null && (currentPathLength + 1) >= bestOption.length) {
- // Skip any existing `toVisit` items that have no chance of being
- // better than bestOption (if it exists)
- continue;
- }
-
- for (var edge in edges(current)) {
- assert(edge != null, '`edges` cannot return null values.');
- final existingPath = distances[edge];
-
- assert(existingPath == null ||
- existingPath.length <= (currentPathLength + 1));
-
- if (existingPath == null) {
- final newOption = List<T>(currentPathLength + 1)
- ..setRange(0, currentPathLength, currentPath)
- ..[currentPathLength] = edge;
-
- if (equals(edge, target)) {
- assert(bestOption == null || bestOption.length > newOption.length);
- bestOption = newOption;
- }
-
- distances[edge] = newOption;
- if (bestOption == null || bestOption.length > newOption.length) {
- // Only add a node to visit if it might be a better path to the
- // target node
- toVisit.add(edge);
- }
- }
- }
- }
-
- return distances;
-}
-
-bool _defaultEquals(a, b) => a == b;
diff --git a/graphs/lib/src/strongly_connected_components.dart b/graphs/lib/src/strongly_connected_components.dart
deleted file mode 100644
index 19519a8..0000000
--- a/graphs/lib/src/strongly_connected_components.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2017, 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:collection';
-import 'dart:math' show min;
-
-/// Finds the strongly connected components of a directed graph using Tarjan's
-/// algorithm.
-///
-/// The result will be a valid reverse topological order ordering of the
-/// strongly connected components. Components further from a root will appear in
-/// the result before the components which they are connected to.
-///
-/// Nodes within a strongly connected component have no ordering guarantees,
-/// except that if the first value in [nodes] is a valid root, and is contained
-/// in a cycle, it will be the last element of that cycle.
-///
-/// [nodes] must contain at least a root of every tree in the graph if there are
-/// disjoint subgraphs but it may contain all nodes in the graph if the roots
-/// are not known.
-///
-/// If [equals] is provided, it is used to compare nodes in the graph. If
-/// [equals] is omitted, the node's own [Object.==] is used instead.
-///
-/// Similarly, if [hashCode] is provided, it is used to produce a hash value
-/// for nodes to efficiently calculate the return value. If it is omitted, the
-/// key's own [Object.hashCode] is used.
-///
-/// If you supply one of [equals] or [hashCode], you should generally also to
-/// supply the other.
-List<List<T>> stronglyConnectedComponents<T>(
- Iterable<T> nodes,
- Iterable<T> Function(T) edges, {
- bool equals(T key1, T key2),
- int hashCode(T key),
-}) {
- final result = <List<T>>[];
- final lowLinks = HashMap<T, int>(equals: equals, hashCode: hashCode);
- final indexes = HashMap<T, int>(equals: equals, hashCode: hashCode);
- final onStack = HashSet<T>(equals: equals, hashCode: hashCode);
-
- equals ??= _defaultEquals;
-
- var index = 0;
- var lastVisited = Queue<T>();
-
- void strongConnect(T node) {
- indexes[node] = index;
- lowLinks[node] = index;
- index++;
- lastVisited.addLast(node);
- onStack.add(node);
- // ignore: omit_local_variable_types
- for (final T next in edges(node) ?? const []) {
- if (!indexes.containsKey(next)) {
- strongConnect(next);
- lowLinks[node] = min(lowLinks[node], lowLinks[next]);
- } else if (onStack.contains(next)) {
- lowLinks[node] = min(lowLinks[node], indexes[next]);
- }
- }
- if (lowLinks[node] == indexes[node]) {
- final component = <T>[];
- T next;
- do {
- next = lastVisited.removeLast();
- onStack.remove(next);
- component.add(next);
- } while (!equals(next, node));
- result.add(component);
- }
- }
-
- for (final node in nodes) {
- if (!indexes.containsKey(node)) strongConnect(node);
- }
- return result;
-}
-
-bool _defaultEquals(a, b) => a == b;
diff --git a/graphs/pubspec.yaml b/graphs/pubspec.yaml
deleted file mode 100644
index 12c5ff4..0000000
--- a/graphs/pubspec.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: graphs
-version: 0.2.0
-description: Graph algorithms that operate on graphs in any representation
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/graphs
-
-environment:
- sdk: '>=2.0.0 <3.0.0'
-
-dev_dependencies:
- pedantic: ^1.3.0
- test: ^1.5.1
-
- # For examples
- analyzer: ^0.34.0
- path: ^1.1.0
diff --git a/mustache/BUILD.gn b/mustache/BUILD.gn
deleted file mode 100644
index 2e8c791..0000000
--- a/mustache/BUILD.gn
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is generated by importer.py for mustache-1.1.1
-
-import("//build/dart/dart_library.gni")
-
-dart_library("mustache") {
- package_name = "mustache"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- ]
-}
diff --git a/mustache/example/basic.dart b/mustache/example/basic.dart
deleted file mode 100644
index 89a293c..0000000
--- a/mustache/example/basic.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
- var source = '''
- {{# names }}
- <div>{{ lastname }}, {{ firstname }}</div>
- {{/ names }}
- {{^ names }}
- <div>No names.</div>
- {{/ names }}
- {{! I am a comment. }}
- ''';
-
- var template = new Template(source, name: 'template-filename.html');
-
- var output = template.renderString({'names': [
- {'firstname': 'Greg', 'lastname': 'Lowe'},
- {'firstname': 'Bob', 'lastname': 'Johnson'}
- ]});
-
- print(output);
-}
\ No newline at end of file
diff --git a/mustache/example/lambdas.dart b/mustache/example/lambdas.dart
deleted file mode 100644
index b7a9ff2..0000000
--- a/mustache/example/lambdas.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
- var t = new Template('{{ foo }}');
- Function lambda = (_) => 'bar';
- var output = t.renderString({'foo': lambda}); // bar
- print(output);
-
- t = new Template('{{# foo }}hidden{{/ foo }}');
- lambda = (_) => 'shown';
- output = t.renderString({'foo': lambda}); // shown
- print(output);
-
- t = new Template('{{# foo }}oi{{/ foo }}');
- lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
- output = t.renderString({'foo': lambda}); // <b>OI</b>
- print(output);
-
- t = new Template('{{# foo }}{{bar}}{{/ foo }}');
- lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
- output = t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
- print(output);
-
- t = new Template('{{# foo }}{{bar}}{{/ foo }}');
- lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>';
- output = t.renderString({'foo': lambda, 'bar': 'pub'}); // <b>PUB</b>
- print(output);
-
- t = new Template('{{# foo }}{{bar}}{{/ foo }}');
- lambda = (LambdaContext ctx) => ctx.renderSource(ctx.source + '{{cmd}}');
- output = t.renderString({'foo': lambda, 'bar': 'pub', 'cmd': 'build'}); // pub build
- print(output);
-}
diff --git a/mustache/example/nested_paths.dart b/mustache/example/nested_paths.dart
deleted file mode 100644
index 5472ce7..0000000
--- a/mustache/example/nested_paths.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
- var template = new Template('{{ author.name }}');
- var output = template.renderString({'author': {'name': 'Greg Lowe'}});
- print(output);
-}
diff --git a/mustache/example/partials.dart b/mustache/example/partials.dart
deleted file mode 100644
index a0c105f..0000000
--- a/mustache/example/partials.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'package:mustache/mustache.dart';
-
-main() {
- var partial = new Template('{{ foo }}', name: 'partial');
-
- var resolver = (String name) {
- if (name == 'partial-name') { // Name of partial tag.
- return partial;
- }
- };
-
- var t = new Template('{{> partial-name }}', partialResolver: resolver);
-
- var output = t.renderString({'foo': 'bar'}); // bar
- print(output);
-}
diff --git a/mustache/lib/src/token.dart b/mustache/lib/src/token.dart
deleted file mode 100644
index e4d7b59..0000000
--- a/mustache/lib/src/token.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-library mustache.token;
-
-class TokenType {
- const TokenType(this.name);
-
- final String name;
-
- String toString() => '(TokenType $name)';
-
- static const TokenType text = const TokenType('text');
- static const TokenType openDelimiter = const TokenType('openDelimiter');
- static const TokenType closeDelimiter = const TokenType('closeDelimiter');
-
- // A sigil is the word commonly used to describe the special character at the
- // start of mustache tag i.e. #, ^ or /.
- static const TokenType sigil = const TokenType('sigil');
- static const TokenType identifier = const TokenType('identifier');
- static const TokenType dot = const TokenType('dot');
-
- static const TokenType changeDelimiter = const TokenType('changeDelimiter');
- static const TokenType whitespace = const TokenType('whitespace');
- static const TokenType lineEnd = const TokenType('lineEnd');
-}
-
-class Token {
- Token(this.type, this.value, this.start, this.end);
-
- final TokenType type;
- final String value;
-
- final int start;
- final int end;
-
- String toString() => "(Token ${type.name} \"$value\" $start $end)";
-}
diff --git a/mustache/pubspec.yaml b/mustache/pubspec.yaml
deleted file mode 100644
index ed01ed6..0000000
--- a/mustache/pubspec.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: mustache
-version: 1.1.1
-author: Greg Lowe <greg@vis.net.nz>
-description: Mustache template library
-homepage: https://github.com/xxgreg/mustache
-environment:
- sdk: '>=2.0.0 <3.0.0'
-dev_dependencies:
- test: '>=0.12.0 <2.0.0'
-analyzer:
- strong-mode: true
diff --git a/mustache/.gitignore b/mustache_template/.gitignore
similarity index 100%
rename from mustache/.gitignore
rename to mustache_template/.gitignore
diff --git a/mustache/.travis.yml b/mustache_template/.travis.yml
similarity index 100%
rename from mustache/.travis.yml
rename to mustache_template/.travis.yml
diff --git a/graphs/BUILD.gn b/mustache_template/BUILD.gn
similarity index 60%
rename from graphs/BUILD.gn
rename to mustache_template/BUILD.gn
index 1258e65..0f80569 100644
--- a/graphs/BUILD.gn
+++ b/mustache_template/BUILD.gn
@@ -1,9 +1,9 @@
-# This file is generated by importer.py for graphs-0.2.0
+# This file is generated by importer.py for mustache_template-1.0.0+1
import("//build/dart/dart_library.gni")
-dart_library("graphs") {
- package_name = "graphs"
+dart_library("mustache_template") {
+ package_name = "mustache_template"
# This parameter is left empty as we don't care about analysis or exporting
# these sources outside of the tree.
diff --git a/mustache/CHANGELOG.md b/mustache_template/CHANGELOG.md
similarity index 87%
rename from mustache/CHANGELOG.md
rename to mustache_template/CHANGELOG.md
index 3a8f600..28d3573 100644
--- a/mustache/CHANGELOG.md
+++ b/mustache_template/CHANGELOG.md
@@ -1,5 +1,16 @@
# CHANGELOG
+## 1.0.0+1
+
+* Fixed regression where lookups from list did not work. Removed failing tests
+ that depend on reflection.
+
+## 1.0.0
+
+ * Forked from original repo. Support for mirrors removed.
+
+## Fork
+
## 1.1.1
* Fixed error "boolean expression must not be null". Thanks Nico.
diff --git a/mustache/LICENSE b/mustache_template/LICENSE
similarity index 100%
rename from mustache/LICENSE
rename to mustache_template/LICENSE
diff --git a/mustache/README.md b/mustache_template/README.md
similarity index 88%
rename from mustache/README.md
rename to mustache_template/README.md
index c2223d7..37a3a14 100644
--- a/mustache/README.md
+++ b/mustache_template/README.md
@@ -2,8 +2,6 @@
A Dart library to parse and render [mustache templates](https://mustache.github.io/).
-[![Build Status](https://api.travis-ci.org/xxgreg/mustache.svg?branch=master)](https://travis-ci.org/xxgreg/mustache) [![Coverage Status](https://coveralls.io/repos/xxgreg/mustache/badge.svg)](https://coveralls.io/r/xxgreg/mustache)
-
See the [mustache manual](http://mustache.github.com/mustache.5.html) for detailed usage information.
This library passes all [mustache specification](https://github.com/mustache/spec/tree/master/specs) tests.
@@ -40,10 +38,6 @@
By default all output from `{{variable}}` tags is html escaped, this behaviour can be changed by passing htmlEscapeValues : false to the Template constructor. You can also use a `{{{triple mustache}}}` tag, or a unescaped variable tag `{{&unescaped}}`, the output from these tags is not escaped.
-## Dart2js
-
-This library uses mirrors. When compiling with dart2js you will need to pass the experimental mirrors flag. You also need to mark any objects which will be rendered with the @mustache annotation. There is also another version of this library available which doesn't use mirrors.
-
## Differences between strict mode and lenient mode.
### Strict mode (default)
diff --git a/mustache_template/analysis_options.yaml b/mustache_template/analysis_options.yaml
new file mode 100644
index 0000000..108d105
--- /dev/null
+++ b/mustache_template/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:pedantic/analysis_options.yaml
diff --git a/mustache/lib/mustache.dart b/mustache_template/lib/mustache.dart
similarity index 84%
rename from mustache/lib/mustache.dart
rename to mustache_template/lib/mustache.dart
index 945c9d2..687459c 100644
--- a/mustache/lib/mustache.dart
+++ b/mustache_template/lib/mustache.dart
@@ -1,14 +1,5 @@
-/// [Mustache template documentation](http://mustache.github.com/mustache.5.html)
-
-library mustache;
-
import 'src/template.dart' as t;
-/// Use new Template(source) instead.
-@deprecated
-Template parse(String source, {bool lenient: false}) =>
- new Template(source, lenient: lenient);
-
/// A Template can be efficiently rendered multiple times with different
/// values.
abstract class Template {
@@ -37,9 +28,9 @@
void render(values, StringSink sink);
}
-typedef Template PartialResolver(String templateName);
+typedef PartialResolver = Template Function(String);
-typedef Object LambdaFunction(LambdaContext context);
+typedef LambdaFunction = Object Function(LambdaContext context);
/// Passed as an argument to a mustache lambda function. The methods on
/// this object may only be called before the lambda function returns. If a
@@ -69,13 +60,6 @@
Object lookup(String variableName);
}
-const MustacheMirrorsUsedAnnotation mustache =
- const MustacheMirrorsUsedAnnotation();
-
-class MustacheMirrorsUsedAnnotation {
- const MustacheMirrorsUsedAnnotation();
-}
-
/// [TemplateException] is used to obtain the line and column numbers
/// of the token which caused parse or render to fail.
abstract class TemplateException implements Exception {
@@ -101,6 +85,4 @@
/// A short source substring of the source at the point the problem occurred
/// with parsing or rendering.
String get context;
-
- String toString();
}
diff --git a/mustache_template/lib/mustache_template.dart b/mustache_template/lib/mustache_template.dart
new file mode 100644
index 0000000..299de3a
--- /dev/null
+++ b/mustache_template/lib/mustache_template.dart
@@ -0,0 +1 @@
+export 'mustache.dart';
diff --git a/mustache/lib/src/lambda_context.dart b/mustache_template/lib/src/lambda_context.dart
similarity index 70%
rename from mustache/lib/src/lambda_context.dart
rename to mustache_template/lib/src/lambda_context.dart
index e233248..31d0a96 100644
--- a/mustache/lib/src/lambda_context.dart
+++ b/mustache_template/lib/src/lambda_context.dart
@@ -1,6 +1,4 @@
-library mustache.lambda_context;
-
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
import 'node.dart';
import 'parser.dart' as parser;
@@ -24,41 +22,45 @@
}
TemplateException _error(String msg) {
- return new TemplateException(
+ return TemplateException(
msg, _renderer.templateName, _renderer.source, _node.start);
}
- /// Render the current section tag in the current context and return the
- /// result as a string.
+ @override
String renderString({Object value}) {
_checkClosed();
- if (_node is! SectionNode) _error(
- 'LambdaContext.renderString() can only be called on section tags.');
- var sink = new StringBuffer();
+ if (_node is! SectionNode) {
+ _error(
+ 'LambdaContext.renderString() can only be called on section tags.');
+ }
+ var sink = StringBuffer();
_renderSubtree(sink, value);
return sink.toString();
}
void _renderSubtree(StringSink sink, Object value) {
- var renderer = new Renderer.subtree(_renderer, sink);
+ var renderer = Renderer.subtree(_renderer, sink);
SectionNode section = _node;
if (value != null) renderer.push(value);
renderer.render(section.children);
}
+ @override
void render({Object value}) {
_checkClosed();
- if (_node is! SectionNode) _error(
- 'LambdaContext.render() can only be called on section tags.');
+ if (_node is! SectionNode) {
+ _error('LambdaContext.render() can only be called on section tags.');
+ }
_renderSubtree(_renderer.sink, value);
}
+ @override
void write(Object object) {
_checkClosed();
_renderer.write(object);
}
- /// Get the unevaluated template source for the current section tag.
+ @override
String get source {
_checkClosed();
@@ -77,10 +79,10 @@
return _renderer.source.substring(node.contentStart, node.contentEnd);
}
- /// Evaluate the string as a mustache template using the current context.
+ @override
String renderSource(String source, {Object value}) {
_checkClosed();
- var sink = new StringBuffer();
+ var sink = StringBuffer();
// Lambdas used for sections should parse with the current delimiters.
var delimiters = '{{ }}';
@@ -92,8 +94,8 @@
var nodes = parser.parse(
source, _renderer.lenient, _renderer.templateName, delimiters);
- var renderer = new Renderer.lambda(
- _renderer, source, _renderer.indent, sink, delimiters);
+ var renderer =
+ Renderer.lambda(_renderer, source, _renderer.indent, sink, delimiters);
if (value != null) renderer.push(value);
renderer.render(nodes);
@@ -101,7 +103,7 @@
return sink.toString();
}
- /// Lookup the value of a variable in the current context.
+ @override
Object lookup(String variableName) {
_checkClosed();
return _renderer.resolveValue(variableName);
diff --git a/mustache/lib/src/node.dart b/mustache_template/lib/src/node.dart
similarity index 84%
rename from mustache/lib/src/node.dart
rename to mustache_template/lib/src/node.dart
index 046baff..0c52012 100644
--- a/mustache/lib/src/node.dart
+++ b/mustache_template/lib/src/node.dart
@@ -1,5 +1,3 @@
-library mustache.node;
-
abstract class Node {
Node(this.start, this.end);
@@ -25,6 +23,7 @@
final String text;
+ @override
String toString() => '(TextNode "$_debugText" $start $end)';
String get _debugText {
@@ -32,24 +31,27 @@
return t.length < 50 ? t : t.substring(0, 48) + '...';
}
+ @override
void accept(Visitor visitor) => visitor.visitText(this);
}
class VariableNode extends Node {
- VariableNode(this.name, int start, int end, {this.escape: true})
+ VariableNode(this.name, int start, int end, {this.escape = true})
: super(start, end);
final String name;
final bool escape;
+ @override
void accept(Visitor visitor) => visitor.visitVariable(this);
+ @override
String toString() => '(VariableNode "$name" escape: $escape $start $end)';
}
class SectionNode extends Node {
SectionNode(this.name, int start, int end, this.delimiters,
- {this.inverse: false})
+ {this.inverse = false})
: contentStart = end,
super(start, end);
@@ -60,13 +62,16 @@
int contentEnd; // Set in parser when close tag is parsed.
final List<Node> children = <Node>[];
+ @override
void accept(Visitor visitor) => visitor.visitSection(this);
+ @override
void visitChildren(Visitor visitor) {
children.forEach((node) => node.accept(visitor));
}
- toString() => '(SectionNode $name inverse: $inverse $start $end)';
+ @override
+ String toString() => '(SectionNode $name inverse: $inverse $start $end)';
}
class PartialNode extends Node {
@@ -78,7 +83,9 @@
// it's content can be correctly indented.
final String indent;
+ @override
void accept(Visitor visitor) => visitor.visitPartial(this);
- toString() => '(PartialNode $name $start $end "$indent")';
+ @override
+ String toString() => '(PartialNode $name $start $end "$indent")';
}
diff --git a/mustache/lib/src/parser.dart b/mustache_template/lib/src/parser.dart
similarity index 80%
rename from mustache/lib/src/parser.dart
rename to mustache_template/lib/src/parser.dart
index 5ebb0c0..867cce6 100644
--- a/mustache/lib/src/parser.dart
+++ b/mustache_template/lib/src/parser.dart
@@ -1,5 +1,3 @@
-library mustache.parser;
-
import 'node.dart';
import 'scanner.dart';
import 'template_exception.dart';
@@ -7,7 +5,7 @@
List<Node> parse(
String source, bool lenient, String templateName, String delimiters) {
- var parser = new Parser(source, templateName, delimiters, lenient: lenient);
+ var parser = Parser(source, templateName, delimiters, lenient: lenient);
return parser.parse();
}
@@ -23,26 +21,25 @@
const TagType(this.name);
final String name;
- static const TagType openSection = const TagType('openSection');
- static const TagType openInverseSection = const TagType('openInverseSection');
- static const TagType closeSection = const TagType('closeSection');
- static const TagType variable = const TagType('variable');
- static const TagType tripleMustache = const TagType('tripleMustache');
- static const TagType unescapedVariable = const TagType('unescapedVariable');
- static const TagType partial = const TagType('partial');
- static const TagType comment = const TagType('comment');
- static const TagType changeDelimiter = const TagType('changeDelimiter');
+ static const TagType openSection = TagType('openSection');
+ static const TagType openInverseSection = TagType('openInverseSection');
+ static const TagType closeSection = TagType('closeSection');
+ static const TagType variable = TagType('variable');
+ static const TagType tripleMustache = TagType('tripleMustache');
+ static const TagType unescapedVariable = TagType('unescapedVariable');
+ static const TagType partial = TagType('partial');
+ static const TagType comment = TagType('comment');
+ static const TagType changeDelimiter = TagType('changeDelimiter');
}
class Parser {
Parser(String source, String templateName, String delimiters,
- {lenient: false})
+ {lenient = false})
: _source = source,
_templateName = templateName,
_delimiters = delimiters,
_lenient = lenient,
- _scanner =
- new Scanner(source, templateName, delimiters);
+ _scanner = Scanner(source, templateName, delimiters);
final String _source;
final bool _lenient;
@@ -58,7 +55,7 @@
_tokens = _scanner.scan();
_currentDelimiters = _delimiters;
_stack.clear();
- _stack.add(new SectionNode('root', 0, 0, _delimiters));
+ _stack.add(SectionNode('root', 0, 0, _delimiters));
// Handle a standalone tag on first line, including special case where the
// first line is empty.
@@ -91,12 +88,12 @@
break;
default:
- throw new Exception('Unreachable code.');
+ throw Exception('Unreachable code.');
}
}
if (_stack.length != 1) {
- throw new TemplateException("Unclosed tag: '${_stack.last.name}'.",
+ throw TemplateException("Unclosed tag: '${_stack.last.name}'.",
_templateName, _source, _stack.last.start);
}
@@ -108,7 +105,7 @@
// Returns null on EOF.
Token _read() {
- var t = null;
+ Token t;
if (_offset < _tokens.length) {
t = _tokens[_offset];
_offset++;
@@ -125,7 +122,7 @@
return token;
}
- Token _readIf(TokenType type, {eofOk: false}) {
+ Token _readIf(TokenType type, {eofOk = false}) {
var token = _peek();
if (!eofOk && token == null) throw _errorEof();
return token != null && token.type == type ? _read() : null;
@@ -135,7 +132,7 @@
_error('Unexpected end of input.', _source.length - 1);
TemplateException _error(String msg, int offset) =>
- new TemplateException(msg, _templateName, _source, offset);
+ TemplateException(msg, _templateName, _source, offset);
// Add a text node to top most section on the stack and merge consecutive
// text nodes together.
@@ -144,10 +141,10 @@
.contains(token.type));
var children = _stack.last.children;
if (children.isEmpty || children.last is! TextNode) {
- children.add(new TextNode(token.value, token.start, token.end));
+ children.add(TextNode(token.value, token.start, token.end));
} else {
var last = children.removeLast() as TextNode;
- var node = new TextNode(last.text + token.value, last.start, token.end);
+ var node = TextNode(last.text + token.value, last.start, token.end);
children.add(node);
}
}
@@ -167,8 +164,8 @@
// {{/...}}
case TagType.closeSection:
if (tag.name != _stack.last.name) {
- throw new TemplateException(
- "Mismatched tag, expected: "
+ throw TemplateException(
+ 'Mismatched tag, expected: '
"'${_stack.last.name}', was: '${tag.name}'",
_templateName,
_source,
@@ -192,7 +189,7 @@
break;
default:
- throw new Exception('Unreachable code.');
+ throw Exception('Unreachable code.');
}
}
@@ -222,7 +219,7 @@
var tagNode = _createNodeFromTag(tag, partialIndent: indent);
var followingWhitespace = _readIf(TokenType.whitespace, eofOk: true);
- const standaloneTypes = const [
+ const standaloneTypes = [
TagType.openSection,
TagType.closeSection,
TagType.openInverseSection,
@@ -249,9 +246,9 @@
}
}
- final RegExp _validIdentifier = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
+ final RegExp _validIdentifier = RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
- static const _tagTypeMap = const {
+ static const _tagTypeMap = {
'#': TagType.openSection,
'^': TagType.openInverseSection,
'/': TagType.closeSection,
@@ -275,7 +272,7 @@
// Change delimiter tags are already parsed by the scanner.
// So just create a tag and return it.
- return new Tag(TagType.changeDelimiter, t.value, t.start, t.end);
+ return Tag(TagType.changeDelimiter, t.value, t.start, t.end);
}
// Start parsing a typical tag.
@@ -331,31 +328,33 @@
var close = _expect(TokenType.closeDelimiter);
- return new Tag(tagType, name, open.start, close.end);
+ return Tag(tagType, name, open.start, close.end);
}
- Node _createNodeFromTag(Tag tag, {String partialIndent: ''}) {
+ Node _createNodeFromTag(Tag tag, {String partialIndent = ''}) {
// Handle EOF case.
- if (tag == null) return null;
+ if (tag == null) {
+ return null;
+ }
- Node node = null;
+ Node node;
switch (tag.type) {
case TagType.openSection:
case TagType.openInverseSection:
- bool inverse = tag.type == TagType.openInverseSection;
- node = new SectionNode(tag.name, tag.start, tag.end, _currentDelimiters,
+ var inverse = tag.type == TagType.openInverseSection;
+ node = SectionNode(tag.name, tag.start, tag.end, _currentDelimiters,
inverse: inverse);
break;
case TagType.variable:
case TagType.unescapedVariable:
case TagType.tripleMustache:
- bool escape = tag.type == TagType.variable;
- node = new VariableNode(tag.name, tag.start, tag.end, escape: escape);
+ var escape = tag.type == TagType.variable;
+ node = VariableNode(tag.name, tag.start, tag.end, escape: escape);
break;
case TagType.partial:
- node = new PartialNode(tag.name, tag.start, tag.end, partialIndent);
+ node = PartialNode(tag.name, tag.start, tag.end, partialIndent);
break;
case TagType.closeSection:
@@ -365,7 +364,7 @@
break;
default:
- throw new Exception('Unreachable code');
+ throw Exception('Unreachable code');
}
return node;
}
diff --git a/mustache/lib/src/renderer.dart b/mustache_template/lib/src/renderer.dart
similarity index 80%
rename from mustache/lib/src/renderer.dart
rename to mustache_template/lib/src/renderer.dart
index bccd7e4..74ca3cf 100644
--- a/mustache/lib/src/renderer.dart
+++ b/mustache_template/lib/src/renderer.dart
@@ -1,22 +1,16 @@
-library mustache.renderer;
-
-@MirrorsUsed(metaTargets: const [m.MustacheMirrorsUsedAnnotation])
-import 'dart:mirrors';
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
import 'lambda_context.dart';
import 'node.dart';
import 'template.dart';
import 'template_exception.dart';
-final RegExp _validTag = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
-final RegExp _integerTag = new RegExp(r'^[0-9]+$');
-
-const Object noSuchProperty = const Object();
+const Object noSuchProperty = Object();
+final RegExp _integerTag = RegExp(r'^[0-9]+$');
class Renderer extends Visitor {
Renderer(this.sink, List stack, this.lenient, this.htmlEscapeValues,
this.partialResolver, this.templateName, this.indent, this.source)
- : _stack = new List.from(stack);
+ : _stack = List.from(stack);
Renderer.partial(Renderer ctx, Template partial, String indent)
: this(
@@ -72,7 +66,8 @@
}
}
- void visitText(TextNode node, {bool lastNode: false}) {
+ @override
+ void visitText(TextNode node, {bool lastNode = false}) {
if (node.text == '') return;
if (indent == null || indent == '') {
write(node.text);
@@ -86,19 +81,21 @@
}
}
+ @override
void visitVariable(VariableNode node) {
var value = resolveValue(node.name);
if (value is Function) {
- var context = new LambdaContext(node, this);
+ var context = LambdaContext(node, this);
Function valueFunction = value;
value = valueFunction(context);
context.close();
}
if (value == noSuchProperty) {
- if (!lenient)
+ if (!lenient) {
throw error('Value was missing for variable tag: ${node.name}.', node);
+ }
} else {
var valueString = (value == null) ? '' : value.toString();
var output = !node.escape || !htmlEscapeValues
@@ -108,11 +105,13 @@
}
}
+ @override
void visitSection(SectionNode node) {
- if (node.inverse)
+ if (node.inverse) {
_renderInvSection(node);
- else
+ } else {
_renderSection(node);
+ }
}
//TODO can probably combine Inv and Normal to shorten.
@@ -132,10 +131,11 @@
// Do nothing.
} else if (value == noSuchProperty) {
- if (!lenient)
+ if (!lenient) {
throw error('Value was missing for section tag: ${node.name}.', node);
+ }
} else if (value is Function) {
- var context = new LambdaContext(node, this);
+ var context = LambdaContext(node, this);
var output = value(context);
context.close();
if (output != null) write(output);
@@ -185,12 +185,13 @@
pop();
}
+ @override
void visitPartial(PartialNode node) {
var partialName = node.name;
Template template =
partialResolver == null ? null : partialResolver(partialName);
if (template != null) {
- var renderer = new Renderer.partial(this, template, node.indent);
+ var renderer = Renderer.partial(this, template, node.indent);
var nodes = getTemplateNodes(template);
renderer.render(nodes);
} else if (lenient) {
@@ -214,7 +215,7 @@
break;
}
}
- for (int i = 1; i < parts.length; i++) {
+ for (var i = 1; i < parts.length; i++) {
if (object == null || object == noSuchProperty) {
return noSuchProperty;
}
@@ -227,35 +228,20 @@
// which contains the key name, this is object[name]. For other
// objects, this is object.name or object.name(). If no property
// by the given name exists, this method returns noSuchProperty.
- _getNamedProperty(object, name) {
+ Object _getNamedProperty(dynamic object, dynamic name) {
if (object is Map && object.containsKey(name)) return object[name];
- if (object is List && _integerTag.hasMatch(name))
+ if (object is List && _integerTag.hasMatch(name)) {
return object[int.parse(name)];
-
- if (lenient && !_validTag.hasMatch(name)) return noSuchProperty;
-
- var instance = reflect(object);
- var field = instance.type.instanceMembers[new Symbol(name)];
- if (field == null) return noSuchProperty;
-
- var invocation = null;
- if ((field is VariableMirror) ||
- ((field is MethodMirror) && (field.isGetter))) {
- invocation = instance.getField(field.simpleName);
- } else if ((field is MethodMirror) && (field.parameters.where((p) => !p.isOptional).length == 0)) {
- invocation = instance.invoke(field.simpleName, []);
}
- if (invocation == null) {
- return noSuchProperty;
- }
- return invocation.reflectee;
+
+ return noSuchProperty;
}
m.TemplateException error(String message, Node node) =>
- new TemplateException(message, templateName, source, node.start);
+ TemplateException(message, templateName, source, node.start);
- static const Map<int, String> _htmlEscapeMap = const {
+ static const Map<int, String> _htmlEscapeMap = {
_AMP: '&',
_LT: '<',
_GT: '>',
@@ -265,10 +251,10 @@
};
String _htmlEscape(String s) {
- var buffer = new StringBuffer();
- int startIndex = 0;
- int i = 0;
- for (int c in s.runes) {
+ var buffer = StringBuffer();
+ var startIndex = 0;
+ var i = 0;
+ for (var c in s.runes) {
if (c == _AMP ||
c == _LT ||
c == _GT ||
diff --git a/mustache/lib/src/scanner.dart b/mustache_template/lib/src/scanner.dart
similarity index 84%
rename from mustache/lib/src/scanner.dart
rename to mustache_template/lib/src/scanner.dart
index 2a668b5..992566a 100644
--- a/mustache/lib/src/scanner.dart
+++ b/mustache_template/lib/src/scanner.dart
@@ -1,5 +1,3 @@
-library mustache.scanner;
-
import 'token.dart';
import 'template_exception.dart';
@@ -26,7 +24,7 @@
_closeDelimiterInner = delimiters.codeUnits[3];
_closeDelimiter = delimiters.codeUnits[4];
} else {
- throw new TemplateException(
+ throw TemplateException(
'Invalid delimiter string $delimiters', null, null, null);
}
}
@@ -38,7 +36,7 @@
int _offset = 0;
int _c = 0;
- final List<Token> _tokens = new List<Token>();
+ final List<Token> _tokens = <Token>[];
// These can be changed by the change delimiter tag.
int _openDelimiter;
@@ -47,21 +45,21 @@
int _closeDelimiter;
List<Token> scan() {
- for (int c = _peek(); c != _EOF; c = _peek()) {
+ for (var c = _peek(); c != _EOF; c = _peek()) {
// Scan text tokens.
if (c != _openDelimiter) {
_scanText();
continue;
}
- int start = _offset;
+ var start = _offset;
// Read first open delimiter character.
_read();
// If only a single delimiter character then create a text token.
if (_openDelimiterInner != null && _peek() != _openDelimiterInner) {
- var value = new String.fromCharCode(_openDelimiter);
+ var value = String.fromCharCode(_openDelimiter);
_append(TokenType.text, value, start, _offset);
continue;
}
@@ -79,14 +77,14 @@
} else {
// Check to see if this is a change delimiter tag. {{= | | =}}
// Need to skip whitespace and check for "=".
- int wsStart = _offset;
+ var wsStart = _offset;
var ws = _readWhile(_isWhitespace);
if (_peek() == _EQUAL) {
_parseChangeDelimiterTag(start);
} else {
// Scan standard mustache tag.
- var value = new String.fromCharCodes(_openDelimiterInner == null
+ var value = String.fromCharCodes(_openDelimiterInner == null
? [_openDelimiter]
: [_openDelimiter, _openDelimiterInner]);
@@ -105,33 +103,34 @@
int _peek() => _c;
int _read() {
- int c = _c;
+ var c = _c;
_offset++;
_c = _itr.moveNext() ? _itr.current : _EOF;
return c;
}
- String _readWhile(bool test(int charCode)) {
+ String _readWhile(bool Function(int charCode) test) {
if (_c == _EOF) return '';
- int start = _offset;
+ var start = _offset;
while (_peek() != _EOF && test(_peek())) {
_read();
}
- int end = _peek() == _EOF ? _source.length : _offset;
+ var end = _peek() == _EOF ? _source.length : _offset;
return _source.substring(start, end);
}
- _expect(int expectedCharCode) {
- int c = _read();
+ void _expect(int expectedCharCode) {
+ var c = _read();
if (c == _EOF) {
- throw new TemplateException(
+ throw TemplateException(
'Unexpected end of input', _templateName, _source, _offset - 1);
- } else if (c != expectedCharCode) {
- throw new TemplateException(
+ }
+ if (c != expectedCharCode) {
+ throw TemplateException(
'Unexpected character, '
- 'expected: ${new String.fromCharCode(expectedCharCode)}, '
- 'was: ${new String.fromCharCode(c)}',
+ 'expected: ${String.fromCharCode(expectedCharCode)}, '
+ 'was: ${String.fromCharCode(c)}',
_templateName,
_source,
_offset - 1);
@@ -139,7 +138,7 @@
}
void _append(TokenType type, String value, int start, int end) =>
- _tokens.add(new Token(type, value, start, end));
+ _tokens.add(Token(type, value, start, end));
bool _isWhitespace(int c) =>
const [_SPACE, _TAB, _NEWLINE, _RETURN].contains(c);
@@ -148,11 +147,11 @@
// tokens for whitespace at the begining of a line. This is because the
// mustache spec requires special handing of whitespace.
void _scanText() {
- int start = 0;
+ var start = 0;
TokenType token;
String value;
- for (int c = _peek(); c != _EOF && c != _openDelimiter; c = _peek()) {
+ for (var c = _peek(); c != _EOF && c != _openDelimiter; c = _peek()) {
start = _offset;
switch (c) {
@@ -199,7 +198,7 @@
(_closeDelimiterInner == null && c == _closeDelimiter) ||
(_closeDelimiterInner != null && c == _closeDelimiterInner);
- for (int c = _peek(); c != _EOF && !isCloseDelimiter(c); c = _peek()) {
+ for (var c = _peek(); c != _EOF && !isCloseDelimiter(c); c = _peek()) {
start = _offset;
switch (c) {
@@ -211,7 +210,7 @@
case _EXCLAIM:
_read();
token = TokenType.sigil;
- value = new String.fromCharCode(c);
+ value = String.fromCharCode(c);
break;
case _SPACE:
@@ -255,12 +254,12 @@
// Scan close delimiter token.
void _scanCloseDelimiter() {
if (_peek() != _EOF) {
- int start = _offset;
+ var start = _offset;
if (_closeDelimiterInner != null) _expect(_closeDelimiterInner);
_expect(_closeDelimiter);
- String value = new String.fromCharCodes(_closeDelimiterInner == null
+ var value = String.fromCharCodes(_closeDelimiterInner == null
? [_closeDelimiter]
: [_closeDelimiterInner, _closeDelimiter]);
@@ -271,7 +270,7 @@
// Scan close triple mustache delimiter token.
void _scanCloseTripleMustache() {
if (_peek() != _EOF) {
- int start = _offset;
+ var start = _offset;
_expect(_CLOSE_MUSTACHE);
_expect(_CLOSE_MUSTACHE);
@@ -307,8 +306,9 @@
c = _read();
- if (_isWhitespace(c) || c == _EQUAL)
+ if (_isWhitespace(c) || c == _EQUAL) {
throw _error('Incorrect change delimiter tag.');
+ }
if (_isWhitespace(_peek()) || _peek() == _EQUAL) {
_closeDelimiterInner = null;
@@ -328,7 +328,7 @@
_expect(delimiter);
// Create delimiter string.
- var buffer = new StringBuffer();
+ var buffer = StringBuffer();
buffer.writeCharCode(_openDelimiter);
if (_openDelimiterInner != null) buffer.writeCharCode(_openDelimiterInner);
buffer.write(' ');
@@ -342,7 +342,7 @@
}
TemplateException _error(String message) {
- return new TemplateException(message, _templateName, _source, _offset);
+ return TemplateException(message, _templateName, _source, _offset);
}
}
@@ -352,26 +352,13 @@
const int _RETURN = 13;
const int _SPACE = 32;
const int _EXCLAIM = 33;
-const int _QUOTE = 34;
-const int _APOS = 39;
const int _HASH = 35;
const int _AMP = 38;
const int _PERIOD = 46;
const int _FORWARD_SLASH = 47;
-const int _LT = 60;
const int _EQUAL = 61;
const int _GT = 62;
const int _CARET = 94;
const int _OPEN_MUSTACHE = 123;
const int _CLOSE_MUSTACHE = 125;
-
-const int _A = 65;
-const int _Z = 90;
-const int _a = 97;
-const int _z = 122;
-const int _0 = 48;
-const int _9 = 57;
-
-const int _UNDERSCORE = 95;
-const int _MINUS = 45;
diff --git a/mustache/lib/src/template.dart b/mustache_template/lib/src/template.dart
similarity index 70%
rename from mustache/lib/src/template.dart
rename to mustache_template/lib/src/template.dart
index 2a33b28..a38cc97 100644
--- a/mustache/lib/src/template.dart
+++ b/mustache_template/lib/src/template.dart
@@ -1,17 +1,15 @@
-library mustache.template;
-
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
import 'node.dart';
import 'parser.dart' as parser;
import 'renderer.dart';
class Template implements m.Template {
Template.fromSource(String source,
- {bool lenient: false,
- bool htmlEscapeValues: true,
+ {bool lenient = false,
+ bool htmlEscapeValues = true,
String name,
m.PartialResolver partialResolver,
- String delimiters: "{{ }}"})
+ String delimiters = '{{ }}'})
: source = source,
_nodes = parser.parse(source, lenient, name, delimiters),
_lenient = lenient,
@@ -19,6 +17,7 @@
_name = name,
_partialResolver = partialResolver;
+ @override
final String source;
final List<Node> _nodes;
final bool _lenient;
@@ -26,20 +25,23 @@
final String _name;
final m.PartialResolver _partialResolver;
+ @override
String get name => _name;
+ @override
String renderString(values) {
- var buf = new StringBuffer();
+ var buf = StringBuffer();
render(values, buf);
return buf.toString();
}
+ @override
void render(values, StringSink sink) {
- var renderer = new Renderer(sink, [values], _lenient, _htmlEscapeValues,
+ var renderer = Renderer(sink, [values], _lenient, _htmlEscapeValues,
_partialResolver, _name, '', source);
renderer.render(_nodes);
}
}
// Expose getter for nodes internally within this package.
-getTemplateNodes(Template template) => template._nodes;
+List<Node> getTemplateNodes(Template template) => template._nodes;
diff --git a/mustache/lib/src/template_exception.dart b/mustache_template/lib/src/template_exception.dart
similarity index 70%
rename from mustache/lib/src/template_exception.dart
rename to mustache_template/lib/src/template_exception.dart
index c1b24ce..d067bdd 100644
--- a/mustache/lib/src/template_exception.dart
+++ b/mustache_template/lib/src/template_exception.dart
@@ -1,13 +1,15 @@
-library mustache.template_exception;
-
-import 'package:mustache/mustache.dart' as m;
+import 'package:mustache_template/mustache.dart' as m;
class TemplateException implements m.TemplateException {
TemplateException(this.message, this.templateName, this.source, this.offset);
+ @override
final String message;
+ @override
final String templateName;
+ @override
final String source;
+ @override
final int offset;
bool _isUpdated = false;
@@ -15,21 +17,25 @@
int _column;
String _context;
+ @override
int get line {
_update();
return _line;
}
+ @override
int get column {
_update();
return _column;
}
+ @override
String get context {
_update();
return _context;
}
+ @override
String toString() {
var list = [];
if (templateName != null) list.add(templateName);
@@ -49,14 +55,14 @@
(offset < 0 || offset > source.length)) return;
// Find line and character column.
- int lineNum = 1;
- int lineStart = 0;
- bool lastWasCR = false;
- for (int i = 0; i < offset; i++) {
- int char = source.codeUnitAt(i);
+ var lineNum = 1;
+ var lineStart = 0;
+ var lastWasCR = false;
+ for (var i = 0; i < offset; i++) {
+ var char = source.codeUnitAt(i);
if (char == 0x0a) {
if (lineStart != i || !lastWasCR) {
- lineNum++;
+ lineNum += 1;
}
lineStart = i + 1;
lastWasCR = false;
@@ -71,38 +77,38 @@
_column = offset - lineStart + 1;
// Find context.
- int lineEnd = source.length;
- for (int i = offset; i < source.length; i++) {
- int char = source.codeUnitAt(i);
+ var lineEnd = source.length;
+ for (var i = offset; i < source.length; i++) {
+ var char = source.codeUnitAt(i);
if (char == 0x0a || char == 0x0d) {
lineEnd = i;
break;
}
}
- int length = lineEnd - lineStart;
- int start = lineStart;
- int end = lineEnd;
- String prefix = "";
- String postfix = "";
+ var length = lineEnd - lineStart;
+ var start = lineStart;
+ var end = lineEnd;
+ var prefix = '';
+ var postfix = '';
if (length > 78) {
// Can't show entire line. Try to anchor at the nearest end, if
// one is within reach.
- int index = offset - lineStart;
+ var index = offset - lineStart;
if (index < 75) {
end = start + 75;
- postfix = "...";
+ postfix = '...';
} else if (end - offset < 75) {
start = end - 75;
- prefix = "...";
+ prefix = '...';
} else {
// Neither end is near, just pick an area around the offset.
start = offset - 36;
end = offset + 36;
- prefix = postfix = "...";
+ prefix = postfix = '...';
}
}
- String slice = source.substring(start, end);
- int markOffset = offset - start + prefix.length;
+ var slice = source.substring(start, end);
+ var markOffset = offset - start + prefix.length;
_context = "$prefix$slice$postfix\n${" " * markOffset}^\n";
}
diff --git a/mustache_template/lib/src/token.dart b/mustache_template/lib/src/token.dart
new file mode 100644
index 0000000..d31361e
--- /dev/null
+++ b/mustache_template/lib/src/token.dart
@@ -0,0 +1,35 @@
+class TokenType {
+ const TokenType(this.name);
+
+ final String name;
+
+ @override
+ String toString() => '(TokenType $name)';
+
+ static const TokenType text = TokenType('text');
+ static const TokenType openDelimiter = TokenType('openDelimiter');
+ static const TokenType closeDelimiter = TokenType('closeDelimiter');
+
+ // A sigil is the word commonly used to describe the special character at the
+ // start of mustache tag i.e. #, ^ or /.
+ static const TokenType sigil = TokenType('sigil');
+ static const TokenType identifier = TokenType('identifier');
+ static const TokenType dot = TokenType('dot');
+
+ static const TokenType changeDelimiter = TokenType('changeDelimiter');
+ static const TokenType whitespace = TokenType('whitespace');
+ static const TokenType lineEnd = TokenType('lineEnd');
+}
+
+class Token {
+ Token(this.type, this.value, this.start, this.end);
+
+ final TokenType type;
+ final String value;
+
+ final int start;
+ final int end;
+
+ @override
+ String toString() => '(Token ${type.name} \"$value\" $start $end)';
+}
diff --git a/mustache_template/pubspec.yaml b/mustache_template/pubspec.yaml
new file mode 100644
index 0000000..216a1e4
--- /dev/null
+++ b/mustache_template/pubspec.yaml
@@ -0,0 +1,11 @@
+name: mustache_template
+version: 1.0.0+1
+description: A mustache template library that supports dart2js and dart2native
+homepage: https://github.com/jonahwilliams/mustache
+
+environment:
+ sdk: '>=2.0.0 <3.0.0'
+
+dev_dependencies:
+ test: '>=0.12.0 <2.0.0'
+ pedantic: 1.9.0
diff --git a/mustache/tool/travis.sh b/mustache_template/tool/travis.sh
similarity index 100%
rename from mustache/tool/travis.sh
rename to mustache_template/tool/travis.sh
diff --git a/package_config/.travis.yml b/package_config/.travis.yml
index 655bf3d..09fc296 100644
--- a/package_config/.travis.yml
+++ b/package_config/.travis.yml
@@ -7,6 +7,11 @@
- dartfmt
- dartanalyzer: --fatal-warnings .
+matrix:
+ include:
+ - dart: dev
+ script: pub run build_runner test -- -p chrome
+
# Only building master means that we don't run two builds for each pull request.
branches:
only: [master]
diff --git a/package_config/BUILD.gn b/package_config/BUILD.gn
index d100e3f..75d009c 100644
--- a/package_config/BUILD.gn
+++ b/package_config/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for package_config-1.1.0
+# This file is generated by importer.py for package_config-1.9.1
import("//build/dart/dart_library.gni")
diff --git a/package_config/CHANGELOG.md b/package_config/CHANGELOG.md
index db4bb00..1cd45d0 100644
--- a/package_config/CHANGELOG.md
+++ b/package_config/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 1.9.1
+
+- Remove accidental transitive import of `dart:io` from entrypoints that are
+ supposed to be cross-platform compatible.
+
+## 1.9.0
+
+- Based on new JSON file format with more content.
+- This version includes all the new functionality intended for a 2.0.0
+ version, as well as the, now deprecated, version 1 functionality.
+ When we release 2.0.0, the deprectated functionality will be removed.
+
## 1.1.0
- Allow parsing files with default-package entries and metadata.
diff --git a/package_config/CONTRIBUTING.md b/package_config/CONTRIBUTING.md
index 6f5e0ea..8423ff9 100644
--- a/package_config/CONTRIBUTING.md
+++ b/package_config/CONTRIBUTING.md
@@ -23,7 +23,7 @@
### File headers
All files in the project must start with the following header.
- // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+ // Copyright (c) 2019, 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.
diff --git a/package_config/LICENSE b/package_config/LICENSE
index de31e1a..f75d7c2 100644
--- a/package_config/LICENSE
+++ b/package_config/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2015, the Dart project authors. All rights reserved.
+Copyright 2019, the Dart project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
diff --git a/package_config/README.md b/package_config/README.md
index 9428220..b47a682 100644
--- a/package_config/README.md
+++ b/package_config/README.md
@@ -1,13 +1,18 @@
-# package_config
+[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config)
+[![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config)
-Support for working with **Package Resolution Configuration** files as described
-in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md),
-under review [here](https://github.com/dart-lang/dart_enhancement_proposals/issues/5).
+Support for working with **Package Configuration** files as described
+in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md).
-[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config)
+The primary libraries are
+* `package_config.dart`:
+ Defines the `PackageConfig` class and other types needed to use
+ package configurations.
-## Features and bugs
+* `package_config_discovery.dart`:
+ Provides functions for reading configurations from files,
+ and writing them back out.
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/package_config/issues
+The package includes deprecated backwards compatible functionality to
+work with the `.packages` file. This functionality will not be maintained,
+and will be removed in a future version of this package.
diff --git a/package_config/analysis_options.yaml b/package_config/analysis_options.yaml
new file mode 100644
index 0000000..66639ec
--- /dev/null
+++ b/package_config/analysis_options.yaml
@@ -0,0 +1,11 @@
+# Copyright (c) 2020, 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.
+
+include: package:pedantic/analysis_options.1.9.0.yaml
+analyzer:
+ errors:
+ annotate_overrides: ignore
+ curly_braces_in_flow_control_structures: ignore
+ prefer_single_quotes: ignore
+ use_function_type_syntax_for_parameters: ignore
diff --git a/package_config/lib/discovery.dart b/package_config/lib/discovery.dart
index 57584b6..a2f53c0 100644
--- a/package_config/lib/discovery.dart
+++ b/package_config/lib/discovery.dart
@@ -2,6 +2,7 @@
// 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.
+@Deprecated("Use the package_config.json based API")
library package_config.discovery;
import "dart:async";
@@ -30,13 +31,11 @@
Future<Packages> loadPackagesFile(Uri packagesFile,
{Future<List<int>> loader(Uri uri)}) async {
Packages parseBytes(List<int> bytes) {
- Map<String, Uri> packageMap = pkgfile.parse(bytes, packagesFile);
- return new MapPackages(packageMap);
+ return MapPackages(pkgfile.parse(bytes, packagesFile));
}
if (packagesFile.scheme == "file") {
- File file = new File.fromUri(packagesFile);
- return parseBytes(await file.readAsBytes());
+ return parseBytes(await File.fromUri(packagesFile).readAsBytes());
}
if (loader == null) {
return parseBytes(await _httpGet(packagesFile));
@@ -54,13 +53,12 @@
/// for example one specified using a `--package-root` comand-line parameter.
Packages getPackagesDirectory(Uri packagesDir) {
if (packagesDir.scheme == "file") {
- Directory directory = new Directory.fromUri(packagesDir);
- return new FilePackagesDirectoryPackages(directory);
+ return FilePackagesDirectoryPackages(Directory.fromUri(packagesDir));
}
if (!packagesDir.path.endsWith('/')) {
packagesDir = packagesDir.replace(path: packagesDir.path + '/');
}
- return new NonFilePackagesDirectoryPackages(packagesDir);
+ return NonFilePackagesDirectoryPackages(packagesDir);
}
/// Discover the package configuration for a Dart script.
@@ -94,13 +92,13 @@
Future<Packages> findPackages(Uri baseUri,
{Future<List<int>> loader(Uri unsupportedUri)}) {
if (baseUri.scheme == "file") {
- return new Future<Packages>.sync(() => findPackagesFromFile(baseUri));
+ return Future<Packages>.sync(() => findPackagesFromFile(baseUri));
} else if (loader != null) {
return findPackagesFromNonFile(baseUri, loader: loader);
} else if (baseUri.scheme == "http" || baseUri.scheme == "https") {
return findPackagesFromNonFile(baseUri, loader: _httpGet);
} else {
- return new Future<Packages>.value(Packages.noPackages);
+ return Future<Packages>.value(Packages.noPackages);
}
}
@@ -114,15 +112,15 @@
/// Returns a [File] object of a `.packages` file if one is found, or a
/// [Directory] object for the `packages/` directory if that is found.
FileSystemEntity _findPackagesFile(String workingDirectory) {
- var dir = new Directory(workingDirectory);
+ var dir = Directory(workingDirectory);
if (!dir.isAbsolute) dir = dir.absolute;
if (!dir.existsSync()) {
- throw new ArgumentError.value(
+ throw ArgumentError.value(
workingDirectory, "workingDirectory", "Directory does not exist.");
}
File checkForConfigFile(Directory directory) {
assert(directory.isAbsolute);
- var file = new File(path.join(directory.path, ".packages"));
+ var file = File(path.join(directory.path, ".packages"));
if (file.existsSync()) return file;
return null;
}
@@ -131,7 +129,7 @@
var packagesCfgFile = checkForConfigFile(dir);
if (packagesCfgFile != null) return packagesCfgFile;
// Check for $cwd/packages/
- var packagesDir = new Directory(path.join(dir.path, "packages"));
+ var packagesDir = Directory(path.join(dir.path, "packages"));
if (packagesDir.existsSync()) return packagesDir;
// Check for cwd(/..)+/.packages
var parentDir = dir.parent;
@@ -156,21 +154,20 @@
/// file, and stops if it finds it.
/// Otherwise it gives up and returns [Packages.noPackages].
Packages findPackagesFromFile(Uri fileBaseUri) {
- Uri baseDirectoryUri = fileBaseUri;
+ var baseDirectoryUri = fileBaseUri;
if (!fileBaseUri.path.endsWith('/')) {
baseDirectoryUri = baseDirectoryUri.resolve(".");
}
- String baseDirectoryPath = baseDirectoryUri.toFilePath();
- FileSystemEntity location = _findPackagesFile(baseDirectoryPath);
+ var baseDirectoryPath = baseDirectoryUri.toFilePath();
+ var location = _findPackagesFile(baseDirectoryPath);
if (location == null) return Packages.noPackages;
if (location is File) {
- List<int> fileBytes = location.readAsBytesSync();
- Map<String, Uri> map =
- pkgfile.parse(fileBytes, new Uri.file(location.path));
- return new MapPackages(map);
+ var fileBytes = location.readAsBytesSync();
+ var map = pkgfile.parse(fileBytes, Uri.file(location.path));
+ return MapPackages(map);
}
assert(location is Directory);
- return new FilePackagesDirectoryPackages(location);
+ return FilePackagesDirectoryPackages(location);
}
/// Finds a package resolution strategy for a Dart script.
@@ -192,37 +189,37 @@
/// UTF-8 encoded.
Future<Packages> findPackagesFromNonFile(Uri nonFileUri,
{Future<List<int>> loader(Uri name)}) async {
- if (loader == null) loader = _httpGet;
- Uri packagesFileUri = nonFileUri.resolve(".packages");
+ loader ??= _httpGet;
+ var packagesFileUri = nonFileUri.resolve(".packages");
try {
- List<int> fileBytes = await loader(packagesFileUri);
- Map<String, Uri> map = pkgfile.parse(fileBytes, packagesFileUri);
- return new MapPackages(map);
+ var fileBytes = await loader(packagesFileUri);
+ var map = pkgfile.parse(fileBytes, packagesFileUri);
+ return MapPackages(map);
} catch (_) {
// Didn't manage to load ".packages". Assume a "packages/" directory.
- Uri packagesDirectoryUri = nonFileUri.resolve("packages/");
- return new NonFilePackagesDirectoryPackages(packagesDirectoryUri);
+ var packagesDirectoryUri = nonFileUri.resolve("packages/");
+ return NonFilePackagesDirectoryPackages(packagesDirectoryUri);
}
}
/// Fetches a file over http.
Future<List<int>> _httpGet(Uri uri) async {
- HttpClient client = new HttpClient();
- HttpClientRequest request = await client.getUrl(uri);
- HttpClientResponse response = await request.close();
+ var client = HttpClient();
+ var request = await client.getUrl(uri);
+ var response = await request.close();
if (response.statusCode != HttpStatus.ok) {
- throw new HttpException('${response.statusCode} ${response.reasonPhrase}',
+ throw HttpException('${response.statusCode} ${response.reasonPhrase}',
uri: uri);
}
- List<List<int>> splitContent = await response.toList();
- int totalLength = 0;
+ var splitContent = await response.toList();
+ var totalLength = 0;
for (var list in splitContent) {
totalLength += list.length;
}
- Uint8List result = new Uint8List(totalLength);
- int offset = 0;
- for (List<int> contentPart in splitContent) {
+ var result = Uint8List(totalLength);
+ var offset = 0;
+ for (var contentPart in splitContent) {
result.setRange(offset, offset + contentPart.length, contentPart);
offset += contentPart.length;
}
diff --git a/package_config/lib/discovery_analysis.dart b/package_config/lib/discovery_analysis.dart
index d623303..2af0729 100644
--- a/package_config/lib/discovery_analysis.dart
+++ b/package_config/lib/discovery_analysis.dart
@@ -10,6 +10,7 @@
/// but more efficiently and with some heuristics for directories that
/// wouldn't otherwise have a package resolution strategy, or that are
/// determined to be "package directories" themselves.
+@Deprecated("Use the package_config.json based API")
library package_config.discovery_analysis;
import "dart:collection" show HashMap;
@@ -57,7 +58,7 @@
/// directory of `directory`. If there is, its corresponding `Packages` object
/// should be provided as `root`.
static PackageContext findAll(Directory directory,
- {Packages root: Packages.noPackages}) {
+ {Packages root = Packages.noPackages}) {
if (!directory.existsSync()) {
throw ArgumentError("Directory not found: $directory");
}
@@ -65,14 +66,13 @@
void findRoots(Directory directory) {
Packages packages;
List<PackageContext> oldContexts;
- File packagesFile = File(path.join(directory.path, ".packages"));
+ var packagesFile = File(path.join(directory.path, ".packages"));
if (packagesFile.existsSync()) {
packages = _loadPackagesFile(packagesFile);
oldContexts = contexts;
contexts = [];
} else {
- Directory packagesDir =
- Directory(path.join(directory.path, "packages"));
+ var packagesDir = Directory(path.join(directory.path, "packages"));
if (packagesDir.existsSync()) {
packages = FilePackagesDirectoryPackages(packagesDir);
oldContexts = contexts;
@@ -110,7 +110,7 @@
Map<Directory, Packages> asMap() {
var result = HashMap<Directory, Packages>();
- recurse(_PackageContext current) {
+ void recurse(_PackageContext current) {
result[current.directory] = current.packages;
for (var child in current.children) {
recurse(child);
@@ -122,19 +122,19 @@
}
PackageContext operator [](Directory directory) {
- String path = directory.path;
+ var path = directory.path;
if (!path.startsWith(this.directory.path)) {
throw ArgumentError("Not inside $path: $directory");
}
- _PackageContext current = this;
+ var current = this;
// The current path is know to agree with directory until deltaIndex.
- int deltaIndex = current.directory.path.length;
+ var deltaIndex = current.directory.path.length;
List children = current.children;
- int i = 0;
+ var i = 0;
while (i < children.length) {
// TODO(lrn): Sort children and use binary search.
_PackageContext child = children[i];
- String childPath = child.directory.path;
+ var childPath = child.directory.path;
if (_stringsAgree(path, childPath, deltaIndex, childPath.length)) {
deltaIndex = childPath.length;
if (deltaIndex == path.length) {
@@ -152,7 +152,7 @@
static bool _stringsAgree(String a, String b, int start, int end) {
if (a.length < end || b.length < end) return false;
- for (int i = start; i < end; i++) {
+ for (var i = start; i < end; i++) {
if (a.codeUnitAt(i) != b.codeUnitAt(i)) return false;
}
return true;
diff --git a/package_config/lib/package_config.dart b/package_config/lib/package_config.dart
new file mode 100644
index 0000000..bca865d
--- /dev/null
+++ b/package_config/lib/package_config.dart
@@ -0,0 +1,174 @@
+// Copyright (c) 2019, 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.
+
+/// A package configuration is a way to assign file paths to package URIs,
+/// and vice-versa,
+library package_config.package_config_discovery;
+
+import "dart:io" show File, Directory;
+import "dart:typed_data" show Uint8List;
+
+import "src/discovery.dart" as discover;
+import "src/errors.dart" show throwError;
+import "src/package_config.dart";
+import "src/package_config_io.dart";
+
+export "package_config_types.dart";
+
+/// Reads a specific package configuration file.
+///
+/// The file must exist and be readable.
+/// It must be either a valid `package_config.json` file
+/// or a valid `.packages` file.
+/// It is considered a `package_config.json` file if its first character
+/// is a `{`.
+///
+/// If the file is a `.packages` file and [preferNewest] is true, the default,
+/// also checks if there is a `.dart_tool/package_config.json` file next to the original file,
+/// and if so, loads that instead.
+/// If [preferNewest] is set to false, a directly specified `.packages` file
+/// is loaded even if there is an available `package_config.json` file.
+/// The caller can determine this from the [PackageConfig.version]
+/// being 1 and look for a `package_config.json` file themselves.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+Future<PackageConfig> loadPackageConfig(File file,
+ {bool preferNewest = true, void onError(Object error)}) =>
+ readAnyConfigFile(file, preferNewest, onError ?? throwError);
+
+/// Reads a specific package configuration URI.
+///
+/// The file of the URI must exist and be readable.
+/// It must be either a valid `package_config.json` file
+/// or a valid `.packages` file.
+/// It is considered a `package_config.json` file if its first
+/// non-whitespace character is a `{`.
+///
+/// If [preferNewest] is true, the default, and the file is a `.packages` file,
+/// first checks if there is a `.dart_tool/package_config.json` file
+/// next to the original file, and if so, loads that instead.
+/// The [file] *must not* be a `package:` URI.
+/// If [preferNewest] is set to false, a directly specified `.packages` file
+/// is loaded even if there is an available `package_config.json` file.
+/// The caller can determine this from the [PackageConfig.version]
+/// being 1 and look for a `package_config.json` file themselves.
+///
+/// If [loader] is provided, URIs are loaded using that function.
+/// The future returned by the loader must complete with a [Uint8List]
+/// containing the entire file content encoded as UTF-8,
+/// or with `null` if the file does not exist.
+/// The loader may throw at its own discretion, for situations where
+/// it determines that an error might be need user attention,
+/// but it is always allowed to return `null`.
+/// This function makes no attempt to catch such errors.
+/// As such, it may throw any error that [loader] throws.
+///
+/// If no [loader] is supplied, a default loader is used which
+/// only accepts `file:`, `http:` and `https:` URIs,
+/// and which uses the platform file system and HTTP requests to
+/// fetch file content. The default loader never throws because
+/// of an I/O issue, as long as the location URIs are valid.
+/// As such, it does not distinguish between a file not existing,
+/// and it being temporarily locked or unreachable.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+Future<PackageConfig> loadPackageConfigUri(Uri file,
+ {Future<Uint8List /*?*/ > loader(Uri uri) /*?*/,
+ bool preferNewest = true,
+ void onError(Object error)}) =>
+ readAnyConfigFileUri(file, loader, onError ?? throwError, preferNewest);
+
+/// Finds a package configuration relative to [directory].
+///
+/// If [directory] contains a package configuration,
+/// either a `.dart_tool/package_config.json` file or,
+/// if not, a `.packages`, then that file is loaded.
+///
+/// If no file is found in the current directory,
+/// then the parent directories are checked recursively,
+/// all the way to the root directory, to check if those contains
+/// a package configuration.
+/// If [recurse] is set to [false], this parent directory check is not
+/// performed.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+///
+/// Returns `null` if no configuration file is found.
+Future<PackageConfig> findPackageConfig(Directory directory,
+ {bool recurse = true, void onError(Object error)}) =>
+ discover.findPackageConfig(directory, recurse, onError ?? throwError);
+
+/// Finds a package configuration relative to [location].
+///
+/// If [location] contains a package configuration,
+/// either a `.dart_tool/package_config.json` file or,
+/// if not, a `.packages`, then that file is loaded.
+/// The [location] URI *must not* be a `package:` URI.
+/// It should be a hierarchical URI which is supported
+/// by [loader].
+///
+/// If no file is found in the current directory,
+/// then the parent directories are checked recursively,
+/// all the way to the root directory, to check if those contains
+/// a package configuration.
+/// If [recurse] is set to [false], this parent directory check is not
+/// performed.
+///
+/// If [loader] is provided, URIs are loaded using that function.
+/// The future returned by the loader must complete with a [Uint8List]
+/// containing the entire file content,
+/// or with `null` if the file does not exist.
+/// The loader may throw at its own discretion, for situations where
+/// it determines that an error might be need user attention,
+/// but it is always allowed to return `null`.
+/// This function makes no attempt to catch such errors.
+///
+/// If no [loader] is supplied, a default loader is used which
+/// only accepts `file:`, `http:` and `https:` URIs,
+/// and which uses the platform file system and HTTP requests to
+/// fetch file content. The default loader never throws because
+/// of an I/O issue, as long as the location URIs are valid.
+/// As such, it does not distinguish between a file not existing,
+/// and it being temporarily locked or unreachable.
+///
+/// If [onError] is provided, the configuration file parsing will report errors
+/// by calling that function, and then try to recover.
+/// The returned package configuration is a *best effort* attempt to create
+/// a valid configuration from the invalid configuration file.
+/// If no [onError] is provided, errors are thrown immediately.
+///
+/// Returns `null` if no configuration file is found.
+Future<PackageConfig> findPackageConfigUri(Uri location,
+ {bool recurse = true,
+ Future<Uint8List /*?*/ > loader(Uri uri),
+ void onError(Object error)}) =>
+ discover.findPackageConfigUri(
+ location, loader, onError ?? throwError, recurse);
+
+/// Writes a package configuration to the provided directory.
+///
+/// Writes `.dart_tool/package_config.json` relative to [directory].
+/// If the `.dart_tool/` directory does not exist, it is created.
+/// If it cannot be created, this operation fails.
+///
+/// Also writes a `.packages` file in [directory].
+/// This will stop happening eventually as the `.packages` file becomes
+/// discontinued.
+/// A comment is generated if `[PackageConfig.extraData]` contains a
+/// `"generator"` entry.
+Future<void> savePackageConfig(
+ PackageConfig configuration, Directory directory) =>
+ writePackageConfigJsonFile(configuration, directory);
diff --git a/package_config/lib/package_config_types.dart b/package_config/lib/package_config_types.dart
new file mode 100644
index 0000000..f0637b1
--- /dev/null
+++ b/package_config/lib/package_config_types.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2019, 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.
+
+/// A package configuration is a way to assign file paths to package URIs,
+/// and vice-versa,
+library package_config.package_config;
+
+export "src/package_config.dart"
+ show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion;
+export "src/errors.dart" show PackageConfigError;
diff --git a/package_config/lib/packages.dart b/package_config/lib/packages.dart
index 886fbc8..203f32f 100644
--- a/package_config/lib/packages.dart
+++ b/package_config/lib/packages.dart
@@ -2,6 +2,7 @@
// 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.
+@Deprecated("Use the package_config.json based API")
library package_config.packages;
import "src/packages_impl.dart";
@@ -16,12 +17,13 @@
/// in which case [packages] and [asMap] will throw if used.
/// One such case is if the packages are resolved relative to a
/// `packages/` directory available over HTTP.
+@Deprecated("Use the package_config.json based API")
abstract class Packages {
/// A [Packages] resolver containing no packages.
///
/// This constant object is returned by [find] above if no
/// package resolution strategy is found.
- static const Packages noPackages = const NoPackages();
+ static const Packages noPackages = NoPackages();
/// Resolve a package URI into a non-package URI.
///
diff --git a/package_config/lib/packages_file.dart b/package_config/lib/packages_file.dart
index 284d8e9..ef0b0b3 100644
--- a/package_config/lib/packages_file.dart
+++ b/package_config/lib/packages_file.dart
@@ -2,6 +2,7 @@
// 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.
+@Deprecated("Use the package_config.json based API")
library package_config.packages_file;
import "package:charcode/ascii.dart";
@@ -31,14 +32,14 @@
/// If default package is allowed, the map maps the empty string to the default package's name.
Map<String, Uri> parse(List<int> source, Uri baseLocation,
{bool allowDefaultPackage = false}) {
- int index = 0;
- Map<String, Uri> result = <String, Uri>{};
+ var index = 0;
+ var result = <String, Uri>{};
while (index < source.length) {
- bool isComment = false;
- int start = index;
- int separatorIndex = -1;
- int end = source.length;
- int char = source[index++];
+ var isComment = false;
+ var start = index;
+ var separatorIndex = -1;
+ var end = source.length;
+ var char = source[index++];
if (char == $cr || char == $lf) {
continue;
}
@@ -62,14 +63,13 @@
if (separatorIndex < 0) {
throw FormatException("No ':' on line", source, index - 1);
}
- var packageName = new String.fromCharCodes(source, start, separatorIndex);
+ var packageName = String.fromCharCodes(source, start, separatorIndex);
if (packageName.isEmpty
? !allowDefaultPackage
: !isValidPackageName(packageName)) {
throw FormatException("Not a valid package name", packageName, 0);
}
- var packageValue =
- new String.fromCharCodes(source, separatorIndex + 1, end);
+ var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
Uri packageLocation;
if (packageName.isEmpty) {
if (!isValidPackageName(packageValue)) {
@@ -106,12 +106,17 @@
/// If [baseUri] is provided, package locations will be made relative
/// to the base URI, if possible, before writing.
///
+/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an
+/// empty string mapping to the _default package name_.
+///
/// All the keys of [packageMapping] must be valid package names,
/// and the values must be URIs that do not have the `package:` scheme.
void write(StringSink output, Map<String, Uri> packageMapping,
- {Uri baseUri, String comment}) {
+ {Uri baseUri, String comment, bool allowDefaultPackage = false}) {
+ ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage');
+
if (baseUri != null && !baseUri.isAbsolute) {
- throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute");
+ throw ArgumentError.value(baseUri, "baseUri", "Must be absolute");
}
if (comment != null) {
@@ -123,17 +128,32 @@
}
} else {
output.write("# generated by package:package_config at ");
- output.write(new DateTime.now());
+ output.write(DateTime.now());
output.writeln();
}
packageMapping.forEach((String packageName, Uri uri) {
+ // If [packageName] is empty then [uri] is the _default package name_.
+ if (allowDefaultPackage && packageName.isEmpty) {
+ final defaultPackageName = uri.toString();
+ if (!isValidPackageName(defaultPackageName)) {
+ throw ArgumentError.value(
+ defaultPackageName,
+ 'defaultPackageName',
+ '"$defaultPackageName" is not a valid package name',
+ );
+ }
+ output.write(':');
+ output.write(defaultPackageName);
+ output.writeln();
+ return;
+ }
// Validate packageName.
if (!isValidPackageName(packageName)) {
- throw new ArgumentError('"$packageName" is not a valid package name');
+ throw ArgumentError('"$packageName" is not a valid package name');
}
if (uri.scheme == "package") {
- throw new ArgumentError.value(
+ throw ArgumentError.value(
"Package location must not be a package: URI", uri.toString());
}
output.write(packageName);
@@ -142,10 +162,10 @@
if (baseUri != null) {
uri = _relativize(uri, baseUri);
}
- output.write(uri);
if (!uri.path.endsWith('/')) {
- output.write('/');
+ uri = uri.replace(path: uri.path + '/');
}
+ output.write(uri);
output.writeln();
});
}
@@ -158,7 +178,7 @@
Uri _relativize(Uri uri, Uri baseUri) {
assert(baseUri.isAbsolute);
if (uri.hasQuery || uri.hasFragment) {
- uri = new Uri(
+ uri = Uri(
scheme: uri.scheme,
userInfo: uri.hasAuthority ? uri.userInfo : null,
host: uri.hasAuthority ? uri.host : null,
@@ -184,14 +204,14 @@
}
baseUri = baseUri.normalizePath();
- List<String> base = baseUri.pathSegments.toList();
+ var base = baseUri.pathSegments.toList();
if (base.isNotEmpty) {
- base = new List<String>.from(base)..removeLast();
+ base = List<String>.from(base)..removeLast();
}
uri = uri.normalizePath();
- List<String> target = uri.pathSegments.toList();
+ var target = uri.pathSegments.toList();
if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
- int index = 0;
+ var index = 0;
while (index < base.length && index < target.length) {
if (base[index] != target[index]) {
break;
@@ -200,11 +220,11 @@
}
if (index == base.length) {
if (index == target.length) {
- return new Uri(path: "./");
+ return Uri(path: "./");
}
- return new Uri(path: target.skip(index).join('/'));
+ return Uri(path: target.skip(index).join('/'));
} else if (index > 0) {
- return new Uri(
+ return Uri(
path: '../' * (base.length - index) + target.skip(index).join('/'));
} else {
return uri;
diff --git a/package_config/lib/src/discovery.dart b/package_config/lib/src/discovery.dart
new file mode 100644
index 0000000..8ac6a01
--- /dev/null
+++ b/package_config/lib/src/discovery.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, 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:io";
+import 'dart:typed_data';
+
+import 'package_config_io.dart';
+
+import "errors.dart";
+import "package_config_impl.dart";
+import "package_config_json.dart";
+import "packages_file.dart" as packages_file;
+import "util_io.dart" show defaultLoader, pathJoin;
+
+final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json");
+final Uri dotPackagesPath = Uri(path: ".packages");
+final Uri currentPath = Uri(path: ".");
+final Uri parentPath = Uri(path: "..");
+
+/// Discover the package configuration for a Dart script.
+///
+/// The [baseDirectory] points to the directory of the Dart script.
+/// A package resolution strategy is found by going through the following steps,
+/// and stopping when something is found.
+///
+/// * Check if a `.dart_tool/package_config.json` file exists in the directory.
+/// * Check if a `.packages` file exists in the directory.
+/// * Repeat these checks for the parent directories until reaching the
+/// root directory if [recursive] is true.
+///
+/// If any of these tests succeed, a `PackageConfig` class is returned.
+/// Returns `null` if no configuration was found. If a configuration
+/// is needed, then the caller can supply [PackageConfig.empty].
+Future<PackageConfig /*?*/ > findPackageConfig(
+ Directory baseDirectory, bool recursive, void onError(Object error)) async {
+ var directory = baseDirectory;
+ if (!directory.isAbsolute) directory = directory.absolute;
+ if (!await directory.exists()) {
+ return null;
+ }
+ do {
+ // Check for $cwd/.packages
+ var packageConfig = await findPackagConfigInDirectory(directory, onError);
+ if (packageConfig != null) return packageConfig;
+ if (!recursive) break;
+ // Check in parent directories.
+ var parentDirectory = directory.parent;
+ if (parentDirectory.path == directory.path) break;
+ directory = parentDirectory;
+ } while (true);
+ return null;
+}
+
+/// Similar to [findPackageConfig] but based on a URI.
+Future<PackageConfig /*?*/ > findPackageConfigUri(
+ Uri location,
+ Future<Uint8List /*?*/ > loader(Uri uri) /*?*/,
+ void onError(Object error) /*?*/,
+ bool recursive) async {
+ if (location.isScheme("package")) {
+ onError(PackageConfigArgumentError(
+ location, "location", "Must not be a package: URI"));
+ return null;
+ }
+ if (loader == null) {
+ if (location.isScheme("file")) {
+ return findPackageConfig(
+ Directory.fromUri(location.resolveUri(currentPath)),
+ recursive,
+ onError);
+ }
+ loader = defaultLoader;
+ }
+ if (!location.path.endsWith("/")) location = location.resolveUri(currentPath);
+ while (true) {
+ var file = location.resolveUri(packageConfigJsonPath);
+ var bytes = await loader(file);
+ if (bytes != null) {
+ return parsePackageConfigBytes(bytes, file, onError);
+ }
+ file = location.resolveUri(dotPackagesPath);
+ bytes = await loader(file);
+ if (bytes != null) {
+ return packages_file.parse(bytes, file, onError);
+ }
+ if (!recursive) break;
+ var parent = location.resolveUri(parentPath);
+ if (parent == location) break;
+ location = parent;
+ }
+ return null;
+}
+
+/// Finds a `.packages` or `.dart_tool/package_config.json` file in [directory].
+///
+/// Loads the file, if it is there, and returns the resulting [PackageConfig].
+/// Returns `null` if the file isn't there.
+/// Reports a [FormatException] if a file is there but the content is not valid.
+/// If the file exists, but fails to be read, the file system error is reported.
+///
+/// If [onError] is supplied, parsing errors are reported using that, and
+/// a best-effort attempt is made to return a package configuration.
+/// This may be the empty package configuration.
+Future<PackageConfig /*?*/ > findPackagConfigInDirectory(
+ Directory directory, void onError(Object error)) async {
+ var packageConfigFile = await checkForPackageConfigJsonFile(directory);
+ if (packageConfigFile != null) {
+ return await readPackageConfigJsonFile(packageConfigFile, onError);
+ }
+ packageConfigFile = await checkForDotPackagesFile(directory);
+ if (packageConfigFile != null) {
+ return await readDotPackagesFile(packageConfigFile, onError);
+ }
+ return null;
+}
+
+Future<File> /*?*/ checkForPackageConfigJsonFile(Directory directory) async {
+ assert(directory.isAbsolute);
+ var file =
+ File(pathJoin(directory.path, ".dart_tool", "package_config.json"));
+ if (await file.exists()) return file;
+ return null;
+}
+
+Future<File /*?*/ > checkForDotPackagesFile(Directory directory) async {
+ var file = File(pathJoin(directory.path, ".packages"));
+ if (await file.exists()) return file;
+ return null;
+}
diff --git a/package_config/lib/src/errors.dart b/package_config/lib/src/errors.dart
new file mode 100644
index 0000000..c973617
--- /dev/null
+++ b/package_config/lib/src/errors.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+
+/// General superclass of most errors and exceptions thrown by this package.
+///
+/// Only covers errors thrown while parsing package configuration files.
+/// Programming errors and I/O exceptions are not covered.
+abstract class PackageConfigError {
+ PackageConfigError._();
+}
+
+class PackageConfigArgumentError extends ArgumentError
+ implements PackageConfigError {
+ PackageConfigArgumentError(Object /*?*/ value, String name, String message)
+ : super.value(value, name, message);
+
+ PackageConfigArgumentError.from(ArgumentError error)
+ : super.value(error.invalidValue, error.name, error.message);
+}
+
+class PackageConfigFormatException extends FormatException
+ implements PackageConfigError {
+ PackageConfigFormatException(String message, Object /*?*/ source,
+ [int /*?*/ offset])
+ : super(message, source, offset);
+
+ PackageConfigFormatException.from(FormatException exception)
+ : super(exception.message, exception.source, exception.offset);
+}
+
+/// The default `onError` handler.
+void /*Never*/ throwError(Object error) => throw error;
diff --git a/package_config/lib/src/package_config.dart b/package_config/lib/src/package_config.dart
new file mode 100644
index 0000000..364df75
--- /dev/null
+++ b/package_config/lib/src/package_config.dart
@@ -0,0 +1,375 @@
+// Copyright (c) 2019, 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:typed_data';
+
+import 'errors.dart';
+import "package_config_impl.dart";
+import 'package_config_json.dart';
+
+/// A package configuration.
+///
+/// Associates configuration data to packages and files in packages.
+///
+/// More members may be added to this class in the future,
+/// so classes outside of this package must not implement [PackageConfig]
+/// or any subclass of it.
+abstract class PackageConfig {
+ /// The largest configuration version currently recognized.
+ static const int maxVersion = 2;
+
+ /// An empty package configuration.
+ ///
+ /// A package configuration with no available packages.
+ /// Is used as a default value where a package configuration
+ /// is expected, but none have been specified or found.
+ static const PackageConfig empty = SimplePackageConfig.empty();
+
+ /// Creats a package configuration with the provided available [packages].
+ ///
+ /// The packages must be valid packages (valid package name, valid
+ /// absolute directory URIs, valid language version, if any),
+ /// and there must not be two packages with the same name.
+ ///
+ /// The package's root ([Package.rootUri]) and package-root
+ /// ([Package.packageUriRoot]) paths must satisfy a number of constraints
+ /// We say that one path (which we know ends with a `/` charater)
+ /// is inside another path, if the latter path is a prefix of the former path,
+ /// including the two paths being the same.
+ ///
+ /// * No package's root must be the same as another package's root.
+ /// * The package-root of a package must be inside the pacakge's root.
+ /// * If one package's package-root is inside another package's root,
+ /// then the latter package's package root must not be inside the former
+ /// package's root. (No getting between a package and its package root!)
+ /// This also disallows a package's root being the same as another
+ /// package's package root.
+ ///
+ /// If supplied, the [extraData] will be available as the
+ /// [PackageConfig.extraData] of the created configuration.
+ ///
+ /// The version of the resulting configuration is always [maxVersion].
+ factory PackageConfig(Iterable<Package> packages, {dynamic extraData}) =>
+ SimplePackageConfig(maxVersion, packages, extraData);
+
+ /// Parses a package configuration file.
+ ///
+ /// The [bytes] must be an UTF-8 encoded JSON object
+ /// containing a valid package configuration.
+ ///
+ /// The [baseUri] is used as the base for resolving relative
+ /// URI references in the configuration file. If the configuration
+ /// has been read from a file, the [baseUri] can be the URI of that
+ /// file, or of the directory it occurs in.
+ ///
+ /// If [onError] is provided, errors found during parsing or building
+ /// the configuration are reported by calling [onError] instead of
+ /// throwing, and parser makes a *best effort* attempt to continue
+ /// despite the error. The input must still be valid JSON.
+ /// The result may be a [PackageConfig.empty] if there is no way to
+ /// extract useful information from the bytes.
+ static PackageConfig parseBytes(Uint8List bytes, Uri baseUri,
+ {void onError(Object error)}) =>
+ parsePackageConfigBytes(bytes, baseUri, onError ?? throwError);
+
+ /// Parses a package configuration file.
+ ///
+ /// The [configuration] must be a JSON object
+ /// containing a valid package configuration.
+ ///
+ /// The [baseUri] is used as the base for resolving relative
+ /// URI references in the configuration file. If the configuration
+ /// has been read from a file, the [baseUri] can be the URI of that
+ /// file, or of the directory it occurs in.
+ ///
+ /// If [onError] is provided, errors found during parsing or building
+ /// the configuration are reported by calling [onError] instead of
+ /// throwing, and parser makes a *best effort* attempt to continue
+ /// despite the error. The input must still be valid JSON.
+ /// The result may be a [PackageConfig.empty] if there is no way to
+ /// extract useful information from the bytes.
+ static PackageConfig parseString(String configuration, Uri baseUri,
+ {void onError(Object error)}) =>
+ parsePackageConfigString(configuration, baseUri, onError ?? throwError);
+
+ /// Parses the JSON data of a package configuration file.
+ ///
+ /// The [configuration] must be a JSON-like Dart data structure,
+ /// like the one provided by parsing JSON text using `dart:convert`,
+ /// containing a valid package configuration.
+ ///
+ /// The [baseUri] is used as the base for resolving relative
+ /// URI references in the configuration file. If the configuration
+ /// has been read from a file, the [baseUri] can be the URI of that
+ /// file, or of the directory it occurs in.
+ ///
+ /// If [onError] is provided, errors found during parsing or building
+ /// the configuration are reported by calling [onError] instead of
+ /// throwing, and parser makes a *best effort* attempt to continue
+ /// despite the error. The input must still be valid JSON.
+ /// The result may be a [PackageConfig.empty] if there is no way to
+ /// extract useful information from the bytes.
+ static PackageConfig parseJson(dynamic jsonData, Uri baseUri,
+ {void onError(Object error)}) =>
+ parsePackageConfigJson(jsonData, baseUri, onError ?? throwError);
+
+ /// Writes a configuration file for this configuration on [output].
+ ///
+ /// If [baseUri] is provided, URI references in the generated file
+ /// will be made relative to [baseUri] where possible.
+ static void writeBytes(PackageConfig configuration, Sink<Uint8List> output,
+ [Uri /*?*/ baseUri]) {
+ writePackageConfigJsonUtf8(configuration, baseUri, output);
+ }
+
+ /// Writes a configuration JSON text for this configuration on [output].
+ ///
+ /// If [baseUri] is provided, URI references in the generated file
+ /// will be made relative to [baseUri] where possible.
+ static void writeString(PackageConfig configuration, StringSink output,
+ [Uri /*?*/ baseUri]) {
+ writePackageConfigJsonString(configuration, baseUri, output);
+ }
+
+ /// Converts a configuration to a JSON-like data structure.
+ ///
+ /// If [baseUri] is provided, URI references in the generated data
+ /// will be made relative to [baseUri] where possible.
+ static Map<String, dynamic> toJson(PackageConfig configuration,
+ [Uri /*?*/ baseUri]) =>
+ packageConfigToJson(configuration, baseUri);
+
+ /// The configuration version number.
+ ///
+ /// Currently this is 1 or 2, where
+ /// * Version one is the `.packages` file format and
+ /// * Version two is the first `package_config.json` format.
+ ///
+ /// Instances of this class supports both, and the version
+ /// is only useful for detecting which kind of file the configuration
+ /// was read from.
+ int get version;
+
+ /// All the available packages of this configuration.
+ ///
+ /// No two of these packages have the same name,
+ /// and no two [Package.root] directories overlap.
+ Iterable<Package> get packages;
+
+ /// Look up a package by name.
+ ///
+ /// Returns the [Package] fron [packages] with [packageName] as
+ /// [Package.name]. Returns `null` if the package is not available in the
+ /// current configuration.
+ Package /*?*/ operator [](String packageName);
+
+ /// Provides the associated package for a specific [file] (or directory).
+ ///
+ /// Returns a [Package] which contains the [file]'s path, if any.
+ /// That is, the [Package.rootUri] directory is a parent directory
+ /// of the [file]'s location.
+ ///
+ /// Returns `null` if the file does not belong to any package.
+ Package /*?*/ packageOf(Uri file);
+
+ /// Resolves a `package:` URI to a non-package URI
+ ///
+ /// The [packageUri] must be a valid package URI. That means:
+ /// * A URI with `package` as scheme,
+ /// * with no authority part (`package://...`),
+ /// * with a path starting with a valid package name followed by a slash, and
+ /// * with no query or fragment part.
+ ///
+ /// Throws an [ArgumentError] (which also implements [PackageConfigError])
+ /// if the package URI is not valid.
+ ///
+ /// Returns `null` if the package name of [packageUri] is not available
+ /// in this package configuration.
+ /// Returns the remaining path of the package URI resolved relative to the
+ /// [Package.packageUriRoot] of the corresponding package.
+ Uri /*?*/ resolve(Uri packageUri);
+
+ /// The package URI which resolves to [nonPackageUri].
+ ///
+ /// The [nonPackageUri] must not have any query or fragment part,
+ /// and it must not have `package` as scheme.
+ /// Throws an [ArgumentError] (which also implements [PackageConfigError])
+ /// if the non-package URI is not valid.
+ ///
+ /// Returns a package URI which [resolve] will convert to [nonPackageUri],
+ /// if any such URI exists. Returns `null` if no such package URI exists.
+ Uri /*?*/ toPackageUri(Uri nonPackageUri);
+
+ /// Extra data associated with the package configuration.
+ ///
+ /// The data may be in any format, depending on who introduced it.
+ /// The standard `packjage_config.json` file storage will only store
+ /// JSON-like list/map data structures.
+ dynamic get extraData;
+}
+
+/// Configuration data for a single package.
+abstract class Package {
+ /// Creates a package with the provided properties.
+ ///
+ /// The [name] must be a valid package name.
+ /// The [root] must be an absolute directory URI, meaning an absolute URI
+ /// with no query or fragment path and a path starting and ending with `/`.
+ /// The [packageUriRoot], if provided, must be either an absolute
+ /// directory URI or a relative URI reference which is then resolved
+ /// relative to [root]. It must then also be a subdirectory of [root],
+ /// or the same directory.
+ /// If [languageVersion] is supplied, it must be a valid Dart language
+ /// version, which means two decimal integer literals separated by a `.`,
+ /// where the integer literals have no leading zeros unless they are
+ /// a single zero digit.
+ /// If [extraData] is supplied, it will be available as the
+ /// [Package.extraData] of the created package.
+ factory Package(String name, Uri root,
+ {Uri /*?*/ packageUriRoot,
+ LanguageVersion /*?*/ languageVersion,
+ dynamic extraData}) =>
+ SimplePackage.validate(
+ name, root, packageUriRoot, languageVersion, extraData, throwError);
+
+ /// The package-name of the package.
+ String get name;
+
+ /// The location of the root of the package.
+ ///
+ /// Is always an absolute URI with no query or fragment parts,
+ /// and with a path ending in `/`.
+ ///
+ /// All files in the [rootUri] directory are considered
+ /// part of the package for purposes where that that matters.
+ Uri get root;
+
+ /// The root of the files available through `package:` URIs.
+ ///
+ /// A `package:` URI with [name] as the package name is
+ /// resolved relative to this location.
+ ///
+ /// Is always an absolute URI with no query or fragment part
+ /// with a path ending in `/`,
+ /// and with a location which is a subdirectory
+ /// of the [root], or the same as the [root].
+ Uri get packageUriRoot;
+
+ /// The default language version associated with this package.
+ ///
+ /// Each package may have a default language version associated,
+ /// which is the language version used to parse and compile
+ /// Dart files in the package.
+ /// A package version is defined by two non-negative numbers,
+ /// the *major* and *minor* version numbers.
+ LanguageVersion /*?*/ get languageVersion;
+
+ /// Extra data associated with the specific package.
+ ///
+ /// The data may be in any format, depending on who introduced it.
+ /// The standard `packjage_config.json` file storage will only store
+ /// JSON-like list/map data structures.
+ dynamic get extraData;
+}
+
+/// A language version.
+///
+/// A language version is represented by two non-negative integers,
+/// the [major] and [minor] version numbers.
+///
+/// If errors during parsing are handled using an `onError` handler,
+/// then an *invalid* language version may be represented by an
+/// [InvalidLanguageVersion] object.
+abstract class LanguageVersion implements Comparable<LanguageVersion> {
+ /// The maximal value allowed by [major] and [minor] values;
+ static const int maxValue = 0x7FFFFFFF;
+ factory LanguageVersion(int major, int minor) {
+ RangeError.checkValueInInterval(major, 0, maxValue, "major");
+ RangeError.checkValueInInterval(minor, 0, maxValue, "major");
+ return SimpleLanguageVersion(major, minor, null);
+ }
+
+ /// Parses a language version string.
+ ///
+ /// A valid language version string has the form
+ ///
+ /// > *decimalNumber* `.` *decimalNumber*
+ ///
+ /// where a *decimalNumber* is a non-empty sequence of decimal digits
+ /// with no unnecessary leading zeros (the decimal number only starts
+ /// with a zero digit if that digit is the entire number).
+ /// No spaces are allowed in the string.
+ ///
+ /// If the [source] is valid then it is parsed into a valid
+ /// [LanguageVersion] object.
+ /// If not, then the [onError] is called with a [FormatException].
+ /// If [onError] is not supplied, it defaults to throwing the exception.
+ /// If the call does not throw, then an [InvalidLanguageVersion] is returned
+ /// containing the original [source].
+ static LanguageVersion parse(String source, {void onError(Object error)}) =>
+ parseLanguageVersion(source, onError ?? throwError);
+
+ /// The major language version.
+ ///
+ /// A non-negative integer less than 2<sup>31</sup>.
+ ///
+ /// The value is negative for objects representing *invalid* language
+ /// versions ([InvalidLanguageVersion]).
+ int get major;
+
+ /// The minor language version.
+ ///
+ /// A non-negative integer less than 2<sup>31</sup>.
+ ///
+ /// The value is negative for objects representing *invalid* language
+ /// versions ([InvalidLanguageVersion]).
+ int get minor;
+
+ /// Compares language versions.
+ ///
+ /// Two language versions are considered equal if they have the
+ /// same major and minor version numbers.
+ ///
+ /// A language version is greater then another if the former's major version
+ /// is greater than the latter's major version, or if they have
+ /// the same major version and the former's minor version is greater than
+ /// the latter's.
+ int compareTo(LanguageVersion other);
+
+ /// Valid language versions with the same [major] and [minor] values are
+ /// equal.
+ ///
+ /// Invalid language versions ([InvalidLanguageVersion]) are not equal to
+ /// any other object.
+ bool operator ==(Object other);
+
+ int get hashCode;
+
+ /// A string representation of the language version.
+ ///
+ /// A valid language version is represented as
+ /// `"${version.major}.${version.minor}"`.
+ String toString();
+}
+
+/// An *invalid* language version.
+///
+/// Stored in a [Package] when the orginal language version string
+/// was invalid and a `onError` handler was passed to the parser
+/// which did not throw on an error.
+abstract class InvalidLanguageVersion implements LanguageVersion {
+ /// The value -1 for an invalid language version.
+ int get major;
+
+ /// The value -1 for an invalid language version.
+ int get minor;
+
+ /// An invalid language version is only equal to itself.
+ bool operator ==(Object other);
+
+ int get hashCode;
+
+ /// The original invalid version string.
+ String toString();
+}
diff --git a/package_config/lib/src/package_config_impl.dart b/package_config/lib/src/package_config_impl.dart
new file mode 100644
index 0000000..f68a9ea
--- /dev/null
+++ b/package_config/lib/src/package_config_impl.dart
@@ -0,0 +1,519 @@
+// Copyright (c) 2019, 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 'errors.dart';
+import "package_config.dart";
+import "util.dart";
+
+export "package_config.dart";
+
+// Implementations of the main data types exposed by the API of this package.
+
+class SimplePackageConfig implements PackageConfig {
+ final int version;
+ final Map<String, Package> _packages;
+ final PackageTree _packageTree;
+ final dynamic extraData;
+
+ factory SimplePackageConfig(int version, Iterable<Package> packages,
+ [dynamic extraData, void onError(Object error)]) {
+ onError ??= throwError;
+ var validVersion = _validateVersion(version, onError);
+ var sortedPackages = [...packages]..sort(_compareRoot);
+ var packageTree = _validatePackages(packages, sortedPackages, onError);
+ return SimplePackageConfig._(validVersion, packageTree,
+ {for (var p in packageTree.allPackages) p.name: p}, extraData);
+ }
+
+ SimplePackageConfig._(
+ this.version, this._packageTree, this._packages, this.extraData);
+
+ /// Creates empty configuration.
+ ///
+ /// The empty configuration can be used in cases where no configuration is
+ /// found, but code expects a non-null configuration.
+ const SimplePackageConfig.empty()
+ : version = 1,
+ _packageTree = const EmptyPackageTree(),
+ _packages = const <String, Package>{},
+ extraData = null;
+
+ static int _validateVersion(int version, void onError(Object error)) {
+ if (version < 0 || version > PackageConfig.maxVersion) {
+ onError(PackageConfigArgumentError(version, "version",
+ "Must be in the range 1 to ${PackageConfig.maxVersion}"));
+ return 2; // The minimal version supporting a SimplePackageConfig.
+ }
+ return version;
+ }
+
+ static PackageTree _validatePackages(Iterable<Package> originalPackages,
+ List<Package> packages, void onError(Object error)) {
+ var packageNames = <String>{};
+ var tree = MutablePackageTree();
+ for (var originalPackage in packages) {
+ if (originalPackage == null) {
+ onError(ArgumentError.notNull("element of packages"));
+ continue;
+ }
+ SimplePackage package;
+ if (originalPackage is! SimplePackage) {
+ // SimplePackage validates these properties.
+ package = SimplePackage.validate(
+ originalPackage.name,
+ originalPackage.root,
+ originalPackage.packageUriRoot,
+ originalPackage.languageVersion,
+ originalPackage.extraData, (error) {
+ if (error is PackageConfigArgumentError) {
+ onError(PackageConfigArgumentError(packages, "packages",
+ "Package ${package.name}: ${error.message}"));
+ } else {
+ onError(error);
+ }
+ });
+ if (package == null) continue;
+ } else {
+ package = originalPackage;
+ }
+ var name = package.name;
+ if (packageNames.contains(name)) {
+ onError(PackageConfigArgumentError(
+ name, "packages", "Duplicate package name"));
+ continue;
+ }
+ packageNames.add(name);
+ tree.add(0, package, (error) {
+ if (error is ConflictException) {
+ // There is a conflict with an existing package.
+ var existingPackage = error.existingPackage;
+ if (error.isRootConflict) {
+ onError(PackageConfigArgumentError(
+ originalPackages,
+ "packages",
+ "Packages ${package.name} and ${existingPackage.name} "
+ "have the same root directory: ${package.root}.\n"));
+ } else {
+ assert(error.isPackageRootConflict);
+ // Package is inside the package URI root of the existing package.
+ onError(PackageConfigArgumentError(
+ originalPackages,
+ "packages",
+ "Package ${package.name} is inside the package URI root of "
+ "package ${existingPackage.name}.\n"
+ "${existingPackage.name} URI root: "
+ "${existingPackage.packageUriRoot}\n"
+ "${package.name} root: ${package.root}\n"));
+ }
+ } else {
+ // Any other error.
+ onError(error);
+ }
+ });
+ }
+ return tree;
+ }
+
+ Iterable<Package> get packages => _packages.values;
+
+ Package /*?*/ operator [](String packageName) => _packages[packageName];
+
+ /// Provides the associated package for a specific [file] (or directory).
+ ///
+ /// Returns a [Package] which contains the [file]'s path.
+ /// That is, the [Package.rootUri] directory is a parent directory
+ /// of the [file]'s location.
+ /// Returns `null` if the file does not belong to any package.
+ Package /*?*/ packageOf(Uri file) => _packageTree.packageOf(file);
+
+ Uri /*?*/ resolve(Uri packageUri) {
+ var packageName = checkValidPackageUri(packageUri, "packageUri");
+ return _packages[packageName]?.packageUriRoot?.resolveUri(
+ Uri(path: packageUri.path.substring(packageName.length + 1)));
+ }
+
+ Uri /*?*/ toPackageUri(Uri nonPackageUri) {
+ if (nonPackageUri.isScheme("package")) {
+ throw PackageConfigArgumentError(
+ nonPackageUri, "nonPackageUri", "Must not be a package URI");
+ }
+ if (nonPackageUri.hasQuery || nonPackageUri.hasFragment) {
+ throw PackageConfigArgumentError(nonPackageUri, "nonPackageUri",
+ "Must not have query or fragment part");
+ }
+ // Find package that file belongs to.
+ var package = _packageTree.packageOf(nonPackageUri);
+ if (package == null) return null;
+ // Check if it is inside the package URI root.
+ var path = nonPackageUri.toString();
+ var root = package.packageUriRoot.toString();
+ if (_beginsWith(package.root.toString().length, root, path)) {
+ var rest = path.substring(root.length);
+ return Uri(scheme: "package", path: "${package.name}/$rest");
+ }
+ return null;
+ }
+}
+
+/// Configuration data for a single package.
+class SimplePackage implements Package {
+ final String name;
+ final Uri root;
+ final Uri packageUriRoot;
+ final LanguageVersion /*?*/ languageVersion;
+ final dynamic extraData;
+
+ SimplePackage._(this.name, this.root, this.packageUriRoot,
+ this.languageVersion, this.extraData);
+
+ /// Creates a [SimplePackage] with the provided content.
+ ///
+ /// The provided arguments must be valid.
+ ///
+ /// If the arguments are invalid then the error is reported by
+ /// calling [onError], then the erroneous entry is ignored.
+ ///
+ /// If [onError] is provided, the user is expected to be able to handle
+ /// errors themselves. An invalid [languageVersion] string
+ /// will be replaced with the string `"invalid"`. This allows
+ /// users to detect the difference between an absent version and
+ /// an invalid one.
+ ///
+ /// Returns `null` if the input is invalid and an approximately valid package
+ /// cannot be salvaged from the input.
+ static SimplePackage /*?*/ validate(
+ String name,
+ Uri root,
+ Uri packageUriRoot,
+ LanguageVersion /*?*/ languageVersion,
+ dynamic extraData,
+ void onError(Object error)) {
+ var fatalError = false;
+ var invalidIndex = checkPackageName(name);
+ if (invalidIndex >= 0) {
+ onError(PackageConfigFormatException(
+ "Not a valid package name", name, invalidIndex));
+ fatalError = true;
+ }
+ if (root.isScheme("package")) {
+ onError(PackageConfigArgumentError(
+ "$root", "root", "Must not be a package URI"));
+ fatalError = true;
+ } else if (!isAbsoluteDirectoryUri(root)) {
+ onError(PackageConfigArgumentError(
+ "$root",
+ "root",
+ "In package $name: Not an absolute URI with no query or fragment "
+ "with a path ending in /"));
+ // Try to recover. If the URI has a scheme,
+ // then ensure that the path ends with `/`.
+ if (!root.hasScheme) {
+ fatalError = true;
+ } else if (!root.path.endsWith("/")) {
+ root = root.replace(path: root.path + "/");
+ }
+ }
+ if (!fatalError) {
+ if (!isAbsoluteDirectoryUri(packageUriRoot)) {
+ onError(PackageConfigArgumentError(
+ packageUriRoot,
+ "packageUriRoot",
+ "In package $name: Not an absolute URI with no query or fragment "
+ "with a path ending in /"));
+ packageUriRoot = root;
+ } else if (!isUriPrefix(root, packageUriRoot)) {
+ onError(PackageConfigArgumentError(packageUriRoot, "packageUriRoot",
+ "The package URI root is not below the package root"));
+ packageUriRoot = root;
+ }
+ }
+ if (fatalError) return null;
+ return SimplePackage._(
+ name, root, packageUriRoot, languageVersion, extraData);
+ }
+}
+
+/// Checks whether [version] is a valid Dart language version string.
+///
+/// The format is (as RegExp) `^(0|[1-9]\d+)\.(0|[1-9]\d+)$`.
+///
+/// Reports a format exception on [onError] if not, or if the numbers
+/// are too large (at most 32-bit signed integers).
+LanguageVersion parseLanguageVersion(
+ String source, void onError(Object error)) {
+ var index = 0;
+ // Reads a positive decimal numeral. Returns the value of the numeral,
+ // or a negative number in case of an error.
+ // Starts at [index] and increments the index to the position after
+ // the numeral.
+ // It is an error if the numeral value is greater than 0x7FFFFFFFF.
+ // It is a recoverable error if the numeral starts with leading zeros.
+ int readNumeral() {
+ const maxValue = 0x7FFFFFFF;
+ if (index == source.length) {
+ onError(PackageConfigFormatException("Missing number", source, index));
+ return -1;
+ }
+ var start = index;
+
+ var char = source.codeUnitAt(index);
+ var digit = char ^ 0x30;
+ if (digit > 9) {
+ onError(PackageConfigFormatException("Missing number", source, index));
+ return -1;
+ }
+ var firstDigit = digit;
+ var value = 0;
+ do {
+ value = value * 10 + digit;
+ if (value > maxValue) {
+ onError(
+ PackageConfigFormatException("Number too large", source, start));
+ return -1;
+ }
+ index++;
+ if (index == source.length) break;
+ char = source.codeUnitAt(index);
+ digit = char ^ 0x30;
+ } while (digit <= 9);
+ if (firstDigit == 0 && index > start + 1) {
+ onError(PackageConfigFormatException(
+ "Leading zero not allowed", source, start));
+ }
+ return value;
+ }
+
+ var major = readNumeral();
+ if (major < 0) {
+ return SimpleInvalidLanguageVersion(source);
+ }
+ if (index == source.length || source.codeUnitAt(index) != $dot) {
+ onError(PackageConfigFormatException("Missing '.'", source, index));
+ return SimpleInvalidLanguageVersion(source);
+ }
+ index++;
+ var minor = readNumeral();
+ if (minor < 0) {
+ return SimpleInvalidLanguageVersion(source);
+ }
+ if (index != source.length) {
+ onError(PackageConfigFormatException(
+ "Unexpected trailing character", source, index));
+ return SimpleInvalidLanguageVersion(source);
+ }
+ return SimpleLanguageVersion(major, minor, source);
+}
+
+abstract class _SimpleLanguageVersionBase implements LanguageVersion {
+ int compareTo(LanguageVersion other) {
+ var result = major.compareTo(other.major);
+ if (result != 0) return result;
+ return minor.compareTo(other.minor);
+ }
+}
+
+class SimpleLanguageVersion extends _SimpleLanguageVersionBase {
+ final int major;
+ final int minor;
+ String /*?*/ _source;
+ SimpleLanguageVersion(this.major, this.minor, this._source);
+
+ bool operator ==(Object other) =>
+ other is LanguageVersion && major == other.major && minor == other.minor;
+
+ int get hashCode => (major * 17 ^ minor * 37) & 0x3FFFFFFF;
+
+ String toString() => _source ??= "$major.$minor";
+}
+
+class SimpleInvalidLanguageVersion extends _SimpleLanguageVersionBase
+ implements InvalidLanguageVersion {
+ final String _source;
+ SimpleInvalidLanguageVersion(this._source);
+ int get major => -1;
+ int get minor => -1;
+
+ String toString() => _source;
+}
+
+abstract class PackageTree {
+ Iterable<Package> get allPackages;
+ SimplePackage /*?*/ packageOf(Uri file);
+}
+
+/// Packages of a package configuration ordered by root path.
+///
+/// A package has a root path and a package root path, where the latter
+/// contains the files exposed by `package:` URIs.
+///
+/// A package is said to be inside another package if the root path URI of
+/// the latter is a prefix of the root path URI of the former.
+///
+/// No two packages of a package may have the same root path, so this
+/// path prefix ordering defines a tree-like partial ordering on packages
+/// of a configuration.
+///
+/// The package root path of a package must not be inside another package's
+/// root path.
+/// Entire other packages are allowed inside a package's root or
+/// package root path.
+///
+/// The package tree contains an ordered mapping of unrelated packages
+/// (represented by their name) to their immediately nested packages' names.
+class MutablePackageTree implements PackageTree {
+ /// A list of packages that are not nested inside each other.
+ final List<SimplePackage> packages = [];
+
+ /// The tree of the immediately nested packages inside each package.
+ ///
+ /// Indexed by [Package.name].
+ /// If a package has no nested packages (which is most often the case),
+ /// there is no tree object associated with it.
+ Map<String, MutablePackageTree /*?*/ > /*?*/ _packageChildren;
+
+ Iterable<Package> get allPackages sync* {
+ for (var package in packages) yield package;
+ if (_packageChildren != null) {
+ for (var tree in _packageChildren.values) yield* tree.allPackages;
+ }
+ }
+
+ /// Tries to (add) `package` to the tree.
+ ///
+ /// Reports a [ConflictException] if the added package conflicts with an
+ /// existing package.
+ /// It conflicts if its root or package root is the same as another
+ /// package's root or package root, or is between the two.
+ ///
+ /// If a conflict is detected between [package] and a previous package,
+ /// then [onError] is called with a [ConflictException] object
+ /// and the [package] is not added to the tree.
+ ///
+ /// The packages are added in order of their root path.
+ /// It is never necessary to insert a node between two existing levels.
+ void add(int start, SimplePackage package, void onError(Object error)) {
+ var path = package.root.toString();
+ for (var treePackage in packages) {
+ // Check is package is inside treePackage.
+ var treePackagePath = treePackage.root.toString();
+ assert(treePackagePath.length > start);
+ assert(path.startsWith(treePackagePath.substring(0, start)));
+ if (_beginsWith(start, treePackagePath, path)) {
+ // Package *is* inside treePackage.
+ var treePackagePathLength = treePackagePath.length;
+ if (path.length == treePackagePathLength) {
+ // Has same root. Do not add package.
+ onError(ConflictException.root(package, treePackage));
+ return;
+ }
+ var treePackageUriRoot = treePackage.packageUriRoot.toString();
+ if (_beginsWith(treePackagePathLength, path, treePackageUriRoot)) {
+ // The treePackage's package root is inside package, which is inside
+ // the treePackage. This is not allowed.
+ onError(ConflictException.packageRoot(package, treePackage));
+ return;
+ }
+ _treeOf(treePackage).add(treePackagePathLength, package, onError);
+ return;
+ }
+ }
+ packages.add(package);
+ }
+
+ SimplePackage /*?*/ packageOf(Uri file) {
+ return findPackageOf(0, file.toString());
+ }
+
+ /// Finds package containing [path] in this tree.
+ ///
+ /// Returns `null` if no such package is found.
+ ///
+ /// Assumes the first [start] characters of path agrees with all
+ /// the packages at this level of the tree.
+ SimplePackage /*?*/ findPackageOf(int start, String path) {
+ for (var childPackage in packages) {
+ var childPath = childPackage.root.toString();
+ if (_beginsWith(start, childPath, path)) {
+ // The [package] is inside [childPackage].
+ var childPathLength = childPath.length;
+ if (path.length == childPathLength) return childPackage;
+ var uriRoot = childPackage.packageUriRoot.toString();
+ // Is [package] is inside the URI root of [childPackage].
+ if (uriRoot.length == childPathLength ||
+ _beginsWith(childPathLength, uriRoot, path)) {
+ return childPackage;
+ }
+ // Otherwise add [package] as child of [childPackage].
+ // TODO(lrn): When NNBD comes, convert to:
+ // return _packageChildren?[childPackage.name]
+ // ?.packageOf(childPathLength, path) ?? childPackage;
+ if (_packageChildren == null) return childPackage;
+ var childTree = _packageChildren[childPackage.name];
+ if (childTree == null) return childPackage;
+ return childTree.findPackageOf(childPathLength, path) ?? childPackage;
+ }
+ }
+ return null;
+ }
+
+ /// Returns the [PackageTree] of the children of [package].
+ ///
+ /// Ensures that the object is allocated if necessary.
+ MutablePackageTree _treeOf(SimplePackage package) {
+ var children = _packageChildren ??= {};
+ return children[package.name] ??= MutablePackageTree();
+ }
+}
+
+class EmptyPackageTree implements PackageTree {
+ const EmptyPackageTree();
+
+ Iterable<Package> get allPackages => const Iterable<Package>.empty();
+
+ SimplePackage packageOf(Uri file) => null;
+}
+
+/// Checks whether [longerPath] begins with [parentPath].
+///
+/// Skips checking the [start] first characters which are assumed to
+/// already have been matched.
+bool _beginsWith(int start, String parentPath, String longerPath) {
+ if (longerPath.length < parentPath.length) return false;
+ for (var i = start; i < parentPath.length; i++) {
+ if (longerPath.codeUnitAt(i) != parentPath.codeUnitAt(i)) return false;
+ }
+ return true;
+}
+
+/// Conflict between packages added to the same configuration.
+///
+/// The [package] conflicts with [existingPackage] if it has
+/// the same root path ([isRootConflict]) or the package URI root path
+/// of [existingPackage] is inside the root path of [package]
+/// ([isPackageRootConflict]).
+class ConflictException {
+ /// The existing package that [package] conflicts with.
+ final SimplePackage existingPackage;
+
+ /// The package that could not be added without a conflict.
+ final SimplePackage package;
+
+ /// Whether the conflict is with the package URI root of [existingPackage].
+ final bool isPackageRootConflict;
+
+ /// Creates a root conflict between [package] and [existingPackage].
+ ConflictException.root(this.package, this.existingPackage)
+ : isPackageRootConflict = false;
+
+ /// Creates a package root conflict between [package] and [existingPackage].
+ ConflictException.packageRoot(this.package, this.existingPackage)
+ : isPackageRootConflict = true;
+
+ /// WHether the conflict is with the root URI of [existingPackage].
+ bool get isRootConflict => !isPackageRootConflict;
+}
+
+/// Used for sorting packages by root path.
+int _compareRoot(Package p1, Package p2) =>
+ p1.root.toString().compareTo(p2.root.toString());
diff --git a/package_config/lib/src/package_config_io.dart b/package_config/lib/src/package_config_io.dart
new file mode 100644
index 0000000..954be6b
--- /dev/null
+++ b/package_config/lib/src/package_config_io.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2019, 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.
+
+// dart:io dependent functionality for reading and writing configuration files.
+
+import "dart:convert";
+import "dart:io";
+import "dart:typed_data";
+
+import "discovery.dart" show packageConfigJsonPath;
+import "errors.dart";
+import "package_config_impl.dart";
+import "package_config_json.dart";
+import "packages_file.dart" as packages_file;
+import "util.dart";
+import "util_io.dart";
+
+/// Reads a package configuration file.
+///
+/// Detects whether the [file] is a version one `.packages` file or
+/// a version two `package_config.json` file.
+///
+/// If the [file] is a `.packages` file and [preferNewest] is true,
+/// first checks whether there is an adjacent `.dart_tool/package_config.json`
+/// file, and if so, reads that instead.
+/// If [preferNewset] is false, the specified file is loaded even if it is
+/// a `.packages` file and there is an available `package_config.json` file.
+///
+/// The file must exist and be a normal file.
+Future<PackageConfig> readAnyConfigFile(
+ File file, bool preferNewest, void onError(Object error)) async {
+ Uint8List bytes;
+ try {
+ bytes = await file.readAsBytes();
+ } catch (e) {
+ onError(e);
+ return const SimplePackageConfig.empty();
+ }
+ var firstChar = firstNonWhitespaceChar(bytes);
+ if (firstChar != $lbrace) {
+ // Definitely not a JSON object, probably a .packages.
+ if (preferNewest) {
+ var alternateFile = File(
+ pathJoin(dirName(file.path), ".dart_tool", "package_config.json"));
+ if (alternateFile.existsSync()) {
+ Uint8List /*?*/ bytes;
+ try {
+ bytes = await alternateFile.readAsBytes();
+ } catch (e) {
+ onError(e);
+ return const SimplePackageConfig.empty();
+ }
+ if (bytes != null) {
+ return parsePackageConfigBytes(bytes, alternateFile.uri, onError);
+ }
+ }
+ }
+ return packages_file.parse(bytes, file.uri, onError);
+ }
+ return parsePackageConfigBytes(bytes, file.uri, onError);
+}
+
+/// Like [readAnyConfigFile] but uses a URI and an optional loader.
+Future<PackageConfig> readAnyConfigFileUri(
+ Uri file,
+ Future<Uint8List /*?*/ > loader(Uri uri) /*?*/,
+ void onError(Object error),
+ bool preferNewest) async {
+ if (file.isScheme("package")) {
+ throw PackageConfigArgumentError(
+ file, "file", "Must not be a package: URI");
+ }
+ if (loader == null) {
+ if (file.isScheme("file")) {
+ return readAnyConfigFile(File.fromUri(file), preferNewest, onError);
+ }
+ loader = defaultLoader;
+ }
+ Uint8List bytes;
+ try {
+ bytes = await loader(file);
+ } catch (e) {
+ onError(e);
+ return const SimplePackageConfig.empty();
+ }
+ if (bytes == null) {
+ onError(PackageConfigArgumentError(
+ file.toString(), "file", "File cannot be read"));
+ return const SimplePackageConfig.empty();
+ }
+ var firstChar = firstNonWhitespaceChar(bytes);
+ if (firstChar != $lbrace) {
+ // Definitely not a JSON object, probably a .packages.
+ if (preferNewest) {
+ // Check if there is a package_config.json file.
+ var alternateFile = file.resolveUri(packageConfigJsonPath);
+ Uint8List alternateBytes;
+ try {
+ alternateBytes = await loader(alternateFile);
+ } catch (e) {
+ onError(e);
+ return const SimplePackageConfig.empty();
+ }
+ if (alternateBytes != null) {
+ return parsePackageConfigBytes(alternateBytes, alternateFile, onError);
+ }
+ }
+ return packages_file.parse(bytes, file, onError);
+ }
+ return parsePackageConfigBytes(bytes, file, onError);
+}
+
+Future<PackageConfig> readPackageConfigJsonFile(
+ File file, void onError(Object error)) async {
+ Uint8List bytes;
+ try {
+ bytes = await file.readAsBytes();
+ } catch (error) {
+ onError(error);
+ return const SimplePackageConfig.empty();
+ }
+ return parsePackageConfigBytes(bytes, file.uri, onError);
+}
+
+Future<PackageConfig> readDotPackagesFile(
+ File file, void onError(Object error)) async {
+ Uint8List bytes;
+ try {
+ bytes = await file.readAsBytes();
+ } catch (error) {
+ onError(error);
+ return const SimplePackageConfig.empty();
+ }
+ return packages_file.parse(bytes, file.uri, onError);
+}
+
+Future<void> writePackageConfigJsonFile(
+ PackageConfig config, Directory targetDirectory) async {
+ // Write .dart_tool/package_config.json first.
+ var file =
+ File(pathJoin(targetDirectory.path, ".dart_tool", "package_config.json"));
+ var baseUri = file.uri;
+ var sink = file.openWrite(encoding: utf8);
+ writePackageConfigJsonUtf8(config, baseUri, sink);
+ var doneJson = sink.close();
+
+ // Write .packages too.
+ file = File(pathJoin(targetDirectory.path, ".packages"));
+ baseUri = file.uri;
+ sink = file.openWrite(encoding: utf8);
+ writeDotPackages(config, baseUri, sink);
+ var donePackages = sink.close();
+
+ await Future.wait([doneJson, donePackages]);
+}
diff --git a/package_config/lib/src/package_config_json.dart b/package_config/lib/src/package_config_json.dart
new file mode 100644
index 0000000..b9b3416
--- /dev/null
+++ b/package_config/lib/src/package_config_json.dart
@@ -0,0 +1,315 @@
+// Copyright (c) 2019, 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.
+
+// Parsing and serialization of package configurations.
+
+import "dart:convert";
+import "dart:typed_data";
+
+import "errors.dart";
+import "package_config_impl.dart";
+import "packages_file.dart" as packages_file;
+import "util.dart";
+
+const String _configVersionKey = "configVersion";
+const String _packagesKey = "packages";
+const List<String> _topNames = [_configVersionKey, _packagesKey];
+const String _nameKey = "name";
+const String _rootUriKey = "rootUri";
+const String _packageUriKey = "packageUri";
+const String _languageVersionKey = "languageVersion";
+const List<String> _packageNames = [
+ _nameKey,
+ _rootUriKey,
+ _packageUriKey,
+ _languageVersionKey
+];
+
+const String _generatedKey = "generated";
+const String _generatorKey = "generator";
+const String _generatorVersionKey = "generatorVersion";
+
+final _jsonUtf8Decoder = json.fuse(utf8).decoder;
+
+PackageConfig parsePackageConfigBytes(
+ Uint8List bytes, Uri file, void onError(Object error)) {
+ // TODO(lrn): Make this simpler. Maybe parse directly from bytes.
+ var jsonObject;
+ try {
+ jsonObject = _jsonUtf8Decoder.convert(bytes);
+ } on FormatException catch (e) {
+ onError(PackageConfigFormatException(e.message, e.source, e.offset));
+ return const SimplePackageConfig.empty();
+ }
+ return parsePackageConfigJson(jsonObject, file, onError);
+}
+
+PackageConfig parsePackageConfigString(
+ String source, Uri file, void onError(Object error)) {
+ var jsonObject;
+ try {
+ jsonObject = jsonDecode(source);
+ } on FormatException catch (e) {
+ onError(PackageConfigFormatException(e.message, e.source, e.offset));
+ return const SimplePackageConfig.empty();
+ }
+ return parsePackageConfigJson(jsonObject, file, onError);
+}
+
+/// Creates a [PackageConfig] from a parsed JSON-like object structure.
+///
+/// The [json] argument must be a JSON object (`Map<String, dynamic>`)
+/// containing a `"configVersion"` entry with an integer value in the range
+/// 1 to [PackageConfig.maxVersion],
+/// and with a `"packages"` entry which is a JSON array (`List<dynamic>`)
+/// containing JSON objects which each has the following properties:
+///
+/// * `"name"`: The package name as a string.
+/// * `"rootUri"`: The root of the package as a URI stored as a string.
+/// * `"packageUri"`: Optionally the root of for `package:` URI resolution
+/// for the package, as a relative URI below the root URI
+/// stored as a string.
+/// * `"languageVersion"`: Optionally a language version string which is a
+/// an integer numeral, a decimal point (`.`) and another integer numeral,
+/// where the integer numeral cannot have a sign, and can only have a
+/// leading zero if the entire numeral is a single zero.
+///
+/// All other properties are stored in [extraData].
+///
+/// The [baseLocation] is used as base URI to resolve the "rootUri"
+/// URI referencestring.
+PackageConfig parsePackageConfigJson(
+ dynamic json, Uri baseLocation, void onError(Object error)) {
+ if (!baseLocation.hasScheme || baseLocation.isScheme("package")) {
+ throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation",
+ "Must be an absolute non-package: URI");
+ }
+
+ if (!baseLocation.path.endsWith("/")) {
+ baseLocation = baseLocation.resolveUri(Uri(path: "."));
+ }
+
+ String typeName<T>() {
+ if (0 is T) return "int";
+ if ("" is T) return "string";
+ if (const [] is T) return "array";
+ return "object";
+ }
+
+ T checkType<T>(dynamic value, String name, [String /*?*/ packageName]) {
+ if (value is T) return value;
+ // The only types we are called with are [int], [String], [List<dynamic>]
+ // and Map<String, dynamic>. Recognize which to give a better error message.
+ var message =
+ "$name${packageName != null ? " of package $packageName" : ""}"
+ " is not a JSON ${typeName<T>()}";
+ onError(PackageConfigFormatException(message, value));
+ return null;
+ }
+
+ Package /*?*/ parsePackage(Map<String, dynamic> entry) {
+ String /*?*/ name;
+ String /*?*/ rootUri;
+ String /*?*/ packageUri;
+ String /*?*/ languageVersion;
+ Map<String, dynamic> /*?*/ extraData;
+ var hasName = false;
+ var hasRoot = false;
+ var hasVersion = false;
+ entry.forEach((key, value) {
+ switch (key) {
+ case _nameKey:
+ hasName = true;
+ name = checkType<String>(value, _nameKey);
+ break;
+ case _rootUriKey:
+ hasRoot = true;
+ rootUri = checkType<String>(value, _rootUriKey, name);
+ break;
+ case _packageUriKey:
+ packageUri = checkType<String>(value, _packageUriKey, name);
+ break;
+ case _languageVersionKey:
+ hasVersion = true;
+ languageVersion = checkType<String>(value, _languageVersionKey, name);
+ break;
+ default:
+ (extraData ??= {})[key] = value;
+ break;
+ }
+ });
+ if (!hasName) {
+ onError(PackageConfigFormatException("Missing name entry", entry));
+ }
+ if (!hasRoot) {
+ onError(PackageConfigFormatException("Missing rootUri entry", entry));
+ }
+ if (name == null || rootUri == null) return null;
+ var root = baseLocation.resolve(rootUri);
+ if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/");
+ var packageRoot = root;
+ if (packageUri != null) packageRoot = root.resolve(packageUri);
+ if (!packageRoot.path.endsWith("/")) {
+ packageRoot = packageRoot.replace(path: packageRoot.path + "/");
+ }
+
+ LanguageVersion /*?*/ version;
+ if (languageVersion != null) {
+ version = parseLanguageVersion(languageVersion, onError);
+ } else if (hasVersion) {
+ version = SimpleInvalidLanguageVersion("invalid");
+ }
+
+ return SimplePackage.validate(name, root, packageRoot, version, extraData,
+ (error) {
+ if (error is ArgumentError) {
+ onError(
+ PackageConfigFormatException(error.message, error.invalidValue));
+ } else {
+ onError(error);
+ }
+ });
+ }
+
+ var map = checkType<Map<String, dynamic>>(json, "value");
+ if (map == null) return const SimplePackageConfig.empty();
+ Map<String, dynamic> /*?*/ extraData;
+ List<Package> /*?*/ packageList;
+ int /*?*/ configVersion;
+ map.forEach((key, value) {
+ switch (key) {
+ case _configVersionKey:
+ configVersion = checkType<int>(value, _configVersionKey) ?? 2;
+ break;
+ case _packagesKey:
+ var packageArray = checkType<List<dynamic>>(value, _packagesKey) ?? [];
+ var packages = <Package>[];
+ for (var package in packageArray) {
+ var packageMap =
+ checkType<Map<String, dynamic>>(package, "package entry");
+ if (packageMap != null) {
+ var entry = parsePackage(packageMap);
+ if (entry != null) {
+ packages.add(entry);
+ }
+ }
+ }
+ packageList = packages;
+ break;
+ default:
+ (extraData ??= {})[key] = value;
+ break;
+ }
+ });
+ if (configVersion == null) {
+ onError(PackageConfigFormatException("Missing configVersion entry", json));
+ configVersion = 2;
+ }
+ if (packageList == null) {
+ onError(PackageConfigFormatException("Missing packages list", json));
+ packageList = [];
+ }
+ return SimplePackageConfig(configVersion, packageList, extraData, (error) {
+ if (error is ArgumentError) {
+ onError(PackageConfigFormatException(error.message, error.invalidValue));
+ } else {
+ onError(error);
+ }
+ });
+}
+
+final _jsonUtf8Encoder = JsonUtf8Encoder(" ");
+
+void writePackageConfigJsonUtf8(
+ PackageConfig config, Uri baseUri, Sink<List<int>> output) {
+ // Can be optimized.
+ var data = packageConfigToJson(config, baseUri);
+ output.add(_jsonUtf8Encoder.convert(data) as Uint8List);
+}
+
+void writePackageConfigJsonString(
+ PackageConfig config, Uri baseUri, StringSink output) {
+ // Can be optimized.
+ var data = packageConfigToJson(config, baseUri);
+ output.write(JsonEncoder.withIndent(" ").convert(data) as Uint8List);
+}
+
+Map<String, dynamic> packageConfigToJson(PackageConfig config, Uri baseUri) =>
+ <String, dynamic>{
+ ...?_extractExtraData(config.extraData, _topNames),
+ _configVersionKey: PackageConfig.maxVersion,
+ _packagesKey: [
+ for (var package in config.packages)
+ <String, dynamic>{
+ _nameKey: package.name,
+ _rootUriKey: relativizeUri(package.root, baseUri).toString(),
+ if (package.root != package.packageUriRoot)
+ _packageUriKey:
+ relativizeUri(package.packageUriRoot, package.root)
+ .toString(),
+ if (package.languageVersion != null &&
+ package.languageVersion is! InvalidLanguageVersion)
+ _languageVersionKey: package.languageVersion.toString(),
+ ...?_extractExtraData(package.extraData, _packageNames),
+ }
+ ],
+ };
+
+void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) {
+ var extraData = config.extraData;
+ // Write .packages too.
+ String /*?*/ comment;
+ if (extraData != null) {
+ String /*?*/ generator = extraData[_generatorKey];
+ if (generator != null) {
+ String /*?*/ generated = extraData[_generatedKey];
+ String /*?*/ generatorVersion = extraData[_generatorVersionKey];
+ comment = "Generated by $generator"
+ "${generatorVersion != null ? " $generatorVersion" : ""}"
+ "${generated != null ? " on $generated" : ""}.";
+ }
+ }
+ packages_file.write(output, config, baseUri: baseUri, comment: comment);
+ return;
+}
+
+/// If "extraData" is a JSON map, then return it, otherwise return null.
+///
+/// If the value contains any of the [reservedNames] for the current context,
+/// entries with that name in the extra data are dropped.
+Map<String, dynamic> /*?*/ _extractExtraData(
+ dynamic data, Iterable<String> reservedNames) {
+ if (data is Map<String, dynamic>) {
+ if (data.isEmpty) return null;
+ for (var name in reservedNames) {
+ if (data.containsKey(name)) {
+ data = {
+ for (var key in data.keys)
+ if (!reservedNames.contains(key)) key: data[key]
+ };
+ if (data.isEmpty) return null;
+ for (var value in data.values) {
+ if (!_validateJson(value)) return null;
+ }
+ }
+ }
+ return data;
+ }
+ return null;
+}
+
+/// Checks that the object is a valid JSON-like data structure.
+bool _validateJson(dynamic object) {
+ if (object == null || true == object || false == object) return true;
+ if (object is num || object is String) return true;
+ if (object is List<dynamic>) {
+ for (var element in object) if (!_validateJson(element)) return false;
+ return true;
+ }
+ if (object is Map<String, dynamic>) {
+ for (var value in object.values) if (!_validateJson(value)) return false;
+ return true;
+ }
+ return false;
+}
diff --git a/package_config/lib/src/packages_file.dart b/package_config/lib/src/packages_file.dart
new file mode 100644
index 0000000..e65e7e8
--- /dev/null
+++ b/package_config/lib/src/packages_file.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2019, 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_config_impl.dart";
+
+import "util.dart";
+import "errors.dart";
+
+/// Parses a `.packages` file into a [PackageConfig].
+///
+/// The [source] is the byte content of a `.packages` file, assumed to be
+/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII,
+/// so Latin-1 or Windows-1252 encoding will also work fine.
+///
+/// If the file content is available as a string, its [String.codeUnits] can
+/// be used as the `source` argument of this function.
+///
+/// The [baseLocation] is used as a base URI to resolve all relative
+/// URI references against.
+/// If the content was read from a file, `baseLocation` should be the
+/// location of that file.
+///
+/// Returns a simple package configuration where each package's
+/// [Package.packageUriRoot] is the same as its [Package.root]
+/// and it has no [Package.languageVersion].
+PackageConfig parse(
+ List<int> source, Uri baseLocation, void onError(Object error)) {
+ if (baseLocation.isScheme("package")) {
+ onError(PackageConfigArgumentError(
+ baseLocation, "baseLocation", "Must not be a package: URI"));
+ return PackageConfig.empty;
+ }
+ var index = 0;
+ var packages = <Package>[];
+ var packageNames = <String>{};
+ while (index < source.length) {
+ var ignoreLine = false;
+ var start = index;
+ var separatorIndex = -1;
+ var end = source.length;
+ var char = source[index++];
+ if (char == $cr || char == $lf) {
+ continue;
+ }
+ if (char == $colon) {
+ onError(PackageConfigFormatException(
+ "Missing package name", source, index - 1));
+ ignoreLine = true; // Ignore if package name is invalid.
+ } else {
+ ignoreLine = char == $hash; // Ignore if comment.
+ }
+ var queryStart = -1;
+ var fragmentStart = -1;
+ while (index < source.length) {
+ char = source[index++];
+ if (char == $colon && separatorIndex < 0) {
+ separatorIndex = index - 1;
+ } else if (char == $cr || char == $lf) {
+ end = index - 1;
+ break;
+ } else if (char == $question && queryStart < 0 && fragmentStart < 0) {
+ queryStart = index - 1;
+ } else if (char == $hash && fragmentStart < 0) {
+ fragmentStart = index - 1;
+ }
+ }
+ if (ignoreLine) continue;
+ if (separatorIndex < 0) {
+ onError(
+ PackageConfigFormatException("No ':' on line", source, index - 1));
+ continue;
+ }
+ var packageName = String.fromCharCodes(source, start, separatorIndex);
+ var invalidIndex = checkPackageName(packageName);
+ if (invalidIndex >= 0) {
+ onError(PackageConfigFormatException(
+ "Not a valid package name", source, start + invalidIndex));
+ continue;
+ }
+ if (queryStart >= 0) {
+ onError(PackageConfigFormatException(
+ "Location URI must not have query", source, queryStart));
+ end = queryStart;
+ } else if (fragmentStart >= 0) {
+ onError(PackageConfigFormatException(
+ "Location URI must not have fragment", source, fragmentStart));
+ end = fragmentStart;
+ }
+ var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
+ Uri packageLocation;
+ try {
+ packageLocation = baseLocation.resolve(packageValue);
+ } on FormatException catch (e) {
+ onError(PackageConfigFormatException.from(e));
+ continue;
+ }
+ if (packageLocation.isScheme("package")) {
+ onError(PackageConfigFormatException(
+ "Package URI as location for package", source, separatorIndex + 1));
+ continue;
+ }
+ if (!packageLocation.path.endsWith('/')) {
+ packageLocation =
+ packageLocation.replace(path: packageLocation.path + "/");
+ }
+ if (packageNames.contains(packageName)) {
+ onError(PackageConfigFormatException(
+ "Same package name occured more than once", source, start));
+ continue;
+ }
+ var package = SimplePackage.validate(
+ packageName, packageLocation, packageLocation, null, null, (error) {
+ if (error is ArgumentError) {
+ onError(PackageConfigFormatException(error.message, source));
+ } else {
+ onError(error);
+ }
+ });
+ if (package != null) {
+ packages.add(package);
+ packageNames.add(packageName);
+ }
+ }
+ return SimplePackageConfig(1, packages, null, onError);
+}
+
+/// Writes the configuration to a [StringSink].
+///
+/// If [comment] is provided, the output will contain this comment
+/// with `# ` in front of each line.
+/// Lines are defined as ending in line feed (`'\n'`). If the final
+/// line of the comment doesn't end in a line feed, one will be added.
+///
+/// If [baseUri] is provided, package locations will be made relative
+/// to the base URI, if possible, before writing.
+///
+/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an
+/// empty string mapping to the _default package name_.
+///
+/// All the keys of [packageMapping] must be valid package names,
+/// and the values must be URIs that do not have the `package:` scheme.
+void write(StringSink output, PackageConfig config,
+ {Uri baseUri, String comment}) {
+ if (baseUri != null && !baseUri.isAbsolute) {
+ throw PackageConfigArgumentError(baseUri, "baseUri", "Must be absolute");
+ }
+
+ if (comment != null) {
+ var lines = comment.split('\n');
+ if (lines.last.isEmpty) lines.removeLast();
+ for (var commentLine in lines) {
+ output.write('# ');
+ output.writeln(commentLine);
+ }
+ } else {
+ output.write("# generated by package:package_config at ");
+ output.write(DateTime.now());
+ output.writeln();
+ }
+ for (var package in config.packages) {
+ var packageName = package.name;
+ var uri = package.packageUriRoot;
+ // Validate packageName.
+ if (!isValidPackageName(packageName)) {
+ throw PackageConfigArgumentError(
+ config, "config", '"$packageName" is not a valid package name');
+ }
+ if (uri.scheme == "package") {
+ throw PackageConfigArgumentError(
+ config, "config", "Package location must not be a package URI: $uri");
+ }
+ output.write(packageName);
+ output.write(':');
+ // If baseUri is provided, make the URI relative to baseUri.
+ if (baseUri != null) {
+ uri = relativizeUri(uri, baseUri);
+ }
+ if (!uri.path.endsWith('/')) {
+ uri = uri.replace(path: uri.path + '/');
+ }
+ output.write(uri);
+ output.writeln();
+ }
+}
diff --git a/package_config/lib/src/packages_impl.dart b/package_config/lib/src/packages_impl.dart
index 817002f..19f1039 100644
--- a/package_config/lib/src/packages_impl.dart
+++ b/package_config/lib/src/packages_impl.dart
@@ -5,6 +5,7 @@
/// Implementations of [Packages] that may be used in either server or browser
/// based applications. For implementations that can only run in the browser,
/// see [package_config.packages_io_impl].
+@Deprecated("Use the package_config.json based API")
library package_config.packages_impl;
import "dart:collection" show UnmodifiableMapView;
@@ -17,13 +18,13 @@
const NoPackages();
Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
- String packageName = checkValidPackageUri(packageUri);
+ var packageName = checkValidPackageUri(packageUri, "packageUri");
if (notFound != null) return notFound(packageUri);
- throw new ArgumentError.value(
+ throw ArgumentError.value(
packageUri, "packageUri", 'No package named "$packageName"');
}
- Iterable<String> get packages => new Iterable<String>.empty();
+ Iterable<String> get packages => Iterable<String>.empty();
Map<String, Uri> asMap() => const <String, Uri>{};
@@ -41,14 +42,14 @@
abstract class PackagesBase implements Packages {
Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
packageUri = packageUri.normalizePath();
- String packageName = checkValidPackageUri(packageUri);
- Uri packageBase = getBase(packageName);
+ var packageName = checkValidPackageUri(packageUri, "packageUri");
+ var packageBase = getBase(packageName);
if (packageBase == null) {
if (notFound != null) return notFound(packageUri);
- throw new ArgumentError.value(
+ throw ArgumentError.value(
packageUri, "packageUri", 'No package named "$packageName"');
}
- String packagePath = packageUri.path.substring(packageName.length + 1);
+ var packagePath = packageUri.path.substring(packageName.length + 1);
return packageBase.resolve(packagePath);
}
@@ -75,13 +76,13 @@
Iterable<String> get packages => _mapping.keys;
- Map<String, Uri> asMap() => new UnmodifiableMapView<String, Uri>(_mapping);
+ Map<String, Uri> asMap() => UnmodifiableMapView<String, Uri>(_mapping);
String get defaultPackageName => _mapping[""]?.toString();
String packageMetadata(String packageName, String key) {
if (packageName.isEmpty) return null;
- Uri uri = _mapping[packageName];
+ var uri = _mapping[packageName];
if (uri == null || !uri.hasFragment) return null;
// This can be optimized, either by caching the map or by
// parsing incrementally instead of parsing the entire fragment.
@@ -112,7 +113,7 @@
Uri getBase(String packageName) => _packageBase.resolve("$packageName/");
Error _failListingPackages() {
- return new UnsupportedError(
+ return UnsupportedError(
"Cannot list packages for a ${_packageBase.scheme}: "
"based package root");
}
diff --git a/package_config/lib/src/packages_io_impl.dart b/package_config/lib/src/packages_io_impl.dart
index 9eba9ce..c623f4d 100644
--- a/package_config/lib/src/packages_io_impl.dart
+++ b/package_config/lib/src/packages_io_impl.dart
@@ -4,15 +4,16 @@
/// Implementations of [Packages] that can only be used in server based
/// applications.
+@Deprecated("Use the package_config.json based API")
library package_config.packages_io_impl;
import "dart:collection" show UnmodifiableMapView;
import "dart:io" show Directory;
-import "package:path/path.dart" as path;
-
import "packages_impl.dart";
+import "util_io.dart";
+
/// A [Packages] implementation based on a local directory.
class FilePackagesDirectoryPackages extends PackagesBase {
final Directory _packageDir;
@@ -22,15 +23,15 @@
Uri getBase(String packageName) {
return _packageToBaseUriMap.putIfAbsent(packageName, () {
- return new Uri.file(path.join(_packageDir.path, packageName, '.'));
+ return Uri.file(pathJoin(_packageDir.path, packageName, '.'));
});
}
Iterable<String> _listPackageNames() {
return _packageDir
.listSync()
- .where((e) => e is Directory)
- .map((e) => path.basename(e.path));
+ .whereType<Directory>()
+ .map((e) => fileName(e.path));
}
Iterable<String> get packages => _listPackageNames();
@@ -40,6 +41,6 @@
for (var packageName in _listPackageNames()) {
result[packageName] = getBase(packageName);
}
- return new UnmodifiableMapView<String, Uri>(result);
+ return UnmodifiableMapView<String, Uri>(result);
}
}
diff --git a/package_config/lib/src/util.dart b/package_config/lib/src/util.dart
index f1e1afd..50b140f 100644
--- a/package_config/lib/src/util.dart
+++ b/package_config/lib/src/util.dart
@@ -1,11 +1,11 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2019, 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.
/// Utility methods used by more than one library in the package.
library package_config.util;
-import "package:charcode/ascii.dart";
+import "errors.dart";
// All ASCII characters that are valid in a package name, with space
// for all the invalid ones (including space).
@@ -15,7 +15,7 @@
/// Tests whether something is a valid Dart package name.
bool isValidPackageName(String string) {
- return _findInvalidCharacter(string) < 0;
+ return checkPackageName(string) < 0;
}
/// Check if a string is a valid package name.
@@ -26,10 +26,10 @@
/// Returns `-1` if the string is valid.
/// Otherwise returns the index of the first invalid character,
/// or `string.length` if the string contains no non-'.' character.
-int _findInvalidCharacter(String string) {
+int checkPackageName(String string) {
// Becomes non-zero if any non-'.' character is encountered.
- int nonDot = 0;
- for (int i = 0; i < string.length; i++) {
+ var nonDot = 0;
+ for (var i = 0; i < string.length; i++) {
var c = string.codeUnitAt(i);
if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) {
return i;
@@ -40,58 +40,199 @@
return -1;
}
-/// Validate that a Uri is a valid package:URI.
-String checkValidPackageUri(Uri packageUri) {
+/// Validate that a [Uri] is a valid `package:` URI.
+///
+/// Used to validate user input.
+///
+/// Returns the package name extracted from the package URI,
+/// which is the path segment between `package:` and the first `/`.
+String checkValidPackageUri(Uri packageUri, String name) {
if (packageUri.scheme != "package") {
- throw new ArgumentError.value(
- packageUri, "packageUri", "Not a package: URI");
+ throw PackageConfigArgumentError(packageUri, name, "Not a package: URI");
}
if (packageUri.hasAuthority) {
- throw new ArgumentError.value(
- packageUri, "packageUri", "Package URIs must not have a host part");
+ throw PackageConfigArgumentError(
+ packageUri, name, "Package URIs must not have a host part");
}
if (packageUri.hasQuery) {
// A query makes no sense if resolved to a file: URI.
- throw new ArgumentError.value(
- packageUri, "packageUri", "Package URIs must not have a query part");
+ throw PackageConfigArgumentError(
+ packageUri, name, "Package URIs must not have a query part");
}
if (packageUri.hasFragment) {
// We could leave the fragment after the URL when resolving,
// but it would be odd if "package:foo/foo.dart#1" and
// "package:foo/foo.dart#2" were considered different libraries.
// Keep the syntax open in case we ever get multiple libraries in one file.
- throw new ArgumentError.value(
- packageUri, "packageUri", "Package URIs must not have a fragment part");
+ throw PackageConfigArgumentError(
+ packageUri, name, "Package URIs must not have a fragment part");
}
if (packageUri.path.startsWith('/')) {
- throw new ArgumentError.value(
- packageUri, "packageUri", "Package URIs must not start with a '/'");
+ throw PackageConfigArgumentError(
+ packageUri, name, "Package URIs must not start with a '/'");
}
- int firstSlash = packageUri.path.indexOf('/');
+ var firstSlash = packageUri.path.indexOf('/');
if (firstSlash == -1) {
- throw new ArgumentError.value(packageUri, "packageUri",
+ throw PackageConfigArgumentError(packageUri, name,
"Package URIs must start with the package name followed by a '/'");
}
- String packageName = packageUri.path.substring(0, firstSlash);
- int badIndex = _findInvalidCharacter(packageName);
+ var packageName = packageUri.path.substring(0, firstSlash);
+ var badIndex = checkPackageName(packageName);
if (badIndex >= 0) {
if (packageName.isEmpty) {
- throw new ArgumentError.value(
- packageUri, "packageUri", "Package names mus be non-empty");
+ throw PackageConfigArgumentError(
+ packageUri, name, "Package names mus be non-empty");
}
if (badIndex == packageName.length) {
- throw new ArgumentError.value(packageUri, "packageUri",
+ throw PackageConfigArgumentError(packageUri, name,
"Package names must contain at least one non-'.' character");
}
assert(badIndex < packageName.length);
- int badCharCode = packageName.codeUnitAt(badIndex);
+ var badCharCode = packageName.codeUnitAt(badIndex);
var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0');
if (badCharCode >= 0x20 && badCharCode <= 0x7e) {
// Printable character.
badChar = "'${packageName[badIndex]}' ($badChar)";
}
- throw new ArgumentError.value(
- packageUri, "packageUri", "Package names must not contain $badChar");
+ throw PackageConfigArgumentError(
+ packageUri, name, "Package names must not contain $badChar");
}
return packageName;
}
+
+/// Checks whether URI is just an absolute directory.
+///
+/// * It must have a scheme.
+/// * It must not have a query or fragment.
+/// * The path must end with `/`.
+bool isAbsoluteDirectoryUri(Uri uri) {
+ if (uri.hasQuery) return false;
+ if (uri.hasFragment) return false;
+ if (!uri.hasScheme) return false;
+ var path = uri.path;
+ if (!path.endsWith("/")) return false;
+ return true;
+}
+
+/// Whether the former URI is a prefix of the latter.
+bool isUriPrefix(Uri prefix, Uri path) {
+ assert(!prefix.hasFragment);
+ assert(!prefix.hasQuery);
+ assert(!path.hasQuery);
+ assert(!path.hasFragment);
+ assert(prefix.path.endsWith('/'));
+ return path.toString().startsWith(prefix.toString());
+}
+
+/// Finds the first non-JSON-whitespace character in a file.
+///
+/// Used to heuristically detect whether a file is a JSON file or an .ini file.
+int firstNonWhitespaceChar(List<int> bytes) {
+ for (var i = 0; i < bytes.length; i++) {
+ var char = bytes[i];
+ if (char != 0x20 && char != 0x09 && char != 0x0a && char != 0x0d) {
+ return char;
+ }
+ }
+ return -1;
+}
+
+/// Attempts to return a relative path-only URI for [uri].
+///
+/// First removes any query or fragment part from [uri].
+///
+/// If [uri] is already relative (has no scheme), it's returned as-is.
+/// If that is not desired, the caller can pass `baseUri.resolveUri(uri)`
+/// as the [uri] instead.
+///
+/// If the [uri] has a scheme or authority part which differs from
+/// the [baseUri], or if there is no overlap in the paths of the
+/// two URIs at all, the [uri] is returned as-is.
+///
+/// Otherwise the result is a path-only URI which satsifies
+/// `baseUri.resolveUri(result) == uri`,
+///
+/// The `baseUri` must be absolute.
+Uri relativizeUri(Uri uri, Uri /*?*/ baseUri) {
+ if (baseUri == null) return uri;
+ assert(baseUri.isAbsolute);
+ if (uri.hasQuery || uri.hasFragment) {
+ uri = Uri(
+ scheme: uri.scheme,
+ userInfo: uri.hasAuthority ? uri.userInfo : null,
+ host: uri.hasAuthority ? uri.host : null,
+ port: uri.hasAuthority ? uri.port : null,
+ path: uri.path);
+ }
+
+ // Already relative. We assume the caller knows what they are doing.
+ if (!uri.isAbsolute) return uri;
+
+ if (baseUri.scheme != uri.scheme) {
+ return uri;
+ }
+
+ // If authority differs, we could remove the scheme, but it's not worth it.
+ if (uri.hasAuthority != baseUri.hasAuthority) return uri;
+ if (uri.hasAuthority) {
+ if (uri.userInfo != baseUri.userInfo ||
+ uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
+ uri.port != baseUri.port) {
+ return uri;
+ }
+ }
+
+ baseUri = baseUri.normalizePath();
+ var base = [...baseUri.pathSegments];
+ if (base.isNotEmpty) base.removeLast();
+ uri = uri.normalizePath();
+ var target = [...uri.pathSegments];
+ if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
+ var index = 0;
+ while (index < base.length && index < target.length) {
+ if (base[index] != target[index]) {
+ break;
+ }
+ index++;
+ }
+ if (index == base.length) {
+ if (index == target.length) {
+ return Uri(path: "./");
+ }
+ return Uri(path: target.skip(index).join('/'));
+ } else if (index > 0) {
+ var buffer = StringBuffer();
+ for (var n = base.length - index; n > 0; --n) {
+ buffer.write("../");
+ }
+ buffer.writeAll(target.skip(index), "/");
+ return Uri(path: buffer.toString());
+ } else {
+ return uri;
+ }
+}
+
+// Character constants used by this package.
+/// "Line feed" control character.
+const int $lf = 0x0a;
+
+/// "Carriage return" control character.
+const int $cr = 0x0d;
+
+/// Space character.
+const int $space = 0x20;
+
+/// Character `#`.
+const int $hash = 0x23;
+
+/// Character `.`.
+const int $dot = 0x2e;
+
+/// Character `:`.
+const int $colon = 0x3a;
+
+/// Character `?`.
+const int $question = 0x3f;
+
+/// Character `{`.
+const int $lbrace = 0x7b;
diff --git a/package_config/lib/src/util_io.dart b/package_config/lib/src/util_io.dart
new file mode 100644
index 0000000..7f21a8d
--- /dev/null
+++ b/package_config/lib/src/util_io.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, 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.
+
+/// Utility methods requiring dart:io and used by more than one library in the
+/// package.
+library package_config.util_io;
+
+import 'dart:io';
+import 'dart:typed_data';
+
+Future<Uint8List> defaultLoader(Uri uri) async {
+ if (uri.isScheme("file")) {
+ var file = File.fromUri(uri);
+ try {
+ return file.readAsBytes();
+ } catch (_) {
+ return null;
+ }
+ }
+ if (uri.isScheme("http") || uri.isScheme("https")) {
+ return _httpGet(uri);
+ }
+ throw UnsupportedError("Default URI unsupported scheme: $uri");
+}
+
+Future<Uint8List /*?*/ > _httpGet(Uri uri) async {
+ assert(uri.isScheme("http") || uri.isScheme("https"));
+ var client = HttpClient();
+ var request = await client.getUrl(uri);
+ var response = await request.close();
+ if (response.statusCode != HttpStatus.ok) {
+ return null;
+ }
+ var splitContent = await response.toList();
+ var totalLength = 0;
+ if (splitContent.length == 1) {
+ var part = splitContent[0];
+ if (part is Uint8List) {
+ return part;
+ }
+ }
+ for (var list in splitContent) {
+ totalLength += list.length;
+ }
+ var result = Uint8List(totalLength);
+ var offset = 0;
+ for (Uint8List contentPart in splitContent) {
+ result.setRange(offset, offset + contentPart.length, contentPart);
+ offset += contentPart.length;
+ }
+ return result;
+}
+
+/// The file name of a path.
+///
+/// The file name is everything after the last occurrence of
+/// [Platform.pathSeparator], or the entire string if no
+/// path separator occurs in the string.
+String fileName(String path) {
+ var separator = Platform.pathSeparator;
+ var lastSeparator = path.lastIndexOf(separator);
+ if (lastSeparator < 0) return path;
+ return path.substring(lastSeparator + separator.length);
+}
+
+/// The directory name of a path.
+///
+/// The directory name is everything before the last occurrence of
+/// [Platform.pathSeparator], or the empty string if no
+/// path separator occurs in the string.
+String dirName(String path) {
+ var separator = Platform.pathSeparator;
+ var lastSeparator = path.lastIndexOf(separator);
+ if (lastSeparator < 0) return "";
+ return path.substring(0, lastSeparator);
+}
+
+/// Join path parts with the [Platform.pathSeparator].
+///
+/// If a part ends with a path separator, then no extra separator is
+/// inserted.
+String pathJoin(String part1, String part2, [String part3]) {
+ var separator = Platform.pathSeparator;
+ var separator1 = part1.endsWith(separator) ? "" : separator;
+ if (part3 == null) {
+ return "$part1$separator1$part2";
+ }
+ var separator2 = part2.endsWith(separator) ? "" : separator;
+ return "$part1$separator1$part2$separator2$part3";
+}
+
+/// Join an unknown number of path parts with [Platform.pathSeparator].
+///
+/// If a part ends with a path separator, then no extra separator is
+/// inserted.
+String pathJoinAll(Iterable<String> parts) {
+ var buffer = StringBuffer();
+ var separator = "";
+ for (var part in parts) {
+ buffer..write(separator)..write(part);
+ separator =
+ part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator;
+ }
+ return buffer.toString();
+}
diff --git a/package_config/pubspec.yaml b/package_config/pubspec.yaml
index b51932e..5c05891 100644
--- a/package_config/pubspec.yaml
+++ b/package_config/pubspec.yaml
@@ -1,15 +1,20 @@
name: package_config
-version: 1.1.0
-description: Support for working with Package Resolution config files.
-author: Dart Team <misc@dartlang.org>
+version: 1.9.1
+description: Support for working with Package Configuration files.
homepage: https://github.com/dart-lang/package_config
environment:
- sdk: '>=2.0.0-dev <3.0.0'
+ sdk: '>=2.7.0 <3.0.0'
dependencies:
+ path: ^1.6.4
charcode: ^1.1.0
- path: ^1.0.0
dev_dependencies:
- test: ^1.3.0
+ test: ^1.6.4
+ matcher: ^0.12.5
+ pedantic: ^1.8.0
+
+ build_runner: ^1.0.0
+ build_web_compilers: ^2.0.0
+ build_test: ^0.10.0
diff --git a/pedantic/BUILD.gn b/pedantic/BUILD.gn
index c7ef7f4..0c47148 100644
--- a/pedantic/BUILD.gn
+++ b/pedantic/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for pedantic-1.8.0+1
+# This file is generated by importer.py for pedantic-1.9.0
import("//build/dart/dart_library.gni")
diff --git a/pedantic/CHANGELOG.md b/pedantic/CHANGELOG.md
index 05399aa..a15b3d0 100644
--- a/pedantic/CHANGELOG.md
+++ b/pedantic/CHANGELOG.md
@@ -1,4 +1,47 @@
+## 1.9.0
+
+- Enforce 17 new lint rules:
+
+ - [`always_declare_return_types`]
+ - [`always_require_non_null_named_parameters`]
+ - [`annotate_overrides`]
+ - [`avoid_null_checks_in_equality_operators`]
+ - [`camel_case_extensions`]
+ - [`omit_local_variable_types`]
+ - [`prefer_adjacent_string_concatenation`]
+ - [`prefer_collection_literals`]
+ - [`prefer_conditional_assignment`]
+ - [`prefer_final_fields`]
+ - [`prefer_for_elements_to_map_fromIterable`]
+ - [`prefer_generic_function_type_aliases`]
+ - [`prefer_if_null_operators`]
+ - [`prefer_single_quotes`]
+ - [`prefer_spread_collections`]
+ - [`unnecessary_this`]
+ - [`use_function_type_syntax_for_parameters`]
+
+- Mark a number of lints unused, see `README.md` for details.
+
+[`always_declare_return_types`]: https://dart-lang.github.io/linter/lints/always_declare_return_types.html
+[`always_require_non_null_named_parameters`]: https://dart-lang.github.io/linter/lints/always_require_non_null_named_parameters.html
+[`annotate_overrides`]: https://dart-lang.github.io/linter/lints/annotate_overrides.html
+[`avoid_null_checks_in_equality_operators`]: https://dart-lang.github.io/linter/lints/avoid_null_checks_in_equality_operators.html
+[`camel_case_extensions`]: https://dart-lang.github.io/linter/lints/camel_case_extensions.html
+[`omit_local_variable_types`]: https://dart-lang.github.io/linter/lints/omit_local_variable_types.html
+[`prefer_adjacent_string_concatenation`]: https://dart-lang.github.io/linter/lints/prefer_adjacent_string_concatenation.html
+[`prefer_collection_literals`]: https://dart-lang.github.io/linter/lints/prefer_collection_literals.html
+[`prefer_conditional_assignment`]: https://dart-lang.github.io/linter/lints/prefer_conditional_assignment.html
+[`prefer_final_fields`]: https://dart-lang.github.io/linter/lints/prefer_final_fields.html
+[`prefer_for_elements_to_map_fromIterable`]: https://dart-lang.github.io/linter/lints/prefer_for_elements_to_map_fromIterable.html
+[`prefer_generic_function_type_aliases`]: https://dart-lang.github.io/linter/lints/prefer_generic_function_type_aliases.html
+[`prefer_if_null_operators`]: https://dart-lang.github.io/linter/lints/prefer_if_null_operators.html
+[`prefer_single_quotes`]: https://dart-lang.github.io/linter/lints/prefer_single_quotes.html
+[`prefer_spread_collections`]: https://dart-lang.github.io/linter/lints/prefer_spread_collections.html
+[`unnecessary_this`]: https://dart-lang.github.io/linter/lints/unnecessary_this.html
+[`use_function_type_syntax_for_parameters`]: https://dart-lang.github.io/linter/lints/use_function_type_syntax_for_parameters.html
+
## 1.8.0
+
- Enforce three new lint rules:
- [`prefer_iterable_whereType`]
diff --git a/pedantic/README.md b/pedantic/README.md
index 3d97288..df8f6de 100644
--- a/pedantic/README.md
+++ b/pedantic/README.md
@@ -27,8 +27,7 @@
- The `TODO` hint is a permanent exception.
- Deprecation hints are a permanent exception. Deprecations are handled
separately on a case by case basis.
- - `unnecessary_no_such_method`, `unused_element`, `unused_field` and
- `unused_local_variable` are allowed.
+ - `unused_element`, `unused_field` and `unused_local_variable` are allowed.
- When a new SDK version adds new errors, warnings or hints, we either clean
up everything before switching SDK version or maintain a whitelist of
allowed violations so it can be gradually cleaned up.
@@ -80,26 +79,174 @@
violates Effective Dart "DO format your code using dartfmt". See note about
Flutter SDK style below.
+`always_put_required_named_parameters_first`
+does not allow for other logical orderings of parameters, such as matching the
+class field order or alphabetical.
+
`always_specify_types`
violates Effective Dart "AVOID type annotating initialized local variables"
and others. See note about Flutter SDK style below.
+`avoid_annotating_with_dynamic`
+violates Effective Dart "PREFER annotating with `dynamic` instead of letting
+inference fail".
+
`avoid_as`
-does not reflect standard usage. See note about Flutter SDK style below.
+does not reflect common usage. See note about Flutter SDK style below.
+
+`avoid_catches_without_on_clauses`
+is too strict, catching anything is useful and common even if not always the
+most correct thing to do.
+
+`avoid_catching_errors`
+is too strict, the distinction between `Error` and `Exception` is followed
+closely in the SDK but is impractical to follow everywhere.
+
+`avoid_classes_with_only_static_members`
+is too strict, Effective Dart explicitly calls out some cases (constants,
+enum-like types) where it makes sense to violate this lint.
+
+`avoid_double_and_int_checks`
+only applies to web, but there is currently no mechanism for enabling a lint
+on web code only.
+
+`avoid_equals_and_hashcode_on_mutable_classes`
+would require the `@immutable` annotation to be consistently and correctly
+used everywhere.
+
+`avoid_field_initializers_in_const_classes`
+does not offer a clear readability benefit.
+
+`avoid_js_rounded_ints`
+only applies to web, but there is currently no mechanism for enabling a lint
+on web code only.
+
+`avoid_print`
+is too strict, it's okay to `print` in some code.
+
+`avoid_returning_null`
+will be obsoleted by NNBD.
+
+`avoid_returning_this`
+has occasional false positives, and adds little value as the cascade operator
+for fluent interfaces in Dart is already very popular.
+
+`avoid_slow_async_io`
+gives wrong advice if the underlying filesystem has unusual properties, for
+example a network mount.
+
+`avoid_void_async`
+prevents a valid style where an asynchronous method has a `void` return type
+to indicate that nobody should `await` for the result.
+
+`cancel_subscriptions`
+has false positives when you use a utility method or class to call `cancel`.
+
+`close_sinks`
+has false positives when you use a utility method or class to call `close`.
+
+`constant_identifier_names`
+is too strict as it does not support the exceptions allowed in Effective Dart
+for use of ALL_CAPS.
`control_flow_in_finally`
does not offer enough value: people are unlikely to do this by accident,
and there are occasional valid uses.
+`directives_ordering`
+would enforce a slightly different ordering to that used by IntelliJ and other
+tools using the analyzer.
+
`empty_statements`
is superfluous, enforcing use of `dartfmt` is sufficient to make empty
statements obvious.
+`flutter_style_todos`
+is for Flutter SDK internal use, see note about Flutter SDK style below.
+
+`invariant_booleans`
+is experimental.
+
+`join_return_with_assignment`
+does not reflect common usage.
+
+`one_member_abstracts`
+is too strict, classes might implement more than one such abstract class and
+there is no equivalent way to do this using functions.
+
+`parameter_assignments`
+does not reflect common usage, and will cause particular problems with NNBD
+code.
+
+`prefer_asserts_in_initializer_lists`
+does not reflect common usage.
+
+`prefer_asserts_with_message`
+is too strict; some asserts do not benefit from documentation.
+
`prefer_bool_in_asserts`
is obsolete in Dart 2; bool is required in asserts.
+`prefer_const_constructors`
+would add a lot of noise to code now that `new` is optional.
+
+`prefer_const_constructors_in_immutables`
+does not often apply as `@immutable` is not widely used.
+
+`prefer_const_literals_to_create_immutables`
+is too strict, requiring `const` everywhere adds noise.
+
+`prefer_constructors_over_static_methods`
+is too strict, in some cases static methods are better.
+
+`prefer_double_quotes`
+does not reflect common usage.
+
+`prefer_expression_function_bodies`
+is too strict, braces look better for long expressions.
+
+`prefer_final_in_for_each`
+does not reflect common usage.
+
`prefer_final_locals`
-does not reflect standard usage.
+does not reflect common usage.
+
+`prefer_foreach`
+is too strict; `forEach` is not always an improvement.
+
+`prefer_int_literals`
+does not reflect common usage.
+
+`prefer_typing_uninitialized_variables`
+will be obsoleted by NNBD, which comes with type inference for uninitialized
+variables.
+
+`literal_only_boolean_expressions`
+does not offer enough value: such expressions are easily spotted and so hard
+to add by accident.
+
+`no_adjacent_strings_in_list`
+does not offer enough value: adjacent strings in lists are easily spotted
+when the code is formatted with `dartfmt`.
+
+`sort_constructors_first`
+does not reflect common usage.
+
+`sort_unnamed_constructors_first`
+is too strict, people are free to choose the best constructor ordering.
+
+`test_types_in_equals`
+does not offer enough value: there are plenty of other mistakes possible in
+`operator ==` implementations. It's better to use codegen.
+
+`unnecessary_null_aware_assignments`
+does not offer enough value: this is hard to do by mistake, and harmless.
+
+`use_setters_to_change_properties`
+is too strict: it can't detect when something is conceptually a property.
+
+`use_to_and_if_as_applicable`
+is too strict: it can't detect when the style rule actually applies.
`throw_in_finally`
does not offer enough value: people are unlikely to do this by accident,
diff --git a/pedantic/lib/analysis_options.1.9.0.yaml b/pedantic/lib/analysis_options.1.9.0.yaml
new file mode 100644
index 0000000..909283b
--- /dev/null
+++ b/pedantic/lib/analysis_options.1.9.0.yaml
@@ -0,0 +1,54 @@
+# Copyright (c) 2019, 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.
+#
+# Google internally enforced rules. See README.md for more information,
+# including a list of lints that are intentionally _not_ enforced.
+
+linter:
+ rules:
+ - always_declare_return_types
+ - always_require_non_null_named_parameters
+ - annotate_overrides
+ - avoid_empty_else
+ - avoid_init_to_null
+ - avoid_null_checks_in_equality_operators
+ - avoid_relative_lib_imports
+ - avoid_return_types_on_setters
+ - avoid_shadowing_type_parameters
+ - avoid_types_as_parameter_names
+ - camel_case_extensions
+ - curly_braces_in_flow_control_structures
+ - empty_catches
+ - empty_constructor_bodies
+ - library_names
+ - library_prefixes
+ - no_duplicate_case_values
+ - null_closures
+ - omit_local_variable_types
+ - prefer_adjacent_string_concatenation
+ - prefer_collection_literals
+ - prefer_conditional_assignment
+ - prefer_contains
+ - prefer_equal_for_default_values
+ - prefer_final_fields
+ - prefer_for_elements_to_map_fromIterable
+ - prefer_generic_function_type_aliases
+ - prefer_if_null_operators
+ - prefer_is_empty
+ - prefer_is_not_empty
+ - prefer_iterable_whereType
+ - prefer_single_quotes
+ - prefer_spread_collections
+ - recursive_getters
+ - slash_for_doc_comments
+ - type_init_formals
+ - unawaited_futures
+ - unnecessary_const
+ - unnecessary_new
+ - unnecessary_null_in_if_null_operators
+ - unnecessary_this
+ - unrelated_type_equality_checks
+ - use_function_type_syntax_for_parameters
+ - use_rethrow_when_possible
+ - valid_regexps
diff --git a/pedantic/lib/analysis_options.yaml b/pedantic/lib/analysis_options.yaml
index c8cc699..cb7021e 100644
--- a/pedantic/lib/analysis_options.yaml
+++ b/pedantic/lib/analysis_options.yaml
@@ -10,4 +10,4 @@
# whenever a new version of `package:pedantic` is released. To avoid this,
# specify a specific version of `analysis_options.yaml` instead.
-include: package:pedantic/analysis_options.1.8.0.yaml
+include: package:pedantic/analysis_options.1.9.0.yaml
diff --git a/pedantic/pubspec.yaml b/pedantic/pubspec.yaml
index 278d457..71d8bde 100644
--- a/pedantic/pubspec.yaml
+++ b/pedantic/pubspec.yaml
@@ -1,5 +1,5 @@
name: pedantic
-version: 1.8.0+1
+version: 1.9.0
description: How to get the most value from Dart static analysis.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/pedantic
diff --git a/plugin_platform_interface/BUILD.gn b/plugin_platform_interface/BUILD.gn
index 7bd3695..9ea1fb5 100644
--- a/plugin_platform_interface/BUILD.gn
+++ b/plugin_platform_interface/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for plugin_platform_interface-1.0.1
+# This file is generated by importer.py for plugin_platform_interface-1.0.2
import("//build/dart/dart_library.gni")
diff --git a/plugin_platform_interface/CHANGELOG.md b/plugin_platform_interface/CHANGELOG.md
index 9fa28ec..1c240ea 100644
--- a/plugin_platform_interface/CHANGELOG.md
+++ b/plugin_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.2
+
+* Make the pedantic dev_dependency explicit.
+
## 1.0.1
* Fixed a bug that made all platform interfaces appear as mocks in release builds (https://github.com/flutter/flutter/issues/46941).
diff --git a/plugin_platform_interface/pubspec.yaml b/plugin_platform_interface/pubspec.yaml
index 4adfe6a..b5f263c 100644
--- a/plugin_platform_interface/pubspec.yaml
+++ b/plugin_platform_interface/pubspec.yaml
@@ -12,7 +12,7 @@
# be done when absolutely necessary and after the ecosystem has already migrated to 1.X.Y version
# that is forward compatible with 2.0.0 (ideally the ecosystem have migrated to depend on:
# `plugin_platform_interface: >=1.X.Y <3.0.0`).
-version: 1.0.1
+version: 1.0.2
homepage: https://github.com/flutter/plugins/plugin_platform_interface
@@ -25,3 +25,4 @@
dev_dependencies:
mockito: ^4.1.1
test: ^1.9.4
+ pedantic: ^1.8.0
diff --git a/scratch_space/BUILD.gn b/scratch_space/BUILD.gn
deleted file mode 100644
index 959a1c8..0000000
--- a/scratch_space/BUILD.gn
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file is generated by importer.py for scratch_space-0.0.4+2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("scratch_space") {
- package_name = "scratch_space"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/path",
- "//third_party/dart-pkg/pub/pedantic",
- "//third_party/dart-pkg/pub/build",
- "//third_party/dart-pkg/pub/pool",
- "//third_party/dart-pkg/pub/crypto",
- ]
-}
diff --git a/scratch_space/CHANGELOG.md b/scratch_space/CHANGELOG.md
deleted file mode 100644
index c36f90f..0000000
--- a/scratch_space/CHANGELOG.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## 0.0.4+2
-
-- Fix a race condition bug where `ensureAssets` would complete before all
- pending writes were completed. If the next build was scheduled before these
- writes finished then they would get the old result.
-
-## 0.0.4+1
-
-- Fix `ScratchSpace.fileFor` on windows to normalize the paths so they dont
- contain mixed separators.
-
-## 0.0.4
-
-- Add `requireContent` argument to `copyOutput` to allow asserting that a file
- produced in a scratch space is not empty.
-
-## 0.0.3+2
-
-- Declare support for `package:build` version `1.x.x`.
-
-## 0.0.3+1
-
-- Increased the upper bound for the sdk to `<3.0.0`.
-
-## 0.0.3
-
-- Use digests to improve `ensureAssets` performance.
- - Scratch spaces can now be used across builds without cleaning them up, and
- will check digests and update assets as needed.
-
-## 0.0.2+1
-
-- Fix a bug where failing to read an asset in serve mode could get the build
- stuck.
-
-## 0.0.2
-
-- Allow creating files at the root of the scratch space.
-
-## 0.0.1+3
-
-- Allow package:build 0.12.0
-
-## 0.0.1+2
-
-- Allow package:build 0.11.0
-
-## 0.0.1+1
-
-- Fix a deadlock issue around the file descriptor pool, only take control of a
- resource right before actually touching disk instead of also encapsulating
- the `readAsBytes` call from the wrapped `AssetReader`.
-
-## 0.0.1
-
-- Initial release, adds the `ScratchSpace` class.
diff --git a/scratch_space/LICENSE b/scratch_space/LICENSE
deleted file mode 100644
index 389ce98..0000000
--- a/scratch_space/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2017, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/scratch_space/README.md b/scratch_space/README.md
deleted file mode 100644
index 341b8ee..0000000
--- a/scratch_space/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
-[![Build Status](https://travis-ci.org/dart-lang/build.svg?branch=master)](https://travis-ci.org/dart-lang/build)
-[![Pub Package](https://img.shields.io/pub/v/scratch_space.svg)](https://pub.dev/packages/scratch_space)
-
-A [`ScratchSpace`][dartdoc:ScratchSpace] is a thin wrapper around a temporary
-directory. The constructor takes zero arguments, so making one is as simple as
-doing `new ScratchSpace()`.
-
-In general, you should wrap a `ScratchSpace` in a `Resource`, so that you can
-re-use the scratch space across build steps in an individual build. This is
-safe to do since you are not allowed to overwrite files within a build.
-
-This should look something like the following:
-
-```
-final myScratchSpaceResource =
- new Resource(() => new ScratchSpace(), dispose: (old) => old.delete());
-```
-
-And then you can get access to it through the `BuildStep#fetchResource` api:
-
-```
-class MyBuilder extends Builder {
- Future build(BuildStep buildStep) async {
- var scratchSpace = await buildStep.fetchResource(myScratchSpaceResource);
- }
-}
-```
-
-### Adding assets to a `ScratchSpace`
-
-To add assets to the `ScratchSpace`, you use the `ensureAssets` method, which
-takes an `Iterable<AssetId>` and an `AssetReader` (for which you should
-generally pass your `BuildStep` which implements that interface).
-
-You must always call this method with all assets that your external executable
-might need in order to set up the proper dependencies and ensure hermetic
-builds.
-
-**Note:** It is important to note that the `ScratchSpace` does not guarantee
-that the version of a file within it is the most updated version, only that
-some version of it exists. For this reason you should create a new
-`ScratchSpace` for each build using the `Resource` class as recommended above.
-
-### Deleting a `ScratchSpace`
-
-When you are done with a `ScratchSpace` you should call `delete` on it to make
-sure it gets cleaned up, otherwise you can end up filling up the users tmp
-directory.
-
-**Note:** You cannot delete individual assets from a `ScratchSpace` today, you
-can only delete the entire thing. If you have a use case for deleting
-individual files you can [file an issue][tracker].
-
-### Getting the actual File objects for a `ScratchSpace`
-
-When invoking an external binary, you probably need to tell it where to look
-for files. There are a few fields/methods to help you do this:
-
- * `String get packagesDir`: The `packages` directory in the `ScratchSpace`.
- * `String get tmpDir`: The root temp directory for the `ScratchSpace`.
- * `File fileFor(AssetId id)`: The File object for `id`.
-
-### Copying back outputs from the temp directory
-
-After running your executable, you most likely have some outputs that you
-need to notify the build system about. To do this you can use the `copyOutput`
-method, which takes an `AssetId` and `AssetWriter` (for which you should
-generally pass your `BuildStep` which implements that interface).
-
-This will copy the asset referenced by the `AssetId` from the temp directory
-back to your actual output directory.
-
-## Feature requests and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/build/issues
-[dartdoc:ScratchSpace]: https://pub.dev/documentation/scratch_space/latest/scratch_space/ScratchSpace-class.html
diff --git a/scratch_space/lib/scratch_space.dart b/scratch_space/lib/scratch_space.dart
deleted file mode 100644
index 95c4c8e..0000000
--- a/scratch_space/lib/scratch_space.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) 2017, 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.
-
-export 'src/scratch_space.dart'
- show ScratchSpace, canonicalUriFor, EmptyOutputException;
diff --git a/scratch_space/lib/src/scratch_space.dart b/scratch_space/lib/src/scratch_space.dart
deleted file mode 100644
index d467cb3..0000000
--- a/scratch_space/lib/src/scratch_space.dart
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2017, 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 'package:build/build.dart';
-import 'package:crypto/crypto.dart';
-import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
-import 'package:pool/pool.dart';
-
-import 'util.dart';
-
-/// Pool for async file writes, we don't want to use too many file handles.
-final _descriptorPool = Pool(32);
-
-/// An on-disk temporary environment for running executables that don't have
-/// a standard Dart library API.
-class ScratchSpace {
- /// Whether or not this scratch space still exists.
- bool exists = true;
-
- /// The `packages` directory under the temp directory.
- final Directory packagesDir;
-
- /// The temp directory at the root of this [ScratchSpace].
- final Directory tempDir;
-
- // Assets which have a file created but are still being written to.
- final _pendingWrites = <AssetId, Future<void>>{};
-
- final _digests = <AssetId, Digest>{};
-
- ScratchSpace._(this.tempDir)
- : packagesDir = Directory(p.join(tempDir.path, 'packages'));
-
- factory ScratchSpace() {
- var tempDir = Directory(Directory.systemTemp
- .createTempSync('scratch_space')
- .resolveSymbolicLinksSync());
- return ScratchSpace._(tempDir);
- }
-
- /// Copies [id] from the tmp dir and writes it back using the [writer].
- ///
- /// Note that [BuildStep] implements [AssetWriter] and that is typically
- /// what you will want to pass in.
- ///
- /// This must be called for all outputs which you want to be included as a
- /// part of the actual build (any other outputs will be deleted with the
- /// tmp dir and won't be available to other [Builder]s).
- ///
- /// If [requireContent] is true and the file is empty an
- /// [EmptyOutputException] is thrown.
- Future copyOutput(AssetId id, AssetWriter writer,
- {bool requireContent = false}) async {
- var file = fileFor(id);
- var bytes = await _descriptorPool.withResource(file.readAsBytes);
- if (requireContent && bytes.isEmpty) throw EmptyOutputException(id);
- await writer.writeAsBytes(id, bytes);
- }
-
- /// Deletes the temp directory for this environment.
- ///
- /// This class is no longer valid once the directory is deleted, you must
- /// create a new [ScratchSpace].
- Future delete() async {
- if (!exists) {
- throw StateError(
- 'Tried to delete a ScratchSpace which was already deleted');
- }
- exists = false;
- _digests.clear();
- if (_pendingWrites.isNotEmpty) {
- try {
- await Future.wait(_pendingWrites.values);
- } catch (_) {
- // Ignore any errors, we are essentially just draining this queue
- // of pending writes but don't care about the result.
- }
- }
- return tempDir.delete(recursive: true);
- }
-
- /// Copies [assetIds] to [tempDir] if they don't exist, using [reader] to
- /// read assets and mark dependencies.
- ///
- /// Note that [BuildStep] implements [AssetReader] and that is typically
- /// what you will want to pass in.
- ///
- /// Any asset that is under a `lib` dir will be output under a `packages`
- /// directory corresponding to its package, and any other assets are output
- /// directly under the temp dir using their unmodified path.
- Future ensureAssets(Iterable<AssetId> assetIds, AssetReader reader) {
- if (!exists) {
- throw StateError('Tried to use a deleted ScratchSpace!');
- }
-
- var futures = assetIds.map((id) async {
- var digest = await reader.digest(id);
- var existing = _digests[id];
- if (digest == existing) {
- await _pendingWrites[id];
- return;
- }
- _digests[id] = digest;
-
- try {
- await _pendingWrites.putIfAbsent(
- id,
- () => _descriptorPool.withResource(() async {
- var file = fileFor(id);
- if (await file.exists()) {
- await file.delete();
- }
- await file.create(recursive: true);
- await file.writeAsBytes(await reader.readAsBytes(id));
- }));
- } finally {
- unawaited(_pendingWrites.remove(id));
- }
- }).toList();
-
- return Future.wait(futures);
- }
-
- /// Returns the actual [File] in this environment corresponding to [id].
- ///
- /// The returned [File] may or may not already exist. Call [ensureAssets]
- /// with [id] to make sure it is actually present.
- File fileFor(AssetId id) =>
- File(p.join(tempDir.path, p.normalize(_relativePathFor(id))));
-}
-
-/// Returns a canonical uri for [id].
-///
-/// If [id] is under a `lib` directory then this returns a `package:` uri,
-/// otherwise it just returns [id#path].
-String canonicalUriFor(AssetId id) {
- if (topLevelDir(id.path) == 'lib') {
- var packagePath =
- p.url.join(id.package, p.url.joinAll(p.url.split(id.path).skip(1)));
- return 'package:$packagePath';
- } else {
- return id.path;
- }
-}
-
-/// The path relative to the root of the environment for a given [id].
-String _relativePathFor(AssetId id) =>
- canonicalUriFor(id).replaceFirst('package:', 'packages/');
-
-/// An indication that an output file which was expect to be non-empty had no
-/// content.
-class EmptyOutputException implements Exception {
- final AssetId id;
- EmptyOutputException(this.id);
-}
diff --git a/scratch_space/lib/src/util.dart b/scratch_space/lib/src/util.dart
deleted file mode 100644
index ae8f1b7..0000000
--- a/scratch_space/lib/src/util.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2017, 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:path/path.dart' as p;
-
-/// Returns the top level directory in [uri].
-///
-/// Throws an [ArgumentError] if [uri] reaches above the top level directory.
-String topLevelDir(String uri) {
- var parts = p.url.split(p.url.normalize(uri));
- if (parts.first == '..') {
- throw ArgumentError('Cannot compute top level dir for path `$uri` '
- 'which reaches outside the root directory.');
- }
- return parts.length == 1 ? null : parts.first;
-}
diff --git a/scratch_space/mono_pkg.yaml b/scratch_space/mono_pkg.yaml
deleted file mode 100644
index 0271728..0000000
--- a/scratch_space/mono_pkg.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-dart:
- - dev
-
-stages:
- - analyze_and_format:
- - group:
- - dartfmt: sdk
- - dartanalyzer: --fatal-infos --fatal-warnings .
- - dartanalyzer: --fatal-warnings .
- dart:
- - 2.3.0
- - unit_test:
- - command: pub run build_runner test
- os:
- - linux
- - windows
-
-cache:
- directories:
- - .dart_tool/build
diff --git a/scratch_space/pubspec.yaml b/scratch_space/pubspec.yaml
deleted file mode 100644
index 11326df..0000000
--- a/scratch_space/pubspec.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: scratch_space
-version: 0.0.4+2
-description: A tool to manage running external executables within package:build
-homepage: https://github.com/dart-lang/build/tree/master/scratch_space
-
-environment:
- sdk: ">=2.3.0 <3.0.0"
-
-dependencies:
- build: ">=0.10.0 <2.0.0"
- crypto: ">=2.0.3 <3.0.0"
- path: ^1.1.0
- pedantic: ^1.0.0
- pool: ^1.0.0
-
-dev_dependencies:
- build_runner: ^1.0.0
- build_test: ^0.10.0
- build_vm_compilers: ">=0.1.0 <2.0.0"
- test: ^1.0.0
diff --git a/source_map_stack_trace/.travis.yml b/source_map_stack_trace/.travis.yml
index 3895dfc..de32a3b 100644
--- a/source_map_stack_trace/.travis.yml
+++ b/source_map_stack_trace/.travis.yml
@@ -5,7 +5,7 @@
dart:
- dev
- - stable
+ - 2.7.0
dart_task:
- test: -p chrome,vm
@@ -16,7 +16,8 @@
- dart: dev
dart_task: dartfmt
- dart: dev
- dart_task: analyzer
+ dart_task:
+ dartanalizer: --fatal-warnings --fatal-infos .
# Only building master means that we don't run two builds for each pull request.
branches:
diff --git a/source_map_stack_trace/BUILD.gn b/source_map_stack_trace/BUILD.gn
index 4d50473..d58f4e1 100644
--- a/source_map_stack_trace/BUILD.gn
+++ b/source_map_stack_trace/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for source_map_stack_trace-1.1.5
+# This file is generated by importer.py for source_map_stack_trace-2.0.0
import("//build/dart/dart_library.gni")
@@ -13,7 +13,6 @@
deps = [
"//third_party/dart-pkg/pub/source_maps",
- "//third_party/dart-pkg/pub/package_resolver",
"//third_party/dart-pkg/pub/path",
"//third_party/dart-pkg/pub/stack_trace",
]
diff --git a/source_map_stack_trace/CHANGELOG.md b/source_map_stack_trace/CHANGELOG.md
index 4acc71e..5bfef35 100644
--- a/source_map_stack_trace/CHANGELOG.md
+++ b/source_map_stack_trace/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 2.0.0
+
+### Breaking Changes
+
+* Removed dependency on `package_resolver` and changed the apis to accept a
+ `Map<String, Uri>` which maps package names to the base uri to resolve the
+ `package:` uris for those packages.
+* The `sdkRoot` argument must be an `Uri`. Use `Uri.parse` for use
+ cases previously passing a `String`.
+* The deprecated `packageRoot` argument has been removed.
+
## 1.1.5
* Set max SDK version to `<3.0.0`.
diff --git a/source_map_stack_trace/analysis_options.yaml b/source_map_stack_trace/analysis_options.yaml
new file mode 100644
index 0000000..76c449a
--- /dev/null
+++ b/source_map_stack_trace/analysis_options.yaml
@@ -0,0 +1,6 @@
+include: package:pedantic/analysis_options.yaml
+analyzer:
+ strong-mode:
+ implicit-casts: false
+ language:
+ strict-raw-types: true
diff --git a/source_map_stack_trace/codereview.settings b/source_map_stack_trace/codereview.settings
deleted file mode 100644
index 78c567f..0000000
--- a/source_map_stack_trace/codereview.settings
+++ /dev/null
@@ -1,3 +0,0 @@
-CODE_REVIEW_SERVER: https://codereview.chromium.org/
-VIEW_VC: https://github.com/dart-lang/source_map_stack_trace/commit/
-CC_LIST: reviews@dartlang.org
\ No newline at end of file
diff --git a/source_map_stack_trace/lib/source_map_stack_trace.dart b/source_map_stack_trace/lib/source_map_stack_trace.dart
index d0252e0..fd1226a 100644
--- a/source_map_stack_trace/lib/source_map_stack_trace.dart
+++ b/source_map_stack_trace/lib/source_map_stack_trace.dart
@@ -2,7 +2,6 @@
// 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:package_resolver/package_resolver.dart';
import 'package:path/path.dart' as p;
import 'package:source_maps/source_maps.dart';
import 'package:stack_trace/stack_trace.dart';
@@ -13,53 +12,31 @@
/// [minified] indicates whether or not the dart2js code was minified. If it
/// hasn't, this tries to clean up the stack frame member names.
///
-/// If [packageResolver] is passed, it's used to reconstruct `package:` URIs for
-/// stack frames that come from packages.
+/// The [packageMap] maps package names to the base uri used to resolve the
+/// `package:` uris for those packages. It is used to it's used to reconstruct
+/// `package:` URIs for stack frames that come from packages.
///
-/// [sdkRoot] is the URI (usually a `file:` URI) for the SDK containing dart2js.
-/// It can be a [String] or a [Uri]. If it's passed, stack frames from the SDK
-/// will have `dart:` URLs.
-///
-/// [packageRoot] is deprecated and shouldn't be used in new code. This throws
-/// an [ArgumentError] if [packageRoot] and [packageResolver] are both passed.
+/// [sdkRoot] is the URI surfaced in the stack traces for SDK libraries.
+/// If it's passed, stack frames from the SDK will have `dart:` URLs.
StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
- {bool minified: false,
- SyncPackageResolver packageResolver,
- sdkRoot,
- @Deprecated("Use the packageResolver parameter instead.") packageRoot}) {
- if (packageRoot != null) {
- if (packageResolver != null) {
- throw new ArgumentError(
- "packageResolver and packageRoot may not both be passed.");
- }
-
- packageResolver = new SyncPackageResolver.root(packageRoot);
- }
-
+ {bool minified = false, Map<String, Uri> packageMap, Uri sdkRoot}) {
if (stackTrace is Chain) {
- return new Chain(stackTrace.traces.map((trace) {
- return new Trace.from(mapStackTrace(sourceMap, trace,
- minified: minified,
- packageResolver: packageResolver,
- sdkRoot: sdkRoot));
+ return Chain(stackTrace.traces.map((trace) {
+ return Trace.from(mapStackTrace(sourceMap, trace,
+ minified: minified, packageMap: packageMap, sdkRoot: sdkRoot));
}));
}
- if (sdkRoot != null && sdkRoot is! String && sdkRoot is! Uri) {
- throw new ArgumentError(
- 'sdkRoot must be a String or a Uri, was "$sdkRoot".');
- }
+ var sdkLib = sdkRoot == null ? null : '$sdkRoot/lib';
- var sdkLib = sdkRoot == null ? null : "$sdkRoot/lib";
-
- var trace = new Trace.from(stackTrace);
- return new Trace(trace.frames.map((frame) {
+ var trace = Trace.from(stackTrace);
+ return Trace(trace.frames.map((frame) {
// If there's no line information, there's no way to translate this frame.
// We could return it as-is, but these lines are usually not useful anyways.
if (frame.line == null) return null;
// If there's no column, try using the first column of the line.
- var column = frame.column == null ? 0 : frame.column;
+ var column = frame.column ?? 0;
// Subtract 1 because stack traces use 1-indexed lines and columns and
// source maps uses 0-indexed.
@@ -72,26 +49,19 @@
var sourceUrl = span.sourceUrl.toString();
if (sdkRoot != null && p.url.isWithin(sdkLib, sourceUrl)) {
- sourceUrl = "dart:" + p.url.relative(sourceUrl, from: sdkLib);
- } else if (packageResolver != null) {
- if (packageResolver.packageRoot != null &&
- p.url.isWithin(packageResolver.packageRoot.toString(), sourceUrl)) {
- sourceUrl = "package:" +
- p.url.relative(sourceUrl,
- from: packageResolver.packageRoot.toString());
- } else if (packageResolver.packageConfigMap != null) {
- for (var package in packageResolver.packageConfigMap.keys) {
- var packageUrl = packageResolver.packageConfigMap[package].toString();
- if (!p.url.isWithin(packageUrl, sourceUrl)) continue;
+ sourceUrl = 'dart:' + p.url.relative(sourceUrl, from: sdkLib);
+ } else if (packageMap != null) {
+ for (var package in packageMap.keys) {
+ var packageUrl = packageMap[package].toString();
+ if (!p.url.isWithin(packageUrl, sourceUrl)) continue;
- sourceUrl =
- "package:$package/" + p.url.relative(sourceUrl, from: packageUrl);
- break;
- }
+ sourceUrl =
+ 'package:$package/' + p.url.relative(sourceUrl, from: packageUrl);
+ break;
}
}
- return new Frame(
+ return Frame(
Uri.parse(sourceUrl),
span.start.line + 1,
span.start.column + 1,
@@ -108,27 +78,26 @@
String _prettifyMember(String member) {
return member
// Get rid of the noise that Firefox sometimes adds.
- .replaceAll(new RegExp(r"/?<$"), "")
+ .replaceAll(RegExp(r'/?<$'), '')
// Get rid of arity indicators and named arguments.
- .replaceAll(new RegExp(r"\$\d+(\$[a-zA-Z_0-9]+)*$"), "")
+ .replaceAll(RegExp(r'\$\d+(\$[a-zA-Z_0-9]+)*$'), '')
// Convert closures to <fn>.
.replaceAllMapped(
- new RegExp(r"(_+)closure\d*\.call$"),
+ RegExp(r'(_+)closure\d*\.call$'),
// The number of underscores before "closure" indicates how nested it
// is.
- (match) => ".<fn>" * match[1].length)
+ (match) => '.<fn>' * match[1].length)
// Get rid of explicitly-generated calls.
- .replaceAll(new RegExp(r"\.call$"), "")
+ .replaceAll(RegExp(r'\.call$'), '')
// Get rid of the top-level method prefix.
- .replaceAll(new RegExp(r"^dart\."), "")
+ .replaceAll(RegExp(r'^dart\.'), '')
// Get rid of library namespaces.
- .replaceAll(new RegExp(r"[a-zA-Z_0-9]+\$"), "")
+ .replaceAll(RegExp(r'[a-zA-Z_0-9]+\$'), '')
// Get rid of the static method prefix. The class name also exists in the
// invocation, so we're not getting rid of any information.
- .replaceAll(new RegExp(r"^[a-zA-Z_0-9]+.(static|dart)."), "")
+ .replaceAll(RegExp(r'^[a-zA-Z_0-9]+.(static|dart).'), '')
// Convert underscores after identifiers to dots. This runs the risk of
// incorrectly converting members that contain underscores, but those are
// contrary to the style guide anyway.
- .replaceAllMapped(
- new RegExp(r"([a-zA-Z0-9]+)_"), (match) => match[1] + ".");
+ .replaceAllMapped(RegExp(r'([a-zA-Z0-9]+)_'), (match) => match[1] + '.');
}
diff --git a/source_map_stack_trace/pubspec.yaml b/source_map_stack_trace/pubspec.yaml
index 77cf804..b998d38 100644
--- a/source_map_stack_trace/pubspec.yaml
+++ b/source_map_stack_trace/pubspec.yaml
@@ -1,18 +1,30 @@
name: source_map_stack_trace
-version: 1.1.5
-
+version: 2.0.0
description: A package for applying source maps to stack traces.
-author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/source_map_stack_trace
environment:
- sdk: '>=1.8.0 <3.0.0'
+ sdk: '>=2.7.0 <3.0.0'
dependencies:
- package_resolver: ^1.0.0
path: ^1.0.0
stack_trace: ^1.0.0
source_maps: ^0.10.2
dev_dependencies:
- test: '>=0.12.0 <2.0.0'
+ source_span: ^1.6.0
+ test: ^1.12.0
+ pedantic: ^1.0.0
+
+dependency_overrides:
+ # Required to get a valid pub solve until package:test updates
+ #test_core:
+ # git:
+ # url: https://github.com/dart-lang/test.git
+ # ref: drop-package-resolver
+ # path: pkgs/test_core
+ #test:
+ # git:
+ # url: https://github.com/dart-lang/test.git
+ # ref: drop-package-resolver
+ # path: pkgs/test
diff --git a/sse/BUILD.gn b/sse/BUILD.gn
index a691b9f..d993492 100644
--- a/sse/BUILD.gn
+++ b/sse/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for sse-3.1.2
+# This file is generated by importer.py for sse-3.2.1
import("//build/dart/dart_library.gni")
diff --git a/sse/CHANGELOG.md b/sse/CHANGELOG.md
index b5fb859..5135fb4 100644
--- a/sse/CHANGELOG.md
+++ b/sse/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 3.2.1
+
+- Fix an issue where `keepAlive` would only allow a single reconnection.
+
+## 3.2.0
+
+- Re-expose `isInKeepAlivePeriod` flag on `SseConnection`. This flag will be
+ `true` when a connection has been dropped and is in the keep-alive period
+ waiting for a client to reconnect.
+
## 3.1.2
- Fix an issue where the `SseClient` would not send a `done` event when there
diff --git a/sse/lib/src/server/sse_handler.dart b/sse/lib/src/server/sse_handler.dart
index 9c3d91e..1749f46 100644
--- a/sse/lib/src/server/sse_handler.dart
+++ b/sse/lib/src/server/sse_handler.dart
@@ -37,7 +37,7 @@
Timer _keepAliveTimer;
/// Whether this connection is currently in the KeepAlive timeout period.
- bool get _isInKeepAlivePeriod => _keepAliveTimer?.isActive ?? false;
+ bool get isInKeepAlivePeriod => _keepAliveTimer?.isActive ?? false;
final _closedCompleter = Completer<void>();
@@ -60,7 +60,7 @@
while (await outgoingStreamQueue.hasNext) {
// If we're in a KeepAlive timeout, there's nowhere to send messages so
// wait a short period and check again.
- if (_isInKeepAlivePeriod) {
+ if (isInKeepAlivePeriod) {
await Future.delayed(const Duration(milliseconds: 200));
continue;
}
@@ -105,7 +105,7 @@
if (_keepAlive == null) {
// Close immediately if we're not keeping alive.
_close();
- } else if (!_isInKeepAlivePeriod) {
+ } else if (!isInKeepAlivePeriod) {
// Otherwise if we didn't already have an active timer, set a timer to
// close after the timeout period. If the connection comes back, this will
// be cancelled and all messages left in the queue tried again.
@@ -155,7 +155,7 @@
// Check if we already have a connection for this ID that is in the process
// of timing out (in which case we can reconnect it transparently).
if (_connections[clientId] != null &&
- _connections[clientId]._isInKeepAlivePeriod) {
+ _connections[clientId].isInKeepAlivePeriod) {
_connections[clientId]._acceptReconnection(sink);
} else {
var connection = SseConnection(sink, keepAlive: _keepAlive);
@@ -163,16 +163,15 @@
unawaited(connection._closedCompleter.future.then((_) {
_connections.remove(clientId);
}));
- // Remove connection when it is remotely closed or the stream is
- // cancelled.
- channel.stream.listen((_) {
- // SSE is unidirectional. Responses are handled through POST requests.
- }, onDone: () {
- connection._handleDisconnect();
- });
-
_connectionController.add(connection);
}
+ // Remove connection when it is remotely closed or the stream is
+ // cancelled.
+ channel.stream.listen((_) {
+ // SSE is unidirectional. Responses are handled through POST requests.
+ }, onDone: () {
+ _connections[clientId]?._handleDisconnect();
+ });
});
return shelf.Response.notFound('');
}
diff --git a/sse/pubspec.yaml b/sse/pubspec.yaml
index 86d3c13..1381d61 100644
--- a/sse/pubspec.yaml
+++ b/sse/pubspec.yaml
@@ -1,5 +1,5 @@
name: sse
-version: 3.1.2
+version: 3.2.1
homepage: https://github.com/dart-lang/sse
description: >-
Provides client and server functionality for setting up bi-directional
diff --git a/stream_transform/.travis.yml b/stream_transform/.travis.yml
index d69c3f7..596c0c6 100644
--- a/stream_transform/.travis.yml
+++ b/stream_transform/.travis.yml
@@ -3,12 +3,21 @@
only: [master]
dart:
- dev
- # 2.2.0
+ - 2.6.0
cache:
directories:
- $HOME/.pub-cache
dart_task:
- - test
- - test -p chrome
- - dartfmt
- - dartanalyzer: --fatal-warnings --fatal-infos .
+ - test --test-randomize-ordering-seed=random
+ - test -p chrome --test-randomize-ordering-seed=random
+
+matrix:
+ include:
+ - dart: dev
+ dart_task: dartfmt
+ - dart: dev
+ dart_task:
+ dartanalyzer: --fatal-warnings --fatal-infos .
+ - dart: 2.6.0
+ dart_task:
+ dartanalyzer: --fatal-warnings .
diff --git a/stream_transform/BUILD.gn b/stream_transform/BUILD.gn
index fcf871b..4ad82b3 100644
--- a/stream_transform/BUILD.gn
+++ b/stream_transform/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for stream_transform-1.1.0
+# This file is generated by importer.py for stream_transform-1.2.0
import("//build/dart/dart_library.gni")
diff --git a/stream_transform/CHANGELOG.md b/stream_transform/CHANGELOG.md
index 686f919..f4cf395 100644
--- a/stream_transform/CHANGELOG.md
+++ b/stream_transform/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 1.2.0
+
+- Add support for emitting the "leading" event in `debounce`.
+
+## 1.1.1
+
+- Fix a bug in `asyncMapSample`, `buffer`, `combineLatest`,
+ `combineLatestAll`, `merge`, and `mergeAll` which would cause an exception
+ when cancelling a subscription after using the transformer if the original
+ stream(s) returned `null` from cancelling their subscriptions.
+
## 1.1.0
- Add `concurrentAsyncExpand` to interleave events emitted by multiple sub
diff --git a/stream_transform/lib/src/aggregate_sample.dart b/stream_transform/lib/src/aggregate_sample.dart
index a069af7..88fc490 100644
--- a/stream_transform/lib/src/aggregate_sample.dart
+++ b/stream_transform/lib/src/aggregate_sample.dart
@@ -32,13 +32,13 @@
StreamSubscription<S> valueSub;
StreamSubscription<void> triggerSub;
- emit() {
+ void emit() {
controller.add(currentResults);
currentResults = null;
waitingForTrigger = true;
}
- onValue(S value) {
+ void onValue(S value) {
currentResults = _aggregate(value, currentResults);
if (!waitingForTrigger) emit();
@@ -49,7 +49,7 @@
}
}
- onValuesDone() {
+ void onValuesDone() {
isValueDone = true;
if (currentResults == null) {
triggerSub?.cancel();
@@ -57,7 +57,7 @@
}
}
- onTrigger(_) {
+ void onTrigger(_) {
waitingForTrigger = false;
if (currentResults != null) emit();
@@ -68,7 +68,7 @@
}
}
- onTriggerDone() {
+ void onTriggerDone() {
isTriggerDone = true;
if (waitingForTrigger) {
valueSub?.cancel();
@@ -107,8 +107,10 @@
} else {
triggerSub.pause();
}
- if (toCancel.isEmpty) return null;
- return Future.wait(toCancel.map((s) => s.cancel()));
+ var cancels =
+ toCancel.map((s) => s.cancel()).where((f) => f != null).toList();
+ if (cancels.isEmpty) return null;
+ return Future.wait(cancels).then((_) => null);
};
};
return controller.stream;
diff --git a/stream_transform/lib/src/async_map.dart b/stream_transform/lib/src/async_map.dart
index f002667..c5b160b 100644
--- a/stream_transform/lib/src/async_map.dart
+++ b/stream_transform/lib/src/async_map.dart
@@ -89,7 +89,7 @@
///
/// The result stream will not close until the source stream closes and all
/// pending conversions have finished.
- Stream<S> concurrentAsyncMap<S>(FutureOr<S> convert(T event)) {
+ Stream<S> concurrentAsyncMap<S>(FutureOr<S> Function(T) convert) {
var valuesWaiting = 0;
var sourceDone = false;
return transform(fromHandlers(handleData: (element, sink) {
@@ -116,7 +116,7 @@
/// rather than once per listener, and [then] is called after completing the
/// work.
StreamTransformer<S, T> _asyncMapThen<S, T>(
- Future<T> convert(S event), void Function(void) then) {
+ Future<T> Function(S) convert, void Function(void) then) {
Future<void> pendingEvent;
return fromHandlers(handleData: (event, sink) {
pendingEvent =
diff --git a/stream_transform/lib/src/combine_latest.dart b/stream_transform/lib/src/combine_latest.dart
index 7fee05d..303b16a 100644
--- a/stream_transform/lib/src/combine_latest.dart
+++ b/stream_transform/lib/src/combine_latest.dart
@@ -175,11 +175,11 @@
};
}
controller.onCancel = () {
- var cancelSource = sourceSubscription.cancel();
- var cancelOther = otherSubscription.cancel();
+ var cancels = [sourceSubscription.cancel(), otherSubscription.cancel()]
+ .where((f) => f != null);
sourceSubscription = null;
otherSubscription = null;
- return Future.wait([cancelSource, cancelOther]);
+ return Future.wait(cancels).then((_) => null);
};
};
return controller.stream;
@@ -249,8 +249,12 @@
};
}
controller.onCancel = () {
- if (subscriptions.isEmpty) return null;
- return Future.wait(subscriptions.map((s) => s.cancel()));
+ var cancels = subscriptions
+ .map((s) => s.cancel())
+ .where((f) => f != null)
+ .toList();
+ if (cancels.isEmpty) return null;
+ return Future.wait(cancels).then((_) => null);
};
};
return controller.stream;
diff --git a/stream_transform/lib/src/concatenate.dart b/stream_transform/lib/src/concatenate.dart
index f9ba747..05c977f 100644
--- a/stream_transform/lib/src/concatenate.dart
+++ b/stream_transform/lib/src/concatenate.dart
@@ -75,17 +75,17 @@
Function currentDoneHandler;
- listen() {
+ void listen() {
subscription = currentStream.listen(controller.add,
onError: controller.addError, onDone: () => currentDoneHandler());
}
- onSecondDone() {
+ void onSecondDone() {
secondDone = true;
controller.close();
}
- onFirstDone() {
+ void onFirstDone() {
firstDone = true;
currentStream = next;
currentDoneHandler = onSecondDone;
diff --git a/stream_transform/lib/src/merge.dart b/stream_transform/lib/src/merge.dart
index 99d19c9..f654d35 100644
--- a/stream_transform/lib/src/merge.dart
+++ b/stream_transform/lib/src/merge.dart
@@ -124,8 +124,12 @@
};
}
controller.onCancel = () {
- if (subscriptions.isEmpty) return null;
- return Future.wait(subscriptions.map((s) => s.cancel()));
+ var cancels = subscriptions
+ .map((s) => s.cancel())
+ .where((f) => f != null)
+ .toList();
+ if (cancels.isEmpty) return null;
+ return Future.wait(cancels).then((_) => null);
};
};
return controller.stream;
@@ -172,7 +176,12 @@
};
}
controller.onCancel = () {
- return Future.wait(subscriptions.map((s) => s.cancel()));
+ var cancels = subscriptions
+ .map((s) => s.cancel())
+ .where((f) => f != null)
+ .toList();
+ if (cancels.isEmpty) return null;
+ return Future.wait(cancels).then((_) => null);
};
};
return controller.stream;
diff --git a/stream_transform/lib/src/rate_limit.dart b/stream_transform/lib/src/rate_limit.dart
index db6d7df..6341c3e 100644
--- a/stream_transform/lib/src/rate_limit.dart
+++ b/stream_transform/lib/src/rate_limit.dart
@@ -9,30 +9,55 @@
/// Utilities to rate limit events.
///
-/// - [debounce] - emit the _first_ event at the _end_ of the period.
-/// - [debounceBuffer] - emit _all_ events at the _end_ of the period.
+/// - [debounce] - emit the the _first_ or _last_ event of a series of closely
+/// spaced events.
+/// - [debounceBuffer] - emit _all_ events at the _end_ of a series of closely
+/// spaced events.
/// - [throttle] - emit the _first_ event at the _beginning_ of the period.
/// - [audit] - emit the _last_ event at the _end_ of the period.
/// - [buffer] - emit _all_ events on a _trigger_.
extension RateLimit<T> on Stream<T> {
- /// Returns a Stream which only emits when the source stream does not emit for
- /// [duration].
+ /// Returns a Stream which suppresses events with less inter-event spacing
+ /// than [duration].
///
- /// Values will always be delayed by at least [duration], and values which
- /// come within this time will replace the old values, only the most
- /// recent value will be emitted.
+ /// Events which are emitted with less than [duration] elapsed between them
+ /// are considered to be part of the same "series". If [leading] is `true`,
+ /// the first event of this series is emitted immediately. If [trailing] is
+ /// `true` the last event of this series is emitted with a delay of at least
+ /// [duration]. By default only trailing events are emitted, both arguments
+ /// must be specified with `leading: true, trailing: false` to emit only
+ /// leading events.
///
/// If the source stream is a broadcast stream, the result will be as well.
/// Errors are forwarded immediately.
///
- /// If there is an event waiting during the debounce period when the source
- /// stream closes the returned stream will wait to emit it following the
- /// debounce period before closing. If there is no pending debounced event
+ /// If there is a trailing event waiting during the debounce period when the
+ /// source stream closes the returned stream will wait to emit it following
+ /// the debounce period before closing. If there is no pending debounced event
/// when the source stream closes the returned stream will close immediately.
///
+ /// For example:
+ ///
+ /// source.debouce(Duration(seconds: 1));
+ ///
+ /// source: 1-2-3---4---5-6-|
+ /// result: ------3---4-----6|
+ ///
+ /// source.debouce(Duration(seconds: 1), leading: true, trailing: false);
+ ///
+ /// source: 1-2-3---4---5-6-|
+ /// result: 1-------4---5---|
+ ///
+ /// source.debouce(Duration(seconds: 1), leading: true);
+ ///
+ /// source: 1-2-3---4---5-6-|
+ /// result: 1-----3-4---5---6|
+ ///
/// To collect values emitted during the debounce period see [debounceBuffer].
- Stream<T> debounce(Duration duration) =>
- transform(_debounceAggregate(duration, _dropPrevious));
+ Stream<T> debounce(Duration duration,
+ {bool leading = false, bool trailing = true}) =>
+ transform(_debounceAggregate(duration, _dropPrevious,
+ leading: leading, trailing: trailing));
/// Returns a Stream which collects values until the source stream does not
/// emit for [duration] then emits the collected values.
@@ -51,7 +76,8 @@
/// To keep only the most recent event during the debounce perios see
/// [debounce].
Stream<List<T>> debounceBuffer(Duration duration) =>
- transform(_debounceAggregate(duration, _collectToList));
+ transform(_debounceAggregate(duration, _collectToList,
+ leading: false, trailing: true));
/// Returns a stream which only emits once per [duration], at the beginning of
/// the period.
@@ -146,25 +172,34 @@
/// Creates a StreamTransformer which aggregates values until the source stream
/// does not emit for [duration], then emits the aggregated values.
StreamTransformer<T, R> _debounceAggregate<T, R>(
- Duration duration, R collect(T element, R soFar)) {
+ Duration duration, R Function(T element, R soFar) collect,
+ {bool leading, bool trailing}) {
Timer timer;
R soFar;
var shouldClose = false;
+ var emittedLatestAsLeading = false;
return fromHandlers(handleData: (T value, EventSink<R> sink) {
timer?.cancel();
- timer = Timer(duration, () {
+ soFar = collect(value, soFar);
+ if (timer == null && leading) {
+ emittedLatestAsLeading = true;
sink.add(soFar);
+ } else {
+ emittedLatestAsLeading = false;
+ }
+ timer = Timer(duration, () {
+ if (trailing && !emittedLatestAsLeading) sink.add(soFar);
if (shouldClose) {
sink.close();
}
soFar = null;
timer = null;
});
- soFar = collect(value, soFar);
}, handleDone: (EventSink<R> sink) {
- if (soFar != null) {
+ if (soFar != null && trailing) {
shouldClose = true;
} else {
+ timer?.cancel();
sink.close();
}
});
diff --git a/stream_transform/lib/src/scan.dart b/stream_transform/lib/src/scan.dart
index b31b9e7..4e022f5 100644
--- a/stream_transform/lib/src/scan.dart
+++ b/stream_transform/lib/src/scan.dart
@@ -14,7 +14,7 @@
/// called for elements in order, and the result stream always maintains the
/// same order as the original.
Stream<S> scan<S>(
- S initialValue, FutureOr<S> combine(S previousValue, T element)) {
+ S initialValue, FutureOr<S> Function(S soFar, T element) combine) {
var accumulated = initialValue;
return asyncMap((value) {
var result = combine(accumulated, value);
diff --git a/stream_transform/lib/src/switch.dart b/stream_transform/lib/src/switch.dart
index 2e2aeba..5125d57 100644
--- a/stream_transform/lib/src/switch.dart
+++ b/stream_transform/lib/src/switch.dart
@@ -15,7 +15,7 @@
///
/// If the source stream is a broadcast stream, the result stream will be as
/// well, regardless of the types of the streams produced by [convert].
- Stream<S> switchMap<S>(Stream<S> convert(T event)) {
+ Stream<S> switchMap<S>(Stream<S> Function(T) convert) {
return map(convert).switchLatest();
}
}
@@ -41,15 +41,11 @@
? StreamController<T>.broadcast(sync: true)
: StreamController<T>(sync: true);
- StreamSubscription<Stream<T>> outerSubscription;
-
controller.onListen = () {
- assert(outerSubscription == null);
-
StreamSubscription<T> innerSubscription;
var outerStreamDone = false;
- outerSubscription = outer.listen(
+ final outerSubscription = outer.listen(
(innerStream) {
innerSubscription?.cancel();
innerSubscription = innerStream.listen(controller.add,
@@ -75,15 +71,12 @@
};
}
controller.onCancel = () {
- var toCancel = <StreamSubscription<void>>[];
- if (!outerStreamDone) toCancel.add(outerSubscription);
- if (innerSubscription != null) {
- toCancel.add(innerSubscription);
- }
- outerSubscription = null;
- innerSubscription = null;
- if (toCancel.isEmpty) return null;
- return Future.wait(toCancel.map((s) => s.cancel()));
+ var cancels = [
+ if (!outerStreamDone) outerSubscription.cancel(),
+ if (innerSubscription != null) innerSubscription.cancel(),
+ ].where((f) => f != null);
+ if (cancels.isEmpty) return null;
+ return Future.wait(cancels).then((_) => null);
};
};
return controller.stream;
diff --git a/stream_transform/lib/src/where.dart b/stream_transform/lib/src/where.dart
index 7026923..8917cb4 100644
--- a/stream_transform/lib/src/where.dart
+++ b/stream_transform/lib/src/where.dart
@@ -17,7 +17,7 @@
/// [S] should be a subtype of the stream's generic type, otherwise nothing of
/// type [S] could possibly be emitted, however there is no static or runtime
/// checking that this is the case.
- Stream<S> whereType<S>() => transform(_WhereType<S>());
+ Stream<S> whereType<S>() => where((e) => e is S).cast<S>();
/// Like [where] but allows the [test] to return a [Future].
///
@@ -34,7 +34,7 @@
///
/// The result stream will not close until the source stream closes and all
/// pending [test] calls have finished.
- Stream<T> asyncWhere(FutureOr<bool> test(T element)) {
+ Stream<T> asyncWhere(FutureOr<bool> Function(T) test) {
var valuesWaiting = 0;
var sourceDone = false;
return transform(fromHandlers(handleData: (element, sink) {
@@ -54,36 +54,3 @@
}));
}
}
-
-class _WhereType<R> extends StreamTransformerBase<Null, R> {
- @override
- Stream<R> bind(Stream<Object> source) {
- var controller = source.isBroadcast
- ? StreamController<R>.broadcast(sync: true)
- : StreamController<R>(sync: true);
-
- StreamSubscription<Object> subscription;
- controller.onListen = () {
- assert(subscription == null);
- subscription = source.listen(
- (value) {
- if (value is R) controller.add(value);
- },
- onError: controller.addError,
- onDone: () {
- subscription = null;
- controller.close();
- });
- if (!source.isBroadcast) {
- controller
- ..onPause = subscription.pause
- ..onResume = subscription.resume;
- }
- controller.onCancel = () {
- subscription?.cancel();
- subscription = null;
- };
- };
- return controller.stream;
- }
-}
diff --git a/stream_transform/pubspec.yaml b/stream_transform/pubspec.yaml
index 9e263e2..c336b81 100644
--- a/stream_transform/pubspec.yaml
+++ b/stream_transform/pubspec.yaml
@@ -1,12 +1,12 @@
name: stream_transform
description: A collection of utilities to transform and manipulate streams.
-author: Dart Team <misc@dartlang.org>
homepage: https://www.github.com/dart-lang/stream_transform
-version: 1.1.0
+version: 1.2.0
environment:
sdk: ">=2.6.0 <3.0.0"
dev_dependencies:
+ async: ^2.0.0
pedantic: ^1.5.0
test: ^1.0.0
diff --git a/sync_http/BUILD.gn b/sync_http/BUILD.gn
index ebe62d4..a0c7317 100644
--- a/sync_http/BUILD.gn
+++ b/sync_http/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for sync_http-0.1.4
+# This file is generated by importer.py for sync_http-0.2.0
import("//build/dart/dart_library.gni")
diff --git a/sync_http/CHANGELOG.md b/sync_http/CHANGELOG.md
index 67c7d12..840953a 100644
--- a/sync_http/CHANGELOG.md
+++ b/sync_http/CHANGELOG.md
@@ -1,3 +1,11 @@
+## v0.2.0
+
+* Preparation for [HttpHeaders change]. Update signature of `add()`
+ and `set()` to match new signature of `HttpHeaders`. The
+ parameter is not yet forwarded and will not behave as expected.
+
+ [HttpHeaders change]: https://github.com/dart-lang/sdk/issues/39657
+
## v0.1.4
* Fixed issue where query parameters were not being sent as part of requests.
diff --git a/sync_http/codereview.settings b/sync_http/codereview.settings
deleted file mode 100644
index 181f5e6..0000000
--- a/sync_http/codereview.settings
+++ /dev/null
@@ -1,4 +0,0 @@
-# This file is used by gcl to get repository specific information.
-CODE_REVIEW_SERVER: http://codereview.chromium.org
-VIEW_VC: https://github.com/dart-lang/sync_http/commit/
-CC_LIST: reviews@dartlang.org
diff --git a/sync_http/lib/src/sync_http.dart b/sync_http/lib/src/sync_http.dart
index fbc0f10..77464a8 100644
--- a/sync_http/lib/src/sync_http.dart
+++ b/sync_http/lib/src/sync_http.dart
@@ -149,7 +149,7 @@
/// Add [value] to the list of values associated with header [name].
@override
- void add(String name, Object value) {
+ void add(String name, Object value, {bool preserveHeaderCase = false}) {
switch (name) {
case HttpHeaders.acceptCharsetHeader:
case HttpHeaders.acceptEncodingHeader:
@@ -222,9 +222,9 @@
/// Replace values associated with key [name] with [value].
@override
- void set(String name, Object value) {
+ void set(String name, Object value, {bool preserveHeaderCase = false}) {
removeAll(name);
- add(name, value);
+ add(name, value, preserveHeaderCase: preserveHeaderCase);
}
/// Returns the values associated with key [name], if it exists, otherwise
@@ -449,7 +449,7 @@
List<String> operator [](String name) => _headers[name];
@override
- void add(String name, Object value) {
+ void add(String name, Object value, {bool preserveHeaderCase = false}) {
throw new UnsupportedError('Response headers are immutable');
}
@@ -586,7 +586,7 @@
}
@override
- void set(String name, Object value) {
+ void set(String name, Object value, {bool preserveHeaderCase = false}) {
throw new UnsupportedError('Response headers are immutable');
}
diff --git a/sync_http/pubspec.yaml b/sync_http/pubspec.yaml
index a590f77..52041ff 100644
--- a/sync_http/pubspec.yaml
+++ b/sync_http/pubspec.yaml
@@ -1,5 +1,5 @@
name: sync_http
-version: 0.1.4
+version: 0.2.0
author: Dart Team <misc@dartlang.org>
description: Synchronous HTTP client for Dart.
homepage: https://github.com/dart-lang/sync_http
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 64a5ad5..bc4297c 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for test-1.9.4
+# This file is generated by importer.py for test-1.14.1
import("//build/dart/dart_library.gni")
@@ -14,6 +14,8 @@
deps = [
"//third_party/dart-pkg/pub/stack_trace",
"//third_party/dart-pkg/pub/pedantic",
+ "//third_party/dart-pkg/pub/package_config",
+ "//third_party/dart-pkg/pub/http",
"//third_party/dart-pkg/pub/shelf_web_socket",
"//third_party/dart-pkg/pub/typed_data",
"//third_party/dart-pkg/pub/shelf",
@@ -25,16 +27,17 @@
"//third_party/dart-pkg/pub/test_api",
"//third_party/dart-pkg/pub/io",
"//third_party/dart-pkg/pub/test_core",
- "//third_party/dart-pkg/pub/path",
+ "//third_party/dart-pkg/pub/coverage",
+ "//third_party/dart-pkg/pub/source_span",
"//third_party/dart-pkg/pub/stream_channel",
"//third_party/dart-pkg/pub/js",
+ "//third_party/dart-pkg/pub/webkit_inspection_protocol",
"//third_party/dart-pkg/pub/pool",
"//third_party/dart-pkg/pub/shelf_static",
- "//third_party/dart-pkg/pub/yaml",
- "//third_party/dart-pkg/pub/source_span",
- "//third_party/dart-pkg/pub/package_resolver",
"//third_party/dart-pkg/pub/web_socket_channel",
+ "//third_party/dart-pkg/pub/yaml",
"//third_party/dart-pkg/pub/boolean_selector",
"//third_party/dart-pkg/pub/async",
+ "//third_party/dart-pkg/pub/path",
]
}
diff --git a/test/CHANGELOG.md b/test/CHANGELOG.md
index 00a3112..ef24aed 100644
--- a/test/CHANGELOG.md
+++ b/test/CHANGELOG.md
@@ -1,3 +1,49 @@
+## 1.14.1
+
+* Allow the latest shelf_packages_handler.
+
+## 1.14.0
+
+* Drop the `package_resolver` dependency for the `package_config` dependency
+ which is lower level.
+
+## 1.13.0
+
+* Enable asserts in code running through `spawnHybrid` APIs.
+* Exit with a non-zero code if no tests were ran, whether due to skips or having
+ no tests defined.
+* Fix the stack trace labels in SDK code for `dart2js` compiled tests.
+* Cancel any StreamQueue that is created as a part of a stream matcher once it
+ is done matching.
+ * This fixes a bug where using a matcher on a custom stream controller and
+ then awaiting the `close()` method on that controller would hang.
+* Avoid causing the test runner to hang if there is a timeout during a
+ `tearDown` callback following a failing test case.
+
+## 1.12.0
+
+* Bump minimum SDK to `2.4.0` for safer usage of for-loop elements.
+* Deprecate `PhantomJS` and provide warning when used. Support for `PhantomJS`
+ will be removed in version `2.0.0`.
+* Support coverage collection for the Chrome platform. See `README.md` for usage
+ details.
+
+## 1.11.1
+
+* Allow `test_api` `0.2.13` to work around a bug in the SDK version `2.3.0`.
+
+## 1.11.0
+
+* Add `file_reporters` configuration option and `--file-reporter` CLI option to
+ allow specifying a separate reporter that writes to a file instead of stdout.
+
+## 1.10.0
+
+* Add `customHtmlTemplateFile` configuration option to allow sharing an
+ html template between tests
+* Depend on the latest `package:test_core`.
+* Depend on the latest `package:test_api`.
+
## 1.9.4
* Extend the timeout for synthetic tests, e.g. `tearDownAll`.
diff --git a/test/README.md b/test/README.md
index 5bd7e1d..63ea8be 100644
--- a/test/README.md
+++ b/test/README.md
@@ -10,6 +10,7 @@
* [Asynchronous Tests](#asynchronous-tests)
* [Stream Matchers](#stream-matchers)
* [Running Tests With Custom HTML](#running-tests-with-custom-html)
+ * [Providing a custom HTML template](#providing-a-custom-html-template)
* [Configuring Tests](#configuring-tests)
* [Skipping Tests](#skipping-tests)
* [Timeouts](#timeouts)
@@ -19,8 +20,8 @@
* [Debugging](#debugging)
* [Browser/VM Hybrid Tests](#browservm-hybrid-tests)
* [Support for Other Packages](#support-for-other-packages)
+ * [`build_runner`](#build_runner)
* [`term_glyph`](#term_glyph)
- * [`barback`](#barback)
* [Further Reading](#further-reading)
## Writing Tests
@@ -32,17 +33,17 @@
[`expect()`]: https://pub.dev/documentation/test_api/latest/test_api/expect.html
```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("String.split() splits the string on the delimiter", () {
- var string = "foo,bar,baz";
- expect(string.split(","), equals(["foo", "bar", "baz"]));
+ test('String.split() splits the string on the delimiter', () {
+ var string = 'foo,bar,baz';
+ expect(string.split(','), equals(['foo', 'bar', 'baz']));
});
- test("String.trim() removes surrounding whitespace", () {
- var string = " foo ";
- expect(string.trim(), equals("foo"));
+ test('String.trim() removes surrounding whitespace', () {
+ var string = ' foo ';
+ expect(string.trim(), equals('foo'));
});
}
```
@@ -53,28 +54,28 @@
[`group()`]: https://pub.dev/documentation/test_api/latest/test_api/group.html
```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- group("String", () {
- test(".split() splits the string on the delimiter", () {
- var string = "foo,bar,baz";
- expect(string.split(","), equals(["foo", "bar", "baz"]));
+ group('String', () {
+ test('.split() splits the string on the delimiter', () {
+ var string = 'foo,bar,baz';
+ expect(string.split(','), equals(['foo', 'bar', 'baz']));
});
- test(".trim() removes surrounding whitespace", () {
- var string = " foo ";
- expect(string.trim(), equals("foo"));
+ test('.trim() removes surrounding whitespace', () {
+ var string = ' foo ';
+ expect(string.trim(), equals('foo'));
});
});
- group("int", () {
- test(".remainder() returns the remainder of division", () {
+ group('int', () {
+ test('.remainder() returns the remainder of division', () {
expect(11.remainder(3), equals(2));
});
- test(".toRadixString() returns a hex string", () {
- expect(11.toRadixString(16), equals("b"));
+ test('.toRadixString() returns a hex string', () {
+ expect(11.toRadixString(16), equals('b'));
});
});
}
@@ -86,14 +87,14 @@
[`matcher`]: https://pub.dev/documentation/matcher/latest/matcher/matcher-library.html
```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test(".split() splits the string on the delimiter", () {
- expect("foo,bar,baz", allOf([
- contains("foo"),
- isNot(startsWith("bar")),
- endsWith("baz")
+ test('.split() splits the string on the delimiter', () {
+ expect('foo,bar,baz', allOf([
+ contains('foo'),
+ isNot(startsWith('bar')),
+ endsWith('baz')
]));
});
}
@@ -105,14 +106,14 @@
fails, to ensure that it has a chance to clean up after itself.
```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
HttpServer server;
Uri url;
setUp(() async {
server = await HttpServer.bind('localhost', 0);
- url = Uri.parse("http://${server.address.host}:${server.port}");
+ url = Uri.parse('http://${server.address.host}:${server.port}');
});
tearDown(() async {
@@ -170,9 +171,22 @@
pub run test --total-shards 3 --shard-index 2 path/to/test.dart
```
+### Shuffling Tests
+Test order can be shuffled with the `--test-randomize-ordering-seed` argument.
+This allows you to shuffle your tests with a specific seed (deterministic) or
+a random seed for each run. For example, consider the following test runs:
+
+```bash
+pub run test --test-randomize-ordering-seed=12345
+pub run test --test-randomize-ordering-seed=random
+```
+
+Setting `--test-randomize-ordering-seed=0` will have the same effect as not
+specifying it at all, meaning the test order will remain as-is.
+
### Collecting Code Coverage
To collect code coverage, you can run tests with the `--coverage <directory>`
-argument. The directory specified can be an absolute or relative path.
+argument. The directory specified can be an absolute or relative path.
If a directory does not exist at the path specified, a directory will be
created. If a directory does exist, files may be overwritten with the latest
coverage data, if they conflict.
@@ -182,7 +196,8 @@
The files can then be formatted using the `package:coverage`
`format_coverage` executable.
-Coverage gathering is currently only implemented for tests run in the Dart VM.
+Coverage gathering is currently only implemented for tests run on the Dart VM or
+Chrome.
### Restricting Tests to Certain Platforms
@@ -194,11 +209,11 @@
`import` declarations:
```dart
-@TestOn("vm")
+@TestOn('vm')
-import "dart:io";
+import 'dart:io';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
// ...
@@ -273,7 +288,7 @@
equivalent to `!windows`.
For example, if you wanted to run a test on every browser but Chrome, you would
-write `@TestOn("browser && !chrome")`.
+write `@TestOn('browser && !chrome')`.
### Running Tests on Node.js
@@ -289,7 +304,7 @@
The test runner looks for an executable named `node` (on Mac OS or Linux) or
`node.exe` (on Windows) on your system path. When compiling Node.js tests, it
passes `-Dnode=true`, so tests can determine whether they're running on Node
-using [`const bool.fromEnvironment("node")`][bool.fromEnvironment]. It also sets
+using [`const bool.fromEnvironment('node')`][bool.fromEnvironment]. It also sets
`--server-mode`, which will tell the compiler that `dart:html` is not available.
[bool.fromEnvironment]: https://api.dart.dev/stable/dart-core/bool/bool.fromEnvironment.html
@@ -303,13 +318,13 @@
won't consider the test finished until the returned `Future` completes.
```dart
-import "dart:async";
+import 'dart:async';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("new Future.value() returns the value", () async {
- var value = await new Future.value(10);
+ test('Future.value() returns the value', () async {
+ var value = await Future.value(10);
expect(value, equals(10));
});
}
@@ -323,13 +338,13 @@
[`completion()`]: https://pub.dev/documentation/test_api/latest/test_api/completion.html
```dart
-import "dart:async";
+import 'dart:async';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("new Future.value() returns the value", () {
- expect(new Future.value(10), completion(equals(10)));
+ test('Future.value() returns the value', () {
+ expect(Future.value(10), completion(equals(10)));
});
}
```
@@ -341,14 +356,14 @@
[`throwsA()`]: https://pub.dev/documentation/test_api/latest/test_api/throwsA.html
```dart
-import "dart:async";
+import 'dart:async';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("new Future.error() throws the error", () {
- expect(new Future.error("oh no"), throwsA(equals("oh no")));
- expect(new Future.error(new StateError("bad state")), throwsStateError);
+ test('Future.error() throws the error', () {
+ expect(Future.error('oh no'), throwsA(equals('oh no')));
+ expect(Future.error(StateError('bad state')), throwsStateError);
});
}
```
@@ -359,13 +374,13 @@
from finishing until the function is called the requisite number of times.
```dart
-import "dart:async";
+import 'dart:async';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("Stream.fromIterable() emits the values in the iterable", () {
- var stream = new Stream.fromIterable([1, 2, 3]);
+ test('Stream.fromIterable() emits the values in the iterable', () {
+ var stream = Stream.fromIterable([1, 2, 3]);
stream.listen(expectAsync1((number) {
expect(number, inInclusiveRange(1, 3));
@@ -386,29 +401,29 @@
[Stream]: https://api.dart.dev/stable/dart-async/Stream-class.html
```dart
-import "dart:async";
+import 'dart:async';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("process emits status messages", () {
+ test('process emits status messages', () {
// Dummy data to mimic something that might be emitted by a process.
- var stdoutLines = new Stream.fromIterable([
- "Ready.",
- "Loading took 150ms.",
- "Succeeded!"
+ var stdoutLines = Stream.fromIterable([
+ 'Ready.',
+ 'Loading took 150ms.',
+ 'Succeeded!'
]);
expect(stdoutLines, emitsInOrder([
// Values match individual events.
- "Ready.",
+ 'Ready.',
// Matchers also run against individual events.
- startsWith("Loading took"),
+ startsWith('Loading took'),
// Stream matchers can be nested. This asserts that one of two events are
// emitted after the "Loading took" line.
- emitsAnyOf(["Succeeded!", "Failed!"]),
+ emitsAnyOf(['Succeeded!', 'Failed!']),
// By default, more events are allowed after the matcher finishes
// matching. This asserts instead that the stream emits a done event and
@@ -429,29 +444,29 @@
[`StreamQueue`]: https://pub.dev/documentation/async/latest/async/StreamQueue-class.html
```dart
-import "dart:async";
+import 'dart:async';
-import "package:async/async.dart";
-import "package:test/test.dart";
+import 'package:async/async.dart';
+import 'package:test/test.dart';
void main() {
- test("process emits a WebSocket URL", () async {
+ test('process emits a WebSocket URL', () async {
// Wrap the Stream in a StreamQueue so that we can request events.
- var stdout = new StreamQueue(new Stream.fromIterable([
- "WebSocket URL:",
- "ws://localhost:1234/",
- "Waiting for connection..."
+ var stdout = StreamQueue(Stream.fromIterable([
+ 'WebSocket URL:',
+ 'ws://localhost:1234/',
+ 'Waiting for connection...'
]));
// Ignore lines from the process until it's about to emit the URL.
- await expect(stdout, emitsThrough("WebSocket URL:"));
+ await expectLater(stdout, emitsThrough('WebSocket URL:'));
// Parse the next line as a URL.
var url = Uri.parse(await stdout.next);
expect(url.host, equals('localhost'));
// You can match against the same StreamQueue multiple times.
- await expect(stdout, emits("Waiting for connection..."));
+ await expectLater(stdout, emits('Waiting for connection...'));
});
}
```
@@ -473,8 +488,7 @@
* [`neverEmits()`] matches a stream that finishes *without* matching an inner
matcher.
-You can also define your own custom stream matchers by calling
-[`new StreamMatcher()`].
+You can also define your own custom stream matchers with [`StreamMatcher()`].
[`emits()`]: https://pub.dev/documentation/test_api/latest/test_api/emits.html
[`emitsError()`]: https://pub.dev/documentation/test_api/latest/test_api/emitsError.html
@@ -485,7 +499,7 @@
[`emitsInOrder()`]: https://pub.dev/documentation/test_api/latest/test_api/emitsInOrder.html
[`emitsInAnyOrder()`]: https://pub.dev/documentation/test_api/latest/test_api/emitsInAnyOrder.html
[`neverEmits()`]: https://pub.dev/documentation/test_api/latest/test_api/neverEmits.html
-[`new StreamMatcher()`]: https://pub.dev/documentation/test_api/latest/test_api/StreamMatcher-class.html
+[`StreamMatcher()`]: https://pub.dev/documentation/test_api/latest/test_api/StreamMatcher-class.html
## Running Tests With Custom HTML
@@ -493,7 +507,9 @@
tests. However, tests that need custom HTML can create their own files. These
files have three requirements:
-* They must have the same name as the test, with `.dart` replaced by `.html`.
+* They must have the same name as the test, with `.dart` replaced by `.html`. You can also
+ provide a configuration path to an html file if you want it to be reused across all tests.
+ See [Providing a custom HTML template](#providing-a-custom-html-template) below.
* They must contain a `link` tag with `rel="x-dart-test"` and an `href`
attribute pointing to the test script.
@@ -518,6 +534,40 @@
</html>
```
+### Providing a custom HTML template
+
+If you want to share the same HTML file across all tests, you can provide a
+`custom-html-template-path` configuration option to your configuration file.
+This file should follow the rules above, except that instead of the link tag
+add exactly one `{{testScript}}` in the place where you want the template processor to insert it.
+
+You can also optionally use any number of `{{testName}}` placeholders which will be replaced by the test filename.
+
+The template can't be named like any test file, as that would clash with using the
+custom HTML mechanics. In such a case, an error will be thrown.
+
+For example:
+
+```yaml
+custom-html-template-path: html_template.html.tpl
+```
+
+```html
+<!doctype html>
+<!-- html_template.html.tpl -->
+<html>
+ <head>
+ <title>{{testName}} Test</title>
+ {{testScript}}
+ <script src="packages/test/dart.js"></script>
+ </head>
+ <body>
+ // ...
+ </body>
+</html>
+```
+
+
## Configuring Tests
### Skipping Tests
@@ -534,9 +584,9 @@
To skip a test suite, put a `@Skip` annotation at the top of the file:
```dart
-@Skip("currently failing (see issue 1234)")
+@Skip('currently failing (see issue 1234)')
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
// ...
@@ -550,16 +600,16 @@
can be either `true` or a String describing why the test is skipped. For example:
```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- group("complicated algorithm tests", () {
+ group('complicated algorithm tests', () {
// ...
}, skip: "the algorithm isn't quite right");
- test("error-checking test", () {
+ test('error-checking test', () {
// ...
- }, skip: "TODO: add error-checking.");
+ }, skip: 'TODO: add error-checking.');
}
```
@@ -572,7 +622,7 @@
```dart
@Timeout(const Duration(seconds: 45))
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
// ...
@@ -587,16 +637,16 @@
parameter takes a `Timeout` object just like the annotation. For example:
```dart
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- group("slow tests", () {
+ group('slow tests', () {
// ...
- test("even slower test", () {
+ test('even slower test', () {
// ...
- }, timeout: new Timeout.factor(2))
- }, timeout: new Timeout(new Duration(minutes: 1)));
+ }, timeout: Timeout.factor(2))
+ }, timeout: Timeout(Duration(minutes: 1)));
}
```
@@ -615,16 +665,16 @@
```dart
@OnPlatform(const {
// Give Windows some extra wiggle-room before timing out.
- "windows": const Timeout.factor(2)
+ 'windows': const Timeout.factor(2)
})
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("do a thing", () {
+ test('do a thing', () {
// ...
}, onPlatform: {
- "safari": new Skip("Safari is currently broken (see #1234)")
+ 'safari': Skip('Safari is currently broken (see #1234)')
});
}
```
@@ -655,18 +705,18 @@
parameter to `test()` and `group()`. For example:
```dart
-@Tags(const ["browser"])
+@Tags(const ['browser'])
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("successfully launches Chrome", () {
+ test('successfully launches Chrome', () {
// ...
- }, tags: "chrome");
+ }, tags: 'chrome');
- test("launches two browsers at once", () {
+ test('launches two browsers at once', () {
// ...
- }, tags: ["chrome", "firefox"]);
+ }, tags: ['chrome', 'firefox']);
}
```
@@ -716,7 +766,7 @@
Tests can be debugged interactively using platforms' built-in development tools.
Tests running on browsers can use those browsers' development consoles to inspect
-the document, set breakpoints, and step through code. Those running on the Dart
+the document, set breakpoints, and step through code. Those running on the Dart
VM use [the Dart Observatory][observatory]'s .
[observatory]: https://dart-lang.github.io/observatory/
@@ -763,9 +813,9 @@
// The library loaded by spawnHybridUri() can import any packages that your
// package depends on, including those that only work on the VM.
-import "package:shelf/shelf_io.dart" as io;
-import "package:shelf_web_socket/shelf_web_socket.dart";
-import "package:stream_channel/stream_channel.dart";
+import 'package:shelf/shelf_io.dart' as io;
+import 'package:shelf_web_socket/shelf_web_socket.dart';
+import 'package:stream_channel/stream_channel.dart';
// Once the hybrid isolate starts, it will call the special function
// hybridMain() with a StreamChannel that's connected to the channel
@@ -773,7 +823,7 @@
hybridMain(StreamChannel channel) async {
// Start a WebSocket server that just sends "hello!" to its clients.
var server = await io.serve(webSocketHandler((webSocket) {
- webSocket.sink.add("hello!");
+ webSocket.sink.add('hello!');
}), 'localhost', 0);
// Send the port number of the WebSocket server to the browser test, so
@@ -784,24 +834,24 @@
// ## test/web_socket_test.dart
-@TestOn("browser")
+@TestOn('browser')
-import "dart:html";
+import 'dart:html';
-import "package:test/test.dart";
+import 'package:test/test.dart';
void main() {
- test("connects to a server-side WebSocket", () async {
+ test('connects to a server-side WebSocket', () async {
// Each spawnHybrid function returns a StreamChannel that communicates with
// the hybrid isolate. You can close this channel to kill the isolate.
- var channel = spawnHybridUri("web_socket_server.dart");
+ var channel = spawnHybridUri('web_socket_server.dart');
// Get the port for the WebSocket server from the hybrid isolate.
var port = await channel.stream.first;
- var socket = new WebSocket('ws://localhost:$port');
+ var socket = WebSocket('ws://localhost:$port');
var message = await socket.onMessage.first;
- expect(message.data, equals("hello!"));
+ expect(message.data, equals('hello!'));
});
}
```
diff --git a/test/doc/configuration.md b/test/doc/configuration.md
index 25514de..7a7cabb 100644
--- a/test/doc/configuration.md
+++ b/test/doc/configuration.md
@@ -47,6 +47,7 @@
* [`pub_serve`](#pub_serve)
* [`reporter`](#reporter)
* [`fold_stack_frames`](#fold_stack_frames)
+ * [`custom_html_template_path`](#custom_html_template_path)
* [Configuring Tags](#configuring-tags)
* [`tags`](#tags)
* [`add_tags`](#add_tags)
@@ -435,6 +436,19 @@
This field is not supported in the
[global configuration file](#global-configuration).
+### `file_reporters`
+
+This field specifies additional reporters to use that will write their output to
+a file rather than stdout. It should be a map of reporter names to filepaths.
+
+```yaml
+file_reporters:
+ json: reports/tests.json
+```
+
+This field is not supported in the
+[global configuration file](#global-configuration).
+
### `fold_stack_frames`
This field controls which packages' stack frames will be folded away
@@ -463,6 +477,11 @@
test/sample_test.dart 5:27 main.<fn>
```
+### `custom_html_template_path`
+
+This field specifies the path of the HTML template file to be used for tests run in an HTML environment.
+Any HTML file that is named the same as the test and in the same directory will take precedence over the template.
+For more information about the usage of this option see [Providing a custom HTML template](https://github.com/dart-lang/test/blob/master/README.md#providing-a-custom-html-template)
## Configuring Tags
diff --git a/test/doc/json_reporter.md b/test/doc/json_reporter.md
index 669eebe..50348e7 100644
--- a/test/doc/json_reporter.md
+++ b/test/doc/json_reporter.md
@@ -19,6 +19,11 @@
pub run test --reporter json <path-to-test-file>
+You may also use the `--file-reporter` option to enable the JSON reporter such
+that it writes to a file instead of stdout.
+
+ pub run test --file-reporter json:reports/tests.json <path-to-test-file>
+
The JSON stream will be emitted via standard output. It will be a stream of JSON
objects, separated by newlines.
diff --git a/test/doc/package_config.md b/test/doc/package_config.md
index 25514de..7a7cabb 100644
--- a/test/doc/package_config.md
+++ b/test/doc/package_config.md
@@ -47,6 +47,7 @@
* [`pub_serve`](#pub_serve)
* [`reporter`](#reporter)
* [`fold_stack_frames`](#fold_stack_frames)
+ * [`custom_html_template_path`](#custom_html_template_path)
* [Configuring Tags](#configuring-tags)
* [`tags`](#tags)
* [`add_tags`](#add_tags)
@@ -435,6 +436,19 @@
This field is not supported in the
[global configuration file](#global-configuration).
+### `file_reporters`
+
+This field specifies additional reporters to use that will write their output to
+a file rather than stdout. It should be a map of reporter names to filepaths.
+
+```yaml
+file_reporters:
+ json: reports/tests.json
+```
+
+This field is not supported in the
+[global configuration file](#global-configuration).
+
### `fold_stack_frames`
This field controls which packages' stack frames will be folded away
@@ -463,6 +477,11 @@
test/sample_test.dart 5:27 main.<fn>
```
+### `custom_html_template_path`
+
+This field specifies the path of the HTML template file to be used for tests run in an HTML environment.
+Any HTML file that is named the same as the test and in the same directory will take precedence over the template.
+For more information about the usage of this option see [Providing a custom HTML template](https://github.com/dart-lang/test/blob/master/README.md#providing-a-custom-html-template)
## Configuring Tags
diff --git a/test/lib/src/bootstrap/browser.dart b/test/lib/src/bootstrap/browser.dart
index 2a7e730..171840e 100644
--- a/test/lib/src/bootstrap/browser.dart
+++ b/test/lib/src/bootstrap/browser.dart
@@ -8,11 +8,11 @@
import '../runner/browser/post_message_channel.dart';
/// Bootstraps a browser test to communicate with the test runner.
-void internalBootstrapBrowserTest(Function getMain()) {
+void internalBootstrapBrowserTest(Function Function() getMain) {
var channel =
serializeSuite(getMain, hidePrints: false, beforeLoad: () async {
var serialized =
- await suiteChannel("test.browser.mapper").stream.first as Map;
+ await suiteChannel('test.browser.mapper').stream.first as Map;
if (serialized == null) return;
setStackTraceMapper(JSStackTraceMapper.deserialize(serialized));
});
diff --git a/test/lib/src/bootstrap/node.dart b/test/lib/src/bootstrap/node.dart
index e1fe100..ca002ba 100644
--- a/test/lib/src/bootstrap/node.dart
+++ b/test/lib/src/bootstrap/node.dart
@@ -8,9 +8,9 @@
import 'package:test_core/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
/// Bootstraps a browser test to communicate with the test runner.
-void internalBootstrapNodeTest(Function getMain()) {
+void internalBootstrapNodeTest(Function Function() getMain) {
var channel = serializeSuite(getMain, beforeLoad: () async {
- var serialized = await suiteChannel("test.node.mapper").stream.first;
+ var serialized = await suiteChannel('test.node.mapper').stream.first;
if (serialized == null || serialized is! Map) return;
setStackTraceMapper(JSStackTraceMapper.deserialize(serialized as Map));
});
diff --git a/test/lib/src/executable.dart b/test/lib/src/executable.dart
index e8313f8..75b2d58 100644
--- a/test/lib/src/executable.dart
+++ b/test/lib/src/executable.dart
@@ -9,7 +9,7 @@
import 'runner/node/platform.dart';
import 'runner/browser/platform.dart';
-main(List<String> args) async {
+void main(List<String> args) async {
registerPlatformPlugin([Runtime.nodeJS], () => NodePlatform());
registerPlatformPlugin([
Runtime.chrome,
diff --git a/test/lib/src/runner/browser/browser.dart b/test/lib/src/runner/browser/browser.dart
index db7e7ec..fa816db 100644
--- a/test/lib/src/runner/browser/browser.dart
+++ b/test/lib/src/runner/browser/browser.dart
@@ -6,7 +6,6 @@
import 'dart:convert';
import 'dart:io';
-import 'package:pedantic/pedantic.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:typed_data/typed_data.dart';
@@ -61,7 +60,7 @@
/// which asynchronously returns the browser process. Any errors in
/// [startBrowser] (even those raised asynchronously after it returns) are
/// piped to [onExit] and will cause the browser to be killed.
- Browser(Future<Process> startBrowser()) {
+ Browser(Future<Process> Function() startBrowser) {
// Don't return a Future here because there's no need for the caller to wait
// for the process to actually start. They should just wait for the HTTP
// request instead.
@@ -70,7 +69,7 @@
_processCompleter.complete(process);
var output = Uint8Buffer();
- drainOutput(Stream<List<int>> stream) {
+ void drainOutput(Stream<List<int>> stream) {
try {
_ioSubscriptions
.add(stream.listen(output.addAll, cancelOnError: true));
@@ -99,9 +98,9 @@
if (!_closed && exitCode != 0) {
var outputString = utf8.decode(output);
- var message = "$name failed with exit code $exitCode.";
+ var message = '$name failed with exit code $exitCode.';
if (outputString.isNotEmpty) {
- message += "\nStandard output:\n$outputString";
+ message += '\nStandard output:\n$outputString';
}
throw ApplicationException(message);
@@ -115,11 +114,11 @@
// Make sure the process dies even if the error wasn't fatal.
_process.then((process) => process.kill());
- if (stackTrace == null) stackTrace = Trace.current();
+ stackTrace ??= Trace.current();
if (_onExitCompleter.isCompleted) return;
_onExitCompleter.completeError(
ApplicationException(
- "Failed to run $name: ${getErrorMessage(error)}."),
+ 'Failed to run $name: ${getErrorMessage(error)}.'),
stackTrace);
});
}
diff --git a/test/lib/src/runner/browser/browser_manager.dart b/test/lib/src/runner/browser/browser_manager.dart
index 91ed9e6..2339908 100644
--- a/test/lib/src/runner/browser/browser_manager.dart
+++ b/test/lib/src/runner/browser/browser_manager.dart
@@ -8,17 +8,15 @@
import 'package:async/async.dart';
import 'package:pool/pool.dart';
import 'package:stream_channel/stream_channel.dart';
-import 'package:web_socket_channel/web_socket_channel.dart';
-
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/environment.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
-
import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/environment.dart'; // ignore: implementation_imports
import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
+import 'package:web_socket_channel/web_socket_channel.dart';
import '../executable_settings.dart';
import 'browser.dart';
@@ -80,7 +78,7 @@
///
/// These are used to mark suites as debugging or not based on the browser's
/// pings.
- final _controllers = Set<RunnerSuiteController>();
+ final _controllers = <RunnerSuiteController>{};
// A timer that's reset whenever we receive a message from the browser.
//
@@ -109,7 +107,7 @@
// TODO(nweiz): Gracefully handle the browser being killed before the
// tests complete.
browser.onExit.then((_) {
- throw ApplicationException("${runtime.name} exited before connecting.");
+ throw ApplicationException('${runtime.name} exited before connecting.');
}).catchError((error, StackTrace stackTrace) {
if (completer.isCompleted) return;
completer.completeError(error, stackTrace);
@@ -127,7 +125,7 @@
return completer.future.timeout(Duration(seconds: 30), onTimeout: () {
browser.close();
throw ApplicationException(
- "Timed out waiting for ${runtime.name} to connect.");
+ 'Timed out waiting for ${runtime.name} to connect.');
});
}
@@ -149,7 +147,7 @@
case Runtime.internetExplorer:
return InternetExplorer(url, settings: settings);
default:
- throw ArgumentError("$browser is not a browser.");
+ throw ArgumentError('$browser is not a browser.');
}
}
@@ -207,16 +205,16 @@
{StackTraceMapper mapper}) async {
url = url.replace(
fragment: Uri.encodeFull(jsonEncode({
- "metadata": suiteConfig.metadata.serialize(),
- "browser": _runtime.identifier
+ 'metadata': suiteConfig.metadata.serialize(),
+ 'browser': _runtime.identifier
})));
var suiteID = _suiteID++;
RunnerSuiteController controller;
- closeIframe() {
+ void closeIframe() {
if (_closed) return;
_controllers.remove(controller);
- _channel.sink.add({"command": "closeSuite", "id": suiteID});
+ _channel.sink.add({'command': 'closeSuite', 'id': suiteID});
}
// The virtual channel will be closed when the suite is closed, in which
@@ -231,17 +229,26 @@
return await _pool.withResource<RunnerSuite>(() async {
_channel.sink.add({
- "command": "loadSuite",
- "url": url.toString(),
- "id": suiteID,
- "channel": suiteChannelID
+ 'command': 'loadSuite',
+ 'url': url.toString(),
+ 'id': suiteID,
+ 'channel': suiteChannelID
});
try {
- controller = deserializeSuite(path, currentPlatform(_runtime),
- suiteConfig, await _environment, suiteChannel, message);
+ controller = deserializeSuite(
+ path,
+ currentPlatform(_runtime),
+ suiteConfig,
+ await _environment,
+ suiteChannel,
+ message, gatherCoverage: () async {
+ var browser = _browser;
+ if (browser is Chrome) return browser.gatherCoverage();
+ return {};
+ });
- controller.channel("test.browser.mapper").sink.add(mapper?.serialize());
+ controller.channel('test.browser.mapper').sink.add(mapper?.serialize());
_controllers.add(controller);
return await controller.suite;
@@ -257,7 +264,7 @@
if (_pauseCompleter != null) return _pauseCompleter.operation;
_pauseCompleter = CancelableCompleter(onCancel: () {
- _channel.sink.add({"command": "resume"});
+ _channel.sink.add({'command': 'resume'});
_pauseCompleter = null;
});
@@ -265,22 +272,22 @@
_pauseCompleter = null;
});
- _channel.sink.add({"command": "displayPause"});
+ _channel.sink.add({'command': 'displayPause'});
return _pauseCompleter.operation;
}
/// The callback for handling messages received from the host page.
void _onMessage(Map message) {
- switch (message["command"] as String) {
- case "ping":
+ switch (message['command'] as String) {
+ case 'ping':
break;
- case "restart":
+ case 'restart':
_onRestartController.add(null);
break;
- case "resume":
+ case 'resume':
if (_pauseCompleter != null) _pauseCompleter.complete();
break;
@@ -310,16 +317,21 @@
class _BrowserEnvironment implements Environment {
final BrowserManager _manager;
+ @override
final supportsDebugging = true;
+ @override
final Uri observatoryUrl;
+ @override
final Uri remoteDebuggerUrl;
+ @override
final Stream onRestart;
_BrowserEnvironment(this._manager, this.observatoryUrl,
this.remoteDebuggerUrl, this.onRestart);
+ @override
CancelableOperation displayPause() => _manager._displayPause();
}
diff --git a/test/lib/src/runner/browser/chrome.dart b/test/lib/src/runner/browser/chrome.dart
index 81c5861..fbecad2 100644
--- a/test/lib/src/runner/browser/chrome.dart
+++ b/test/lib/src/runner/browser/chrome.dart
@@ -3,17 +3,21 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
import 'dart:io';
+import 'package:coverage/coverage.dart';
+import 'package:http/http.dart' as http;
+import 'package:path/path.dart' as p;
import 'package:pedantic/pedantic.dart';
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
import '../executable_settings.dart';
import 'browser.dart';
import 'default_settings.dart';
-// TODO(nweiz): move this into its own package?
/// A class for running an instance of Chrome.
///
/// Most of the communication with the browser is expected to happen via HTTP,
@@ -22,38 +26,45 @@
///
/// Any errors starting or running the process are reported through [onExit].
class Chrome extends Browser {
- final name = "Chrome";
+ @override
+ final name = 'Chrome';
+ @override
final Future<Uri> remoteDebuggerUrl;
+ final Future<WipConnection> _tabConnection;
+ final Map<String, String> _idToUrl;
+
/// Starts a new instance of Chrome open to the given [url], which may be a
/// [Uri] or a [String].
factory Chrome(Uri url, {ExecutableSettings settings, bool debug = false}) {
settings ??= defaultSettings[Runtime.chrome];
var remoteDebuggerCompleter = Completer<Uri>.sync();
+ var connectionCompleter = Completer<WipConnection>();
+ var idToUrl = <String, String>{};
return Chrome._(() async {
var tryPort = ([int port]) async {
var dir = createTempDir();
var args = [
- "--user-data-dir=$dir",
+ '--user-data-dir=$dir',
url.toString(),
- "--disable-extensions",
- "--disable-popup-blocking",
- "--bwsi",
- "--no-first-run",
- "--no-default-browser-check",
- "--disable-default-apps",
- "--disable-translate",
- "--disable-dev-shm-usage",
+ '--disable-extensions',
+ '--disable-popup-blocking',
+ '--bwsi',
+ '--no-first-run',
+ '--no-default-browser-check',
+ '--disable-default-apps',
+ '--disable-translate',
+ '--disable-dev-shm-usage',
];
if (!debug && settings.headless) {
args.addAll([
- "--headless",
- "--disable-gpu",
+ '--headless',
+ '--disable-gpu',
// We don't actually connect to the remote debugger, but Chrome will
// close as soon as the page is loaded if we don't turn it on.
- "--remote-debugging-port=0"
+ '--remote-debugging-port=0'
]);
}
@@ -64,13 +75,15 @@
// but without a reliable and fast way to tell if it succeeded that
// doesn't provide us much. It's very unlikely that this port will fail,
// though.
- if (port != null) args.add("--remote-debugging-port=$port");
+ if (port != null) args.add('--remote-debugging-port=$port');
var process = await Process.start(settings.executable, args);
if (port != null) {
remoteDebuggerCompleter.complete(
- getRemoteDebuggerUrl(Uri.parse("http://localhost:$port")));
+ getRemoteDebuggerUrl(Uri.parse('http://localhost:$port')));
+
+ connectionCompleter.complete(_connect(process, port, idToUrl, url));
} else {
remoteDebuggerCompleter.complete(null);
}
@@ -83,9 +96,96 @@
if (!debug) return tryPort();
return getUnusedPort<Process>(tryPort);
- }, remoteDebuggerCompleter.future);
+ }, remoteDebuggerCompleter.future, connectionCompleter.future, idToUrl);
}
- Chrome._(Future<Process> startBrowser(), this.remoteDebuggerUrl)
+ /// Returns a Dart based hit-map containing coverage report, suitable for use
+ /// with `package:coverage`.
+ Future<Map<String, dynamic>> gatherCoverage() async {
+ var tabConnection = await _tabConnection;
+ var response = await tabConnection.debugger.connection
+ .sendCommand('Profiler.takePreciseCoverage', {});
+ var result = response.result['result'];
+ var coverage = await parseChromeCoverage(
+ (result as List).cast(),
+ _sourceProvider,
+ _sourceMapProvider,
+ _sourceUriProvider,
+ );
+ return coverage;
+ }
+
+ Chrome._(Future<Process> Function() startBrowser, this.remoteDebuggerUrl,
+ this._tabConnection, this._idToUrl)
: super(startBrowser);
+
+ Future<Uri> _sourceUriProvider(String sourceUrl, String scriptId) async {
+ var script = _idToUrl[scriptId];
+ if (script == null) return null;
+ var uri = Uri.parse(script);
+ var path = p.join(
+ p.joinAll(uri.pathSegments.sublist(1, uri.pathSegments.length - 1)),
+ sourceUrl);
+ return path.contains('/packages/')
+ ? Uri(scheme: 'package', path: path.split('/packages/').last)
+ : Uri.file(p.absolute(path));
+ }
+
+ Future<String> _sourceMapProvider(String scriptId) async {
+ var script = _idToUrl[scriptId];
+ if (script == null) return null;
+ var mapResponse = await http.get('$script.map');
+ if (mapResponse.statusCode != HttpStatus.ok) return null;
+ return mapResponse.body;
+ }
+
+ Future<String> _sourceProvider(String scriptId) async {
+ var script = _idToUrl[scriptId];
+ if (script == null) return null;
+ var scriptResponse = await http.get(script);
+ if (scriptResponse.statusCode != HttpStatus.ok) return null;
+ return scriptResponse.body;
+ }
+}
+
+Future<WipConnection> _connect(
+ Process process, int port, Map<String, String> idToUrl, Uri url) async {
+ // Wait for Chrome to be in a ready state.
+ await process.stderr
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .firstWhere((line) => line.startsWith('DevTools listening'));
+
+ var chromeConnection = ChromeConnection('localhost', port);
+ ChromeTab tab;
+ var attempt = 0;
+ while (tab == null) {
+ attempt++;
+ var tabs = await chromeConnection.getTabs();
+ tab =
+ tabs.firstWhere((tab) => tab.url == url.toString(), orElse: () => null);
+ if (tab == null) {
+ await Future.delayed(Duration(milliseconds: 100));
+ if (attempt > 5) {
+ throw StateError('Could not connect to test tab with url: $url');
+ }
+ }
+ }
+ var tabConnection = await tab.connect();
+
+ // Enable debugging.
+ await tabConnection.debugger.enable();
+
+ // Coverage reports are in terms of scriptIds so keep note of URLs.
+ tabConnection.debugger.onScriptParsed.listen((data) {
+ var script = data.script;
+ if (script.url.isNotEmpty) idToUrl[script.scriptId] = script.url;
+ });
+
+ // Enable coverage collection.
+ await tabConnection.debugger.connection.sendCommand('Profiler.enable', {});
+ await tabConnection.debugger.connection.sendCommand(
+ 'Profiler.startPreciseCoverage', {'detailed': true, 'callCount': false});
+
+ return tabConnection;
}
diff --git a/test/lib/src/runner/browser/firefox.dart b/test/lib/src/runner/browser/firefox.dart
index aa51a88..cf0efe6 100644
--- a/test/lib/src/runner/browser/firefox.dart
+++ b/test/lib/src/runner/browser/firefox.dart
@@ -7,7 +7,6 @@
import 'package:path/path.dart' as p;
import 'package:pedantic/pedantic.dart';
-
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
@@ -29,7 +28,8 @@
///
/// Any errors starting or running the process are reported through [onExit].
class Firefox extends Browser {
- final name = "Firefox";
+ @override
+ final name = 'Firefox';
Firefox(url, {ExecutableSettings settings})
: super(() => _startBrowser(url, settings));
@@ -41,11 +41,15 @@
var dir = createTempDir();
File(p.join(dir, 'prefs.js')).writeAsStringSync(_preferences);
- var process = await Process.start(
- settings.executable,
- ["--profile", "$dir", url.toString(), "--no-remote"]
- ..addAll(settings.arguments),
- environment: {"MOZ_CRASHREPORTER_DISABLE": "1"});
+ var process = await Process.start(settings.executable, [
+ '--profile',
+ '$dir',
+ url.toString(),
+ '--no-remote',
+ ...settings.arguments,
+ ], environment: {
+ 'MOZ_CRASHREPORTER_DISABLE': '1'
+ });
unawaited(process.exitCode
.then((_) => Directory(dir).deleteSync(recursive: true)));
diff --git a/test/lib/src/runner/browser/internet_explorer.dart b/test/lib/src/runner/browser/internet_explorer.dart
index 4ddba9e..d79c9e4 100644
--- a/test/lib/src/runner/browser/internet_explorer.dart
+++ b/test/lib/src/runner/browser/internet_explorer.dart
@@ -14,7 +14,8 @@
///
/// Any errors starting or running the process are reported through [onExit].
class InternetExplorer extends Browser {
- final name = "Internet Explorer";
+ @override
+ final name = 'Internet Explorer';
InternetExplorer(url, {ExecutableSettings settings})
: super(() => _startBrowser(url, settings));
@@ -24,7 +25,10 @@
static Future<Process> _startBrowser(url, ExecutableSettings settings) {
settings ??= defaultSettings[Runtime.internetExplorer];
- return Process.start(settings.executable,
- ['-extoff', url.toString()]..addAll(settings.arguments));
+ return Process.start(settings.executable, [
+ '-extoff',
+ '$url',
+ ...settings.arguments,
+ ]);
}
}
diff --git a/test/lib/src/runner/browser/phantom_js.dart b/test/lib/src/runner/browser/phantom_js.dart
index 75e1d48..d2adbcd 100644
--- a/test/lib/src/runner/browser/phantom_js.dart
+++ b/test/lib/src/runner/browser/phantom_js.dart
@@ -7,12 +7,10 @@
import 'package:path/path.dart' as p;
import 'package:pedantic/pedantic.dart';
-
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
-
+import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/exit_codes.dart' // ignore: implementation_imports
as exit_codes;
-import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
import '../executable_settings.dart';
@@ -20,7 +18,7 @@
import 'default_settings.dart';
/// The PhantomJS script that opens the host page.
-final _script = """
+final _script = '''
var system = require('system');
var page = require('webpage').create();
@@ -36,14 +34,16 @@
page.open(system.args[1], function(status) {
if (status !== "success") phantom.exit(1);
});
-""";
+''';
/// A class for running an instance of PhantomJS.
///
/// Any errors starting or running the process are reported through [onExit].
class PhantomJS extends Browser {
- final name = "PhantomJS";
+ @override
+ final name = 'PhantomJS';
+ @override
final Future<Uri> remoteDebuggerUrl;
factory PhantomJS(url, {ExecutableSettings settings, bool debug = false}) {
@@ -51,7 +51,7 @@
var remoteDebuggerCompleter = Completer<Uri>.sync();
return PhantomJS._(() async {
var dir = createTempDir();
- var script = p.join(dir, "script.js");
+ var script = p.join(dir, 'script.js');
File(script).writeAsStringSync(_script);
var port = debug ? await getUnsafeUnusedPort() : null;
@@ -59,7 +59,7 @@
var args = settings.arguments.toList();
if (debug) {
args.addAll(
- ["--remote-debugger-port=$port", "--remote-debugger-autorun=yes"]);
+ ['--remote-debugger-port=$port', '--remote-debugger-autorun=yes']);
}
args.addAll([script, url.toString()]);
var process = await Process.start(settings.executable, args);
@@ -73,13 +73,13 @@
if (exitCode == exit_codes.protocol) {
throw ApplicationException(
- "Only PhantomJS version 2.0.0 or greater is supported");
+ 'Only PhantomJS version 2.0.0 or greater is supported');
}
}));
if (port != null) {
remoteDebuggerCompleter.complete(Uri.parse(
- "http://localhost:$port/webkit/inspector/inspector.html?page=2"));
+ 'http://localhost:$port/webkit/inspector/inspector.html?page=2'));
} else {
remoteDebuggerCompleter.complete(null);
}
@@ -88,6 +88,6 @@
}, remoteDebuggerCompleter.future);
}
- PhantomJS._(Future<Process> startBrowser(), this.remoteDebuggerUrl)
+ PhantomJS._(Future<Process> Function() startBrowser, this.remoteDebuggerUrl)
: super(startBrowser);
}
diff --git a/test/lib/src/runner/browser/platform.dart b/test/lib/src/runner/browser/platform.dart
index 1b67088..75c8eb0 100644
--- a/test/lib/src/runner/browser/platform.dart
+++ b/test/lib/src/runner/browser/platform.dart
@@ -9,7 +9,6 @@
import 'package:async/async.dart';
import 'package:http_multi_server/http_multi_server.dart';
-import 'package:package_resolver/package_resolver.dart';
import 'package:path/path.dart' as p;
import 'package:pool/pool.dart';
import 'package:shelf/shelf.dart' as shelf;
@@ -37,6 +36,7 @@
import 'package:test_core/src/runner/plugin/customizable_platform.dart'; // ignore: implementation_imports
import '../executable_settings.dart';
+import '../../util/package_map.dart';
import '../../util/path_handler.dart';
import '../../util/one_off_handler.dart';
import 'browser_manager.dart';
@@ -55,6 +55,8 @@
Configuration.current,
p.fromUri(await Isolate.resolvePackageUri(
Uri.parse('package:test/src/runner/browser/static/favicon.ico'))),
+ p.fromUri(await Isolate.resolvePackageUri(Uri.parse(
+ 'package:test/src/runner/browser/static/default.html.tpl'))),
root: root);
}
@@ -71,7 +73,7 @@
final _secret = Uri.encodeComponent(randomBase64(24));
/// The URL for this server.
- Uri get url => _server.url.resolve(_secret + "/");
+ Uri get url => _server.url.resolve(_secret + '/');
/// A [OneOffHandler] for servicing WebSocket connections for
/// [BrowserManager]s.
@@ -121,15 +123,19 @@
///
/// This is used to make sure that a given test suite is only compiled once
/// per run, rather than once per browser per run.
- final _compileFutures = Map<String, Future>();
+ final _compileFutures = <String, Future>{};
/// Mappers for Dartifying stack traces, indexed by test path.
- final _mappers = Map<String, StackTraceMapper>();
+ final _mappers = <String, StackTraceMapper>{};
+
+ /// The default template for html tests.
+ final String _defaultTemplatePath;
BrowserPlatform._(this._server, Configuration config, String faviconPath,
+ this._defaultTemplatePath,
{String root})
: _config = config,
- _root = root == null ? p.current : root,
+ _root = root ?? p.current,
_compiledDir = config.pubServeUrl == null ? createTempDir() : null,
_http = config.pubServeUrl == null ? null : HttpClient() {
var cascade = shelf.Cascade().add(_webSocketHandler.handler);
@@ -160,7 +166,7 @@
shelf.Response _wrapperHandler(shelf.Request request) {
var path = p.fromUri(request.url);
- if (path.endsWith(".browser_test.dart")) {
+ if (path.endsWith('.browser_test.dart')) {
var testPath = p.basename(p.withoutExtension(p.withoutExtension(path)));
return shelf.Response.ok('''
import "package:stream_channel/stream_channel.dart";
@@ -177,36 +183,34 @@
''', headers: {'Content-Type': 'application/dart'});
}
- if (path.endsWith(".html")) {
- var test = p.withoutExtension(path) + ".dart";
-
- // Link to the Dart wrapper on Dartium and the compiled JS version
- // elsewhere.
+ if (path.endsWith('.html')) {
+ var test = p.withoutExtension(path) + '.dart';
var scriptBase = htmlEscape.convert(p.basename(test));
var link = '<link rel="x-dart-test" href="$scriptBase">';
-
- return shelf.Response.ok('''
- <!DOCTYPE html>
- <html>
- <head>
- <title>${htmlEscape.convert(test)} Test</title>
- $link
- <script src="packages/test/dart.js"></script>
- </head>
- </html>
- ''', headers: {'Content-Type': 'text/html'});
+ var testName = htmlEscape.convert(test);
+ var template = _config.customHtmlTemplatePath ?? _defaultTemplatePath;
+ var contents = File(template).readAsStringSync();
+ var processedContents = contents
+ // Checked during loading phase that there is only one {{testScript}} placeholder.
+ .replaceFirst('{{testScript}}', link)
+ .replaceAll('{{testName}}', testName);
+ return shelf.Response.ok(processedContents,
+ headers: {'Content-Type': 'text/html'});
}
return shelf.Response.notFound('Not found.');
}
+ @override
ExecutableSettings parsePlatformSettings(YamlMap settings) =>
ExecutableSettings.parse(settings);
+ @override
ExecutableSettings mergePlatformSettings(
ExecutableSettings settings1, ExecutableSettings settings2) =>
settings1.merge(settings2);
+ @override
void customizePlatform(Runtime runtime, ExecutableSettings settings) {
var oldSettings =
_browserSettings[runtime] ?? _browserSettings[runtime.root];
@@ -218,22 +222,40 @@
///
/// This will start a browser to load the suite if one isn't already running.
/// Throws an [ArgumentError] if `platform.platform` isn't a browser.
+ @override
Future<RunnerSuite> load(String path, SuitePlatform platform,
SuiteConfiguration suiteConfig, Object message) async {
var browser = platform.runtime;
assert(suiteConfig.runtimes.contains(browser.identifier));
if (!browser.isBrowser) {
- throw ArgumentError("$browser is not a browser.");
+ throw ArgumentError('$browser is not a browser.');
}
- var htmlPath = p.withoutExtension(path) + '.html';
- if (File(htmlPath).existsSync() &&
- !File(htmlPath).readAsStringSync().contains('packages/test/dart.js')) {
- throw LoadException(
- path,
- '"${htmlPath}" must contain <script src="packages/test/dart.js">'
- '</script>.');
+ var htmlPathFromTestPath = p.withoutExtension(path) + '.html';
+ if (File(htmlPathFromTestPath).existsSync()) {
+ if (_config.customHtmlTemplatePath != null &&
+ p.basename(htmlPathFromTestPath) ==
+ p.basename(_config.customHtmlTemplatePath)) {
+ throw LoadException(
+ path,
+ 'template file "${p.basename(_config.customHtmlTemplatePath)}" cannot be named '
+ 'like the test file.');
+ }
+ _checkHtmlCorrectness(htmlPathFromTestPath, path);
+ } else if (_config.customHtmlTemplatePath != null) {
+ var htmlTemplatePath = _config.customHtmlTemplatePath;
+ if (!File(htmlTemplatePath).existsSync()) {
+ throw LoadException(
+ path, '"${htmlTemplatePath}" does not exist or is not readable');
+ }
+
+ final templateFileContents = File(htmlTemplatePath).readAsStringSync();
+ if ('{{testScript}}'.allMatches(templateFileContents).length != 1) {
+ throw LoadException(path,
+ '"${htmlTemplatePath}" must contain exactly one {{testScript}} placeholder');
+ }
+ _checkHtmlCorrectness(htmlTemplatePath, path);
}
Uri suiteUrl;
@@ -257,7 +279,7 @@
if (_closed) return null;
suiteUrl = url.resolveUri(
- p.toUri(p.withoutExtension(p.relative(path, from: _root)) + ".html"));
+ p.toUri(p.withoutExtension(p.relative(path, from: _root)) + '.html'));
}
if (_closed) return null;
@@ -272,6 +294,16 @@
return suite;
}
+ void _checkHtmlCorrectness(String htmlPath, String path) {
+ if (!File(htmlPath).readAsStringSync().contains('packages/test/dart.js')) {
+ throw LoadException(
+ path,
+ '"${htmlPath}" must contain <script src="packages/test/dart.js">'
+ '</script>.');
+ }
+ }
+
+ @override
StreamChannel loadChannel(String path, SuitePlatform platform) =>
throw UnimplementedError();
@@ -308,16 +340,17 @@
throw LoadException(
path,
- "Error getting $url: ${response.statusCode} "
- "${response.reasonPhrase}\n"
+ 'Error getting $url: ${response.statusCode} '
+ '${response.reasonPhrase}\n'
'Make sure "pub serve" is serving the test/ directory.');
}
if (getSourceMap && !suiteConfig.jsTrace) {
_mappers[path] = JSStackTraceMapper(await utf8.decodeStream(response),
mapUrl: url,
- packageResolver: SyncPackageResolver.root('packages'),
- sdkRoot: p.toUri('packages/\$sdk'));
+ sdkRoot: p.toUri('packages/\$sdk'),
+ packageMap:
+ (await currentPackageConfig).toPackagesDirPackageMap());
return;
}
@@ -326,13 +359,13 @@
} on IOException catch (error) {
var message = getErrorMessage(error);
if (error is SocketException) {
- message = "${error.osError.message} "
- "(errno ${error.osError.errorCode})";
+ message = '${error.osError.message} '
+ '(errno ${error.osError.errorCode})';
}
throw LoadException(
path,
- "Error getting $url: $message\n"
+ 'Error getting $url: $message\n'
'Make sure "pub serve" is running.');
} finally {
timer.cancel();
@@ -347,7 +380,7 @@
Future _compileSuite(String dartPath, SuiteConfiguration suiteConfig) {
return _compileFutures.putIfAbsent(dartPath, () async {
var dir = Directory(_compiledDir).createTempSync('test_').path;
- var jsPath = p.join(dir, p.basename(dartPath) + ".browser_test.dart.js");
+ var jsPath = p.join(dir, p.basename(dartPath) + '.browser_test.dart.js');
await _compilers.compile('''
import "package:test/src/bootstrap/browser.dart";
@@ -378,8 +411,8 @@
var mapPath = jsPath + '.map';
_mappers[dartPath] = JSStackTraceMapper(File(mapPath).readAsStringSync(),
mapUrl: p.toUri(mapPath),
- packageResolver: await PackageResolver.current.asSync,
- sdkRoot: p.toUri(sdkDir));
+ sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
+ packageMap: (await currentPackageConfig).toPackageMap());
});
}
@@ -393,7 +426,7 @@
var completer = Completer<WebSocketChannel>.sync();
var path = _webSocketHandler.create(webSocketHandler(completer.complete));
var webSocketUrl = url.replace(scheme: 'ws').resolve(path);
- var hostUrl = (_config.pubServeUrl == null ? url : _config.pubServeUrl)
+ var hostUrl = (_config.pubServeUrl ?? url)
.resolve('packages/test/src/runner/browser/static/index.html')
.replace(queryParameters: {
'managerUrl': webSocketUrl.toString(),
@@ -415,6 +448,7 @@
///
/// Note that this doesn't close the server itself. Browser tests can still be
/// loaded, they'll just spawn new browsers.
+ @override
Future closeEphemeral() {
var managers = _browserManagers.values.toList();
_browserManagers.clear();
@@ -429,6 +463,7 @@
///
/// Returns a [Future] that completes once the server is closed and its
/// resources have been fully released.
+ @override
Future close() => _closeMemo.runOnce(() async {
var futures =
_browserManagers.values.map<Future<dynamic>>((future) async {
diff --git a/test/lib/src/runner/browser/post_message_channel.dart b/test/lib/src/runner/browser/post_message_channel.dart
index 71e3dfa..595c2ec 100644
--- a/test/lib/src/runner/browser/post_message_channel.dart
+++ b/test/lib/src/runner/browser/post_message_channel.dart
@@ -12,7 +12,7 @@
import 'package:stream_channel/stream_channel.dart';
// Avoid using this from dart:html to work around dart-lang/sdk#32113.
-@JS("window.parent.postMessage")
+@JS('window.parent.postMessage')
external void _postParentMessage(Object message, String targetOrigin);
/// Constructs a [StreamChannel] wrapping [MessageChannel] communication with
@@ -29,7 +29,7 @@
// very unlikely that a malicious site would care about hacking someone's
// unit tests, let alone be able to find the test server while it's
// running, but it's good practice to check the origin anyway.
- return message.origin == window.location.origin && message.data == "port";
+ return message.origin == window.location.origin && message.data == 'port';
}).then((message) {
var port = message.ports.first;
var portSubscription = port.onMessage.listen((message) {
@@ -37,9 +37,9 @@
});
controller.local.stream.listen((data) {
- port.postMessage({"data": data});
+ port.postMessage({'data': data});
}, onDone: () {
- port.postMessage({"event": "done"});
+ port.postMessage({'event': 'done'});
portSubscription.cancel();
});
});
@@ -47,7 +47,7 @@
// Send a ready message once we're listening so the host knows it's safe to
// start sending events.
// TODO(nweiz): Stop manually adding href here once issue 22554 is fixed.
- _postParentMessage(jsify({"href": window.location.href, "ready": true}),
+ _postParentMessage(jsify({'href': window.location.href, 'ready': true}),
window.location.origin);
return controller.foreign;
diff --git a/test/lib/src/runner/browser/safari.dart b/test/lib/src/runner/browser/safari.dart
index 40faa4f..a47bb09 100644
--- a/test/lib/src/runner/browser/safari.dart
+++ b/test/lib/src/runner/browser/safari.dart
@@ -8,19 +8,19 @@
import 'package:path/path.dart' as p;
import 'package:pedantic/pedantic.dart';
-
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports
+import '../executable_settings.dart';
import 'browser.dart';
import 'default_settings.dart';
-import '../executable_settings.dart';
/// A class for running an instance of Safari.
///
/// Any errors starting or running the process are reported through [onExit].
class Safari extends Browser {
- final name = "Safari";
+ @override
+ final name = 'Safari';
Safari(url, {ExecutableSettings settings})
: super(() => _startBrowser(url, settings));
@@ -36,7 +36,7 @@
// want it to load.
var redirect = p.join(dir, 'redirect.html');
File(redirect).writeAsStringSync(
- "<script>location = " + jsonEncode(url.toString()) + "</script>");
+ '<script>location = ' + jsonEncode(url.toString()) + '</script>');
var process = await Process.start(
settings.executable, settings.arguments.toList()..add(redirect));
diff --git a/test/lib/src/runner/browser/static/default.html.tpl b/test/lib/src/runner/browser/static/default.html.tpl
new file mode 100644
index 0000000..a92f529
--- /dev/null
+++ b/test/lib/src/runner/browser/static/default.html.tpl
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>{{testName}} Test</title>
+ {{testScript}}
+ <script src="packages/test/dart.js"></script>
+ </head>
+</html>
diff --git a/test/lib/src/runner/executable_settings.dart b/test/lib/src/runner/executable_settings.dart
index e793d12..5aa9b8d 100644
--- a/test/lib/src/runner/executable_settings.dart
+++ b/test/lib/src/runner/executable_settings.dart
@@ -72,7 +72,7 @@
/// Parses settings from a user-provided YAML mapping.
factory ExecutableSettings.parse(YamlMap settings) {
List<String> arguments;
- var argumentsNode = settings.nodes["arguments"];
+ var argumentsNode = settings.nodes['arguments'];
if (argumentsNode != null) {
var value = argumentsNode.value;
if (value is String) {
@@ -83,14 +83,14 @@
}
} else {
throw SourceSpanFormatException(
- "Must be a string.", argumentsNode.span);
+ 'Must be a string.', argumentsNode.span);
}
}
String linuxExecutable;
String macOSExecutable;
String windowsExecutable;
- var executableNode = settings.nodes["executable"];
+ var executableNode = settings.nodes['executable'];
if (executableNode != null) {
var value = executableNode.value;
if (value is String) {
@@ -104,25 +104,25 @@
macOSExecutable = value;
windowsExecutable = value;
} else if (executableNode is YamlMap) {
- linuxExecutable = _getExecutable(executableNode.nodes["linux"]);
- macOSExecutable = _getExecutable(executableNode.nodes["mac_os"]);
- windowsExecutable = _getExecutable(executableNode.nodes["windows"],
+ linuxExecutable = _getExecutable(executableNode.nodes['linux']);
+ macOSExecutable = _getExecutable(executableNode.nodes['mac_os']);
+ windowsExecutable = _getExecutable(executableNode.nodes['windows'],
allowRelative: true);
} else {
throw SourceSpanFormatException(
- "Must be a map or a string.", executableNode.span);
+ 'Must be a map or a string.', executableNode.span);
}
}
var headless = true;
- var headlessNode = settings.nodes["headless"];
+ var headlessNode = settings.nodes['headless'];
if (headlessNode != null) {
var value = headlessNode.value;
if (value is bool) {
headless = value;
} else {
throw SourceSpanFormatException(
- "Must be a boolean.", headlessNode.span);
+ 'Must be a boolean.', headlessNode.span);
}
}
@@ -142,7 +142,7 @@
{bool allowRelative = false}) {
if (executableNode == null || executableNode.value == null) return null;
if (executableNode.value is! String) {
- throw SourceSpanFormatException("Must be a string.", executableNode.span);
+ throw SourceSpanFormatException('Must be a string.', executableNode.span);
}
if (!allowRelative) _assertNotRelative(executableNode as YamlScalar);
return executableNode.value as String;
@@ -159,7 +159,7 @@
if (p.posix.basename(executable) == executable) return;
throw SourceSpanFormatException(
- "Linux and Mac OS executables may not be relative paths.",
+ 'Linux and Mac OS executables may not be relative paths.',
executableNode.span);
}
diff --git a/test/lib/src/runner/node/platform.dart b/test/lib/src/runner/node/platform.dart
index 3d5d9ba..bea9aa9 100644
--- a/test/lib/src/runner/node/platform.dart
+++ b/test/lib/src/runner/node/platform.dart
@@ -7,10 +7,9 @@
import 'dart:convert';
import 'package:async/async.dart';
+import 'package:package_config/package_config.dart';
import 'package:multi_server_socket/multi_server_socket.dart';
import 'package:node_preamble/preamble.dart' as preamble;
-import 'package:pedantic/pedantic.dart';
-import 'package:package_resolver/package_resolver.dart';
import 'package:path/path.dart' as p;
import 'package:stream_channel/stream_channel.dart';
import 'package:yaml/yaml.dart';
@@ -33,6 +32,7 @@
import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
import '../executable_settings.dart';
+import '../../util/package_map.dart';
/// A platform that loads tests in Node.js processes.
class NodePlatform extends PlatformPlugin
@@ -41,7 +41,7 @@
final Configuration _config;
/// The [CompilerPool] managing active instances of `dart2js`.
- final _compilers = CompilerPool(["-Dnode=true", "--server-mode"]);
+ final _compilers = CompilerPool(['-Dnode=true', '--server-mode']);
/// The temporary directory in which compiled JS is emitted.
final _compiledDir = createTempDir();
@@ -53,38 +53,43 @@
/// it.
final _settings = {
Runtime.nodeJS: ExecutableSettings(
- linuxExecutable: "node",
- macOSExecutable: "node",
- windowsExecutable: "node.exe")
+ linuxExecutable: 'node',
+ macOSExecutable: 'node',
+ windowsExecutable: 'node.exe')
};
NodePlatform()
: _config = Configuration.current,
_http = Configuration.current.pubServeUrl == null ? null : HttpClient();
+ @override
ExecutableSettings parsePlatformSettings(YamlMap settings) =>
ExecutableSettings.parse(settings);
+ @override
ExecutableSettings mergePlatformSettings(
ExecutableSettings settings1, ExecutableSettings settings2) =>
settings1.merge(settings2);
+ @override
void customizePlatform(Runtime runtime, ExecutableSettings settings) {
var oldSettings = _settings[runtime] ?? _settings[runtime.root];
if (oldSettings != null) settings = oldSettings.merge(settings);
_settings[runtime] = settings;
}
+ @override
StreamChannel loadChannel(String path, SuitePlatform platform) =>
throw UnimplementedError();
+ @override
Future<RunnerSuite> load(String path, SuitePlatform platform,
SuiteConfiguration suiteConfig, Object message) async {
var pair = await _loadChannel(path, platform.runtime, suiteConfig);
var controller = deserializeSuite(
path, platform, suiteConfig, PluginEnvironment(), pair.first, message);
- controller.channel("test.node.mapper").sink.add(pair.last?.serialize());
+ controller.channel('test.node.mapper').sink.add(pair.last?.serialize());
return await controller.suite;
}
@@ -146,7 +151,7 @@
Future<Pair<Process, StackTraceMapper>> _spawnNormalProcess(String testPath,
Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async {
var dir = Directory(_compiledDir).createTempSync('test_').path;
- var jsPath = p.join(dir, p.basename(testPath) + ".node_test.dart.js");
+ var jsPath = p.join(dir, p.basename(testPath) + '.node_test.dart.js');
await _compilers.compile('''
import "package:test/src/bootstrap/node.dart";
@@ -168,8 +173,8 @@
var mapPath = jsPath + '.map';
mapper = JSStackTraceMapper(await File(mapPath).readAsString(),
mapUrl: p.toUri(mapPath),
- packageResolver: await PackageResolver.current.asSync,
- sdkRoot: p.toUri(sdkDir));
+ sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
+ packageMap: (await currentPackageConfig).toPackageMap());
}
return Pair(await _startProcess(runtime, jsPath, socketPort), mapper);
@@ -187,12 +192,11 @@
var jsPath = p.join(precompiledPath, '$testPath.node_test.dart.js');
if (!suiteConfig.jsTrace) {
var mapPath = jsPath + '.map';
- var resolver = await SyncPackageResolver.loadConfig(
- p.toUri(p.join(precompiledPath, '.packages')));
mapper = JSStackTraceMapper(await File(mapPath).readAsString(),
mapUrl: p.toUri(mapPath),
- packageResolver: resolver,
- sdkRoot: p.toUri(sdkDir));
+ sdkRoot: Uri.parse('org-dartlang-sdk:///sdk'),
+ packageMap: (await findPackageConfig(Directory(precompiledPath)))
+ .toPackageMap());
}
return Pair(await _startProcess(runtime, jsPath, socketPort), mapper);
@@ -204,7 +208,7 @@
Future<Pair<Process, StackTraceMapper>> _spawnPubServeProcess(String testPath,
Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async {
var dir = Directory(_compiledDir).createTempSync('test_').path;
- var jsPath = p.join(dir, p.basename(testPath) + ".node_test.dart.js");
+ var jsPath = p.join(dir, p.basename(testPath) + '.node_test.dart.js');
var url = _config.pubServeUrl.resolveUri(
p.toUri(p.relative(testPath, from: 'test') + '.node_test.dart.js'));
@@ -216,8 +220,8 @@
var mapUrl = url.replace(path: url.path + '.map');
mapper = JSStackTraceMapper(await _get(mapUrl, testPath),
mapUrl: mapUrl,
- packageResolver: SyncPackageResolver.root('packages'),
- sdkRoot: p.toUri('packages/\$sdk'));
+ sdkRoot: p.toUri('packages/\$sdk'),
+ packageMap: (await currentPackageConfig).toPackagesDirPackageMap());
}
return Pair(await _startProcess(runtime, jsPath, socketPort), mapper);
@@ -229,8 +233,8 @@
var settings = _settings[runtime];
var nodeModules = p.absolute('node_modules');
- var nodePath = Platform.environment["NODE_PATH"];
- nodePath = nodePath == null ? nodeModules : "$nodePath:$nodeModules";
+ var nodePath = Platform.environment['NODE_PATH'];
+ nodePath = nodePath == null ? nodeModules : '$nodePath:$nodeModules';
try {
return await Process.start(settings.executable,
@@ -239,7 +243,7 @@
} catch (error, stackTrace) {
await Future.error(
ApplicationException(
- "Failed to run ${runtime.name}: ${getErrorMessage(error)}"),
+ 'Failed to run ${runtime.name}: ${getErrorMessage(error)}'),
stackTrace);
return null;
}
@@ -259,8 +263,8 @@
throw LoadException(
suitePath,
- "Error getting $url: ${response.statusCode} "
- "${response.reasonPhrase}\n"
+ 'Error getting $url: ${response.statusCode} '
+ '${response.reasonPhrase}\n'
'Make sure "pub serve" is serving the test/ directory.');
}
@@ -268,17 +272,18 @@
} on IOException catch (error) {
var message = getErrorMessage(error);
if (error is SocketException) {
- message = "${error.osError.message} "
- "(errno ${error.osError.errorCode})";
+ message = '${error.osError.message} '
+ '(errno ${error.osError.errorCode})';
}
throw LoadException(
suitePath,
- "Error getting $url: $message\n"
+ 'Error getting $url: $message\n'
'Make sure "pub serve" is running.');
}
}
+ @override
Future close() => _closeMemo.runOnce(() async {
await _compilers.close();
diff --git a/test/lib/src/runner/node/socket_channel.dart b/test/lib/src/runner/node/socket_channel.dart
index c00a139..0c2036a 100644
--- a/test/lib/src/runner/node/socket_channel.dart
+++ b/test/lib/src/runner/node/socket_channel.dart
@@ -9,10 +9,10 @@
import 'package:stream_channel/stream_channel.dart';
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
-@JS("require")
+@JS('require')
external _Net _require(String module);
-@JS("process.argv")
+@JS('process.argv')
external List<String> get _args;
@JS()
@@ -22,9 +22,9 @@
@JS()
class _Socket {
- external setEncoding(String encoding);
- external on(String event, void callback(String chunk));
- external write(String data);
+ external void setEncoding(String encoding);
+ external void on(String event, void Function(String chunk) callback);
+ external void write(String data);
}
/// Returns a [StreamChannel] of JSON-encodable objects that communicates over a
@@ -32,12 +32,12 @@
StreamChannel<Object> socketChannel() {
var controller =
StreamChannelController<String>(allowForeignErrors: false, sync: true);
- var net = _require("net");
+ var net = _require('net');
var socket = net.connect(int.parse(_args[2]));
- socket.setEncoding("utf8");
+ socket.setEncoding('utf8');
controller.local.stream.listen((chunk) => socket.write(chunk));
- socket.on("data", allowInterop(controller.local.sink.add));
+ socket.on('data', allowInterop(controller.local.sink.add));
return controller.foreign.transform(chunksToLines).transform(jsonDocument);
}
diff --git a/test/lib/src/util/one_off_handler.dart b/test/lib/src/util/one_off_handler.dart
index a317072..7667df3 100644
--- a/test/lib/src/util/one_off_handler.dart
+++ b/test/lib/src/util/one_off_handler.dart
@@ -12,7 +12,7 @@
/// invalid and don't need to have a persistent URL.
class OneOffHandler {
/// A map from URL paths to handlers.
- final _handlers = Map<String, shelf.Handler>();
+ final _handlers = <String, shelf.Handler>{};
/// The counter of handlers that have been activated.
var _counter = 0;
diff --git a/test/lib/src/util/package_map.dart b/test/lib/src/util/package_map.dart
new file mode 100644
index 0000000..948b6a6
--- /dev/null
+++ b/test/lib/src/util/package_map.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, 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:isolate';
+
+import 'package:package_config/package_config.dart';
+
+/// The [PackageConfig] parsed from the current isolates package config file.
+final Future<PackageConfig> currentPackageConfig = () async {
+ return loadPackageConfigUri(await Isolate.packageConfig);
+}();
+
+/// Adds methods to convert to a package map on [PackageConfig].
+extension PackageMap on PackageConfig {
+ /// A package map exactly matching the current package config
+ Map<String, Uri> toPackageMap() =>
+ {for (var package in packages) package.name: package.packageUriRoot};
+
+ /// A package map with all the current packages but where the uris are all
+ /// of the form 'packages/${package.name}'.
+ Map<String, Uri> toPackagesDirPackageMap() => {
+ for (var package in packages)
+ package.name: Uri.parse('packages/${package.name}')
+ };
+}
diff --git a/test/lib/src/util/path_handler.dart b/test/lib/src/util/path_handler.dart
index b5303d5..2fe31c4 100644
--- a/test/lib/src/util/path_handler.dart
+++ b/test/lib/src/util/path_handler.dart
@@ -48,7 +48,7 @@
handlerIndex = i;
}
- if (handler == null) return shelf.Response.notFound("Not found.");
+ if (handler == null) return shelf.Response.notFound('Not found.');
return handler(
request.change(path: p.url.joinAll(components.take(handlerIndex + 1))));
@@ -58,5 +58,5 @@
/// A trie node.
class _Node {
shelf.Handler handler;
- final children = Map<String, _Node>();
+ final children = <String, _Node>{};
}
diff --git a/test/mono_pkg.yaml b/test/mono_pkg.yaml
index e2c26a6..ef401af 100644
--- a/test/mono_pkg.yaml
+++ b/test/mono_pkg.yaml
@@ -9,10 +9,10 @@
dart: dev
- group:
- dartanalyzer: --fatal-warnings .
- dart: 2.2.0
+ dart: 2.7.0
- unit_test:
- - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 0
- - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 1
- - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 2
- - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 3
- - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis --total-shards 5 --shard-index 4
+ - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 0
+ - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 1
+ - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 2
+ - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 3
+ - command: xvfb-run -s "-screen 0 1024x768x24" pub run test --preset travis -x phantomjs --total-shards 5 --shard-index 4
diff --git a/test/pubspec.yaml b/test/pubspec.yaml
index 3693289..26df200 100644
--- a/test/pubspec.yaml
+++ b/test/pubspec.yaml
@@ -1,43 +1,43 @@
name: test
-version: 1.9.4
-author: Dart Team <misc@dartlang.org>
+version: 1.14.1
description: A full featured library for writing and running Dart tests.
homepage: https://github.com/dart-lang/test/blob/master/pkgs/test
environment:
- sdk: '>=2.2.0 <3.0.0'
+ sdk: '>=2.7.0 <3.0.0'
dependencies:
- analyzer: ">=0.36.0 <0.40.0"
+ analyzer: '>=0.36.0 <0.40.0'
async: ^2.0.0
- boolean_selector: ^1.0.0
+ boolean_selector: '>=1.0.0 <3.0.0'
+ coverage: ^0.13.4
+ http: ^0.12.0
http_multi_server: ^2.0.0
io: ^0.3.0
js: ^0.6.0
multi_server_socket: ^1.0.0
node_preamble: ^1.3.0
- package_resolver: ^1.0.0
+ package_config: ^1.9.0
path: ^1.2.0
pedantic: ^1.1.0
pool: ^1.3.0
shelf: ^0.7.0
- shelf_packages_handler: ^1.0.0
+ shelf_packages_handler: ">=1.0.0 <3.0.0"
shelf_static: ^0.2.6
shelf_web_socket: ^0.2.0
source_span: ^1.4.0
stack_trace: ^1.9.0
- stream_channel: ">=1.7.0 <3.0.0"
+ stream_channel: '>=1.7.0 <3.0.0'
typed_data: ^1.0.0
web_socket_channel: ^1.0.0
+ webkit_inspection_protocol: ^0.5.0
yaml: ^2.0.0
# Use an exact version until the test_api and test_core package are stable.
- test_api: 0.2.11
- test_core: 0.2.15
+ test_api: 0.2.15
+ test_core: 0.3.2
dev_dependencies:
fake_async: ^1.0.0
shelf_test_handler: ^1.0.0
test_descriptor: ^1.0.0
test_process: ^1.0.0
-
-
diff --git a/test/tool/host.dart b/test/tool/host.dart
index fb296c7..c1b229c 100644
--- a/test/tool/host.dart
+++ b/test/tool/host.dart
@@ -38,18 +38,19 @@
/// running.
external Function get restartCurrent;
- external factory _JSApi({void resume(), void restartCurrent()});
+ external factory _JSApi(
+ {void Function() resume, void Function() restartCurrent});
}
/// Sets the top-level `dartTest` object so that it's visible to JS.
-@JS("dartTest")
+@JS('dartTest')
external set _jsApi(_JSApi api);
/// The iframes created for each loaded test suite, indexed by the suite id.
-final _iframes = Map<int, IFrameElement>();
+final _iframes = <int, IFrameElement>{};
/// Subscriptions created for each loaded test suite, indexed by the suite id.
-final _subscriptions = Map<int, List<StreamSubscription>>();
+final _subscriptions = <int, List<StreamSubscription>>{};
/// The URL for the current page.
final _currentUrl = Uri.parse(window.location.href);
@@ -140,22 +141,22 @@
// Send periodic pings to the test runner so it can know when the browser is
// paused for debugging.
Timer.periodic(Duration(seconds: 1),
- (_) => serverChannel.sink.add({"command": "ping"}));
+ (_) => serverChannel.sink.add({'command': 'ping'}));
- var play = document.querySelector("#play");
+ var play = document.querySelector('#play');
play.onClick.listen((_) {
if (!document.body.classes.remove('paused')) return;
- serverChannel.sink.add({"command": "resume"});
+ serverChannel.sink.add({'command': 'resume'});
});
_jsApi = _JSApi(resume: allowInterop(() {
if (!document.body.classes.remove('paused')) return;
- serverChannel.sink.add({"command": "resume"});
+ serverChannel.sink.add({'command': 'resume'});
}), restartCurrent: allowInterop(() {
- serverChannel.sink.add({"command": "restart"});
+ serverChannel.sink.add({'command': 'restart'});
}));
}, onError: (error, StackTrace stackTrace) {
- print("$error\n${Trace.from(stackTrace).terse}");
+ print('$error\n${Trace.from(stackTrace).terse}');
});
}
@@ -207,25 +208,25 @@
// TODO(nweiz): Stop manually checking href here once issue 22554 is
// fixed.
- if (message.data["href"] != iframe.src) return;
+ if (message.data['href'] != iframe.src) return;
message.stopPropagation();
- if (message.data["ready"] == true) {
+ if (message.data['ready'] == true) {
// This message indicates that the iframe is actively listening for
// events, so the message channel's second port can now be transferred.
iframe.contentWindow
- .postMessage("port", window.location.origin, [channel.port2]);
+ .postMessage('port', window.location.origin, [channel.port2]);
readyCompleter.complete();
- } else if (message.data["exception"] == true) {
+ } else if (message.data['exception'] == true) {
// This message from `dart.js` indicates that an exception occurred
// loading the test.
- controller.local.sink.add(message.data["data"]);
+ controller.local.sink.add(message.data['data']);
}
}));
subscriptions.add(channel.port1.onMessage.listen((message) {
- controller.local.sink.add(message.data["data"]);
+ controller.local.sink.add(message.data['data']);
}));
subscriptions.add(controller.local.stream.listen((message) async {
diff --git a/test_api/BUILD.gn b/test_api/BUILD.gn
index b020187..4960a26 100644
--- a/test_api/BUILD.gn
+++ b/test_api/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for test_api-0.2.11
+# This file is generated by importer.py for test_api-0.2.15
import("//build/dart/dart_library.gni")
@@ -13,7 +13,6 @@
deps = [
"//third_party/dart-pkg/pub/stack_trace",
- "//third_party/dart-pkg/pub/pedantic",
"//third_party/dart-pkg/pub/async",
"//third_party/dart-pkg/pub/matcher",
"//third_party/dart-pkg/pub/collection",
diff --git a/test_api/CHANGELOG.md b/test_api/CHANGELOG.md
index 3a31124..ddbb2db 100644
--- a/test_api/CHANGELOG.md
+++ b/test_api/CHANGELOG.md
@@ -1,3 +1,27 @@
+## 0.2.15
+
+* Cancel any StreamQueue that is created as a part of a stream matcher once it
+ is done matching.
+ * This fixes a bug where using a matcher on a custom stream controller and
+ then awaiting the `close()` method on that controller would hang.
+* Avoid causing the test runner to hang if there is a timeout during a
+ `tearDown` callback following a failing test case.
+
+## 0.2.14
+
+* Bump minimum SDK to `2.4.0` for safer usage of for-loop elements.
+
+## 0.2.13
+
+* Work around a bug in the `2.3.0` SDK by avoiding for-loop elements at the top
+ level.
+
+## 0.2.12
+
+* Link to docs on setting timeout when a test times out with the default
+ duration.
+* No longer directly depend on `package:pedantic`.
+
## 0.2.11
* Extend the timeout for synthetic tests, e.g. `tearDownAll`.
diff --git a/test_api/lib/src/backend/closed_exception.dart b/test_api/lib/src/backend/closed_exception.dart
index 4432466..08a45a0 100644
--- a/test_api/lib/src/backend/closed_exception.dart
+++ b/test_api/lib/src/backend/closed_exception.dart
@@ -7,5 +7,6 @@
class ClosedException implements Exception {
ClosedException();
- String toString() => "This test has been closed.";
+ @override
+ String toString() => 'This test has been closed.';
}
diff --git a/test_api/lib/src/backend/declarer.dart b/test_api/lib/src/backend/declarer.dart
index cc4b1fd..f4a41b4 100644
--- a/test_api/lib/src/backend/declarer.dart
+++ b/test_api/lib/src/backend/declarer.dart
@@ -50,13 +50,13 @@
final bool _noRetry;
/// The set-up functions to run for each test in this group.
- final _setUps = List<Function()>();
+ final _setUps = <dynamic Function()>[];
/// The tear-down functions to run for each test in this group.
- final _tearDowns = List<Function()>();
+ final _tearDowns = <dynamic Function()>[];
/// The set-up functions to run once for this group.
- final _setUpAlls = List<Function()>();
+ final _setUpAlls = <dynamic Function()>[];
/// The default timeout for synthetic tests.
final _timeout = Timeout(Duration(minutes: 12));
@@ -69,7 +69,7 @@
Trace _setUpAllTrace;
/// The tear-down functions to run once for this group.
- final _tearDownAlls = List<Function()>();
+ final _tearDownAlls = <Function()>[];
/// The trace for the first call to [tearDownAll].
///
@@ -78,13 +78,13 @@
Trace _tearDownAllTrace;
/// The children of this group, either tests or sub-groups.
- final _entries = List<GroupEntry>();
+ final _entries = <GroupEntry>[];
/// Whether [build] has been called for this declarer.
bool _built = false;
/// The tests and/or groups that have been flagged as solo.
- final _soloEntries = Set<GroupEntry>();
+ final _soloEntries = <GroupEntry>[];
/// Whether any tests and/or groups have been flagged as solo.
bool get _solo => _soloEntries.isNotEmpty;
@@ -127,10 +127,11 @@
/// Runs [body] with this declarer as [Declarer.current].
///
/// Returns the return value of [body].
- declare(body()) => runZoned(body, zoneValues: {#test.declarer: this});
+ T declare<T>(T Function() body) =>
+ runZoned(body, zoneValues: {#test.declarer: this});
/// Defines a test case with the given name and body.
- void test(String name, body(),
+ void test(String name, dynamic Function() body,
{String testOn,
Timeout timeout,
skip,
@@ -138,7 +139,7 @@
tags,
int retry,
bool solo = false}) {
- _checkNotBuilt("test");
+ _checkNotBuilt('test');
var newMetadata = Metadata.parse(
testOn: testOn,
@@ -181,7 +182,7 @@
}
/// Creates a group of tests.
- void group(String name, void body(),
+ void group(String name, void Function() body,
{String testOn,
Timeout timeout,
skip,
@@ -189,7 +190,7 @@
tags,
int retry,
bool solo = false}) {
- _checkNotBuilt("group");
+ _checkNotBuilt('group');
var newMetadata = Metadata.parse(
testOn: testOn,
@@ -209,7 +210,7 @@
// result of a void method.
var result = (body as dynamic)();
if (result is! Future) return;
- throw ArgumentError("Groups may not be async.");
+ throw ArgumentError('Groups may not be async.');
});
_entries.add(declarer.build());
@@ -219,44 +220,45 @@
}
/// Returns [name] prefixed with this declarer's group name.
- String _prefix(String name) => _name == null ? name : "$_name $name";
+ String _prefix(String name) => _name == null ? name : '$_name $name';
/// Registers a function to be run before each test in this group.
- void setUp(callback()) {
- _checkNotBuilt("setUp");
+ void setUp(dynamic Function() callback) {
+ _checkNotBuilt('setUp');
_setUps.add(callback);
}
/// Registers a function to be run after each test in this group.
- void tearDown(callback()) {
- _checkNotBuilt("tearDown");
+ void tearDown(dynamic Function() callback) {
+ _checkNotBuilt('tearDown');
_tearDowns.add(callback);
}
/// Registers a function to be run once before all tests.
- void setUpAll(callback()) {
- _checkNotBuilt("setUpAll");
+ void setUpAll(dynamic Function() callback) {
+ _checkNotBuilt('setUpAll');
if (_collectTraces) _setUpAllTrace ??= Trace.current(2);
_setUpAlls.add(callback);
}
/// Registers a function to be run once after all tests.
- void tearDownAll(callback()) {
- _checkNotBuilt("tearDownAll");
+ void tearDownAll(dynamic Function() callback) {
+ _checkNotBuilt('tearDownAll');
if (_collectTraces) _tearDownAllTrace ??= Trace.current(2);
_tearDownAlls.add(callback);
}
/// Like [tearDownAll], but called from within a running [setUpAll] test to
/// dynamically add a [tearDownAll].
- void addTearDownAll(callback()) => _tearDownAlls.add(callback);
+ void addTearDownAll(dynamic Function() callback) =>
+ _tearDownAlls.add(callback);
/// Finalizes and returns the group being declared.
///
/// **Note**: The tests in this group must be run in a [Invoker.guard]
/// context; otherwise, test errors won't be captured.
Group build() {
- _checkNotBuilt("build");
+ _checkNotBuilt('build');
_built = true;
var entries = _entries.map((entry) {
@@ -298,7 +300,7 @@
Test get _setUpAll {
if (_setUpAlls.isEmpty) return null;
- return LocalTest(_prefix("(setUpAll)"), _metadata.change(timeout: _timeout),
+ return LocalTest(_prefix('(setUpAll)'), _metadata.change(timeout: _timeout),
() {
return runZoned(() => Future.forEach(_setUpAlls, (setUp) => setUp()),
// Make the declarer visible to running scaffolds so they can add to
@@ -314,7 +316,7 @@
if (_setUpAlls.isEmpty && _tearDownAlls.isEmpty) return null;
return LocalTest(
- _prefix("(tearDownAll)"), _metadata.change(timeout: _timeout), () {
+ _prefix('(tearDownAll)'), _metadata.change(timeout: _timeout), () {
return runZoned(() {
return Invoker.current.unclosable(() async {
while (_tearDownAlls.isNotEmpty) {
diff --git a/test_api/lib/src/backend/group.dart b/test_api/lib/src/backend/group.dart
index 3f831f0..30f5238 100644
--- a/test_api/lib/src/backend/group.dart
+++ b/test_api/lib/src/backend/group.dart
@@ -13,10 +13,13 @@
///
/// It includes metadata that applies to all contained tests.
class Group implements GroupEntry {
+ @override
final String name;
+ @override
final Metadata metadata;
+ @override
final Trace trace;
/// The children of this group.
@@ -49,8 +52,9 @@
Group(this.name, Iterable<GroupEntry> entries,
{Metadata metadata, this.trace, this.setUpAll, this.tearDownAll})
: entries = List<GroupEntry>.unmodifiable(entries),
- metadata = metadata == null ? Metadata() : metadata;
+ metadata = metadata ?? Metadata();
+ @override
Group forPlatform(SuitePlatform platform) {
if (!metadata.testOn.evaluate(platform)) return null;
var newMetadata = metadata.forPlatform(platform);
@@ -63,7 +67,8 @@
tearDownAll: tearDownAll);
}
- Group filter(bool callback(Test test)) {
+ @override
+ Group filter(bool Function(Test) callback) {
var filtered = _map((entry) => entry.filter(callback));
if (filtered.isEmpty && entries.isNotEmpty) return null;
return Group(name, filtered,
@@ -76,7 +81,7 @@
/// Returns the entries of this group mapped using [callback].
///
/// Any `null` values returned by [callback] will be removed.
- List<GroupEntry> _map(GroupEntry callback(GroupEntry entry)) {
+ List<GroupEntry> _map(GroupEntry Function(GroupEntry) callback) {
return entries
.map((entry) => callback(entry))
.where((entry) => entry != null)
diff --git a/test_api/lib/src/backend/group_entry.dart b/test_api/lib/src/backend/group_entry.dart
index 2d2a341..44b3054 100644
--- a/test_api/lib/src/backend/group_entry.dart
+++ b/test_api/lib/src/backend/group_entry.dart
@@ -35,5 +35,5 @@
///
/// Returns `null` if this is a test that doesn't match [callback] or a group
/// where no child tests match [callback].
- GroupEntry filter(bool callback(Test test));
+ GroupEntry filter(bool Function(Test) callback);
}
diff --git a/test_api/lib/src/backend/invoker.dart b/test_api/lib/src/backend/invoker.dart
index 5b44624..2c83b2d 100644
--- a/test_api/lib/src/backend/invoker.dart
+++ b/test_api/lib/src/backend/invoker.dart
@@ -4,7 +4,6 @@
import 'dart:async';
-import 'package:pedantic/pedantic.dart';
import 'package:stack_trace/stack_trace.dart';
import '../frontend/expect.dart';
@@ -24,8 +23,11 @@
/// A test in this isolate.
class LocalTest extends Test {
+ @override
final String name;
+ @override
final Metadata metadata;
+ @override
final Trace trace;
/// Whether this is a test defined using `setUpAll()` or `tearDownAll()`.
@@ -51,11 +53,13 @@
this.isScaffoldAll);
/// Loads a single runnable instance of this test.
+ @override
LiveTest load(Suite suite, {Iterable<Group> groups}) {
var invoker = Invoker._(suite, this, groups: groups, guarded: _guarded);
return invoker.liveTest;
}
+ @override
Test forPlatform(SuitePlatform platform) {
if (!metadata.testOn.evaluate(platform)) return null;
return LocalTest._(name, metadata.forPlatform(platform), _body, trace,
@@ -111,7 +115,7 @@
var counter = Zone.current[_counterKey] as _AsyncCounter;
if (counter != null) return counter;
throw StateError("Can't add or remove outstanding callbacks outside "
- "of a test body.");
+ 'of a test body.');
}
/// All the zones created by [waitForOutstandingCallbacks], in the order they
@@ -140,7 +144,7 @@
/// Runs [callback] in a zone where unhandled errors from [LiveTest]s are
/// caught and dispatched to the appropriate [Invoker].
- static T guard<T>(T callback()) =>
+ static T guard<T>(T Function() callback) =>
runZoned(callback, zoneSpecification: ZoneSpecification(
// Use [handleUncaughtError] rather than [onError] so we can
// capture [zone] and with it the outstanding callback counter for
@@ -183,7 +187,7 @@
///
/// The [callback] may return a [Future]. Like all tear-downs, callbacks are
/// run in the reverse of the order they're declared.
- void addTearDown(callback()) {
+ void addTearDown(dynamic Function() callback) {
if (closed) throw ClosedException();
if (_test.isScaffoldAll) {
@@ -267,15 +271,20 @@
if (liveTest.isComplete) return;
if (_timeoutTimer != null) _timeoutTimer.cancel();
- var timeout = liveTest.test.metadata.timeout.apply(Duration(seconds: 30));
+ const defaultTimeout = Duration(seconds: 30);
+ var timeout = liveTest.test.metadata.timeout.apply(defaultTimeout);
if (timeout == null) return;
+ String message() {
+ var message = 'Test timed out after ${niceDuration(timeout)}.';
+ if (timeout == defaultTimeout) {
+ message += ' See https://pub.dev/packages/test#timeouts';
+ }
+ return message;
+ }
+
_timeoutTimer = _invokerZone.createTimer(timeout, () {
_outstandingCallbackZones.last.run(() {
- if (liveTest.isComplete) return;
- _handleError(
- Zone.current,
- TimeoutException(
- "Test timed out after ${niceDuration(timeout)}.", timeout));
+ _handleError(Zone.current, TimeoutException(message(), timeout));
});
});
}
@@ -291,9 +300,9 @@
// Set the state explicitly so we don't get an extra error about the test
// failing after being complete.
_controller.setState(const State(Status.complete, Result.error));
- throw "This test was marked as skipped after it had already completed. "
- "Make sure to use\n"
- "[expectAsync] or the [completes] matcher when testing async code.";
+ throw 'This test was marked as skipped after it had already completed. '
+ 'Make sure to use\n'
+ '[expectAsync] or the [completes] matcher when testing async code.';
}
if (message != null) _controller.message(Message.skip(message));
@@ -305,7 +314,7 @@
void printOnFailure(String message) {
message = message.trim();
if (liveTest.state.result.isFailing) {
- print("\n$message");
+ print('\n$message');
} else {
_printsOnFailure.add(message);
}
@@ -340,13 +349,13 @@
zone.run(() => _outstandingCallbacks.complete());
if (!liveTest.test.metadata.chainStackTraces) {
- _printsOnFailure.add("Consider enabling the flag chain-stack-traces to "
- "receive more detailed exceptions.\n"
+ _printsOnFailure.add('Consider enabling the flag chain-stack-traces to '
+ 'receive more detailed exceptions.\n'
"For example, 'pub run test --chain-stack-traces'.");
}
if (_printsOnFailure.isNotEmpty) {
- print(_printsOnFailure.join("\n\n"));
+ print(_printsOnFailure.join('\n\n'));
_printsOnFailure.clear();
}
@@ -360,9 +369,9 @@
_handleError(
zone,
- "This test failed after it had already completed. Make sure to use "
- "[expectAsync]\n"
- "or the [completes] matcher when testing async code.",
+ 'This test failed after it had already completed. Make sure to use '
+ '[expectAsync]\n'
+ 'or the [completes] matcher when testing async code.',
stackTrace);
}
@@ -386,8 +395,7 @@
// corresponding [onStateChange], which violates the timing
// guarantees.
//
- // Using [new Future] also avoids starving the DOM or other
- // microtask-level events.
+ // Use the event loop over the microtask queue to avoid starvation.
unawaited(Future(() async {
await _test._body();
await unclosable(_runTearDowns);
@@ -399,7 +407,7 @@
if (liveTest.state.result != Result.success &&
_runCount < liveTest.test.metadata.retry + 1) {
- _controller.message(Message.print("Retry: ${liveTest.test.name}"));
+ _controller.message(Message.print('Retry: ${liveTest.test.name}'));
_onRun();
return;
}
diff --git a/test_api/lib/src/backend/live_test.dart b/test_api/lib/src/backend/live_test.dart
index ca5a260..875b4d6 100644
--- a/test_api/lib/src/backend/live_test.dart
+++ b/test_api/lib/src/backend/live_test.dart
@@ -109,7 +109,7 @@
// The test will have the same name as the group for virtual tests created
// to represent skipping the entire group.
- if (test.name.length == group.name.length) return "";
+ if (test.name.length == group.name.length) return '';
return test.name.substring(group.name.length + 1);
}
diff --git a/test_api/lib/src/backend/live_test_controller.dart b/test_api/lib/src/backend/live_test_controller.dart
index c8a6671..0aad846 100644
--- a/test_api/lib/src/backend/live_test_controller.dart
+++ b/test_api/lib/src/backend/live_test_controller.dart
@@ -18,27 +18,38 @@
class _LiveTest extends LiveTest {
final LiveTestController _controller;
+ @override
Suite get suite => _controller._suite;
+ @override
List<Group> get groups => _controller._groups;
+ @override
Test get test => _controller._test;
+ @override
State get state => _controller._state;
+ @override
Stream<State> get onStateChange =>
_controller._onStateChangeController.stream;
+ @override
List<AsyncError> get errors => UnmodifiableListView(_controller._errors);
+ @override
Stream<AsyncError> get onError => _controller._onErrorController.stream;
+ @override
Stream<Message> get onMessage => _controller._onMessageController.stream;
+ @override
Future<void> get onComplete => _controller.onComplete;
+ @override
Future<void> run() => _controller._run();
+ @override
Future<void> close() => _controller._close();
_LiveTest(this._controller);
@@ -76,7 +87,7 @@
final Function _onClose;
/// The list of errors caught by the test.
- final _errors = List<AsyncError>();
+ final _errors = <AsyncError>[];
/// The current state of the test.
var _state = const State(Status.pending, Result.success);
@@ -125,7 +136,8 @@
///
/// If [groups] is passed, it's used to populate the list of groups that
/// contain this test. Otherwise, `suite.group` is used.
- LiveTestController(Suite suite, this._test, void onRun(), void onClose(),
+ LiveTestController(
+ Suite suite, this._test, void Function() onRun, void Function() onClose,
{Iterable<Group> groups})
: _suite = suite,
_onRun = onRun,
@@ -175,10 +187,10 @@
/// [LiveTest.run].
Future<void> _run() {
if (_runCalled) {
- throw StateError("LiveTest.run() may not be called more than once.");
+ throw StateError('LiveTest.run() may not be called more than once.');
} else if (_isClosed) {
- throw StateError("LiveTest.run() may not be called for a closed "
- "test.");
+ throw StateError('LiveTest.run() may not be called for a closed '
+ 'test.');
}
_runCalled = true;
diff --git a/test_api/lib/src/backend/message.dart b/test_api/lib/src/backend/message.dart
index 3c24c52..efe152f 100644
--- a/test_api/lib/src/backend/message.dart
+++ b/test_api/lib/src/backend/message.dart
@@ -20,19 +20,19 @@
class MessageType {
/// A message explicitly printed by the user's test.
- static const print = MessageType._("print");
+ static const print = MessageType._('print');
/// A message indicating that a test, or some portion of one, was skipped.
- static const skip = MessageType._("skip");
+ static const skip = MessageType._('skip');
/// The name of the message type.
final String name;
factory MessageType.parse(String name) {
switch (name) {
- case "print":
+ case 'print':
return MessageType.print;
- case "skip":
+ case 'skip':
return MessageType.skip;
default:
throw ArgumentError('Invalid message type "$name".');
@@ -41,5 +41,6 @@
const MessageType._(this.name);
+ @override
String toString() => name;
}
diff --git a/test_api/lib/src/backend/metadata.dart b/test_api/lib/src/backend/metadata.dart
index fc4dbba..a020abc 100644
--- a/test_api/lib/src/backend/metadata.dart
+++ b/test_api/lib/src/backend/metadata.dart
@@ -100,7 +100,7 @@
'"$platform".');
}
- skip = metadatum.reason == null ? true : metadatum.reason;
+ skip = metadatum.reason ?? true;
} else {
throw ArgumentError('Metadata for platform "$platform" must be a '
'Timeout, Skip, or List of those; was "$metadata".');
@@ -116,15 +116,15 @@
///
/// Throws an [ArgumentError] if [tags] is not a [String] or an [Iterable].
static Set<String> _parseTags(tags) {
- if (tags == null) return Set();
- if (tags is String) return Set.from([tags]);
+ if (tags == null) return {};
+ if (tags is String) return {tags};
if (tags is! Iterable) {
throw ArgumentError.value(
- tags, "tags", "must be either a String or an Iterable.");
+ tags, 'tags', 'must be either a String or an Iterable.');
}
if ((tags as Iterable).any((tag) => tag is! String)) {
- throw ArgumentError.value(tags, "tags", "must contain only Strings.");
+ throw ArgumentError.value(tags, 'tags', 'must contain only Strings.');
}
return Set.from(tags as Iterable);
@@ -149,7 +149,7 @@
Map<PlatformSelector, Metadata> onPlatform,
Map<BooleanSelector, Metadata> forTag}) {
// Returns metadata without forTag resolved at all.
- _unresolved() => Metadata._(
+ Metadata _unresolved() => Metadata._(
testOn: testOn,
timeout: timeout,
skip: skip,
@@ -172,7 +172,7 @@
// doing it for every test individually.
var empty = Metadata._();
var merged = forTag.keys.toList().fold(empty, (Metadata merged, selector) {
- if (!selector.evaluate(tags)) return merged;
+ if (!selector.evaluate(tags.contains)) return merged;
return merged.merge(forTag.remove(selector));
});
@@ -194,17 +194,17 @@
Iterable<String> tags,
Map<PlatformSelector, Metadata> onPlatform,
Map<BooleanSelector, Metadata> forTag})
- : testOn = testOn == null ? PlatformSelector.all : testOn,
- timeout = timeout == null ? const Timeout.factor(1) : timeout,
+ : testOn = testOn ?? PlatformSelector.all,
+ timeout = timeout ?? const Timeout.factor(1),
_skip = skip,
_verboseTrace = verboseTrace,
_chainStackTraces = chainStackTraces,
_retry = retry,
- tags = UnmodifiableSetView(tags == null ? Set() : tags.toSet()),
+ tags = UnmodifiableSetView(tags == null ? {} : tags.toSet()),
onPlatform =
onPlatform == null ? const {} : UnmodifiableMapView(onPlatform),
forTag = forTag == null ? const {} : UnmodifiableMapView(forTag) {
- if (retry != null) RangeError.checkNotNegative(retry, "retry");
+ if (retry != null) RangeError.checkNotNegative(retry, 'retry');
_validateTags();
}
@@ -224,7 +224,7 @@
: testOn = testOn == null
? PlatformSelector.all
: PlatformSelector.parse(testOn),
- timeout = timeout == null ? const Timeout.factor(1) : timeout,
+ timeout = timeout ?? const Timeout.factor(1),
_skip = skip == null ? null : skip != false,
_verboseTrace = verboseTrace,
_chainStackTraces = chainStackTraces,
@@ -237,7 +237,7 @@
throw ArgumentError('"skip" must be a String or a bool, was "$skip".');
}
- if (retry != null) RangeError.checkNotNegative(retry, "retry");
+ if (retry != null) RangeError.checkNotNegative(retry, 'retry');
_validateTags();
}
@@ -254,9 +254,11 @@
_chainStackTraces = serialized['chainStackTraces'] as bool,
_retry = serialized['retry'] as int,
tags = Set.from(serialized['tags'] as Iterable),
- onPlatform = Map.fromIterable(serialized['onPlatform'] as Iterable,
- key: (pair) => PlatformSelector.parse(pair.first as String),
- value: (pair) => Metadata.deserialize(pair.last)),
+ onPlatform = {
+ for (var pair in serialized['onPlatform'])
+ PlatformSelector.parse(pair.first as String):
+ Metadata.deserialize(pair.last)
+ },
forTag = (serialized['forTag'] as Map).map((key, nested) => MapEntry(
BooleanSelector.parse(key as String),
Metadata.deserialize(nested)));
@@ -280,8 +282,8 @@
if (invalidTags.isEmpty) return;
throw ArgumentError("Invalid ${pluralize('tag', invalidTags.length)} "
- "${toSentence(invalidTags)}. Tags must be (optionally hyphenated) "
- "Dart identifiers.");
+ '${toSentence(invalidTags)}. Tags must be (optionally hyphenated) '
+ 'Dart identifiers.');
}
/// Throws a [FormatException] if any [PlatformSelector]s use any variables
@@ -328,10 +330,10 @@
Map<BooleanSelector, Metadata> forTag}) {
testOn ??= this.testOn;
timeout ??= this.timeout;
- skip ??= this._skip;
- verboseTrace ??= this._verboseTrace;
- chainStackTraces ??= this._chainStackTraces;
- retry ??= this._retry;
+ skip ??= _skip;
+ verboseTrace ??= _verboseTrace;
+ chainStackTraces ??= _chainStackTraces;
+ retry ??= _retry;
skipReason ??= this.skipReason;
onPlatform ??= this.onPlatform;
tags ??= this.tags;
@@ -363,8 +365,8 @@
}
/// Serializes [this] into a JSON-safe object that can be deserialized using
- /// [new Metadata.deserialize].
- serialize() {
+ /// [Metadata.deserialize].
+ Map<String, dynamic> serialize() {
// Make this a list to guarantee that the order is preserved.
var serializedOnPlatform = [];
onPlatform.forEach((key, value) {
@@ -387,7 +389,7 @@
}
/// Serializes timeout into a JSON-safe object.
- _serializeTimeout(Timeout timeout) {
+ dynamic _serializeTimeout(Timeout timeout) {
if (timeout == Timeout.none) return 'none';
return {
'duration':
diff --git a/test_api/lib/src/backend/operating_system.dart b/test_api/lib/src/backend/operating_system.dart
index b914e64..f2b7639 100644
--- a/test_api/lib/src/backend/operating_system.dart
+++ b/test_api/lib/src/backend/operating_system.dart
@@ -9,31 +9,31 @@
/// running the test runner.
class OperatingSystem {
/// Microsoft Windows.
- static const windows = OperatingSystem._("Windows", "windows");
+ static const windows = OperatingSystem._('Windows', 'windows');
/// Mac OS X.
- static const macOS = OperatingSystem._("OS X", "mac-os");
+ static const macOS = OperatingSystem._('OS X', 'mac-os');
/// GNU/Linux.
- static const linux = OperatingSystem._("Linux", "linux");
+ static const linux = OperatingSystem._('Linux', 'linux');
/// Android.
///
/// Since this is the operating system the test runner is running on, this
/// won't be true when testing remotely on an Android browser.
- static const android = OperatingSystem._("Android", "android");
+ static const android = OperatingSystem._('Android', 'android');
/// iOS.
///
/// Since this is the operating system the test runner is running on, this
/// won't be true when testing remotely on an iOS browser.
- static const iOS = OperatingSystem._("iOS", "ios");
+ static const iOS = OperatingSystem._('iOS', 'ios');
/// No operating system.
///
/// This is used when running in the browser, or if an unrecognized operating
/// system is used. It can't be referenced by name in platform selectors.
- static const none = OperatingSystem._("none", "none");
+ static const none = OperatingSystem._('none', 'none');
/// A list of all instances of [OperatingSystem] other than [none].
static const all = [windows, macOS, linux, android, iOS];
@@ -51,15 +51,15 @@
/// If no operating system is found, returns [none].
static OperatingSystem findByIoName(String name) {
switch (name) {
- case "windows":
+ case 'windows':
return windows;
- case "macos":
+ case 'macos':
return macOS;
- case "linux":
+ case 'linux':
return linux;
- case "android":
+ case 'android':
return android;
- case "ios":
+ case 'ios':
return iOS;
default:
return none;
@@ -77,5 +77,6 @@
const OperatingSystem._(this.name, this.identifier);
+ @override
String toString() => name;
}
diff --git a/test_api/lib/src/backend/platform_selector.dart b/test_api/lib/src/backend/platform_selector.dart
index 8fd956f..f2ab5a9 100644
--- a/test_api/lib/src/backend/platform_selector.dart
+++ b/test_api/lib/src/backend/platform_selector.dart
@@ -10,10 +10,16 @@
import 'suite_platform.dart';
/// The set of variable names that are valid for all platform selectors.
-final _universalValidVariables =
- Set<String>.from(["posix", "dart-vm", "browser", "js", "blink", "google"])
- ..addAll(Runtime.builtIn.map((runtime) => runtime.identifier))
- ..addAll(OperatingSystem.all.map((os) => os.identifier));
+final _universalValidVariables = {
+ 'posix',
+ 'dart-vm',
+ 'browser',
+ 'js',
+ 'blink',
+ 'google',
+ for (var runtime in Runtime.builtIn) runtime.identifier,
+ for (var os in OperatingSystem.all) os.identifier,
+};
/// An expression for selecting certain platforms, including operating systems
/// and browsers.
@@ -46,7 +52,7 @@
/// [SourceSpanFormatException] using [span].
///
/// If [span] is `null`, runs [body] as-is.
- static T _wrapFormatException<T>(T body(), SourceSpan span) {
+ static T _wrapFormatException<T>(T Function() body, SourceSpan span) {
if (span == null) return body();
try {
@@ -78,17 +84,17 @@
if (variable == platform.runtime.parent?.identifier) return true;
if (variable == platform.os.identifier) return true;
switch (variable) {
- case "dart-vm":
+ case 'dart-vm':
return platform.runtime.isDartVM;
- case "browser":
+ case 'browser':
return platform.runtime.isBrowser;
- case "js":
+ case 'js':
return platform.runtime.isJS;
- case "blink":
+ case 'blink':
return platform.runtime.isBlink;
- case "posix":
+ case 'posix':
return platform.os.isPosix;
- case "google":
+ case 'google':
return platform.inGoogle;
default:
return false;
@@ -103,10 +109,13 @@
return PlatformSelector._(_inner.intersection(other._inner));
}
+ @override
String toString() => _inner.toString();
+ @override
bool operator ==(other) =>
other is PlatformSelector && _inner == other._inner;
+ @override
int get hashCode => _inner.hashCode;
}
diff --git a/test_api/lib/src/backend/runtime.dart b/test_api/lib/src/backend/runtime.dart
index 4236a8f..380be9c 100644
--- a/test_api/lib/src/backend/runtime.dart
+++ b/test_api/lib/src/backend/runtime.dart
@@ -8,30 +8,30 @@
// variable tests in test/backend/platform_selector/evaluate_test.
/// The command-line Dart VM.
- static const Runtime vm = Runtime("VM", "vm", isDartVM: true);
+ static const Runtime vm = Runtime('VM', 'vm', isDartVM: true);
/// Google Chrome.
static const Runtime chrome =
- Runtime("Chrome", "chrome", isBrowser: true, isJS: true, isBlink: true);
+ Runtime('Chrome', 'chrome', isBrowser: true, isJS: true, isBlink: true);
/// PhantomJS.
- static const Runtime phantomJS = Runtime("PhantomJS", "phantomjs",
+ static const Runtime phantomJS = Runtime('PhantomJS', 'phantomjs',
isBrowser: true, isJS: true, isBlink: true, isHeadless: true);
/// Mozilla Firefox.
static const Runtime firefox =
- Runtime("Firefox", "firefox", isBrowser: true, isJS: true);
+ Runtime('Firefox', 'firefox', isBrowser: true, isJS: true);
/// Apple Safari.
static const Runtime safari =
- Runtime("Safari", "safari", isBrowser: true, isJS: true);
+ Runtime('Safari', 'safari', isBrowser: true, isJS: true);
/// Microsoft Internet Explorer.
static const Runtime internetExplorer =
- Runtime("Internet Explorer", "ie", isBrowser: true, isJS: true);
+ Runtime('Internet Explorer', 'ie', isBrowser: true, isJS: true);
/// The command-line Node.js VM.
- static const Runtime nodeJS = Runtime("Node.js", "node", isJS: true);
+ static const Runtime nodeJS = Runtime('Node.js', 'node', isJS: true);
/// The platforms that are supported by the test runner by default.
static const List<Runtime> builtIn = [
@@ -102,45 +102,45 @@
}
var map = serialized as Map;
- var parent = map["parent"];
+ var parent = map['parent'];
if (parent != null) {
// Note that the returned platform's [parent] won't necessarily be `==` to
// a separately-deserialized parent platform. This should be fine, though,
// since we only deserialize platforms in the remote execution context
// where they're only used to evaluate platform selectors.
- return Runtime._child(map["name"] as String, map["identifier"] as String,
+ return Runtime._child(map['name'] as String, map['identifier'] as String,
Runtime.deserialize(parent));
}
- return Runtime(map["name"] as String, map["identifier"] as String,
- isDartVM: map["isDartVM"] as bool,
- isBrowser: map["isBrowser"] as bool,
- isJS: map["isJS"] as bool,
- isBlink: map["isBlink"] as bool,
- isHeadless: map["isHeadless"] as bool);
+ return Runtime(map['name'] as String, map['identifier'] as String,
+ isDartVM: map['isDartVM'] as bool,
+ isBrowser: map['isBrowser'] as bool,
+ isJS: map['isJS'] as bool,
+ isBlink: map['isBlink'] as bool,
+ isHeadless: map['isHeadless'] as bool);
}
/// Converts [this] into a JSON-safe object that can be converted back to a
- /// [Runtime] using [new Runtime.deserialize].
+ /// [Runtime] using [Runtime.deserialize].
Object serialize() {
if (builtIn.contains(this)) return identifier;
if (parent != null) {
return {
- "name": name,
- "identifier": identifier,
- "parent": parent.serialize()
+ 'name': name,
+ 'identifier': identifier,
+ 'parent': parent.serialize()
};
}
return {
- "name": name,
- "identifier": identifier,
- "isDartVM": isDartVM,
- "isBrowser": isBrowser,
- "isJS": isJS,
- "isBlink": isBlink,
- "isHeadless": isHeadless
+ 'name': name,
+ 'identifier': identifier,
+ 'isDartVM': isDartVM,
+ 'isBrowser': isBrowser,
+ 'isJS': isJS,
+ 'isBlink': isBlink,
+ 'isHeadless': isHeadless
};
}
@@ -150,8 +150,9 @@
/// This may not be called on a platform that's already a child.
Runtime extend(String name, String identifier) {
if (parent == null) return Runtime._child(name, identifier, this);
- throw StateError("A child platform may not be extended.");
+ throw StateError('A child platform may not be extended.');
}
+ @override
String toString() => name;
}
diff --git a/test_api/lib/src/backend/stack_trace_formatter.dart b/test_api/lib/src/backend/stack_trace_formatter.dart
index 62d5243..2bb897e 100644
--- a/test_api/lib/src/backend/stack_trace_formatter.dart
+++ b/test_api/lib/src/backend/stack_trace_formatter.dart
@@ -22,12 +22,12 @@
/// as-is.
StackTraceMapper _mapper;
- /// The list of packages to fold when producing terse [Chain]s.
- var _except = Set<String>.from(['test', 'stream_channel', 'test_api']);
+ /// The set of packages to fold when producing terse [Chain]s.
+ var _except = {'test', 'stream_channel', 'test_api'};
/// If non-empty, all packages not in this list will be folded when producing
/// terse [Chain]s.
- var _only = Set<String>();
+ var _only = <String>{};
/// Returns the current manager, or `null` if this isn't called within a call
/// to [asCurrent].
@@ -38,7 +38,8 @@
///
/// This is zone-scoped, so [this] will be the current configuration in any
/// asynchronous callbacks transitively created by [body].
- T asCurrent<T>(T body()) => runZoned(body, zoneValues: {_currentKey: this});
+ T asCurrent<T>(T Function() body) =>
+ runZoned(body, zoneValues: {_currentKey: this});
/// Configure how stack traces are formatted.
///
diff --git a/test_api/lib/src/backend/state.dart b/test_api/lib/src/backend/state.dart
index 3151c1b..ba82cd0 100644
--- a/test_api/lib/src/backend/state.dart
+++ b/test_api/lib/src/backend/state.dart
@@ -27,26 +27,29 @@
const State(this.status, this.result);
+ @override
bool operator ==(other) =>
other is State && status == other.status && result == other.result;
+ @override
int get hashCode => status.hashCode ^ (7 * result.hashCode);
+ @override
String toString() {
- if (status == Status.pending) return "pending";
+ if (status == Status.pending) return 'pending';
if (status == Status.complete) return result.toString();
- if (result == Result.success) return "running";
- return "running with $result";
+ if (result == Result.success) return 'running';
+ return 'running with $result';
}
}
/// Where the test is in its process of running.
class Status {
/// The test has not yet begun running.
- static const pending = Status._("pending");
+ static const pending = Status._('pending');
/// The test is currently running.
- static const running = Status._("running");
+ static const running = Status._('running');
/// The test has finished running.
///
@@ -55,18 +58,18 @@
/// first error or when all [expectAsync] callbacks have been called and any
/// returned [Future] has completed, but it's possible for further processing
/// to happen, which may cause further errors.
- static const complete = Status._("complete");
+ static const complete = Status._('complete');
/// The name of the status.
final String name;
factory Status.parse(String name) {
switch (name) {
- case "pending":
+ case 'pending':
return Status.pending;
- case "running":
+ case 'running':
return Status.running;
- case "complete":
+ case 'complete':
return Status.complete;
default:
throw ArgumentError('Invalid status name "$name".');
@@ -75,6 +78,7 @@
const Status._(this.name);
+ @override
String toString() => name;
}
@@ -83,24 +87,24 @@
/// The test has not yet failed in any way.
///
/// Note that this doesn't mean that the test won't fail in the future.
- static const success = Result._("success");
+ static const success = Result._('success');
/// The test, or some part of it, has been skipped.
///
/// This implies that the test hasn't failed *yet*. However, it this doesn't
/// mean that the test won't fail in the future.
- static const skipped = Result._("skipped");
+ static const skipped = Result._('skipped');
/// The test has failed.
///
/// A failure is specifically caused by a [TestFailure] being thrown; any
/// other exception causes an error.
- static const failure = Result._("failure");
+ static const failure = Result._('failure');
/// The test has crashed.
///
/// Any exception other than a [TestFailure] is considered to be an error.
- static const error = Result._("error");
+ static const error = Result._('error');
/// The name of the result.
final String name;
@@ -119,13 +123,13 @@
factory Result.parse(String name) {
switch (name) {
- case "success":
+ case 'success':
return Result.success;
- case "skipped":
+ case 'skipped':
return Result.skipped;
- case "failure":
+ case 'failure':
return Result.failure;
- case "error":
+ case 'error':
return Result.error;
default:
throw ArgumentError('Invalid result name "$name".');
@@ -134,5 +138,6 @@
const Result._(this.name);
+ @override
String toString() => name;
}
diff --git a/test_api/lib/src/backend/suite.dart b/test_api/lib/src/backend/suite.dart
index 2a1a13f..695d305 100644
--- a/test_api/lib/src/backend/suite.dart
+++ b/test_api/lib/src/backend/suite.dart
@@ -48,9 +48,9 @@
///
/// Unlike [GroupEntry.filter], this never returns `null`. If all entries are
/// filtered out, it returns an empty suite.
- Suite filter(bool callback(Test test)) {
+ Suite filter(bool Function(Test) callback) {
var filtered = group.filter(callback);
- if (filtered == null) filtered = Group.root([], metadata: metadata);
+ filtered ??= Group.root([], metadata: metadata);
return Suite(filtered, platform, path: path);
}
diff --git a/test_api/lib/src/backend/suite_platform.dart b/test_api/lib/src/backend/suite_platform.dart
index 1f049eb..5f80997 100644
--- a/test_api/lib/src/backend/suite_platform.dart
+++ b/test_api/lib/src/backend/suite_platform.dart
@@ -41,7 +41,7 @@
}
/// Converts [this] into a JSON-safe object that can be converted back to a
- /// [SuitePlatform] using [new SuitePlatform.deserialize].
+ /// [SuitePlatform] using [SuitePlatform.deserialize].
Object serialize() => {
'runtime': runtime.serialize(),
'os': os.identifier,
diff --git a/test_api/lib/src/backend/test.dart b/test_api/lib/src/backend/test.dart
index 07df8c3..870f5e1 100644
--- a/test_api/lib/src/backend/test.dart
+++ b/test_api/lib/src/backend/test.dart
@@ -17,10 +17,13 @@
/// directly. To run one, load a live version using [Test.load] and run it using
/// [LiveTest.run].
abstract class Test implements GroupEntry {
+ @override
String get name;
+ @override
Metadata get metadata;
+ @override
Trace get trace;
/// Loads a live version of this test, which can be used to run it a single
@@ -31,7 +34,9 @@
/// defaults to just containing `suite.group`.
LiveTest load(Suite suite, {Iterable<Group> groups});
+ @override
Test forPlatform(SuitePlatform platform);
- Test filter(bool callback(Test test)) => callback(this) ? this : null;
+ @override
+ Test filter(bool Function(Test) callback) => callback(this) ? this : null;
}
diff --git a/test_api/lib/src/frontend/async_matcher.dart b/test_api/lib/src/frontend/async_matcher.dart
index e2c544e..e956aec 100644
--- a/test_api/lib/src/frontend/async_matcher.dart
+++ b/test_api/lib/src/frontend/async_matcher.dart
@@ -27,13 +27,14 @@
///
/// If this returns a [String] synchronously, [expect] will synchronously
/// throw a [TestFailure] and [matches] will synchronusly return `false`.
- /*FutureOr<String>*/ matchAsync(item);
+ dynamic /*FutureOr<String>*/ matchAsync(item);
+ @override
bool matches(item, Map matchState) {
var result = matchAsync(item);
expect(result,
anyOf([equals(null), TypeMatcher<Future>(), TypeMatcher<String>()]),
- reason: "matchAsync() may only return a String, a Future, or null.");
+ reason: 'matchAsync() may only return a String, a Future, or null.');
if (result is Future) {
Invoker.current.addOutstandingCallback();
@@ -51,6 +52,7 @@
return true;
}
+ @override
Description describeMismatch(
item, Description description, Map matchState, bool verbose) =>
StringDescription(matchState[this] as String);
diff --git a/test_api/lib/src/frontend/expect.dart b/test_api/lib/src/frontend/expect.dart
index 7fcd503..b69dc2f 100644
--- a/test_api/lib/src/frontend/expect.dart
+++ b/test_api/lib/src/frontend/expect.dart
@@ -18,12 +18,13 @@
TestFailure(this.message);
+ @override
String toString() => message;
}
/// The type used for functions that can be used to build up error reports
/// upon failures in [expect].
-@Deprecated("Will be removed in 0.13.0.")
+@Deprecated('Will be removed in 0.13.0.')
typedef ErrorFormatter = String Function(dynamic actual, Matcher matcher,
String reason, Map matchState, bool verbose);
@@ -54,8 +55,8 @@
void expect(actual, matcher,
{String reason,
skip,
- @Deprecated("Will be removed in 0.13.0.") bool verbose = false,
- @Deprecated("Will be removed in 0.13.0.") ErrorFormatter formatter}) {
+ @Deprecated('Will be removed in 0.13.0.') bool verbose = false,
+ @Deprecated('Will be removed in 0.13.0.') ErrorFormatter formatter}) {
_expect(actual, matcher,
reason: reason, skip: skip, verbose: verbose, formatter: formatter);
}
@@ -86,25 +87,25 @@
};
if (Invoker.current == null) {
- throw StateError("expect() may only be called within a test.");
+ throw StateError('expect() may only be called within a test.');
}
if (Invoker.current.closed) throw ClosedException();
if (skip != null && skip is! bool && skip is! String) {
- throw ArgumentError.value(skip, "skip", "must be a bool or a String");
+ throw ArgumentError.value(skip, 'skip', 'must be a bool or a String');
}
matcher = wrapMatcher(matcher);
if (skip != null && skip != false) {
String message;
if (skip is String) {
- message = "Skip expect: $skip";
+ message = 'Skip expect: $skip';
} else if (reason != null) {
- message = "Skip expect ($reason).";
+ message = 'Skip expect ($reason).';
} else {
var description = StringDescription().addDescriptionOf(matcher);
- message = "Skip expect ($description).";
+ message = 'Skip expect ($description).';
}
Invoker.current.skip(message);
@@ -116,7 +117,7 @@
var result = matcher.matchAsync(actual);
expect(result,
anyOf([equals(null), TypeMatcher<Future>(), TypeMatcher<String>()]),
- reason: "matchAsync() may only return a String, a Future, or null.");
+ reason: 'matchAsync() may only return a String, a Future, or null.');
if (result is String) {
fail(formatFailure(matcher as Matcher, actual, result, reason: reason));
@@ -153,7 +154,7 @@
Null fail(String message) => throw TestFailure(message);
// The default error formatter.
-@Deprecated("Will be removed in 0.13.0.")
+@Deprecated('Will be removed in 0.13.0.')
String formatFailure(Matcher expected, actual, String which, {String reason}) {
var buffer = StringBuffer();
buffer.writeln(indent(prettyPrint(expected), first: 'Expected: '));
diff --git a/test_api/lib/src/frontend/expect_async.dart b/test_api/lib/src/frontend/expect_async.dart
index 07d408c..10abf03 100644
--- a/test_api/lib/src/frontend/expect_async.dart
+++ b/test_api/lib/src/frontend/expect_async.dart
@@ -18,20 +18,6 @@
typedef Func5<T, A, B, C, D, E> = T Function([A a, B b, C c, D d, E e]);
typedef Func6<T, A, B, C, D, E, F> = T Function([A a, B b, C c, D d, E e, F f]);
-// Functions used to check how many arguments a callback takes. We can't use the
-// previous functions for this, because (a) {} is not a subtype of
-// ([dynamic]) -> dynamic.
-
-typedef _Func0 = Function();
-typedef _Func1 = Function(Null a);
-typedef _Func2 = Function(Null a, Null b);
-typedef _Func3 = Function(Null a, Null b, Null c);
-typedef _Func4 = Function(Null a, Null b, Null c, Null d);
-typedef _Func5 = Function(Null a, Null b, Null c, Null d, Null e);
-typedef _Func6 = Function(Null a, Null b, Null c, Null d, Null e, Null f);
-
-typedef _IsDoneCallback = bool Function();
-
/// A wrapper for a function that ensures that it's called the appropriate
/// number of times.
///
@@ -62,7 +48,7 @@
///
/// This may be `null`. If so, the function is considered to be done after
/// it's been run once.
- final _IsDoneCallback _isDone;
+ final bool Function() _isDone;
/// A descriptive name for the function.
final String _id;
@@ -91,20 +77,20 @@
/// as a reason it's expected to be called. If [isDone] is passed, the test
/// won't be allowed to complete until it returns `true`.
_ExpectedFunction(Function callback, int minExpected, int maxExpected,
- {String id, String reason, bool isDone()})
- : this._callback = callback,
+ {String id, String reason, bool Function() isDone})
+ : _callback = callback,
_minExpectedCalls = minExpected,
_maxExpectedCalls =
(maxExpected == 0 && minExpected > 0) ? minExpected : maxExpected,
- this._isDone = isDone,
- this._reason = reason == null ? '' : '\n$reason',
- this._zone = Zone.current,
- this._id = _makeCallbackId(id, callback) {
+ _isDone = isDone,
+ _reason = reason == null ? '' : '\n$reason',
+ _zone = Zone.current,
+ _id = _makeCallbackId(id, callback) {
if (_invoker == null) {
- throw StateError("[expectAsync] was called outside of a test.");
+ throw StateError('[expectAsync] was called outside of a test.');
} else if (maxExpected > 0 && minExpected > maxExpected) {
- throw ArgumentError("max ($maxExpected) may not be less than count "
- "($minExpected).");
+ throw ArgumentError('max ($maxExpected) may not be less than count '
+ '($minExpected).');
}
if (isDone != null || minExpected > 0) {
@@ -120,7 +106,7 @@
/// If [id] is passed, uses that. Otherwise, tries to determine a name from
/// calling `toString`. If no name can be found, returns the empty string.
static String _makeCallbackId(String id, Function callback) {
- if (id != null) return "$id ";
+ if (id != null) return '$id ';
// If the callback is not an anonymous closure, try to get the
// name.
@@ -132,19 +118,19 @@
start += prefix.length;
var end = toString.indexOf("'", start);
if (end == -1) return '';
- return "${toString.substring(start, end)} ";
+ return '${toString.substring(start, end)} ';
}
/// Returns a function that has the same number of positional arguments as the
/// wrapped function (up to a total of 6).
Function get func {
- if (_callback is _Func6) return max6;
- if (_callback is _Func5) return max5;
- if (_callback is _Func4) return max4;
- if (_callback is _Func3) return max3;
- if (_callback is _Func2) return max2;
- if (_callback is _Func1) return max1;
- if (_callback is _Func0) return max0;
+ if (_callback is Function(Null, Null, Null, Null, Null Nulll)) return max6;
+ if (_callback is Function(Null, Null, Null, Null, Null)) return max5;
+ if (_callback is Function(Null, Null, Null, Null)) return max4;
+ if (_callback is Function(Null, Null, Null)) return max3;
+ if (_callback is Function(Null, Null)) return max2;
+ if (_callback is Function(Null)) return max1;
+ if (_callback is Function()) return max0;
_invoker.removeOutstandingCallback();
throw ArgumentError(
@@ -227,11 +213,11 @@
/// Use [expectAsync0], [expectAsync1],
/// [expectAsync2], [expectAsync3], [expectAsync4], [expectAsync5], or
/// [expectAsync6] instead.
-@Deprecated("Will be removed in 0.13.0")
+@Deprecated('Will be removed in 0.13.0')
Function expectAsync(Function callback,
{int count = 1, int max = 0, String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync() may only be called within a test.");
+ throw StateError('expectAsync() may only be called within a test.');
}
return _ExpectedFunction(callback, count, max, id: id, reason: reason).func;
@@ -258,10 +244,10 @@
/// This method takes callbacks with zero arguments. See also
/// [expectAsync1], [expectAsync2], [expectAsync3], [expectAsync4],
/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func0<T> expectAsync0<T>(T callback(),
+Func0<T> expectAsync0<T>(T Function() callback,
{int count = 1, int max = 0, String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync0() may only be called within a test.");
+ throw StateError('expectAsync0() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -289,10 +275,10 @@
/// This method takes callbacks with one argument. See also
/// [expectAsync0], [expectAsync2], [expectAsync3], [expectAsync4],
/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func1<T, A> expectAsync1<T, A>(T callback(A a),
+Func1<T, A> expectAsync1<T, A>(T Function(A) callback,
{int count = 1, int max = 0, String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync1() may only be called within a test.");
+ throw StateError('expectAsync1() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -320,10 +306,10 @@
/// This method takes callbacks with two arguments. See also
/// [expectAsync0], [expectAsync1], [expectAsync3], [expectAsync4],
/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func2<T, A, B> expectAsync2<T, A, B>(T callback(A a, B b),
+Func2<T, A, B> expectAsync2<T, A, B>(T Function(A, B) callback,
{int count = 1, int max = 0, String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync2() may only be called within a test.");
+ throw StateError('expectAsync2() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -351,10 +337,10 @@
/// This method takes callbacks with three arguments. See also
/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync4],
/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func3<T, A, B, C> expectAsync3<T, A, B, C>(T callback(A a, B b, C c),
+Func3<T, A, B, C> expectAsync3<T, A, B, C>(T Function(A, B, C) callback,
{int count = 1, int max = 0, String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync3() may only be called within a test.");
+ throw StateError('expectAsync3() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -382,10 +368,14 @@
/// This method takes callbacks with four arguments. See also
/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
-Func4<T, A, B, C, D> expectAsync4<T, A, B, C, D>(T callback(A a, B b, C c, D d),
- {int count = 1, int max = 0, String id, String reason}) {
+Func4<T, A, B, C, D> expectAsync4<T, A, B, C, D>(
+ T Function(A, B, C, D) callback,
+ {int count = 1,
+ int max = 0,
+ String id,
+ String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync4() may only be called within a test.");
+ throw StateError('expectAsync4() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -414,13 +404,13 @@
/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
/// [expectAsync4], and [expectAsync6] for callbacks with different arity.
Func5<T, A, B, C, D, E> expectAsync5<T, A, B, C, D, E>(
- T callback(A a, B b, C c, D d, E e),
+ T Function(A, B, C, D, E) callback,
{int count = 1,
int max = 0,
String id,
String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync5() may only be called within a test.");
+ throw StateError('expectAsync5() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -449,13 +439,13 @@
/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
/// [expectAsync4], and [expectAsync5] for callbacks with different arity.
Func6<T, A, B, C, D, E, F> expectAsync6<T, A, B, C, D, E, F>(
- T callback(A a, B b, C c, D d, E e, F f),
+ T Function(A, B, C, D, E, F) callback,
{int count = 1,
int max = 0,
String id,
String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsync6() may only be called within a test.");
+ throw StateError('expectAsync6() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
@@ -466,11 +456,11 @@
/// Use [expectAsyncUntil0], [expectAsyncUntil1],
/// [expectAsyncUntil2], [expectAsyncUntil3], [expectAsyncUntil4],
/// [expectAsyncUntil5], or [expectAsyncUntil6] instead.
-@Deprecated("Will be removed in 0.13.0")
-Function expectAsyncUntil(Function callback, bool isDone(),
+@Deprecated('Will be removed in 0.13.0')
+Function expectAsyncUntil(Function callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil() may only be called within a test.");
+ throw StateError('expectAsyncUntil() may only be called within a test.');
}
return _ExpectedFunction(callback, 0, -1,
@@ -495,10 +485,10 @@
/// [expectAsyncUntil1], [expectAsyncUntil2], [expectAsyncUntil3],
/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
/// callbacks with different arity.
-Func0<T> expectAsyncUntil0<T>(T callback(), bool isDone(),
+Func0<T> expectAsyncUntil0<T>(T Function() callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil0() may only be called within a test.");
+ throw StateError('expectAsyncUntil0() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
@@ -523,10 +513,11 @@
/// [expectAsyncUntil0], [expectAsyncUntil2], [expectAsyncUntil3],
/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
/// callbacks with different arity.
-Func1<T, A> expectAsyncUntil1<T, A>(T callback(A a), bool isDone(),
+Func1<T, A> expectAsyncUntil1<T, A>(
+ T Function(A) callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil1() may only be called within a test.");
+ throw StateError('expectAsyncUntil1() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
@@ -551,10 +542,11 @@
/// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil3],
/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
/// callbacks with different arity.
-Func2<T, A, B> expectAsyncUntil2<T, A, B>(T callback(A a, B b), bool isDone(),
+Func2<T, A, B> expectAsyncUntil2<T, A, B>(
+ T Function(A, B) callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil2() may only be called within a test.");
+ throw StateError('expectAsyncUntil2() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
@@ -580,10 +572,10 @@
/// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
/// callbacks with different arity.
Func3<T, A, B, C> expectAsyncUntil3<T, A, B, C>(
- T callback(A a, B b, C c), bool isDone(),
+ T Function(A, B, C) callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil3() may only be called within a test.");
+ throw StateError('expectAsyncUntil3() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
@@ -609,10 +601,10 @@
/// [expectAsyncUntil3], [expectAsyncUntil5], and [expectAsyncUntil6] for
/// callbacks with different arity.
Func4<T, A, B, C, D> expectAsyncUntil4<T, A, B, C, D>(
- T callback(A a, B b, C c, D d), bool isDone(),
+ T Function(A, B, C, D) callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil4() may only be called within a test.");
+ throw StateError('expectAsyncUntil4() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
@@ -638,10 +630,10 @@
/// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil6] for
/// callbacks with different arity.
Func5<T, A, B, C, D, E> expectAsyncUntil5<T, A, B, C, D, E>(
- T callback(A a, B b, C c, D d, E e), bool isDone(),
+ T Function(A, B, C, D, E) callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil5() may only be called within a test.");
+ throw StateError('expectAsyncUntil5() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
@@ -667,10 +659,10 @@
/// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil5] for
/// callbacks with different arity.
Func6<T, A, B, C, D, E, F> expectAsyncUntil6<T, A, B, C, D, E, F>(
- T callback(A a, B b, C c, D d, E e, F f), bool isDone(),
+ T Function(A, B, C, D, E, F) callback, bool Function() isDone,
{String id, String reason}) {
if (Invoker.current == null) {
- throw StateError("expectAsyncUntil() may only be called within a test.");
+ throw StateError('expectAsyncUntil() may only be called within a test.');
}
return _ExpectedFunction<T>(callback, 0, -1,
diff --git a/test_api/lib/src/frontend/future_matchers.dart b/test_api/lib/src/frontend/future_matchers.dart
index e9566c3..8117395 100644
--- a/test_api/lib/src/frontend/future_matchers.dart
+++ b/test_api/lib/src/frontend/future_matchers.dart
@@ -45,8 +45,9 @@
const _Completes(this._matcher);
// Avoid async/await so we synchronously start listening to [item].
- /*FutureOr<String>*/ matchAsync(item) {
- if (item is! Future) return "was not a Future";
+ @override
+ dynamic /*FutureOr<String>*/ matchAsync(item) {
+ if (item is! Future) return 'was not a Future';
return item.then((value) async {
if (_matcher == null) return null;
@@ -70,6 +71,7 @@
});
}
+ @override
Description describe(Description description) {
if (_matcher == null) {
description.add('completes successfully');
@@ -90,11 +92,13 @@
class _DoesNotComplete extends Matcher {
const _DoesNotComplete();
+ @override
Description describe(Description description) {
- description.add("does not complete");
+ description.add('does not complete');
return description;
}
+ @override
bool matches(item, Map matchState) {
if (item is! Future) return false;
item.then((value) {
@@ -105,9 +109,10 @@
return true;
}
+ @override
Description describeMismatch(
item, Description description, Map matchState, bool verbose) {
- if (item is! Future) return description.add("$item is not a Future");
+ if (item is! Future) return description.add('$item is not a Future');
return description;
}
}
diff --git a/test_api/lib/src/frontend/never_called.dart b/test_api/lib/src/frontend/never_called.dart
index 98bc314..0ea5351 100644
--- a/test_api/lib/src/frontend/never_called.dart
+++ b/test_api/lib/src/frontend/never_called.dart
@@ -57,10 +57,10 @@
zone.handleUncaughtError(
TestFailure(
- "Callback should never have been called, but it was called with" +
+ 'Callback should never have been called, but it was called with' +
(arguments.isEmpty
- ? " no arguments."
- : ":\n${bullet(arguments.map(prettyPrint))}")),
+ ? ' no arguments.'
+ : ':\n${bullet(arguments.map(prettyPrint))}')),
zone.run(() => Chain.current()));
return null;
};
diff --git a/test_api/lib/src/frontend/prints_matcher.dart b/test_api/lib/src/frontend/prints_matcher.dart
index 5f0380e..48cf8a9 100644
--- a/test_api/lib/src/frontend/prints_matcher.dart
+++ b/test_api/lib/src/frontend/prints_matcher.dart
@@ -30,8 +30,9 @@
// Avoid async/await so we synchronously fail if the function is
// synchronous.
- /*FutureOr<String>*/ matchAsync(item) {
- if (item is! Function()) return "was not a unary Function";
+ @override
+ dynamic /*FutureOr<String>*/ matchAsync(item) {
+ if (item is! Function()) return 'was not a unary Function';
var buffer = StringBuffer();
var result = runZoned(item as Function(),
@@ -44,6 +45,7 @@
: _check(buffer.toString());
}
+ @override
Description describe(Description description) =>
description.add('prints ').addDescriptionOf(_matcher);
diff --git a/test_api/lib/src/frontend/spawn_hybrid.dart b/test_api/lib/src/frontend/spawn_hybrid.dart
index 46c9d68..1b0cde2 100644
--- a/test_api/lib/src/frontend/spawn_hybrid.dart
+++ b/test_api/lib/src/frontend/spawn_hybrid.dart
@@ -24,17 +24,17 @@
// `hybridMain` can send any json encodeable type.
final _transformer = StreamChannelTransformer<dynamic, dynamic>(
StreamTransformer.fromHandlers(handleData: (message, sink) {
- switch (message["type"] as String) {
- case "data":
- sink.add(message["data"]);
+ switch (message['type'] as String) {
+ case 'data':
+ sink.add(message['data']);
break;
- case "print":
- print(message["line"]);
+ case 'print':
+ print(message['line']);
break;
- case "error":
- var error = RemoteException.deserialize(message["error"]);
+ case 'error':
+ var error = RemoteException.deserialize(message['error']);
sink.addError(error.error, error.stackTrace);
break;
}
@@ -98,12 +98,12 @@
} else if (uri is String) {
parsedUrl = Uri.parse(uri);
} else {
- throw ArgumentError.value(uri, "uri", "must be a Uri or a String.");
+ throw ArgumentError.value(uri, 'uri', 'must be a Uri or a String.');
}
String absoluteUri;
if (parsedUrl.scheme.isEmpty) {
- var isRootRelative = parsedUrl.path.startsWith("/");
+ var isRootRelative = parsedUrl.path.startsWith('/');
// If we're running in a browser context, the working directory is already
// relative to the test file, whereas on the VM the working directory is the
@@ -113,9 +113,9 @@
// A root-relative URL is interpreted as relative to the package root,
// which means placing it beneath the URL secret.
var secret = Uri.encodeComponent(Uri.base.pathSegments[0]);
- absoluteUri = p.absolute("/$secret$parsedUrl");
- print("Uri.base: ${Uri.base}");
- print("absoluteUri: ${absoluteUri}");
+ absoluteUri = p.absolute('/$secret$parsedUrl');
+ print('Uri.base: ${Uri.base}');
+ print('absoluteUri: ${absoluteUri}');
} else {
absoluteUri = p.absolute(parsedUrl.toString());
}
@@ -192,8 +192,6 @@
StreamChannel _spawn(String uri, Object message, {bool stayAlive = false}) {
var channel = Zone.current[#test.runner.test_channel] as MultiChannel;
if (channel == null) {
- // TODO(nweiz): Link to an issue tracking support when running the test file
- // directly.
throw UnsupportedError("Can't connect to the test runner.\n"
'spawnHybridUri() is currently only supported within "pub run test".');
}
@@ -203,10 +201,10 @@
var virtualChannel = channel.virtualChannel();
StreamChannel isolateChannel = virtualChannel;
channel.sink.add({
- "type": "spawn-hybrid-uri",
- "url": uri,
- "message": message,
- "channel": virtualChannel.id
+ 'type': 'spawn-hybrid-uri',
+ 'url': uri,
+ 'message': message,
+ 'channel': virtualChannel.id
});
if (!stayAlive) {
diff --git a/test_api/lib/src/frontend/stream_matcher.dart b/test_api/lib/src/frontend/stream_matcher.dart
index e37c5c6..b1b96e9 100644
--- a/test_api/lib/src/frontend/stream_matcher.dart
+++ b/test_api/lib/src/frontend/stream_matcher.dart
@@ -6,15 +6,11 @@
import 'package:async/async.dart';
import 'package:matcher/matcher.dart';
-import 'package:pedantic/pedantic.dart';
import '../utils.dart';
import 'async_matcher.dart';
import 'format_stack_trace.dart';
-/// The type for [_StreamMatcher._matchQueue].
-typedef _MatchQueue = Future<String> Function(StreamQueue queue);
-
/// A matcher that matches events from [Stream]s or [StreamQueue]s.
///
/// Stream matchers are designed to make it straightforward to create complex
@@ -46,17 +42,17 @@
/// at different times:
///
/// ```dart
-/// var stdout = new StreamQueue(stdoutLineStream);
+/// var stdout = StreamQueue(stdoutLineStream);
///
/// // Ignore lines from the process until it's about to emit the URL.
-/// await expect(stdout, emitsThrough("WebSocket URL:"));
+/// await expectLater(stdout, emitsThrough('WebSocket URL:'));
///
/// // Parse the next line as a URL.
/// var url = Uri.parse(await stdout.next);
/// expect(url.host, equals('localhost'));
///
/// // You can match against the same StreamQueue multiple times.
-/// await expect(stdout, emits("Waiting for connection..."));
+/// await expectLater(stdout, emits('Waiting for connection...'));
/// ```
///
/// Users can call [new StreamMatcher] to create custom matchers.
@@ -89,7 +85,7 @@
/// should be grammatically valid when used after the word "should". For
/// example, it might be "emit the right events".
factory StreamMatcher(
- Future<String> matchQueue(StreamQueue queue), String description) =
+ Future<String> Function(StreamQueue) matchQueue, String description) =
_StreamMatcher;
/// Tries to match events emitted by [queue].
@@ -116,23 +112,28 @@
/// This is separate from the original type to hide the private [AsyncMatcher]
/// interface.
class _StreamMatcher extends AsyncMatcher implements StreamMatcher {
+ @override
final String description;
/// The callback used to implement [matchQueue].
- final _MatchQueue _matchQueue;
+ final Future<String> Function(StreamQueue) _matchQueue;
_StreamMatcher(this._matchQueue, this.description);
+ @override
Future<String> matchQueue(StreamQueue queue) => _matchQueue(queue);
- /*FutureOr<String>*/ matchAsync(item) {
+ @override
+ dynamic /*FutureOr<String>*/ matchAsync(item) {
StreamQueue queue;
+ var shouldCancelQueue = false;
if (item is StreamQueue) {
queue = item;
} else if (item is Stream) {
queue = StreamQueue(item);
+ shouldCancelQueue = true;
} else {
- return "was not a Stream or a StreamQueue";
+ return 'was not a Stream or a StreamQueue';
}
// Avoid async/await in the outer method so that we synchronously error out
@@ -161,30 +162,34 @@
var eventsString = events.map((event) {
if (event == null) {
- return "x Stream closed.";
+ return 'x Stream closed.';
} else if (event.isValue) {
return addBullet(event.asValue.value.toString());
} else {
var error = event.asError;
var chain = formatStackTrace(error.stackTrace);
- var text = "${error.error}\n$chain";
- return prefixLines(text, " ", first: "! ");
+ var text = '${error.error}\n$chain';
+ return prefixLines(text, ' ', first: '! ');
}
- }).join("\n");
- if (eventsString.isEmpty) eventsString = "no events";
+ }).join('\n');
+ if (eventsString.isEmpty) eventsString = 'no events';
transaction.reject();
var buffer = StringBuffer();
- buffer.writeln(indent(eventsString, first: "emitted "));
- if (result.isNotEmpty) buffer.writeln(indent(result, first: " which "));
+ buffer.writeln(indent(eventsString, first: 'emitted '));
+ if (result.isNotEmpty) buffer.writeln(indent(result, first: ' which '));
return buffer.toString().trimRight();
}, onError: (error) {
transaction.reject();
throw error;
+ }).then((result) {
+ if (shouldCancelQueue) queue.cancel();
+ return result;
});
}
+ @override
Description describe(Description description) =>
- description.add("should ").add(this.description);
+ description.add('should ').add(this.description);
}
diff --git a/test_api/lib/src/frontend/stream_matchers.dart b/test_api/lib/src/frontend/stream_matchers.dart
index dec9859..53f7c8c 100644
--- a/test_api/lib/src/frontend/stream_matchers.dart
+++ b/test_api/lib/src/frontend/stream_matchers.dart
@@ -14,7 +14,7 @@
/// Returns a [StreamMatcher] that asserts that the stream emits a "done" event.
final emitsDone = StreamMatcher(
- (queue) async => (await queue.hasNext) ? "" : null, "be done");
+ (queue) async => (await queue.hasNext) ? '' : null, 'be done');
/// Returns a [StreamMatcher] for [matcher].
///
@@ -32,7 +32,7 @@
var matcherDescription = wrapped.describe(StringDescription());
return StreamMatcher((queue) async {
- if (!await queue.hasNext) return "";
+ if (!await queue.hasNext) return '';
var matchState = {};
var actual = await queue.next;
@@ -41,11 +41,11 @@
var mismatchDescription = StringDescription();
wrapped.describeMismatch(actual, mismatchDescription, matchState, false);
- if (mismatchDescription.length == 0) return "";
- return "emitted an event that $mismatchDescription";
+ if (mismatchDescription.length == 0) return '';
+ return 'emitted an event that $mismatchDescription';
},
// TODO(nweiz): add "should" once matcher#42 is fixed.
- "emit an event that $matcherDescription");
+ 'emit an event that $matcherDescription');
}
/// Returns a [StreamMatcher] that matches a single error event that matches
@@ -58,7 +58,7 @@
return StreamMatcher(
(queue) => throwsMatcher.matchAsync(queue.next) as Future<String>,
// TODO(nweiz): add "should" once matcher#42 is fixed.
- "emit an error that $matcherDescription");
+ 'emit an error that $matcherDescription');
}
/// Returns a [StreamMatcher] that allows (but doesn't require) [matcher] to
@@ -72,7 +72,7 @@
await queue.withTransaction(
(copy) async => (await streamMatcher.matchQueue(copy)) == null);
return null;
- }, "maybe ${streamMatcher.description}");
+ }, 'maybe ${streamMatcher.description}');
}
/// Returns a [StreamMatcher] that matches the stream if at least one of
@@ -87,11 +87,11 @@
StreamMatcher emitsAnyOf(Iterable matchers) {
var streamMatchers = matchers.map(emits).toList();
if (streamMatchers.isEmpty) {
- throw ArgumentError("matcher may not be empty");
+ throw ArgumentError('matcher may not be empty');
}
if (streamMatchers.length == 1) return streamMatchers.first;
- var description = "do one of the following:\n" +
+ var description = 'do one of the following:\n' +
bullet(streamMatchers.map((matcher) => matcher.description));
return StreamMatcher((queue) async {
@@ -143,16 +143,16 @@
var failureMessages = <String>[];
for (var i = 0; i < matchers.length; i++) {
- var message = "failed to ${streamMatchers[i].description}";
+ var message = 'failed to ${streamMatchers[i].description}';
if (failures[i].isNotEmpty) {
- message += message.contains("\n") ? "\n" : " ";
- message += "because it ${failures[i]}";
+ message += message.contains('\n') ? '\n' : ' ';
+ message += 'because it ${failures[i]}';
}
failureMessages.add(message);
}
- return "failed all options:\n${bullet(failureMessages)}";
+ return 'failed all options:\n${bullet(failureMessages)}';
} else {
transaction.commit(consumedMost);
return null;
@@ -168,7 +168,7 @@
var streamMatchers = matchers.map(emits).toList();
if (streamMatchers.length == 1) return streamMatchers.first;
- var description = "do the following in order:\n" +
+ var description = 'do the following in order:\n' +
bullet(streamMatchers.map((matcher) => matcher.description));
return StreamMatcher((queue) async {
@@ -179,8 +179,8 @@
var newResult = "didn't ${matcher.description}";
if (result.isNotEmpty) {
- newResult += newResult.contains("\n") ? "\n" : " ";
- newResult += "because it $result";
+ newResult += newResult.contains('\n') ? '\n' : ' ';
+ newResult += 'because it $result';
}
return newResult;
}
@@ -199,7 +199,7 @@
return StreamMatcher((queue) async {
var failures = <String>[];
- tryHere() => queue.withTransaction((copy) async {
+ Future<bool> tryHere() => queue.withTransaction((copy) async {
var result = await streamMatcher.matchQueue(copy);
if (result == null) return true;
failures.add(result);
@@ -215,17 +215,17 @@
// stream.
if (await tryHere()) return null;
- var result = "never did ${streamMatcher.description}";
+ var result = 'never did ${streamMatcher.description}';
var failureMessages =
bullet(failures.where((failure) => failure.isNotEmpty));
if (failureMessages.isNotEmpty) {
- result += result.contains("\n") ? "\n" : " ";
- result += "because it:\n$failureMessages";
+ result += result.contains('\n') ? '\n' : ' ';
+ result += 'because it:\n$failureMessages';
}
return result;
- }, "eventually ${streamMatcher.description}");
+ }, 'eventually ${streamMatcher.description}');
}
/// Returns a [StreamMatcher] that matches any number of events that match
@@ -238,8 +238,8 @@
var streamMatcher = emits(matcher);
var description = streamMatcher.description;
- description += description.contains("\n") ? "\n" : " ";
- description += "zero or more times";
+ description += description.contains('\n') ? '\n' : ' ';
+ description += 'zero or more times';
return StreamMatcher((queue) async {
while (await _tryMatch(queue, streamMatcher)) {
@@ -279,8 +279,8 @@
if (!matched) return null;
return "after $events ${pluralize('event', events)} did "
- "${streamMatcher.description}";
- }, "never ${streamMatcher.description}");
+ '${streamMatcher.description}';
+ }, 'never ${streamMatcher.description}');
}
/// Returns whether [matcher] matches [queue] at its current position.
@@ -312,11 +312,11 @@
StreamMatcher emitsInAnyOrder(Iterable matchers) {
var streamMatchers = matchers.map(emits).toSet();
if (streamMatchers.length == 1) return streamMatchers.first;
- var description = "do the following in any order:\n" +
+ var description = 'do the following in any order:\n' +
bullet(streamMatchers.map((matcher) => matcher.description));
return StreamMatcher(
- (queue) async => await _tryInAnyOrder(queue, streamMatchers) ? null : "",
+ (queue) async => await _tryInAnyOrder(queue, streamMatchers) ? null : '',
description);
}
diff --git a/test_api/lib/src/frontend/throws_matcher.dart b/test_api/lib/src/frontend/throws_matcher.dart
index c6e34d7..cdf9c6e 100644
--- a/test_api/lib/src/frontend/throws_matcher.dart
+++ b/test_api/lib/src/frontend/throws_matcher.dart
@@ -15,7 +15,7 @@
/// Use [throwsA] instead. We strongly recommend that you add assertions about
/// at least the type of the error, but you can write `throwsA(anything)` to
/// mimic the behavior of this matcher.
-@Deprecated("Will be removed in 0.13.0")
+@Deprecated('Will be removed in 0.13.0')
const Matcher throws = Throws();
/// This can be used to match three kinds of objects:
@@ -38,17 +38,18 @@
Matcher throwsA(matcher) => Throws(wrapMatcher(matcher));
/// Use the [throwsA] function instead.
-@Deprecated("Will be removed in 0.13.0")
+@Deprecated('Will be removed in 0.13.0')
class Throws extends AsyncMatcher {
final Matcher _matcher;
- const Throws([Matcher matcher]) : this._matcher = matcher;
+ const Throws([Matcher matcher]) : _matcher = matcher;
// Avoid async/await so we synchronously fail if we match a synchronous
// function.
- /*FutureOr<String>*/ matchAsync(item) {
+ @override
+ dynamic /*FutureOr<String>*/ matchAsync(item) {
if (item is! Function && item is! Future) {
- return "was not a Function or Future";
+ return 'was not a Function or Future';
}
if (item is Future) {
@@ -71,9 +72,10 @@
}
}
+ @override
Description describe(Description description) {
if (_matcher == null) {
- return description.add("throws");
+ return description.add('throws');
} else {
return description.add('throws ').addDescriptionOf(_matcher);
}
diff --git a/test_api/lib/src/frontend/timeout.dart b/test_api/lib/src/frontend/timeout.dart
index 21b8890..9c1e02e 100644
--- a/test_api/lib/src/frontend/timeout.dart
+++ b/test_api/lib/src/frontend/timeout.dart
@@ -9,18 +9,18 @@
/// This is intended to scan through a number without actually encoding the full
/// Dart number grammar. It doesn't stop on "e" because that can be a component
/// of numbers.
-final _untilUnit = RegExp(r"[^a-df-z\s]+", caseSensitive: false);
+final _untilUnit = RegExp(r'[^a-df-z\s]+', caseSensitive: false);
/// A regular expression that matches a time unit.
-final _unit = RegExp(r"([um]s|[dhms])", caseSensitive: false);
+final _unit = RegExp(r'([um]s|[dhms])', caseSensitive: false);
/// A regular expression that matches a section of whitespace.
-final _whitespace = RegExp(r"\s+");
+final _whitespace = RegExp(r'\s+');
/// A class representing a modification to the default timeout for a test.
///
/// By default, a test will time out after 30 seconds. With [new Timeout], that
-/// can be overridden entirely; with [new Timeout.factor], it can be scaled
+/// can be overridden entirely; with [Timeout.factor], it can be scaled
/// relative to the default.
class Timeout {
/// A constant indicating that a test should never time out.
@@ -70,17 +70,17 @@
var scanner = StringScanner(timeout);
// First check for the string "none".
- if (scanner.scan("none")) {
+ if (scanner.scan('none')) {
scanner.expectDone();
return Timeout.none;
}
// Scan a number. This will be either a time unit or a scale factor.
- scanner.expect(_untilUnit, name: "number");
+ scanner.expect(_untilUnit, name: 'number');
var number = double.parse(scanner.lastMatch[0]);
// A number followed by "x" is a scale factor.
- if (scanner.scan("x") || scanner.scan("X")) {
+ if (scanner.scan('x') || scanner.scan('X')) {
scanner.expectDone();
return Timeout.factor(number);
}
@@ -89,7 +89,7 @@
// the loop because we've already parsed the first number.
var microseconds = 0.0;
while (true) {
- scanner.expect(_unit, name: "unit");
+ scanner.expect(_unit, name: 'unit');
microseconds += _microsecondsFor(number, scanner.lastMatch[0]);
scanner.scan(_whitespace);
@@ -106,20 +106,20 @@
/// Returns the number of microseconds in [number] [unit]s.
static double _microsecondsFor(double number, String unit) {
switch (unit) {
- case "d":
+ case 'd':
return number * 24 * 60 * 60 * 1000000;
- case "h":
+ case 'h':
return number * 60 * 60 * 1000000;
- case "m":
+ case 'm':
return number * 60 * 1000000;
- case "s":
+ case 's':
return number * 1000000;
- case "ms":
+ case 'ms':
return number * 1000;
- case "us":
+ case 'us':
return number;
default:
- throw ArgumentError("Unknown unit $unit.");
+ throw ArgumentError('Unknown unit $unit.');
}
}
@@ -141,19 +141,22 @@
/// If this is [none], returns `null`.
Duration apply(Duration base) {
if (this == none) return null;
- return duration == null ? base * scaleFactor : duration;
+ return duration ?? base * scaleFactor;
}
+ @override
int get hashCode => duration.hashCode ^ 5 * scaleFactor.hashCode;
+ @override
bool operator ==(other) =>
other is Timeout &&
other.duration == duration &&
other.scaleFactor == scaleFactor;
+ @override
String toString() {
if (duration != null) return duration.toString();
- if (scaleFactor != null) return "${scaleFactor}x";
- return "none";
+ if (scaleFactor != null) return '${scaleFactor}x';
+ return 'none';
}
}
diff --git a/test_api/lib/src/frontend/utils.dart b/test_api/lib/src/frontend/utils.dart
index c91e16e..17dc2bd 100644
--- a/test_api/lib/src/frontend/utils.dart
+++ b/test_api/lib/src/frontend/utils.dart
@@ -14,9 +14,6 @@
Future pumpEventQueue({int times}) {
times ??= 20;
if (times == 0) return Future.value();
- // Use [new Future] future to allow microtask events to finish. The [new
- // Future.value] constructor uses scheduleMicrotask itself and would therefore
- // not wait for microtask callbacks that are scheduled after invoking this
- // method.
+ // Use the event loop to allow the microtask queue to finish.
return Future(() => pumpEventQueue(times: times - 1));
}
diff --git a/test_api/lib/src/remote_listener.dart b/test_api/lib/src/remote_listener.dart
index 970b598..e745eb4 100644
--- a/test_api/lib/src/remote_listener.dart
+++ b/test_api/lib/src/remote_listener.dart
@@ -44,8 +44,8 @@
///
/// If [beforeLoad] is passed, it's called before the tests have been declared
/// for this worker.
- static StreamChannel start(Function getMain(),
- {bool hidePrints = true, Future beforeLoad()}) {
+ static StreamChannel start(Function Function() getMain,
+ {bool hidePrints = true, Future Function() beforeLoad}) {
// This has to be synchronous to work around sdk#25745. Otherwise, there'll
// be an asynchronous pause before a syntax error notification is sent,
// which will cause the send to fail entirely.
@@ -58,7 +58,7 @@
var printZone = hidePrints ? null : Zone.current;
var spec = ZoneSpecification(print: (_, __, ___, line) {
if (printZone != null) printZone.print(line);
- channel.sink.add({"type": "print", "line": line});
+ channel.sink.add({'type': 'print', 'line': line});
});
// Work-around for https://github.com/dart-lang/sdk/issues/32556. Remove
@@ -73,7 +73,7 @@
main = getMain();
} on NoSuchMethodError catch (_) {
_sendLoadException(
- channel, "No top-level main() function defined.");
+ channel, 'No top-level main() function defined.');
return;
} catch (error, stackTrace) {
_sendError(channel, error, stackTrace, verboseChain);
@@ -82,11 +82,11 @@
if (main is! Function) {
_sendLoadException(
- channel, "Top-level main getter is not a function.");
+ channel, 'Top-level main getter is not a function.');
return;
} else if (main is! Function()) {
_sendLoadException(
- channel, "Top-level main() function takes arguments.");
+ channel, 'Top-level main() function takes arguments.');
return;
}
@@ -95,12 +95,12 @@
assert(message['type'] == 'initial');
queue.rest.listen((message) {
- if (message["type"] == "close") {
+ if (message['type'] == 'close') {
controller.local.sink.close();
return;
}
- assert(message["type"] == "suiteChannel");
+ assert(message['type'] == 'suiteChannel');
SuiteChannelManager.current.connectIn(message['name'] as String,
channel.virtualChannel(message['id'] as int));
});
@@ -155,15 +155,15 @@
///
/// [message] should describe the failure.
static void _sendLoadException(StreamChannel channel, String message) {
- channel.sink.add({"type": "loadException", "message": message});
+ channel.sink.add({'type': 'loadException', 'message': message});
}
/// Sends a message over [channel] indicating an error from user code.
static void _sendError(
StreamChannel channel, error, StackTrace stackTrace, bool verboseChain) {
channel.sink.add({
- "type": "error",
- "error": RemoteException.serialize(
+ 'type': 'error',
+ 'error': RemoteException.serialize(
error,
StackTraceFormatter.current
.formatStackTrace(stackTrace, verbose: verboseChain))
@@ -176,8 +176,8 @@
/// commands to run the tests.
void _listen(MultiChannel channel) {
channel.sink.add({
- "type": "success",
- "root": _serializeGroup(channel, _suite.group, [])
+ 'type': 'success',
+ 'root': _serializeGroup(channel, _suite.group, [])
});
}
@@ -188,13 +188,13 @@
MultiChannel channel, Group group, Iterable<Group> parents) {
parents = parents.toList()..add(group);
return {
- "type": "group",
- "name": group.name,
- "metadata": group.metadata.serialize(),
- "trace": group.trace?.toString(),
- "setUpAll": _serializeTest(channel, group.setUpAll, parents),
- "tearDownAll": _serializeTest(channel, group.tearDownAll, parents),
- "entries": group.entries.map((entry) {
+ 'type': 'group',
+ 'name': group.name,
+ 'metadata': group.metadata.serialize(),
+ 'trace': group.trace?.toString(),
+ 'setUpAll': _serializeTest(channel, group.setUpAll, parents),
+ 'tearDownAll': _serializeTest(channel, group.tearDownAll, parents),
+ 'entries': group.entries.map((entry) {
return entry is Group
? _serializeGroup(channel, entry, parents)
: _serializeTest(channel, entry as Test, parents);
@@ -217,11 +217,11 @@
});
return {
- "type": "test",
- "name": test.name,
- "metadata": test.metadata.serialize(),
- "trace": test.trace?.toString(),
- "channel": testChannel.id
+ 'type': 'test',
+ 'name': test.name,
+ 'metadata': test.metadata.serialize(),
+ 'trace': test.trace?.toString(),
+ 'channel': testChannel.id
};
}
@@ -234,16 +234,16 @@
liveTest.onStateChange.listen((state) {
channel.sink.add({
- "type": "state-change",
- "status": state.status.name,
- "result": state.result.name
+ 'type': 'state-change',
+ 'status': state.status.name,
+ 'result': state.result.name
});
});
liveTest.onError.listen((asyncError) {
channel.sink.add({
- "type": "error",
- "error": RemoteException.serialize(
+ 'type': 'error',
+ 'error': RemoteException.serialize(
asyncError.error,
StackTraceFormatter.current.formatStackTrace(asyncError.stackTrace,
verbose: liveTest.test.metadata.verboseTrace))
@@ -253,14 +253,14 @@
liveTest.onMessage.listen((message) {
if (_printZone != null) _printZone.print(message.text);
channel.sink.add({
- "type": "message",
- "message-type": message.type.name,
- "text": message.text
+ 'type': 'message',
+ 'message-type': message.type.name,
+ 'text': message.text
});
});
runZoned(() {
- liveTest.run().then((_) => channel.sink.add({"type": "complete"}));
+ liveTest.run().then((_) => channel.sink.add({'type': 'complete'}));
}, zoneValues: {#test.runner.test_channel: channel});
}
}
diff --git a/test_api/lib/src/suite_channel_manager.dart b/test_api/lib/src/suite_channel_manager.dart
index aebe837..1f70d5f 100644
--- a/test_api/lib/src/suite_channel_manager.dart
+++ b/test_api/lib/src/suite_channel_manager.dart
@@ -20,7 +20,7 @@
final _outgoingConnections = <String, StreamChannelCompleter>{};
/// The channel names that have already been used.
- final _names = Set<String>();
+ final _names = <String>{};
/// Returns the current manager, or `null` if this isn't called within a call
/// to [asCurrent].
@@ -31,7 +31,8 @@
///
/// This is zone-scoped, so [this] will be the current configuration in any
/// asynchronous callbacks transitively created by [body].
- T asCurrent<T>(T body()) => runZoned(body, zoneValues: {_currentKey: this});
+ T asCurrent<T>(T Function() body) =>
+ runZoned(body, zoneValues: {_currentKey: this});
/// Creates a connection to the test runnner's channel with the given [name].
StreamChannel connectOut(String name) {
diff --git a/test_api/lib/src/util/iterable_set.dart b/test_api/lib/src/util/iterable_set.dart
index 5166a72..bba6433 100644
--- a/test_api/lib/src/util/iterable_set.dart
+++ b/test_api/lib/src/util/iterable_set.dart
@@ -19,17 +19,22 @@
/// The base iterable that set operations forward to.
final Iterable<E> _base;
+ @override
int get length => _base.length;
+ @override
Iterator<E> get iterator => _base.iterator;
/// Creates a [Set] view of [base].
IterableSet(this._base);
+ @override
bool contains(Object element) => _base.contains(element);
+ @override
E lookup(Object needle) =>
_base.firstWhere((element) => element == needle, orElse: () => null);
+ @override
Set<E> toSet() => _base.toSet();
}
diff --git a/test_api/lib/src/util/remote_exception.dart b/test_api/lib/src/util/remote_exception.dart
index a0582d5..bb6fc62 100644
--- a/test_api/lib/src/util/remote_exception.dart
+++ b/test_api/lib/src/util/remote_exception.dart
@@ -29,7 +29,7 @@
///
/// Other than JSON- and isolate-safety, no guarantees are made about the
/// serialized format.
- static serialize(error, StackTrace stackTrace) {
+ static Map<String, dynamic> serialize(error, StackTrace stackTrace) {
String message;
if (error is String) {
message = error;
@@ -77,6 +77,7 @@
RemoteException._(this.message, this.type, this._toString);
+ @override
String toString() => _toString;
}
diff --git a/test_api/lib/src/util/test.dart b/test_api/lib/src/util/test.dart
index ae5e6a8..de36fbf 100644
--- a/test_api/lib/src/util/test.dart
+++ b/test_api/lib/src/util/test.dart
@@ -13,7 +13,7 @@
/// callbacks registered outside of [body].
///
/// This may only be called within a test.
-Future errorsDontStopTest(body()) {
+Future errorsDontStopTest(dynamic Function() body) {
var completer = Completer();
Invoker.current.addOutstandingCallback();
diff --git a/test_api/lib/src/utils.dart b/test_api/lib/src/utils.dart
index 2e90a7c..ee1cde6 100644
--- a/test_api/lib/src/utils.dart
+++ b/test_api/lib/src/utils.dart
@@ -31,7 +31,7 @@
final chunksToLines = StreamChannelTransformer<String, String>(
const LineSplitter(),
StreamSinkTransformer.fromHandlers(
- handleData: (data, sink) => sink.add("$data\n")));
+ handleData: (data, sink) => sink.add('$data\n')));
/// A regular expression to match the exception prefix that some exceptions'
/// [Object.toString] values contain.
@@ -43,8 +43,13 @@
/// Directories that are specific to OS X.
///
/// This is used to try to distinguish OS X and Linux in [currentOSGuess].
-final _macOSDirectories = Set<String>.from(
- ["/Applications", "/Library", "/Network", "/System", "/Users"]);
+final _macOSDirectories = {
+ '/Applications',
+ '/Library',
+ '/Network',
+ '/System',
+ '/Users',
+};
/// Returns the best guess for the current operating system without using
/// `dart:io`.
@@ -63,12 +68,12 @@
///
/// This is like a standard Dart identifier, except that it can also contain
/// hyphens.
-final _hyphenatedIdentifier = RegExp(r"[a-zA-Z_-][a-zA-Z0-9_-]*");
+final _hyphenatedIdentifier = RegExp(r'[a-zA-Z_-][a-zA-Z0-9_-]*');
/// Like [_hyphenatedIdentifier], but anchored so that it must match the entire
/// string.
final anchoredHyphenatedIdentifier =
- RegExp("^${_hyphenatedIdentifier.pattern}\$");
+ RegExp('^${_hyphenatedIdentifier.pattern}\$');
/// A pair of values.
class Pair<E, F> {
@@ -77,13 +82,16 @@
Pair(this.first, this.last);
+ @override
String toString() => '($first, $last)';
+ @override
bool operator ==(other) {
if (other is! Pair) return false;
return other.first == first && other.last == last;
}
+ @override
int get hashCode => first.hashCode ^ last.hashCode;
}
@@ -100,7 +108,7 @@
/// [size] defaults to `first.length`. Otherwise, [size] defaults to 2.
String indent(String string, {int size, String first}) {
size ??= first == null ? 2 : first.length;
- return prefixLines(string, " " * size, first: first);
+ return prefixLines(string, ' ' * size, first: first);
}
/// Returns a sentence fragment listing the elements of [iter].
@@ -111,8 +119,8 @@
String toSentence(Iterable iter, {String conjunction}) {
if (iter.length == 1) return iter.first.toString();
- var result = iter.take(iter.length - 1).join(", ");
- if (iter.length > 2) result += ",";
+ var result = iter.take(iter.length - 1).join(', ');
+ if (iter.length > 2) result += ',';
return "$result ${conjunction ?? 'and'} ${iter.last}";
}
@@ -128,7 +136,7 @@
/// Returns [noun] with an indefinite article ("a" or "an") added, based on
/// whether its first letter is a vowel.
-String a(String noun) => noun.startsWith(_vowel) ? "an $noun" : "a $noun";
+String a(String noun) => noun.startsWith(_vowel) ? 'an $noun' : 'a $noun';
/// A regular expression matching terminal color codes.
final _colorCode = RegExp('\u001b\\[[0-9;]+m');
@@ -141,7 +149,7 @@
///
/// The return value *may or may not* be unmodifiable.
Map<K, V> mergeUnmodifiableMaps<K, V>(Map<K, V> map1, Map<K, V> map2,
- {V value(V value1, V value2)}) {
+ {V Function(V, V) value}) {
if (map1.isEmpty) return map2;
if (map2.isEmpty) return map1;
return mergeMaps(map1, map2, value: value);
@@ -195,13 +203,13 @@
var decaseconds = (duration.inMilliseconds % 1000) ~/ 100;
var buffer = StringBuffer();
- if (minutes != 0) buffer.write("$minutes minutes");
+ if (minutes != 0) buffer.write('$minutes minutes');
if (minutes == 0 || seconds != 0) {
- if (minutes != 0) buffer.write(", ");
+ if (minutes != 0) buffer.write(', ');
buffer.write(seconds);
- if (decaseconds != 0) buffer.write(".$decaseconds");
- buffer.write(" seconds");
+ if (decaseconds != 0) buffer.write('.$decaseconds');
+ buffer.write(' seconds');
}
return buffer.toString();
@@ -233,14 +241,6 @@
return controller.stream;
}
-/// Runs [fn] and discards its return value.
-///
-/// This is useful for making a block of code async without forcing the
-/// containing method to return a future.
-void invoke(fn()) {
- fn();
-}
-
/// Returns a random base64 string containing [bytes] bytes of data.
///
/// [seed] is passed to [math.Random].
@@ -279,10 +279,10 @@
/// Indents [text], and adds a bullet at the beginning.
String addBullet(String text) =>
- prefixLines(text, " ", first: "${glyph.bullet} ");
+ prefixLines(text, ' ', first: '${glyph.bullet} ');
/// Converts [strings] to a bulleted list.
-String bullet(Iterable<String> strings) => strings.map(addBullet).join("\n");
+String bullet(Iterable<String> strings) => strings.map(addBullet).join('\n');
/// Prepends each line in [text] with [prefix].
///
@@ -297,15 +297,15 @@
single ??= first ?? last ?? prefix;
var lines = text.split('\n');
- if (lines.length == 1) return "$single$text";
+ if (lines.length == 1) return '$single$text';
- var buffer = StringBuffer("$first${lines.first}\n");
+ var buffer = StringBuffer('$first${lines.first}\n');
// Write out all but the first and last lines with [prefix].
for (var line in lines.skip(1).take(lines.length - 2)) {
- buffer.writeln("$prefix$line");
+ buffer.writeln('$prefix$line');
}
- buffer.write("$last${lines.last}");
+ buffer.write('$last${lines.last}');
return buffer.toString();
}
@@ -315,3 +315,12 @@
/// we can use it through StringDescription.
String prettyPrint(value) =>
StringDescription().addDescriptionOf(value).toString();
+
+/// Indicates to tools that [future] is intentionally not `await`-ed.
+///
+/// In an `async` context, it is normally expected that all [Future]s are
+/// awaited, and that is the basis of the lint `unawaited_futures`. However,
+/// there are times where one or more futures are intentionally not awaited.
+/// This function may be used to ignore a particular future. It silences the
+/// `unawaited_futures` lint.
+void unawaited(Future<void> future) {}
diff --git a/test_api/lib/test_api.dart b/test_api/lib/test_api.dart
index 9fab4e1..2927580 100644
--- a/test_api/lib/test_api.dart
+++ b/test_api/lib/test_api.dart
@@ -73,15 +73,15 @@
/// annotation classes: [Timeout], [Skip], or lists of those. These
/// annotations apply only on the given platforms. For example:
///
-/// test("potentially slow test", () {
+/// test('potentially slow test', () {
/// // ...
/// }, onPlatform: {
/// // This test is especially slow on Windows.
-/// "windows": new Timeout.factor(2),
-/// "browser": [
-/// new Skip("TODO: add browser support"),
+/// 'windows': Timeout.factor(2),
+/// 'browser': [
+/// Skip('TODO: add browser support'),
/// // This will be slow on browsers once it works on them.
-/// new Timeout.factor(2)
+/// Timeout.factor(2)
/// ]
/// });
///
@@ -94,7 +94,7 @@
/// avoid this flag if possible and instead use the test runner flag `-n` to
/// filter tests by name.
@isTest
-void test(description, body(),
+void test(description, dynamic Function() body,
{String testOn,
Timeout timeout,
skip,
@@ -151,15 +151,15 @@
/// annotation classes: [Timeout], [Skip], or lists of those. These
/// annotations apply only on the given platforms. For example:
///
-/// group("potentially slow tests", () {
+/// group('potentially slow tests', () {
/// // ...
/// }, onPlatform: {
/// // These tests are especially slow on Windows.
-/// "windows": new Timeout.factor(2),
-/// "browser": [
-/// new Skip("TODO: add browser support"),
+/// 'windows': Timeout.factor(2),
+/// 'browser': [
+/// Skip('TODO: add browser support'),
/// // They'll be slow on browsers once it works on them.
-/// new Timeout.factor(2)
+/// Timeout.factor(2)
/// ]
/// });
///
@@ -172,7 +172,7 @@
/// avoid this flag if possible, and instead use the test runner flag `-n` to
/// filter tests by name.
@isTestGroup
-void group(description, body(),
+void group(description, dynamic Function() body,
{String testOn,
Timeout timeout,
skip,
@@ -207,7 +207,7 @@
///
/// Each callback at the top level or in a given group will be run in the order
/// they were declared.
-void setUp(callback()) => _declarer.setUp(callback);
+void setUp(dynamic Function() callback) => _declarer.setUp(callback);
/// Registers a function to be run after tests.
///
@@ -222,7 +222,7 @@
/// reverse of the order they were declared.
///
/// See also [addTearDown], which adds tear-downs to a running test.
-void tearDown(callback()) => _declarer.tearDown(callback);
+void tearDown(dynamic Function() callback) => _declarer.tearDown(callback);
/// Registers a function to be run after the current test.
///
@@ -235,9 +235,9 @@
///
/// If this is called from within a [setUpAll] or [tearDownAll] callback, it
/// instead runs the function after *all* tests in the current test suite.
-void addTearDown(callback()) {
+void addTearDown(dynamic Function() callback) {
if (Invoker.current == null) {
- throw StateError("addTearDown() may only be called within a test.");
+ throw StateError('addTearDown() may only be called within a test.');
}
Invoker.current.addTearDown(callback);
@@ -256,7 +256,7 @@
/// dependencies between tests that should be isolated. In general, you should
/// prefer [setUp], and only use [setUpAll] if the callback is prohibitively
/// slow.
-void setUpAll(callback()) => _declarer.setUpAll(callback);
+void setUpAll(dynamic Function() callback) => _declarer.setUpAll(callback);
/// Registers a function to be run once after all tests.
///
@@ -269,7 +269,8 @@
/// dependencies between tests that should be isolated. In general, you should
/// prefer [tearDown], and only use [tearDownAll] if the callback is
/// prohibitively slow.
-void tearDownAll(callback()) => _declarer.tearDownAll(callback);
+void tearDownAll(dynamic Function() callback) =>
+ _declarer.tearDownAll(callback);
/// Registers an exception that was caught for the current test.
void registerException(error, [StackTrace stackTrace]) {
diff --git a/test_api/mono_pkg.yaml b/test_api/mono_pkg.yaml
index 62b9aba..5f08191 100644
--- a/test_api/mono_pkg.yaml
+++ b/test_api/mono_pkg.yaml
@@ -6,7 +6,7 @@
dart: dev
- group:
- dartanalyzer: --fatal-warnings .
- dart: 2.1.0
+ dart: 2.4.0
- unit_test:
- group:
- test: --preset travis
diff --git a/test_api/pubspec.yaml b/test_api/pubspec.yaml
index eab4b86..8b34a9c 100644
--- a/test_api/pubspec.yaml
+++ b/test_api/pubspec.yaml
@@ -1,19 +1,17 @@
name: test_api
-version: 0.2.11
-author: Dart Team <misc@dartlang.org>
+version: 0.2.15
description: A library for writing Dart tests.
homepage: https://github.com/dart-lang/test/blob/master/pkgs/test_api
environment:
- sdk: ">=2.2.0 <3.0.0"
+ sdk: ">=2.4.0 <3.0.0"
dependencies:
async: ^2.0.0
- boolean_selector: ^1.0.0
+ boolean_selector: ">=1.0.0 <3.0.0"
collection: ^1.8.0
meta: ^1.1.5
path: ^1.2.0
- pedantic: ^1.0.0
source_span: ^1.4.0
stack_trace: ^1.9.0
stream_channel: ">=1.7.0 <3.0.0"
@@ -26,6 +24,7 @@
dev_dependencies:
fake_async: ^1.0.0
+ pedantic: ^1.0.0
test_descriptor: ^1.0.0
test_process: ^1.0.0
test: any
diff --git a/test_core/BUILD.gn b/test_core/BUILD.gn
index 033d445..f8e5333 100644
--- a/test_core/BUILD.gn
+++ b/test_core/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for test_core-0.2.15
+# This file is generated by importer.py for test_core-0.3.2
import("//build/dart/dart_library.gni")
@@ -23,13 +23,12 @@
"//third_party/dart-pkg/pub/meta",
"//third_party/dart-pkg/pub/analyzer",
"//third_party/dart-pkg/pub/io",
- "//third_party/dart-pkg/pub/source_span",
"//third_party/dart-pkg/pub/path",
+ "//third_party/dart-pkg/pub/source_span",
"//third_party/dart-pkg/pub/stream_channel",
"//third_party/dart-pkg/pub/pool",
"//third_party/dart-pkg/pub/source_maps",
"//third_party/dart-pkg/pub/source_map_stack_trace",
- "//third_party/dart-pkg/pub/package_resolver",
"//third_party/dart-pkg/pub/yaml",
"//third_party/dart-pkg/pub/vm_service",
"//third_party/dart-pkg/pub/boolean_selector",
diff --git a/test_core/CHANGELOG.md b/test_core/CHANGELOG.md
index cb4d969..dcb572a 100644
--- a/test_core/CHANGELOG.md
+++ b/test_core/CHANGELOG.md
@@ -1,3 +1,51 @@
+## 0.3.2
+
+* Drop the `package_resolver` dependency.
+
+## 0.3.1
+
+* Support latest `package:vm_service`.
+* Enable asserts in code running through `spawnHybrid` APIs.
+* Exit with a non-zero code if no tests were ran, whether due to skips or having
+ no tests defined.
+
+## 0.3.0
+
+* Bump minimum SDK to `2.4.0` for safer usage of for-loop elements.
+* Deprecate `PhantomJS` and provide warning when used. Support for `PhantomJS`
+ will be removed in version `2.0.0`.
+* Differentiate between test-randomize-ordering-seed not set and 0 being chosen
+ as the random seed.
+* `deserializeSuite` now takes an optional `gatherCoverage` callback.
+* Support retrying of entire test suites when they fail to load.
+* Fix the `compiling` message in precompiled mode so it says `loading` instead,
+ which is more accurate.
+* Change the behavior of the concurrency setting so that loading and running
+ don't have separate pools.
+ * The loading and running of a test are now done with the same resource, and
+ the concurrency setting uniformly affects each. With `-j1` only a single
+ test will ever be loaded at a time.
+ * Previously the loading pool was 2x larger than the actual concurrency
+ setting which could cause flaky tests due to tests being loaded while
+ other tests were running, even with `-j1`.
+* Avoid printing uncaught errors within `spawnHybridUri`.
+
+## 0.2.18
+
+* Allow `test_api` `0.2.13` to work around a bug in the SDK version `2.3.0`.
+
+## 0.2.17
+
+* Add `file_reporters` configuration option and `--file-reporter` CLI option to
+ allow specifying a separate reporter that writes to a file instead of stdout.
+
+## 0.2.16
+
+* Internal cleanup.
+* Add `customHtmlTemplateFile` configuration option to allow sharing an
+ html template between tests
+* Depend on the latest `test_api`.
+
## 0.2.15
* Add a `StringSink` argument to reporters to prepare for reporting to a file.
diff --git a/test_core/lib/src/bootstrap/vm.dart b/test_core/lib/src/bootstrap/vm.dart
index d18366e..41b9269 100644
--- a/test_core/lib/src/bootstrap/vm.dart
+++ b/test_core/lib/src/bootstrap/vm.dart
@@ -2,14 +2,14 @@
// 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:isolate";
+import 'dart:isolate';
-import "package:stream_channel/isolate_channel.dart";
+import 'package:stream_channel/isolate_channel.dart';
-import "package:test_core/src/runner/plugin/remote_platform_helpers.dart";
+import 'package:test_core/src/runner/plugin/remote_platform_helpers.dart';
/// Bootstraps a vm test to communicate with the test runner.
-void internalBootstrapVmTest(Function getMain(), SendPort sendPort) {
+void internalBootstrapVmTest(Function Function() getMain, SendPort sendPort) {
var channel = serializeSuite(getMain);
IsolateChannel.connectSend(sendPort).pipe(channel);
}
diff --git a/test_core/lib/src/executable.dart b/test_core/lib/src/executable.dart
index f1e3bb5..f3749f0 100644
--- a/test_core/lib/src/executable.dart
+++ b/test_core/lib/src/executable.dart
@@ -2,9 +2,6 @@
// 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.
-// TODO(nweiz): This is under lib so that it can be used by the unittest dummy
-// package. Once that package is no longer being updated, move this back into
-// bin.
import 'dart:async';
import 'dart:io';
@@ -14,11 +11,10 @@
import 'package:stack_trace/stack_trace.dart';
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
-import 'runner.dart';
import 'runner/application_exception.dart';
import 'runner/configuration.dart';
import 'runner/version.dart';
-
+import 'runner.dart';
import 'util/exit_codes.dart' as exit_codes;
import 'util/io.dart';
@@ -36,7 +32,7 @@
}
}();
-main(List<String> args) async {
+Future<void> main(List<String> args) async {
await _execute(args);
completeShutdown();
}
@@ -159,9 +155,9 @@
} catch (error, stackTrace) {
stderr.writeln(getErrorMessage(error));
stderr.writeln(Trace.from(stackTrace).terse);
- stderr.writeln("This is an unexpected error. Please file an issue at "
- "http://github.com/dart-lang/test\n"
- "with the stack trace and instructions for reproducing the error.");
+ stderr.writeln('This is an unexpected error. Please file an issue at '
+ 'http://github.com/dart-lang/test\n'
+ 'with the stack trace and instructions for reproducing the error.');
exitCode = exit_codes.software;
} finally {
await runner?.close();
@@ -169,7 +165,7 @@
// TODO(grouma) - figure out why the executable can hang in the travis
// environment. https://github.com/dart-lang/test/issues/599
- if (Platform.environment["FORCE_TEST_EXIT"] == "true") {
+ if (Platform.environment['FORCE_TEST_EXIT'] == 'true') {
exit(exitCode);
}
@@ -183,16 +179,16 @@
void _printUsage([String error]) {
var output = stdout;
- var message = "Runs tests in this package.";
+ var message = 'Runs tests in this package.';
if (error != null) {
message = error;
output = stderr;
}
- output.write("""${wordWrap(message)}
+ output.write('''${wordWrap(message)}
Usage: pub run test [files or directories...]
${Configuration.usage}
-""");
+''');
}
diff --git a/test_core/lib/src/runner.dart b/test_core/lib/src/runner.dart
index 68a3331..89ed8bd 100644
--- a/test_core/lib/src/runner.dart
+++ b/test_core/lib/src/runner.dart
@@ -16,6 +16,7 @@
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
+import 'package:test_core/src/runner/reporter/multiplex.dart';
import 'util/io.dart';
import 'runner/application_exception.dart';
@@ -58,7 +59,7 @@
///
/// This is used to avoid printing duplicate warnings when a suite is loaded
/// on multiple platforms.
- final _tagWarningSuites = Set<String>();
+ final _tagWarningSuites = <String>{};
/// The current debug operation, if any.
///
@@ -69,17 +70,36 @@
final _closeMemo = AsyncMemoizer();
bool get _closed => _closeMemo.hasRun;
+ /// Sinks created for each file reporter (if there are any).
+ final List<IOSink> _sinks;
+
/// Creates a new runner based on [configuration].
factory Runner(Configuration config) => config.asCurrent(() {
var engine =
Engine(concurrency: config.concurrency, coverage: config.coverage);
- var reporterDetails = allReporters[config.reporter];
+ var sinks = <IOSink>[];
+ Reporter createFileReporter(String reporterName, String filepath) {
+ final sink =
+ (File(filepath)..createSync(recursive: true)).openWrite();
+ sinks.add(sink);
+ return allReporters[reporterName].factory(config, engine, sink);
+ }
+
return Runner._(
- engine, reporterDetails.factory(config, engine, stdout));
+ engine,
+ MultiplexReporter([
+ // Standard reporter.
+ allReporters[config.reporter].factory(config, engine, stdout),
+ // File reporters.
+ for (var reporter in config.fileReporters.keys)
+ createFileReporter(reporter, config.fileReporters[reporter]),
+ ]),
+ sinks,
+ );
});
- Runner._(this._engine, this._reporter);
+ Runner._(this._engine, this._reporter, this._sinks);
/// Starts the runner.
///
@@ -87,7 +107,7 @@
/// or not they ran successfully.
Future<bool> run() => _config.asCurrent(() async {
if (_closed) {
- throw StateError("run() may not be called on a closed Runner.");
+ throw StateError('run() may not be called on a closed Runner.');
}
_warnForUnsupportedPlatforms();
@@ -140,9 +160,8 @@
throw ApplicationException('No tests match $patterns.');
}
- // Explicitly check "== true" here because [Engine.run] can return `null`
- // if the engine was closed prematurely.
- return success == true;
+ return (success ?? false) &&
+ (_engine.passed.isNotEmpty || _engine.skipped.isNotEmpty);
});
/// Emits a warning if the user is trying to run on a platform that's
@@ -175,7 +194,7 @@
unsupportedNames
.addAll(unsupportedBrowsers.map((runtime) => runtime.name));
} else {
- unsupportedNames.add("browsers");
+ unsupportedNames.add('browsers');
}
}
@@ -188,13 +207,13 @@
if (supportsAnyOS) {
unsupportedNames.add(currentOS.name);
} else {
- unsupportedNames.add("the Dart VM");
+ unsupportedNames.add('the Dart VM');
}
}
warn("this package doesn't support running tests on " +
- toSentence(unsupportedNames, conjunction: "or") +
- ".");
+ toSentence(unsupportedNames, conjunction: 'or') +
+ '.');
}
/// Closes the runner.
@@ -211,8 +230,8 @@
// Pause the reporter while we print to ensure that we don't interfere
// with its output.
_reporter.pause();
- print("Waiting for current test(s) to finish.");
- print("Press Control-C again to terminate immediately.");
+ print('Waiting for current test(s) to finish.');
+ print('Press Control-C again to terminate immediately.');
_reporter.resume();
});
}
@@ -231,6 +250,10 @@
await Future.wait([_loader.closeEphemeral(), _engine.close()]);
if (timer != null) timer.cancel();
await _loader.close();
+
+ // Flush any IOSinks created for file reporters.
+ await Future.wait(_sinks.map((s) => s.flush().then((_) => s.close())));
+ _sinks.clear();
});
/// Return a stream of [LoadSuite]s in [_config.paths].
@@ -261,12 +284,12 @@
}
// If the user provided tags, skip tests that don't match all of them.
- if (!suite.config.includeTags.evaluate(test.metadata.tags)) {
+ if (!suite.config.includeTags.evaluate(test.metadata.tags.contains)) {
return false;
}
// Skip tests that do match any tags the user wants to exclude.
- if (suite.config.excludeTags.evaluate(test.metadata.tags)) {
+ if (suite.config.excludeTags.evaluate(test.metadata.tags.contains)) {
return false;
}
@@ -290,23 +313,23 @@
var noColor = _config.color ? '\u001b[0m' : '';
var buffer = StringBuffer()
- ..write("${yellow}Warning:$noColor ")
- ..write(unknownTags.length == 1 ? "A tag was " : "Tags were ")
- ..write("used that ")
+ ..write('${yellow}Warning:$noColor ')
+ ..write(unknownTags.length == 1 ? 'A tag was ' : 'Tags were ')
+ ..write('used that ')
..write(unknownTags.length == 1 ? "wasn't " : "weren't ")
- ..writeln("specified in dart_test.yaml.");
+ ..writeln('specified in dart_test.yaml.');
unknownTags.forEach((tag, entries) {
- buffer.write(" $bold$tag$noColor was used in");
+ buffer.write(' $bold$tag$noColor was used in');
if (entries.length == 1) {
- buffer.writeln(" ${_entryDescription(entries.single)}");
+ buffer.writeln(' ${_entryDescription(entries.single)}');
return;
}
- buffer.write(":");
+ buffer.write(':');
for (var entry in entries) {
- buffer.write("\n ${_entryDescription(entry)}");
+ buffer.write('\n ${_entryDescription(entry)}');
}
buffer.writeln();
});
@@ -320,10 +343,10 @@
/// This returns a map from tag names to lists of entries that use those tags.
Map<String, List<GroupEntry>> _collectUnknownTags(Suite suite) {
var unknownTags = <String, List<GroupEntry>>{};
- var currentTags = Set<String>();
+ var currentTags = <String>{};
- collect(GroupEntry entry) {
- var newTags = Set<String>();
+ void collect(GroupEntry entry) {
+ var newTags = <String>{};
for (var unknownTag
in entry.metadata.tags.difference(_config.knownTags)) {
if (currentTags.contains(unknownTag)) continue;
diff --git a/test_core/lib/src/runner/application_exception.dart b/test_core/lib/src/runner/application_exception.dart
index 919d3ec..23155a2 100644
--- a/test_core/lib/src/runner/application_exception.dart
+++ b/test_core/lib/src/runner/application_exception.dart
@@ -8,5 +8,6 @@
ApplicationException(this.message);
+ @override
String toString() => message;
}
diff --git a/test_core/lib/src/runner/compiler_pool.dart b/test_core/lib/src/runner/compiler_pool.dart
index 0465b07..7556ab5 100644
--- a/test_core/lib/src/runner/compiler_pool.dart
+++ b/test_core/lib/src/runner/compiler_pool.dart
@@ -5,9 +5,9 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
+import 'dart:isolate';
import 'package:async/async.dart';
-import 'package:package_resolver/package_resolver.dart';
import 'package:path/path.dart' as p;
import 'package:pool/pool.dart';
@@ -17,7 +17,7 @@
/// A regular expression matching the first status line printed by dart2js.
final _dart2jsStatus =
- RegExp(r"^Dart file \(.*\) compiled to JavaScript: .*\n?");
+ RegExp(r'^Dart file \(.*\) compiled to JavaScript: .*\n?');
/// A pool of `dart2js` instances.
///
@@ -30,7 +30,7 @@
final Pool _pool;
/// The currently-active dart2js processes.
- final _processes = Set<Process>();
+ final _processes = <Process>{};
/// Whether [close] has been called.
bool get _closed => _closeMemo.hasRun;
@@ -57,22 +57,22 @@
if (_closed) return null;
return withTempDir((dir) async {
- var wrapperPath = p.join(dir, "runInBrowser.dart");
+ var wrapperPath = p.join(dir, 'runInBrowser.dart');
File(wrapperPath).writeAsStringSync(code);
var dart2jsPath = _config.dart2jsPath;
if (Platform.isWindows) dart2jsPath += '.bat';
var args = [
- "--enable-asserts",
+ '--enable-asserts',
wrapperPath,
- "--out=$jsPath",
- await PackageResolver.current.processArgument
- ]
- ..addAll(_extraArgs)
- ..addAll(suiteConfig.dart2jsArgs);
+ '--out=$jsPath',
+ '--packages=${await Isolate.packageConfig}',
+ ..._extraArgs,
+ ...suiteConfig.dart2jsArgs
+ ];
- if (_config.color) args.add("--enable-diagnostic-colors");
+ if (_config.color) args.add('--enable-diagnostic-colors');
var process = await Process.start(dart2jsPath, args);
if (_closed) {
@@ -101,7 +101,7 @@
var output = buffer.toString().replaceFirst(_dart2jsStatus, '');
if (output.isNotEmpty) print(output);
- if (exitCode != 0) throw "dart2js failed.";
+ if (exitCode != 0) throw 'dart2js failed.';
_fixSourceMap(jsPath + '.map');
});
@@ -118,7 +118,7 @@
map['sources'] = map['sources'].map((source) {
var url = Uri.parse(root + '$source');
if (url.scheme != '' && url.scheme != 'file') return source;
- if (url.path.endsWith("/runInBrowser.dart")) return "";
+ if (url.path.endsWith('/runInBrowser.dart')) return '';
return p.toUri(mapPath).resolveUri(url).toString();
}).toList();
diff --git a/test_core/lib/src/runner/configuration.dart b/test_core/lib/src/runner/configuration.dart
index 26f0c62..e442f91 100644
--- a/test_core/lib/src/runner/configuration.dart
+++ b/test_core/lib/src/runner/configuration.dart
@@ -43,6 +43,9 @@
bool get help => _help ?? false;
final bool _help;
+ /// Custom HTML template file.
+ final String customHtmlTemplatePath;
+
/// Whether `--version` was passed.
bool get version => _version ?? false;
final bool _version;
@@ -62,7 +65,7 @@
/// The path to the file from which to load more configuration information.
///
/// This is *not* resolved automatically.
- String get configurationPath => _configurationPath ?? "dart_test.yaml";
+ String get configurationPath => _configurationPath ?? 'dart_test.yaml';
final String _configurationPath;
/// The path to dart2js.
@@ -73,6 +76,10 @@
String get reporter => _reporter ?? defaultReporter;
final String _reporter;
+ /// The map of file reporters where the key is the name of the reporter and
+ /// the value is the filepath to which its output should be written.
+ final Map<String, String> fileReporters;
+
/// Whether to disable retries of tests.
bool get noRetry => _noRetry ?? false;
final bool _noRetry;
@@ -112,16 +119,16 @@
final int totalShards;
/// The list of packages to fold when producing [StackTrace]s.
- Set<String> get foldTraceExcept => _foldTraceExcept ?? Set();
+ Set<String> get foldTraceExcept => _foldTraceExcept ?? {};
final Set<String> _foldTraceExcept;
/// If non-empty, all packages not in this list will be folded when producing
/// [StackTrace]s.
- Set<String> get foldTraceOnly => _foldTraceOnly ?? Set();
+ Set<String> get foldTraceOnly => _foldTraceOnly ?? {};
final Set<String> _foldTraceOnly;
/// The paths from which to load tests.
- List<String> get paths => _paths ?? ["test"];
+ List<String> get paths => _paths ?? ['test'];
final List<String> _paths;
/// Whether the load paths were passed explicitly or the default was used.
@@ -216,6 +223,7 @@
factory Configuration(
{bool help,
+ String customHtmlTemplatePath,
bool version,
bool pauseAfterLoad,
bool debug,
@@ -223,6 +231,7 @@
String configurationPath,
String dart2jsPath,
String reporter,
+ Map<String, String> fileReporters,
String coverage,
int pubServePort,
int concurrency,
@@ -263,6 +272,7 @@
var chosenPresetSet = chosenPresets?.toSet();
var configuration = Configuration._(
help: help,
+ customHtmlTemplatePath: customHtmlTemplatePath,
version: version,
pauseAfterLoad: pauseAfterLoad,
debug: debug,
@@ -270,6 +280,7 @@
configurationPath: configurationPath,
dart2jsPath: dart2jsPath,
reporter: reporter,
+ fileReporters: fileReporters,
coverage: coverage,
pubServePort: pubServePort,
concurrency: concurrency,
@@ -323,6 +334,7 @@
/// Unlike [new Configuration], this assumes [presets] is already resolved.
Configuration._(
{bool help,
+ String customHtmlTemplatePath,
bool version,
bool pauseAfterLoad,
bool debug,
@@ -330,6 +342,7 @@
String configurationPath,
String dart2jsPath,
String reporter,
+ Map<String, String> fileReporters,
String coverage,
int pubServePort,
int concurrency,
@@ -346,6 +359,7 @@
bool noRetry,
SuiteConfiguration suiteDefaults})
: _help = help,
+ customHtmlTemplatePath = customHtmlTemplatePath,
_version = version,
_pauseAfterLoad = pauseAfterLoad,
_debug = debug,
@@ -353,16 +367,17 @@
_configurationPath = configurationPath,
_dart2jsPath = dart2jsPath,
_reporter = reporter,
+ fileReporters = fileReporters ?? {},
_coverage = coverage,
pubServeUrl = pubServePort == null
? null
- : Uri.parse("http://localhost:$pubServePort"),
+ : Uri.parse('http://localhost:$pubServePort'),
_concurrency = concurrency,
_paths = _list(paths),
_foldTraceExcept = _set(foldTraceExcept),
_foldTraceOnly = _set(foldTraceOnly),
_filename = filename,
- chosenPresets = UnmodifiableSetView(chosenPresets?.toSet() ?? Set()),
+ chosenPresets = UnmodifiableSetView(chosenPresets?.toSet() ?? {}),
presets = _map(presets),
overrideRuntimes = _map(overrideRuntimes),
defineRuntimes = _map(defineRuntimes),
@@ -374,15 +389,15 @@
if (_filename != null && _filename.context.style != p.style) {
throw ArgumentError(
"filename's context must match the current operating system, was "
- "${_filename.context.style}.");
+ '${_filename.context.style}.');
}
if ((shardIndex == null) != (totalShards == null)) {
throw ArgumentError(
- "shardIndex and totalShards may only be passed together.");
+ 'shardIndex and totalShards may only be passed together.');
} else if (shardIndex != null) {
RangeError.checkValueInInterval(
- shardIndex, 0, totalShards - 1, "shardIndex");
+ shardIndex, 0, totalShards - 1, 'shardIndex');
}
}
@@ -420,7 +435,8 @@
///
/// This is zone-scoped, so [this] will be the current configuration in any
/// asynchronous callbacks transitively created by [body].
- T asCurrent<T>(T body()) => runZoned(body, zoneValues: {_currentKey: this});
+ T asCurrent<T>(T Function() body) =>
+ runZoned(body, zoneValues: {_currentKey: this});
/// Throws a [FormatException] if [this] refers to any undefined runtimes.
void validateRuntimes(List<Runtime> allRuntimes) {
@@ -469,12 +485,15 @@
var result = Configuration._(
help: other._help ?? _help,
+ customHtmlTemplatePath:
+ other.customHtmlTemplatePath ?? customHtmlTemplatePath,
version: other._version ?? _version,
pauseAfterLoad: other._pauseAfterLoad ?? _pauseAfterLoad,
color: other._color ?? _color,
configurationPath: other._configurationPath ?? _configurationPath,
dart2jsPath: other._dart2jsPath ?? _dart2jsPath,
reporter: other._reporter ?? _reporter,
+ fileReporters: mergeMaps(fileReporters, other.fileReporters),
coverage: other._coverage ?? _coverage,
pubServePort: (other.pubServeUrl ?? pubServeUrl)?.port,
concurrency: other._concurrency ?? _concurrency,
@@ -510,6 +529,7 @@
/// always replaced by the new one.
Configuration change(
{bool help,
+ String customHtmlTemplatePath,
bool version,
bool pauseAfterLoad,
bool color,
@@ -553,6 +573,8 @@
Iterable<String> addTags}) {
var config = Configuration._(
help: help ?? _help,
+ customHtmlTemplatePath:
+ customHtmlTemplatePath ?? this.customHtmlTemplatePath,
version: version ?? _version,
pauseAfterLoad: pauseAfterLoad ?? _pauseAfterLoad,
color: color ?? _color,
@@ -615,12 +637,12 @@
merged.merge(newPresets.remove(preset) ?? Configuration.empty));
if (merged == empty) return this;
- var result = this.change(presets: newPresets).merge(merged);
+ var result = change(presets: newPresets).merge(merged);
// Make sure the configuration knows about presets that were selected and
// thus removed from [newPresets].
- result._knownPresets = UnmodifiableSetView(
- result.knownPresets.toSet()..addAll(this.presets.keys));
+ result._knownPresets =
+ UnmodifiableSetView(result.knownPresets.toSet()..addAll(presets.keys));
return result;
}
diff --git a/test_core/lib/src/runner/configuration/args.dart b/test_core/lib/src/runner/configuration/args.dart
index 0d04fdb..02e5384 100644
--- a/test_core/lib/src/runner/configuration/args.dart
+++ b/test_core/lib/src/runner/configuration/args.dart
@@ -7,11 +7,12 @@
import 'package:args/args.dart';
import 'package:boolean_selector/boolean_selector.dart';
-
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/frontend/timeout.dart'; // ignore: implementation_imports
-import '../runtime_selection.dart';
+
+import '../../util/io.dart';
import '../configuration.dart';
+import '../runtime_selection.dart';
import 'reporters.dart';
import 'values.dart';
@@ -23,129 +24,133 @@
if (!Platform.isMacOS) allRuntimes.remove(Runtime.safari);
if (!Platform.isWindows) allRuntimes.remove(Runtime.internetExplorer);
- parser.addFlag("help",
- abbr: "h", negatable: false, help: "Shows this usage information.");
- parser.addFlag("version",
+ parser.addFlag('help',
+ abbr: 'h', negatable: false, help: 'Shows this usage information.');
+ parser.addFlag('version',
negatable: false, help: "Shows the package's version.");
// Note that defaultsTo declarations here are only for documentation purposes.
- // We pass null values rather than defaults to [new Configuration] so that it
- // merges properly with the config file.
+ // We pass null instead of the default so that it merges properly with the
+ // config file.
- parser.addSeparator("======== Selecting Tests");
- parser.addMultiOption("name",
+ parser.addSeparator('======== Selecting Tests');
+ parser.addMultiOption('name',
abbr: 'n',
help: 'A substring of the name of the test to run.\n'
'Regular expression syntax is supported.\n'
'If passed multiple times, tests must match all substrings.',
splitCommas: false);
- parser.addMultiOption("plain-name",
+ parser.addMultiOption('plain-name',
abbr: 'N',
help: 'A plain-text substring of the name of the test to run.\n'
'If passed multiple times, tests must match all substrings.',
splitCommas: false);
- parser.addMultiOption("tags",
+ parser.addMultiOption('tags',
abbr: 't',
help: 'Run only tests with all of the specified tags.\n'
'Supports boolean selector syntax.');
- parser.addMultiOption("tag", hide: true);
- parser.addMultiOption("exclude-tags",
+ parser.addMultiOption('tag', hide: true);
+ parser.addMultiOption('exclude-tags',
abbr: 'x',
help: "Don't run tests with any of the specified tags.\n"
- "Supports boolean selector syntax.");
- parser.addMultiOption("exclude-tag", hide: true);
- parser.addFlag("run-skipped",
+ 'Supports boolean selector syntax.');
+ parser.addMultiOption('exclude-tag', hide: true);
+ parser.addFlag('run-skipped',
help: 'Run skipped tests instead of skipping them.');
- parser.addSeparator("======== Running Tests");
+ parser.addSeparator('======== Running Tests');
// The UI term "platform" corresponds with the implementation term "runtime".
// The [Runtime] class used to be called [TestPlatform], but it was changed to
// avoid conflicting with [SuitePlatform]. We decided not to also change the
// UI to avoid a painful migration.
- parser.addMultiOption("platform",
+ parser.addMultiOption('platform',
abbr: 'p',
help: 'The platform(s) on which to run the tests.\n'
'[vm (default), '
'${allRuntimes.map((runtime) => runtime.identifier).join(", ")}]');
- parser.addMultiOption("preset",
+ parser.addMultiOption('preset',
abbr: 'P', help: 'The configuration preset(s) to use.');
- parser.addOption("concurrency",
+ parser.addOption('concurrency',
abbr: 'j',
help: 'The number of concurrent test suites run.',
defaultsTo: defaultConcurrency.toString(),
valueHelp: 'threads');
- parser.addOption("total-shards",
+ parser.addOption('total-shards',
help: 'The total number of invocations of the test runner being run.');
- parser.addOption("shard-index",
+ parser.addOption('shard-index',
help: 'The index of this test runner invocation (of --total-shards).');
- parser.addOption("pub-serve",
+ parser.addOption('pub-serve',
help: 'The port of a pub serve instance serving "test/".',
valueHelp: 'port');
- parser.addOption("timeout",
+ parser.addOption('timeout',
help: 'The default test timeout. For example: 15s, 2x, none',
defaultsTo: '30s');
- parser.addFlag("pause-after-load",
+ parser.addFlag('pause-after-load',
help: 'Pauses for debugging before any tests execute.\n'
'Implies --concurrency=1, --debug, and --timeout=none.\n'
'Currently only supported for browser tests.',
negatable: false);
- parser.addFlag("debug",
+ parser.addFlag('debug',
help: 'Runs the VM and Chrome tests in debug mode.', negatable: false);
- parser.addOption("coverage",
+ parser.addOption('coverage',
help: 'Gathers coverage and outputs it to the specified directory.\n'
'Implies --debug.',
valueHelp: 'directory');
- parser.addFlag("chain-stack-traces",
+ parser.addFlag('chain-stack-traces',
help: 'Chained stack traces to provide greater exception details\n'
'especially for asynchronous code. It may be useful to disable\n'
'to provide improved test performance but at the cost of\n'
'debuggability.',
defaultsTo: true);
- parser.addFlag("no-retry",
+ parser.addFlag('no-retry',
help: "Don't re-run tests that have retry set.",
defaultsTo: false,
negatable: false);
- parser.addOption("test-randomize-ordering-seed",
- help: 'If positive, use this as a seed to randomize the execution\n'
- 'of test cases (must be a 32bit unsigned integer).\n'
+ parser.addOption('test-randomize-ordering-seed',
+ help: 'The seed to randomize the execution order of test cases.\n'
+ 'Must be a 32bit unsigned integer or "random".\n'
'If "random", pick a random seed to use.\n'
- 'If 0 or not set, do not randomize test case execution order.\n');
+ 'If not passed, do not randomize test case execution order.');
var reporterDescriptions = <String, String>{};
for (var reporter in allReporters.keys) {
reporterDescriptions[reporter] = allReporters[reporter].description;
}
- parser.addSeparator("======== Output");
- parser.addOption("reporter",
+ parser.addSeparator('======== Output');
+ parser.addOption('reporter',
abbr: 'r',
help: 'The runner used to print test results.',
defaultsTo: defaultReporter,
allowed: reporterDescriptions.keys.toList(),
allowedHelp: reporterDescriptions);
- parser.addFlag("verbose-trace",
+ parser.addOption('file-reporter',
+ help: 'The reporter used to write test results to a file.\n'
+ 'Should be in the form <reporter>:<filepath>, '
+ 'e.g. "json:reports/tests.json"');
+ parser.addFlag('verbose-trace',
negatable: false,
help: 'Whether to emit stack traces with core library frames.');
- parser.addFlag("js-trace",
+ parser.addFlag('js-trace',
negatable: false,
help: 'Whether to emit raw JavaScript stack traces for browser tests.');
- parser.addFlag("color",
+ parser.addFlag('color',
help: 'Whether to use terminal colors.\n(auto-detected by default)');
/// The following options are used only by the internal Google test runner.
/// They're hidden and not supported as stable API surface outside Google.
- parser.addOption("configuration",
+ parser.addOption('configuration',
help: 'The path to the configuration file.', hide: true);
- parser.addOption("dart2js-path",
+ parser.addOption('dart2js-path',
help: 'The path to the dart2js executable.', hide: true);
- parser.addMultiOption("dart2js-args",
+ parser.addMultiOption('dart2js-args',
help: 'Extra arguments to pass to dart2js.', hide: true);
// If we're running test/dir/my_test.dart, we'll look for
// test/dir/my_test.dart.html in the precompiled directory.
- parser.addOption("precompiled",
+ parser.addOption('precompiled',
help: 'The path to a mirror of the package directory containing HTML '
'that points to precompiled JS.',
hide: true);
@@ -200,13 +205,13 @@
var totalShards = _parseOption('total-shards', int.parse);
if ((shardIndex == null) != (totalShards == null)) {
throw FormatException(
- "--shard-index and --total-shards may only be passed together.");
+ '--shard-index and --total-shards may only be passed together.');
} else if (shardIndex != null) {
if (shardIndex < 0) {
- throw FormatException("--shard-index may not be negative.");
+ throw FormatException('--shard-index may not be negative.');
} else if (shardIndex >= totalShards) {
throw FormatException(
- "--shard-index must be less than --total-shards.");
+ '--shard-index must be less than --total-shards.');
}
}
@@ -215,12 +220,26 @@
var seed = value == 'random'
? Random().nextInt(4294967295)
: int.parse(value).toUnsigned(32);
- if (seed != null && seed > 0) {
+ if (seed != null) {
print('Shuffling test order with --test-randomize-ordering-seed=$seed');
}
return seed;
});
+ var color = _ifParsed<bool>('color') ?? canUseSpecialChars;
+
+ var platform = _ifParsed<List<String>>('platform')
+ ?.map((runtime) => RuntimeSelection(runtime))
+ ?.toList();
+ if (platform
+ ?.any((runtime) => runtime.name == Runtime.phantomJS.identifier) ??
+ false) {
+ var yellow = color ? '\u001b[33m' : '';
+ var noColor = color ? '\u001b[0m' : '';
+ print('${yellow}Warning:$noColor '
+ 'PhatomJS is deprecated and will be removed in version ^2.0.0');
+ }
+
return Configuration(
help: _ifParsed('help'),
version: _ifParsed('version'),
@@ -229,12 +248,13 @@
jsTrace: _ifParsed('js-trace'),
pauseAfterLoad: _ifParsed('pause-after-load'),
debug: _ifParsed('debug'),
- color: _ifParsed('color'),
+ color: color,
configurationPath: _ifParsed('configuration'),
dart2jsPath: _ifParsed('dart2js-path'),
dart2jsArgs: _ifParsed('dart2js-args'),
precompiledPath: _ifParsed('precompiled'),
reporter: _ifParsed('reporter'),
+ fileReporters: _parseFileReporterOption(),
coverage: _ifParsed('coverage'),
pubServePort: _parseOption('pub-serve', int.parse),
concurrency: _parseOption('concurrency', int.parse),
@@ -242,9 +262,7 @@
totalShards: totalShards,
timeout: _parseOption('timeout', (value) => Timeout.parse(value)),
patterns: patterns,
- runtimes: _ifParsed<List<String>>('platform')
- ?.map((runtime) => RuntimeSelection(runtime))
- ?.toList(),
+ runtimes: platform,
runSkipped: _ifParsed('run-skipped'),
chosenPresets: _ifParsed('preset'),
paths: _options.rest.isEmpty ? null : _options.rest,
@@ -264,7 +282,7 @@
/// Runs [parse] on the value of the option [name], and wraps any
/// [FormatException] it throws with additional information.
- T _parseOption<T>(String name, T parse(String value)) {
+ T _parseOption<T>(String name, T Function(String) parse) {
if (!_options.wasParsed(name)) return null;
var value = _options[name];
@@ -273,9 +291,24 @@
return _wrapFormatException(name, () => parse(value as String));
}
+ Map<String, String> _parseFileReporterOption() =>
+ _parseOption('file-reporter', (value) {
+ if (!value.contains(':')) {
+ throw FormatException(
+ 'option must be in the form <reporter>:<filepath>, e.g. '
+ '"json:reports/tests.json"');
+ }
+ final sep = value.indexOf(':');
+ final reporter = value.substring(0, sep);
+ if (!allReporters.containsKey(reporter)) {
+ throw FormatException('"$reporter" is not a supported reporter');
+ }
+ return {reporter: value.substring(sep + 1)};
+ });
+
/// Runs [parse], and wraps any [FormatException] it throws with additional
/// information.
- T _wrapFormatException<T>(String name, T parse()) {
+ T _wrapFormatException<T>(String name, T Function() parse) {
try {
return parse();
} on FormatException catch (error) {
diff --git a/test_core/lib/src/runner/configuration/load.dart b/test_core/lib/src/runner/configuration/load.dart
index fdb5c43..d188b3e 100644
--- a/test_core/lib/src/runner/configuration/load.dart
+++ b/test_core/lib/src/runner/configuration/load.dart
@@ -27,7 +27,7 @@
/// A regular expression matching a Dart identifier.
///
/// This also matches a package name, since they must be Dart identifiers.
-final _identifierRegExp = RegExp(r"[a-zA-Z_]\w*");
+final _identifierRegExp = RegExp(r'[a-zA-Z_]\w*');
/// A regular expression matching allowed package names.
///
@@ -35,7 +35,7 @@
/// compatibility with Google's internal Dart packages, but they may not be used
/// when publishing a package to pub.dev.
final _packageName =
- RegExp("^${_identifierRegExp.pattern}(\\.${_identifierRegExp.pattern})*\$");
+ RegExp('^${_identifierRegExp.pattern}(\\.${_identifierRegExp.pattern})*\$');
/// Loads configuration information from a YAML file at [path].
///
@@ -52,7 +52,7 @@
if (document is! Map) {
throw SourceSpanFormatException(
- "The configuration must be a YAML map.", document.span, source);
+ 'The configuration must be a YAML map.', document.span, source);
}
var loader =
@@ -91,14 +91,14 @@
/// If an `include` node is contained in [node], merges and returns [config].
Configuration _loadIncludeConfig() {
if (!_runnerConfig) {
- _disallow("include");
+ _disallow('include');
return Configuration.empty;
}
- var includeNode = _document.nodes["include"];
+ var includeNode = _document.nodes['include'];
if (includeNode == null) return Configuration.empty;
- var includePath = _parseNode(includeNode, "include path", p.fromUri);
+ var includePath = _parseNode(includeNode, 'include path', p.fromUri);
var basePath =
p.join(p.dirname(p.fromUri(_document.span.sourceUrl)), includePath);
try {
@@ -111,22 +111,22 @@
/// Loads test configuration that's allowed in the global configuration file.
Configuration _loadGlobalTestConfig() {
- var verboseTrace = _getBool("verbose_trace");
- var chainStackTraces = _getBool("chain_stack_traces");
+ var verboseTrace = _getBool('verbose_trace');
+ var chainStackTraces = _getBool('chain_stack_traces');
var foldStackFrames = _loadFoldedStackFrames();
- var jsTrace = _getBool("js_trace");
+ var jsTrace = _getBool('js_trace');
- var timeout = _parseValue("timeout", (value) => Timeout.parse(value));
+ var timeout = _parseValue('timeout', (value) => Timeout.parse(value));
- var onPlatform = _getMap("on_platform",
- key: (keyNode) => _parseNode(keyNode, "on_platform key",
+ var onPlatform = _getMap('on_platform',
+ key: (keyNode) => _parseNode(keyNode, 'on_platform key',
(value) => PlatformSelector.parse(value, keyNode.span)),
value: (valueNode) =>
- _nestedConfig(valueNode, "on_platform value", runnerConfig: false));
+ _nestedConfig(valueNode, 'on_platform value', runnerConfig: false));
- var onOS = _getMap("on_os",
+ var onOS = _getMap('on_os',
key: (keyNode) {
- _validate(keyNode, "on_os key must be a string.",
+ _validate(keyNode, 'on_os key must be a string.',
(value) => value is String);
var os = OperatingSystem.find(keyNode.value as String);
@@ -137,11 +137,11 @@
keyNode.span,
_source);
},
- value: (valueNode) => _nestedConfig(valueNode, "on_os value"));
+ value: (valueNode) => _nestedConfig(valueNode, 'on_os value'));
- var presets = _getMap("presets",
- key: (keyNode) => _parseIdentifierLike(keyNode, "presets key"),
- value: (valueNode) => _nestedConfig(valueNode, "presets value"));
+ var presets = _getMap('presets',
+ key: (keyNode) => _parseIdentifierLike(keyNode, 'presets key'),
+ value: (valueNode) => _nestedConfig(valueNode, 'presets value'));
var config = Configuration(
verboseTrace: verboseTrace,
@@ -149,8 +149,8 @@
timeout: timeout,
presets: presets,
chainStackTraces: chainStackTraces,
- foldTraceExcept: foldStackFrames["except"],
- foldTraceOnly: foldStackFrames["only"])
+ foldTraceExcept: foldStackFrames['except'],
+ foldTraceOnly: foldStackFrames['only'])
.merge(_extractPresets<PlatformSelector>(
onPlatform, (map) => Configuration(onPlatform: map)));
@@ -165,15 +165,15 @@
/// configuration fields.
Configuration _loadLocalTestConfig() {
if (_global) {
- _disallow("skip");
- _disallow("retry");
- _disallow("test_on");
- _disallow("add_tags");
- _disallow("tags");
+ _disallow('skip');
+ _disallow('retry');
+ _disallow('test_on');
+ _disallow('add_tags');
+ _disallow('tags');
return Configuration.empty;
}
- var skipRaw = _getValue("skip", "boolean or string",
+ var skipRaw = _getValue('skip', 'boolean or string',
(value) => value is bool || value is String);
String skipReason;
bool skip;
@@ -184,18 +184,18 @@
skip = skipRaw as bool;
}
- var testOn = _parsePlatformSelector("test_on");
+ var testOn = _parsePlatformSelector('test_on');
var addTags = _getList(
- "add_tags", (tagNode) => _parseIdentifierLike(tagNode, "Tag name"));
+ 'add_tags', (tagNode) => _parseIdentifierLike(tagNode, 'Tag name'));
- var tags = _getMap("tags",
+ var tags = _getMap('tags',
key: (keyNode) => _parseNode(
- keyNode, "tags key", (value) => BooleanSelector.parse(value)),
+ keyNode, 'tags key', (value) => BooleanSelector.parse(value)),
value: (valueNode) =>
- _nestedConfig(valueNode, "tag value", runnerConfig: false));
+ _nestedConfig(valueNode, 'tag value', runnerConfig: false));
- var retry = _getNonNegativeInt("retry");
+ var retry = _getNonNegativeInt('retry');
return Configuration(
skip: skip,
@@ -214,47 +214,66 @@
/// runner-level configuration fields.
Configuration _loadGlobalRunnerConfig() {
if (!_runnerConfig) {
- _disallow("pause_after_load");
- _disallow("reporter");
- _disallow("concurrency");
- _disallow("names");
- _disallow("plain_names");
- _disallow("platforms");
- _disallow("add_presets");
- _disallow("override_platforms");
- _disallow("include");
+ _disallow('pause_after_load');
+ _disallow('reporter');
+ _disallow('file_reporters');
+ _disallow('concurrency');
+ _disallow('names');
+ _disallow('plain_names');
+ _disallow('platforms');
+ _disallow('add_presets');
+ _disallow('override_platforms');
+ _disallow('include');
return Configuration.empty;
}
- var pauseAfterLoad = _getBool("pause_after_load");
- var runSkipped = _getBool("run_skipped");
+ var pauseAfterLoad = _getBool('pause_after_load');
+ var runSkipped = _getBool('run_skipped');
- var reporter = _getString("reporter");
+ var reporter = _getString('reporter');
if (reporter != null && !allReporters.keys.contains(reporter)) {
- _error('Unknown reporter "$reporter".', "reporter");
+ _error('Unknown reporter "$reporter".', 'reporter');
}
- var concurrency = _getInt("concurrency");
+ var fileReporters = _getMap('file_reporters', key: (keyNode) {
+ _validate(keyNode, 'file_reporters key must be a string',
+ (value) => value is String);
+ final reporter = keyNode.value as String;
+ if (!allReporters.keys.contains(reporter)) {
+ _error('Unknown reporter "$reporter".', 'file_reporters');
+ }
+ return reporter;
+ }, value: (valueNode) {
+ _validate(valueNode, 'file_reporters value must be a string',
+ (value) => value is String);
+ return valueNode.value as String;
+ });
+
+ var concurrency = _getInt('concurrency');
// The UI term "platform" corresponds with the implementation term
// "runtime". The [Runtime] class used to be called [TestPlatform], but it
// was changed to avoid conflicting with [SuitePlatform]. We decided not to
// also change the UI to avoid a painful migration.
var runtimes = _getList(
- "platforms",
+ 'platforms',
(runtimeNode) => RuntimeSelection(
- _parseIdentifierLike(runtimeNode, "Platform name"),
+ _parseIdentifierLike(runtimeNode, 'Platform name'),
runtimeNode.span));
- var chosenPresets = _getList("add_presets",
- (presetNode) => _parseIdentifierLike(presetNode, "Preset name"));
+ var chosenPresets = _getList('add_presets',
+ (presetNode) => _parseIdentifierLike(presetNode, 'Preset name'));
var overrideRuntimes = _loadOverrideRuntimes();
+ var customHtmlTemplatePath = _getString('custom_html_template_path');
+
return Configuration(
pauseAfterLoad: pauseAfterLoad,
+ customHtmlTemplatePath: customHtmlTemplatePath,
runSkipped: runSkipped,
reporter: reporter,
+ fileReporters: fileReporters,
concurrency: concurrency,
runtimes: runtimes,
chosenPresets: chosenPresets,
@@ -264,21 +283,21 @@
/// Loads the `override_platforms` field.
Map<String, RuntimeSettings> _loadOverrideRuntimes() {
var runtimesNode =
- _getNode("override_platforms", "map", (value) => value is Map)
+ _getNode('override_platforms', 'map', (value) => value is Map)
as YamlMap;
if (runtimesNode == null) return const {};
var runtimes = <String, RuntimeSettings>{};
runtimesNode.nodes.forEach((identifierNode, valueNode) {
var identifier = _parseIdentifierLike(
- identifierNode as YamlNode, "Platform identifier");
+ identifierNode as YamlNode, 'Platform identifier');
- _validate(valueNode, "Platform definition must be a map.",
+ _validate(valueNode, 'Platform definition must be a map.',
(value) => value is Map);
var map = valueNode as YamlMap;
- var settings = _expect(map, "settings");
- _validate(settings, "Must be a map.", (value) => value is Map);
+ var settings = _expect(map, 'settings');
+ _validate(settings, 'Must be a map.', (value) => value is Map);
runtimes[identifier] = RuntimeSettings(
identifier, (identifierNode as YamlNode).span, [settings as YamlMap]);
@@ -293,41 +312,41 @@
/// if there are any local test-level configuration fields.
Configuration _loadLocalRunnerConfig() {
if (!_runnerConfig || _global) {
- _disallow("pub_serve");
- _disallow("names");
- _disallow("plain_names");
- _disallow("paths");
- _disallow("filename");
- _disallow("include_tags");
- _disallow("exclude_tags");
- _disallow("define_platforms");
+ _disallow('pub_serve');
+ _disallow('names');
+ _disallow('plain_names');
+ _disallow('paths');
+ _disallow('filename');
+ _disallow('include_tags');
+ _disallow('exclude_tags');
+ _disallow('define_platforms');
return Configuration.empty;
}
- var pubServePort = _getInt("pub_serve");
+ var pubServePort = _getInt('pub_serve');
- var patterns = _getList("names", (nameNode) {
- _validate(nameNode, "Names must be strings.", (value) => value is String);
- return _parseNode(nameNode, "name", (value) => RegExp(value));
+ var patterns = _getList('names', (nameNode) {
+ _validate(nameNode, 'Names must be strings.', (value) => value is String);
+ return _parseNode(nameNode, 'name', (value) => RegExp(value));
})
- ..addAll(_getList("plain_names", (nameNode) {
+ ..addAll(_getList('plain_names', (nameNode) {
_validate(
- nameNode, "Names must be strings.", (value) => value is String);
- return _parseNode(nameNode, "name", (value) => RegExp(value));
+ nameNode, 'Names must be strings.', (value) => value is String);
+ return _parseNode(nameNode, 'name', (value) => RegExp(value));
}));
- var paths = _getList("paths", (pathNode) {
- _validate(pathNode, "Paths must be strings.", (value) => value is String);
- _validate(pathNode, "Paths must be relative.",
+ var paths = _getList('paths', (pathNode) {
+ _validate(pathNode, 'Paths must be strings.', (value) => value is String);
+ _validate(pathNode, 'Paths must be relative.',
(value) => p.url.isRelative(value as String));
- return _parseNode(pathNode, "path", p.fromUri);
+ return _parseNode(pathNode, 'path', p.fromUri);
});
- var filename = _parseValue("filename", (value) => Glob(value));
+ var filename = _parseValue('filename', (value) => Glob(value));
- var includeTags = _parseBooleanSelector("include_tags");
- var excludeTags = _parseBooleanSelector("exclude_tags");
+ var includeTags = _parseBooleanSelector('include_tags');
+ var excludeTags = _parseBooleanSelector('exclude_tags');
var defineRuntimes = _loadDefineRuntimes();
@@ -348,10 +367,10 @@
/// test [Chain].
Map<String, List<String>> _loadFoldedStackFrames() {
var foldOptionSet = false;
- return _getMap("fold_stack_frames", key: (keyNode) {
- _validate(keyNode, "Must be a string", (value) => value is String);
+ return _getMap('fold_stack_frames', key: (keyNode) {
+ _validate(keyNode, 'Must be a string', (value) => value is String);
_validate(keyNode, 'Must be "only" or "except".',
- (value) => value == "only" || value == "except");
+ (value) => value == 'only' || value == 'except');
if (foldOptionSet) {
throw SourceSpanFormatException(
@@ -364,14 +383,14 @@
}, value: (valueNode) {
_validate(
valueNode,
- "Folded packages must be strings.",
+ 'Folded packages must be strings.',
(valueList) =>
valueList is YamlList &&
valueList.every((value) => value is String));
_validate(
valueNode,
- "Invalid package name.",
+ 'Invalid package name.',
(valueList) => (valueList as Iterable)
.every((value) => _packageName.hasMatch(value as String)));
@@ -382,27 +401,27 @@
/// Loads the `define_platforms` field.
Map<String, CustomRuntime> _loadDefineRuntimes() {
var runtimesNode =
- _getNode("define_platforms", "map", (value) => value is Map) as YamlMap;
+ _getNode('define_platforms', 'map', (value) => value is Map) as YamlMap;
if (runtimesNode == null) return const {};
var runtimes = <String, CustomRuntime>{};
runtimesNode.nodes.forEach((identifierNode, valueNode) {
var identifier = _parseIdentifierLike(
- identifierNode as YamlNode, "Platform identifier");
+ identifierNode as YamlNode, 'Platform identifier');
- _validate(valueNode, "Platform definition must be a map.",
+ _validate(valueNode, 'Platform definition must be a map.',
(value) => value is Map);
var map = valueNode as YamlMap;
- var nameNode = _expect(map, "name");
- _validate(nameNode, "Must be a string.", (value) => value is String);
+ var nameNode = _expect(map, 'name');
+ _validate(nameNode, 'Must be a string.', (value) => value is String);
var name = nameNode.value as String;
- var parentNode = _expect(map, "extends");
- var parent = _parseIdentifierLike(parentNode, "Platform parent");
+ var parentNode = _expect(map, 'extends');
+ var parent = _parseIdentifierLike(parentNode, 'Platform parent');
- var settings = _expect(map, "settings");
- _validate(settings, "Must be a map.", (value) => value is Map);
+ var settings = _expect(map, 'settings');
+ _validate(settings, 'Must be a map.', (value) => value is Map);
runtimes[identifier] = CustomRuntime(
name,
@@ -418,7 +437,7 @@
/// Throws an exception with [message] if [test] returns `false` when passed
/// [node]'s value.
- void _validate(YamlNode node, String message, bool test(value)) {
+ void _validate(YamlNode node, String message, bool Function(dynamic) test) {
if (test(node.value)) return;
throw SourceSpanFormatException(message, node.span, _source);
}
@@ -427,45 +446,47 @@
///
/// If [typeTest] returns `false` for that value, instead throws an error
/// complaining that the field is not a [typeName].
- _getValue(String field, String typeName, bool typeTest(value)) {
+ dynamic _getValue(
+ String field, String typeName, bool Function(dynamic) typeTest) {
var value = _document[field];
if (value == null || typeTest(value)) return value;
- _error("$field must be ${a(typeName)}.", field);
+ _error('$field must be ${a(typeName)}.', field);
}
/// Returns the YAML node at [field].
///
/// If [typeTest] returns `false` for that node's value, instead throws an
/// error complaining that the field is not a [typeName].
- YamlNode _getNode(String field, String typeName, bool typeTest(value)) {
+ YamlNode _getNode(
+ String field, String typeName, bool Function(dynamic) typeTest) {
var node = _document.nodes[field];
if (node == null) return null;
- _validate(node, "$field must be ${a(typeName)}.", typeTest);
+ _validate(node, '$field must be ${a(typeName)}.', typeTest);
return node;
}
/// Asserts that [field] is an int and returns its value.
int _getInt(String field) =>
- _getValue(field, "int", (value) => value is int) as int;
+ _getValue(field, 'int', (value) => value is int) as int;
/// Asserts that [field] is a non-negative int and returns its value.
int _getNonNegativeInt(String field) => _getValue(
- field, "non-negative int", (value) => value is int && value >= 0) as int;
+ field, 'non-negative int', (value) => value is int && value >= 0) as int;
/// Asserts that [field] is a boolean and returns its value.
bool _getBool(String field) =>
- _getValue(field, "boolean", (value) => value is bool) as bool;
+ _getValue(field, 'boolean', (value) => value is bool) as bool;
/// Asserts that [field] is a string and returns its value.
String _getString(String field) =>
- _getValue(field, "string", (value) => value is String) as String;
+ _getValue(field, 'string', (value) => value is String) as String;
/// Asserts that [field] is a list and runs [forElement] for each element it
/// contains.
///
/// Returns a list of values returned by [forElement].
- List<T> _getList<T>(String field, T forElement(YamlNode elementNode)) {
- var node = _getNode(field, "list", (value) => value is List) as YamlList;
+ List<T> _getList<T>(String field, T Function(YamlNode) forElement) {
+ var node = _getNode(field, 'list', (value) => value is List) as YamlList;
if (node == null) return [];
return node.nodes.map(forElement).toList();
}
@@ -475,19 +496,19 @@
/// Returns a map with the keys and values returned by [key] and [value]. Each
/// of these defaults to asserting that the value is a string.
Map<K, V> _getMap<K, V>(String field,
- {K key(YamlNode keyNode), V value(YamlNode valueNode)}) {
- var node = _getNode(field, "map", (value) => value is Map) as YamlMap;
+ {K Function(YamlNode) key, V Function(YamlNode) value}) {
+ var node = _getNode(field, 'map', (value) => value is Map) as YamlMap;
if (node == null) return {};
key ??= (keyNode) {
_validate(
- keyNode, "$field keys must be strings.", (value) => value is String);
+ keyNode, '$field keys must be strings.', (value) => value is String);
return keyNode.value as K;
};
value ??= (valueNode) {
- _validate(valueNode, "$field values must be strings.",
+ _validate(valueNode, '$field values must be strings.',
(value) => value is String);
return valueNode.value as V;
@@ -500,8 +521,8 @@
/// Verifies that [node]'s value is an optionally hyphenated Dart identifier,
/// and returns it
String _parseIdentifierLike(YamlNode node, String name) {
- _validate(node, "$name must be a string.", (value) => value is String);
- _validate(node, "$name must be an (optionally hyphenated) Dart identifier.",
+ _validate(node, '$name must be a string.', (value) => value is String);
+ _validate(node, '$name must be an (optionally hyphenated) Dart identifier.',
(value) => (value as String).contains(anchoredHyphenatedIdentifier));
return node.value as String;
}
@@ -523,8 +544,8 @@
///
/// If [parse] throws a [FormatException], it's wrapped to include [node]'s
/// span.
- T _parseNode<T>(YamlNode node, String name, T parse(String value)) {
- _validate(node, "$name must be a string.", (value) => value is String);
+ T _parseNode<T>(YamlNode node, String name, T Function(String) parse) {
+ _validate(node, '$name must be a string.', (value) => value is String);
try {
return parse(node.value as String);
@@ -539,7 +560,7 @@
///
/// If [parse] throws a [FormatException], it's wrapped to include [field]'s
/// span.
- T _parseValue<T>(String field, T parse(String value)) {
+ T _parseValue<T>(String field, T Function(String) parse) {
var node = _document.nodes[field];
if (node == null) return null;
return _parseNode(node, field, parse);
@@ -553,7 +574,7 @@
Configuration _nestedConfig(YamlNode node, String name, {bool runnerConfig}) {
if (node == null || node.value == null) return Configuration.empty;
- _validate(node, "$name must be a map.", (value) => value is Map);
+ _validate(node, '$name must be a map.', (value) => value is Map);
var loader = _ConfigurationLoader(node as YamlMap, _source,
global: _global, runnerConfig: runnerConfig ?? _runnerConfig);
return loader.load();
@@ -569,7 +590,7 @@
/// [SuiteConfiguration]s. The [create] function is used to construct
/// [Configuration]s from the resolved maps.
Configuration _extractPresets<T>(Map<T, Configuration> map,
- Configuration create(Map<T, SuiteConfiguration> map)) {
+ Configuration Function(Map<T, SuiteConfiguration>) create) {
if (map.isEmpty) return Configuration.empty;
var base = <T, SuiteConfiguration>{};
diff --git a/test_core/lib/src/runner/configuration/reporters.dart b/test_core/lib/src/runner/configuration/reporters.dart
index 7fe1656..dc557cf 100644
--- a/test_core/lib/src/runner/configuration/reporters.dart
+++ b/test_core/lib/src/runner/configuration/reporters.dart
@@ -29,17 +29,17 @@
UnmodifiableMapView<String, ReporterDetails>(_allReporters);
final _allReporters = <String, ReporterDetails>{
- "expanded": ReporterDetails(
- "A separate line for each update.",
+ 'expanded': ReporterDetails(
+ 'A separate line for each update.',
(config, engine, sink) => ExpandedReporter.watch(engine, sink,
color: config.color,
printPath: config.paths.length > 1 ||
Directory(config.paths.single).existsSync(),
printPlatform: config.suiteDefaults.runtimes.length > 1)),
- "compact": ReporterDetails("A single line, updated continuously.",
+ 'compact': ReporterDetails('A single line, updated continuously.',
(_, engine, sink) => CompactReporter.watch(engine, sink)),
- "json": ReporterDetails(
- "A machine-readable format (see https://goo.gl/gBsV1a).",
+ 'json': ReporterDetails(
+ 'A machine-readable format (see https://goo.gl/gBsV1a).',
(_, engine, sink) => JsonReporter.watch(engine, sink)),
};
diff --git a/test_core/lib/src/runner/configuration/values.dart b/test_core/lib/src/runner/configuration/values.dart
index 37abc16..6e2f50a 100644
--- a/test_core/lib/src/runner/configuration/values.dart
+++ b/test_core/lib/src/runner/configuration/values.dart
@@ -16,4 +16,4 @@
/// The default filename pattern.
///
/// This is stored here so that we don't have to recompile it multiple times.
-final defaultFilename = Glob("*_test.dart");
+final defaultFilename = Glob('*_test.dart');
diff --git a/test_core/lib/src/runner/console.dart b/test_core/lib/src/runner/console.dart
index 85fd112..1592d6d 100644
--- a/test_core/lib/src/runner/console.dart
+++ b/test_core/lib/src/runner/console.dart
@@ -6,8 +6,7 @@
import 'dart:math' as math;
import 'package:async/async.dart';
-
-import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
+import 'package:pedantic/pedantic.dart';
import '../util/io.dart';
@@ -41,7 +40,7 @@
: _red = color ? '\u001b[31m' : '',
_bold = color ? '\u001b[1m' : '',
_noColor = color ? '\u001b[0m' : '' {
- registerCommand("help", "Displays this help information.", _displayHelp);
+ registerCommand('help', 'Displays this help information.', _displayHelp);
}
/// Registers a command to be run whenever the user types [name].
@@ -49,7 +48,8 @@
/// The [description] should be a one-line description of the command to print
/// in the help output. The [body] callback will be called when the user types
/// the command, and may return a [Future].
- void registerCommand(String name, String description, body()) {
+ void registerCommand(
+ String name, String description, dynamic Function() body) {
if (_commands.containsKey(name)) {
throw ArgumentError('The console already has a command named "$name".');
}
@@ -62,9 +62,9 @@
/// This prints the initial prompt and loops while waiting for user input.
void start() {
_running = true;
- invoke(() async {
+ unawaited(() async {
while (_running) {
- stdout.write("> ");
+ stdout.write('> ');
_nextLine = stdinLines.cancelable((queue) => queue.next);
var commandName = await _nextLine.value;
_nextLine = null;
@@ -72,13 +72,13 @@
var command = _commands[commandName];
if (command == null) {
stderr.writeln(
- "${_red}Unknown command $_bold$commandName$_noColor$_red."
- "$_noColor");
+ '${_red}Unknown command $_bold$commandName$_noColor$_red.'
+ '$_noColor');
} else {
await command.body();
}
}
- });
+ }());
}
/// Stops the console running.
@@ -97,7 +97,7 @@
for (var command in _commands.values) {
var name = command.name.padRight(maxCommandLength + 4);
- print("$_bold$name$_noColor${command.description}");
+ print('$_bold$name$_noColor${command.description}');
}
}
}
diff --git a/test_core/lib/src/runner/coverage.dart b/test_core/lib/src/runner/coverage.dart
index 7dc2184..841bdd7 100644
--- a/test_core/lib/src/runner/coverage.dart
+++ b/test_core/lib/src/runner/coverage.dart
@@ -5,30 +5,20 @@
import 'dart:convert';
import 'dart:io';
-import 'package:coverage/coverage.dart';
import 'package:path/path.dart' as p;
import 'live_suite_controller.dart';
-import 'runner_suite.dart';
-/// Collects coverage and outputs to the [coverage] path.
-Future<void> gatherCoverage(
- String coverage, LiveSuiteController controller) async {
- final RunnerSuite suite = controller.liveSuite.suite;
-
- if (!suite.platform.runtime.isDartVM) return;
-
- final String isolateId = Uri.parse(suite.environment.observatoryUrl.fragment)
- .queryParameters['isolateId'];
-
- final cov = await collect(
- suite.environment.observatoryUrl, false, false, false, Set(),
- isolateIds: {isolateId});
-
- final outfile = File(p.join('$coverage', '${suite.path}.vm.json'))
+/// Collects coverage and outputs to the [coveragePath] path.
+Future<void> writeCoverage(
+ String coveragePath, LiveSuiteController controller) async {
+ var suite = controller.liveSuite.suite;
+ var coverage = await controller.liveSuite.suite.gatherCoverage();
+ final outfile = File(p.join(coveragePath,
+ '${suite.path}.${suite.platform.runtime.name.toLowerCase()}.json'))
..createSync(recursive: true);
- final IOSink out = outfile.openWrite();
- out.write(json.encode(cov));
+ final out = outfile.openWrite();
+ out.write(json.encode(coverage));
await out.flush();
await out.close();
}
diff --git a/test_core/lib/src/runner/coverage_stub.dart b/test_core/lib/src/runner/coverage_stub.dart
index 5a2285f..64f69c7 100644
--- a/test_core/lib/src/runner/coverage_stub.dart
+++ b/test_core/lib/src/runner/coverage_stub.dart
@@ -4,6 +4,7 @@
import 'live_suite_controller.dart';
-Future<void> gatherCoverage(String coverage, LiveSuiteController controller) =>
+Future<void> writeCoverage(
+ String coveragePath, LiveSuiteController controller) =>
throw UnsupportedError(
'Coverage is only supported through the test runner.');
diff --git a/test_core/lib/src/runner/debugger.dart b/test_core/lib/src/runner/debugger.dart
index e273d1c..524f08e 100644
--- a/test_core/lib/src/runner/debugger.dart
+++ b/test_core/lib/src/runner/debugger.dart
@@ -89,8 +89,8 @@
_Debugger(this._engine, this._reporter, this._suite)
: _console = Console(color: Configuration.current.color) {
- _console.registerCommand("restart",
- "Restart the current test after it finishes running.", _restartTest);
+ _console.registerCommand('restart',
+ 'Restart the current test after it finishes running.', _restartTest);
_onRestartSubscription = _suite.environment.onRestart.listen((_) {
_restartTest();
@@ -141,35 +141,35 @@
var url = _suite.environment.observatoryUrl;
if (url == null) {
print("${yellow}Observatory URL not found. Make sure you're using "
- "${runtime.name} 1.11 or later.$noColor");
+ '${runtime.name} 1.11 or later.$noColor');
} else {
- print("Observatory URL: $bold$url$noColor");
+ print('Observatory URL: $bold$url$noColor');
}
}
if (runtime.isHeadless && !runtime.isDartVM) {
var url = _suite.environment.remoteDebuggerUrl;
if (url == null) {
- print("${yellow}Remote debugger URL not found.$noColor");
+ print('${yellow}Remote debugger URL not found.$noColor');
} else {
- print("Remote debugger URL: $bold$url$noColor");
+ print('Remote debugger URL: $bold$url$noColor');
}
}
var buffer =
- StringBuffer("${bold}The test runner is paused.${noColor} ");
+ StringBuffer('${bold}The test runner is paused.${noColor} ');
if (runtime.isDartVM) {
- buffer.write("Open the Observatory ");
+ buffer.write('Open the Observatory ');
} else {
if (!runtime.isHeadless) {
- buffer.write("Open the dev console in $runtime ");
+ buffer.write('Open the dev console in $runtime ');
} else {
- buffer.write("Open the remote debugger ");
+ buffer.write('Open the remote debugger ');
}
}
buffer.write("and set breakpoints. Once you're finished, return to "
- "this terminal and press Enter.");
+ 'this terminal and press Enter.');
print(wordWrap(buffer.toString()));
}
diff --git a/test_core/lib/src/runner/engine.dart b/test_core/lib/src/runner/engine.dart
index 812d7a8..a60ea7f 100644
--- a/test_core/lib/src/runner/engine.dart
+++ b/test_core/lib/src/runner/engine.dart
@@ -73,12 +73,6 @@
/// A pool that limits the number of test suites running concurrently.
final Pool _runPool;
- /// A pool that limits the number of test suites loaded concurrently.
- ///
- /// Once this reaches its limit, loading any additional test suites will cause
- /// previous suites to be unloaded in the order they completed.
- final Pool _loadPool;
-
/// A completer that will complete when [this] is unpaused.
///
/// If [this] isn't paused, [_pauseCompleter] is `null`.
@@ -96,8 +90,7 @@
/// This will be `null` if [close] was called before all the tests finished
/// running.
Future<bool> get success async {
- await Future.wait(<Future>[_group.future, _loadPool.done],
- eagerError: true);
+ await Future.wait(<Future>[_group.future, _runPool.done], eagerError: true);
if (_closedBeforeDone) return null;
return liveTests.every((liveTest) =>
liveTest.state.result.isPassing &&
@@ -108,7 +101,7 @@
final _group = FutureGroup();
/// All of the engine's stream subscriptions.
- final _subscriptions = Set<StreamSubscription>();
+ final _subscriptions = <StreamSubscription>{};
/// A sink used to pass [RunnerSuite]s in to the engine to run.
///
@@ -125,7 +118,7 @@
/// Note that if a [LoadSuite] is added, this will only contain that suite,
/// not the suite it loads.
Set<RunnerSuite> get addedSuites => UnmodifiableSetView(_addedSuites);
- final _addedSuites = Set<RunnerSuite>();
+ final _addedSuites = <RunnerSuite>{};
/// A broadcast stream that emits each [RunnerSuite] as it's added to the
/// engine via [suiteSink].
@@ -146,7 +139,7 @@
/// [LoadSuite]s, both the [LoadSuite] and the suite it loads will eventually
/// be in this set.
Set<LiveSuite> get liveSuites => UnmodifiableSetView(_liveSuites);
- final _liveSuites = Set<LiveSuite>();
+ final _liveSuites = <LiveSuite>{};
/// A broadcast stream that emits each [LiveSuite] as it's loaded.
///
@@ -196,13 +189,13 @@
///
/// This is always a subset of [active]. Once a test in here has finished
/// running, it's run again.
- final _restarted = Set<LiveTest>();
+ final _restarted = <LiveTest>{};
/// The tests from [LoadSuite]s that are still running, in the order they
/// began running.
///
/// This is separate from [active] because load tests aren't always surfaced.
- final _activeLoadTests = List<LiveTest>();
+ final _activeLoadTests = <LiveTest>{};
/// Whether this engine is idle—that is, not currently executing a test.
bool get isIdle => _group.isIdle;
@@ -215,17 +208,15 @@
// dart:io is unavailable.
/// Creates an [Engine] that will run all tests provided via [suiteSink].
///
- /// [concurrency] controls how many suites are run at once, and defaults to 1.
- /// [maxSuites] controls how many suites are *loaded* at once, and defaults to
- /// four times [concurrency].
- Engine({int concurrency, int maxSuites, String coverage})
+ /// [concurrency] controls how many suites are loaded and ran at once, and
+ /// defaults to 1.
+ Engine({int concurrency, String coverage})
: _runPool = Pool(concurrency ?? 1),
- _loadPool = Pool(maxSuites ?? (concurrency ?? 1) * 2),
_coverage = coverage {
_group.future.then((_) {
_onTestStartedGroup.close();
_onSuiteStartedController.close();
- if (_closedBeforeDone == null) _closedBeforeDone = false;
+ _closedBeforeDone ??= false;
}).catchError((_) {
// Don't top-level errors. They'll be thrown via [success] anyway.
});
@@ -255,7 +246,7 @@
/// closed.
Future<bool> run() {
if (_runCalled) {
- throw StateError("Engine.run() may not be called more than once.");
+ throw StateError('Engine.run() may not be called more than once.');
}
_runCalled = true;
@@ -265,35 +256,32 @@
_onSuiteAddedController.add(suite);
_group.add(() async {
- var loadResource = await _loadPool.request();
-
+ var resource = await _runPool.request();
LiveSuiteController controller;
- if (suite is LoadSuite) {
- await _onUnpaused;
- controller = await _addLoadSuite(suite);
- if (controller == null) {
- loadResource.release();
- return;
+ try {
+ if (suite is LoadSuite) {
+ await _onUnpaused;
+ controller = await _addLoadSuite(suite);
+ if (controller == null) return;
+ } else {
+ controller = LiveSuiteController(suite);
}
- } else {
- controller = LiveSuiteController(suite);
- }
- _addLiveSuite(controller.liveSuite);
+ _addLiveSuite(controller.liveSuite);
- await _runPool.withResource(() async {
if (_closed) return;
await _runGroup(controller, controller.liveSuite.suite.group, []);
controller.noMoreLiveTests();
- if (_coverage != null) await gatherCoverage(_coverage, controller);
- loadResource.allowRelease(() => controller.close());
- });
+ if (_coverage != null) await writeCoverage(_coverage, controller);
+ } finally {
+ resource.allowRelease(() => controller?.close());
+ }
}());
}, onDone: () {
_subscriptions.remove(subscription);
_onSuiteAddedController.close();
_group.close();
- _loadPool.close();
+ _runPool.close();
});
_subscriptions.add(subscription);
@@ -323,7 +311,8 @@
if (!_closed && setUpAllSucceeded) {
// shuffle the group entries
var entries = group.entries.toList();
- if (suiteConfig.testRandomizeOrderingSeed > 0) {
+ if (suiteConfig.testRandomizeOrderingSeed != null &&
+ suiteConfig.testRandomizeOrderingSeed > 0) {
entries.shuffle(Random(suiteConfig.testRandomizeOrderingSeed));
}
@@ -416,7 +405,7 @@
if (skipped.metadata.skipReason != null) {
controller
- .message(Message.skip("Skip: ${skipped.metadata.skipReason}"));
+ .message(Message.skip('Skip: ${skipped.metadata.skipReason}'));
}
controller.setState(const State(Status.complete, Result.skipped));
@@ -437,7 +426,7 @@
if (!_active.contains(liveTest)) {
throw StateError("Can't restart inactive test "
- "\"${liveTest.test.name}\".");
+ '\"${liveTest.test.name}\".');
}
_restarted.add(liveTest);
@@ -545,23 +534,21 @@
/// Closing [suiteSink] indicates that no more input will be provided, closing
/// the engine indicates that no more output should be emitted.
Future close() async {
- // TODO(grouma) - Remove this unecessary await.
- await Future(() {});
_closed = true;
if (_closedBeforeDone != null) _closedBeforeDone = true;
- await _onSuiteAddedController.close();
await _suiteController.close();
+ await _onSuiteAddedController.close();
// Close the running tests first so that we're sure to wait for them to
// finish before we close their suites and cause them to become unloaded.
var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests);
var futures = allLiveTests.map((liveTest) => liveTest.close()).toList();
- // Closing the load pool will close the test suites as soon as their tests
+ // Closing the run pool will close the test suites as soon as their tests
// are done. For browser suites this is effectively immediate since their
// tests shut down as soon as they're closed, but for VM suites we may need
// to wait for tearDowns or tearDownAlls to run.
- futures.add(_loadPool.close());
+ futures.add(_runPool.close());
await Future.wait(futures, eagerError: true);
}
}
diff --git a/test_core/lib/src/runner/environment.dart b/test_core/lib/src/runner/environment.dart
index 164aaa4..2ddfdb3 100644
--- a/test_core/lib/src/runner/environment.dart
+++ b/test_core/lib/src/runner/environment.dart
@@ -36,15 +36,20 @@
/// The default environment for platform plugins.
class PluginEnvironment implements Environment {
+ @override
final supportsDebugging = false;
+ @override
Stream get onRestart => StreamController.broadcast().stream;
const PluginEnvironment();
+ @override
Uri get observatoryUrl => null;
+ @override
Uri get remoteDebuggerUrl => null;
+ @override
CancelableOperation displayPause() => throw UnsupportedError(
- "PluginEnvironment.displayPause is not supported.");
+ 'PluginEnvironment.displayPause is not supported.');
}
diff --git a/test_core/lib/src/runner/hybrid_listener.dart b/test_core/lib/src/runner/hybrid_listener.dart
index c818a59..022405b 100644
--- a/test_core/lib/src/runner/hybrid_listener.dart
+++ b/test_core/lib/src/runner/hybrid_listener.dart
@@ -2,14 +2,14 @@
// 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 'dart:async';
+import 'dart:isolate';
-import "package:async/async.dart";
-import "package:stack_trace/stack_trace.dart";
-import "package:stream_channel/isolate_channel.dart";
-import "package:stream_channel/stream_channel.dart";
-import "package:test_api/src/util/remote_exception.dart"; // ignore: implementation_imports
+import 'package:async/async.dart';
+import 'package:stack_trace/stack_trace.dart';
+import 'package:stream_channel/isolate_channel.dart';
+import 'package:stream_channel/stream_channel.dart';
+import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
/// A sink transformer that wraps data and error events so that errors can be
@@ -17,10 +17,10 @@
final _transformer = StreamSinkTransformer<dynamic, dynamic>.fromHandlers(
handleData: (data, sink) {
ensureJsonEncodable(data);
- sink.add({"type": "data", "data": data});
+ sink.add({'type': 'data', 'data': data});
}, handleError: (error, stackTrace, sink) {
sink.add(
- {"type": "error", "error": RemoteException.serialize(error, stackTrace)});
+ {'type': 'error', 'error': RemoteException.serialize(error, stackTrace)});
});
/// Runs the body of a hybrid isolate and communicates its messages, errors, and
@@ -32,7 +32,7 @@
///
/// The [data] argument contains two values: a [SendPort] that communicates with
/// the main isolate, and a message to pass to `hybridMain()`.
-void listen(Function getMain(), List data) {
+void listen(Function Function() getMain, List data) {
var channel = IsolateChannel.connectSend(data.first as SendPort);
var message = data.last;
@@ -42,7 +42,7 @@
try {
main = getMain();
} on NoSuchMethodError catch (_) {
- _sendError(channel, "No top-level hybridMain() function defined.");
+ _sendError(channel, 'No top-level hybridMain() function defined.');
return;
} catch (error, stackTrace) {
_sendError(channel, error, stackTrace);
@@ -50,12 +50,12 @@
}
if (main is! Function) {
- _sendError(channel, "Top-level hybridMain is not a function.");
+ _sendError(channel, 'Top-level hybridMain is not a function.');
return;
} else if (main is! Function(StreamChannel) &&
main is! Function(StreamChannel, Null)) {
_sendError(channel,
- "Top-level hybridMain() function must take one or two arguments.");
+ 'Top-level hybridMain() function must take one or two arguments.');
return;
}
@@ -69,19 +69,19 @@
main(transformedChannel, message);
}
}, zoneSpecification: ZoneSpecification(print: (_, __, ___, line) {
- channel.sink.add({"type": "print", "line": line});
+ channel.sink.add({'type': 'print', 'line': line});
}));
}, onError: (error, stackTrace) async {
_sendError(channel, error, stackTrace);
await channel.sink.close();
- Zone.current.handleUncaughtError(error, stackTrace);
+ Isolate.current.kill();
});
}
/// Sends a message over [channel] indicating an error from user code.
void _sendError(StreamChannel channel, error, [StackTrace stackTrace]) {
channel.sink.add({
- "type": "error",
- "error": RemoteException.serialize(error, stackTrace ?? Chain.current())
+ 'type': 'error',
+ 'error': RemoteException.serialize(error, stackTrace ?? Chain.current())
});
}
diff --git a/test_core/lib/src/runner/live_suite.dart b/test_core/lib/src/runner/live_suite.dart
index 9c84492..e580845 100644
--- a/test_core/lib/src/runner/live_suite.dart
+++ b/test_core/lib/src/runner/live_suite.dart
@@ -59,11 +59,12 @@
///
/// This is guaranteed to contain the same tests as the union of [passed],
/// [skipped], [failed], and [active].
- Set<LiveTest> get liveTests {
- var sets = [passed, skipped, failed];
- if (active != null) sets.add(Set.from([active]));
- return UnionSet.from(sets);
- }
+ Set<LiveTest> get liveTests => UnionSet.from([
+ passed,
+ skipped,
+ failed,
+ if (active != null) {active}
+ ]);
/// A stream that emits each [LiveTest] in this suite as it's about to start
/// running.
diff --git a/test_core/lib/src/runner/live_suite_controller.dart b/test_core/lib/src/runner/live_suite_controller.dart
index e33bfde..e2ec1dc 100644
--- a/test_core/lib/src/runner/live_suite_controller.dart
+++ b/test_core/lib/src/runner/live_suite_controller.dart
@@ -18,25 +18,35 @@
class _LiveSuite extends LiveSuite {
final LiveSuiteController _controller;
+ @override
RunnerSuite get suite => _controller._suite;
+ @override
bool get isComplete => _controller._isComplete;
+ @override
Future get onComplete => _controller._onCompleteGroup.future;
+ @override
bool get isClosed => _controller._onCloseCompleter.isCompleted;
+ @override
Future get onClose => _controller._onCloseCompleter.future;
+ @override
Stream<LiveTest> get onTestStarted =>
_controller._onTestStartedController.stream;
+ @override
Set<LiveTest> get passed => UnmodifiableSetView(_controller._passed);
+ @override
Set<LiveTest> get skipped => UnmodifiableSetView(_controller._skipped);
+ @override
Set<LiveTest> get failed => UnmodifiableSetView(_controller._failed);
+ @override
LiveTest get active => _controller._active;
_LiveSuite(this._controller);
@@ -76,13 +86,13 @@
StreamController<LiveTest>.broadcast(sync: true);
/// The set that backs [LiveTest.passed].
- final _passed = Set<LiveTest>();
+ final _passed = <LiveTest>{};
/// The set that backs [LiveTest.skipped].
- final _skipped = Set<LiveTest>();
+ final _skipped = <LiveTest>{};
/// The set that backs [LiveTest.failed].
- final _failed = Set<LiveTest>();
+ final _failed = <LiveTest>{};
/// The test exposed through [LiveTest.active].
LiveTest _active;
diff --git a/test_core/lib/src/runner/load_exception.dart b/test_core/lib/src/runner/load_exception.dart
index b94df49..dcc5f17 100644
--- a/test_core/lib/src/runner/load_exception.dart
+++ b/test_core/lib/src/runner/load_exception.dart
@@ -12,6 +12,7 @@
LoadException(this.path, this.innerError);
+ @override
String toString({bool color = false}) {
var buffer = StringBuffer();
if (color) buffer.write('\u001b[31m'); // red
@@ -22,10 +23,10 @@
if (innerError is SourceSpanException) {
innerString = (innerError as SourceSpanException)
.toString(color: color)
- .replaceFirst(" of $path", "");
+ .replaceFirst(' of $path', '');
}
- buffer.write(innerString.contains("\n") ? "\n" : " ");
+ buffer.write(innerString.contains('\n') ? '\n' : ' ');
buffer.write(innerString);
return buffer.toString();
}
diff --git a/test_core/lib/src/runner/load_suite.dart b/test_core/lib/src/runner/load_suite.dart
index 246c489..fd6dfb0 100644
--- a/test_core/lib/src/runner/load_suite.dart
+++ b/test_core/lib/src/runner/load_suite.dart
@@ -6,27 +6,23 @@
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
-
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
+import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
-import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
-import 'runner_suite.dart';
-import 'suite.dart';
-
import '../../test_core.dart';
-
-// ignore: uri_does_not_exist
import '../util/io_stub.dart'
// ignore: uri_does_not_exist
if (dart.library.io) '../util/io.dart';
import 'load_exception.dart';
import 'plugin/environment.dart';
+import 'runner_suite.dart';
+import 'suite.dart';
/// The timeout for loading a test suite.
///
@@ -51,9 +47,13 @@
/// suite itself is returned by [suite] once it's avaialble, but any errors or
/// prints will be emitted through the running [LiveTest].
class LoadSuite extends Suite implements RunnerSuite {
+ @override
final environment = const PluginEnvironment();
+ @override
final SuiteConfiguration config;
+ @override
final isDebugging = false;
+ @override
final onDebugging = StreamController<bool>().stream;
@override
@@ -87,14 +87,14 @@
/// If the the load test is closed before [body] is complete, it will close
/// the suite returned by [body] once it completes.
factory LoadSuite(String name, SuiteConfiguration config,
- SuitePlatform platform, FutureOr<RunnerSuite> body(),
+ SuitePlatform platform, FutureOr<RunnerSuite> Function() body,
{String path}) {
var completer = Completer<Pair<RunnerSuite, Zone>>.sync();
return LoadSuite._(name, config, platform, () {
var invoker = Invoker.current;
invoker.addOutstandingCallback();
- invoke(() async {
+ unawaited(() async {
var suite = await body();
if (completer.isCompleted) {
// If the load test has already been closed, close the suite it
@@ -105,7 +105,7 @@
completer.complete(suite == null ? null : Pair(suite, Zone.current));
invoker.removeOutstandingCallback();
- });
+ }());
// If the test completes before the body callback, either an out-of-band
// error occurred or the test was canceled. Either way, we return a `null`
@@ -126,10 +126,10 @@
factory LoadSuite.forLoadException(
LoadException exception, SuiteConfiguration config,
{SuitePlatform platform, StackTrace stackTrace}) {
- if (stackTrace == null) stackTrace = Trace.current();
+ stackTrace ??= Trace.current();
return LoadSuite(
- "loading ${exception.path}",
+ 'loading ${exception.path}',
config ?? SuiteConfiguration.empty,
platform ?? currentPlatform(Runtime.vm),
() => Future.error(exception, stackTrace),
@@ -139,12 +139,12 @@
/// A utility constructor for a load suite that just emits [suite].
factory LoadSuite.forSuite(RunnerSuite suite) {
return LoadSuite(
- "loading ${suite.path}", suite.config, suite.platform, () => suite,
+ 'loading ${suite.path}', suite.config, suite.platform, () => suite,
path: suite.path);
}
- LoadSuite._(String name, this.config, SuitePlatform platform, void body(),
- this._suiteAndZone, {String path})
+ LoadSuite._(String name, this.config, SuitePlatform platform,
+ void Function() body, this._suiteAndZone, {String path})
: super(
Group.root(
[LocalTest(name, Metadata(timeout: Timeout(_timeout)), body)]),
@@ -168,7 +168,7 @@
/// If [suite] completes to `null`, [change] won't be run. [change] is run
/// within the load test's zone, so any errors or prints it emits will be
/// associated with that test.
- LoadSuite changeSuite(RunnerSuite change(RunnerSuite suite)) {
+ LoadSuite changeSuite(RunnerSuite Function(RunnerSuite) change) {
return LoadSuite._changeSuite(this, _suiteAndZone.then((pair) {
if (pair == null) return null;
@@ -197,14 +197,21 @@
throw 'unreachable';
}
- LoadSuite filter(bool callback(Test test)) {
+ @override
+ LoadSuite filter(bool Function(Test) callback) {
var filtered = this.group.filter(callback);
- if (filtered == null) filtered = Group.root([], metadata: metadata);
+ filtered ??= Group.root([], metadata: metadata);
return LoadSuite._filtered(this, filtered);
}
+ @override
StreamChannel channel(String name) =>
- throw UnsupportedError("LoadSuite.channel() is not supported.");
+ throw UnsupportedError('LoadSuite.channel() is not supported.');
+ @override
Future close() async {}
+
+ @override
+ Future<Map<String, dynamic>> gatherCoverage() =>
+ throw UnsupportedError('Coverage is not supported for LoadSuite tests.');
}
diff --git a/test_core/lib/src/runner/loader.dart b/test_core/lib/src/runner/loader.dart
index 74fe5f2..b8c779f 100644
--- a/test_core/lib/src/runner/loader.dart
+++ b/test_core/lib/src/runner/loader.dart
@@ -35,7 +35,7 @@
final _config = Configuration.current;
/// All suites that have been created by the loader.
- final _suites = Set<RunnerSuite>();
+ final _suites = <RunnerSuite>{};
/// Memoizers for platform plugins, indexed by the runtimes they support.
final _platformPlugins = <Runtime, AsyncMemoizer<PlatformPlugin>>{};
@@ -179,7 +179,8 @@
return;
}
- if (_config.suiteDefaults.excludeTags.evaluate(suiteConfig.metadata.tags)) {
+ if (_config.suiteDefaults.excludeTags
+ .evaluate(suiteConfig.metadata.tags.contains)) {
return;
}
@@ -207,28 +208,44 @@
yield LoadSuite.forSuite(RunnerSuite(
const PluginEnvironment(),
platformConfig,
- Group.root([LocalTest("(suite)", platformConfig.metadata, () {})],
+ Group.root([LocalTest('(suite)', platformConfig.metadata, () {})],
metadata: platformConfig.metadata),
platform,
path: path));
continue;
}
- var name = (platform.runtime.isJS ? "compiling " : "loading ") + path;
+ var name =
+ (platform.runtime.isJS && platformConfig.precompiledPath == null
+ ? 'compiling '
+ : 'loading ') +
+ path;
yield LoadSuite(name, platformConfig, platform, () async {
var memo = _platformPlugins[platform.runtime];
- try {
- var plugin = await memo.runOnce(_platformCallbacks[platform.runtime]);
- _customizePlatform(plugin, platform.runtime);
- var suite = await plugin.load(path, platform, platformConfig,
- {"platformVariables": _runtimeVariables.toList()});
- if (suite != null) _suites.add(suite);
- return suite;
- } catch (error, stackTrace) {
- if (error is LoadException) rethrow;
- await Future.error(LoadException(path, error), stackTrace);
- return null;
+ var retriesLeft = suiteConfig.metadata.retry;
+ while (true) {
+ try {
+ var plugin =
+ await memo.runOnce(_platformCallbacks[platform.runtime]);
+ _customizePlatform(plugin, platform.runtime);
+ var suite = await plugin.load(path, platform, platformConfig,
+ {'platformVariables': _runtimeVariables.toList()});
+ if (suite != null) _suites.add(suite);
+ return suite;
+ } catch (error, stackTrace) {
+ if (retriesLeft > 0) {
+ retriesLeft--;
+ print('Retrying load of $path in 1s ($retriesLeft remaining)');
+ await Future.delayed(Duration(seconds: 1));
+ continue;
+ }
+ if (error is LoadException) {
+ rethrow;
+ }
+ await Future.error(LoadException(path, error), stackTrace);
+ return null;
+ }
}
}, path: path);
}
diff --git a/test_core/lib/src/runner/parse_metadata.dart b/test_core/lib/src/runner/parse_metadata.dart
index 40366a2..1de3d33 100644
--- a/test_core/lib/src/runner/parse_metadata.dart
+++ b/test_core/lib/src/runner/parse_metadata.dart
@@ -42,7 +42,7 @@
Set<String> _prefixes;
/// The actual contents of the file.
- String _contents;
+ final String _contents;
_Parser(this._path, this._contents, this._platformVariables) {
// ignore: deprecated_member_use
@@ -162,7 +162,7 @@
/// constructor for the annotation, if any.
///
/// Returns either `true` or a reason string.
- _parseSkip(Annotation annotation, String constructorName) {
+ dynamic _parseSkip(Annotation annotation, String constructorName) {
var args = annotation.arguments.arguments;
return args.isEmpty ? true : _parseString(args.first).stringValue;
}
@@ -170,7 +170,7 @@
/// Parses a `Skip` constructor.
///
/// Returns either `true` or a reason string.
- _parseSkipConstructor(Expression constructor) {
+ dynamic _parseSkipConstructor(Expression constructor) {
_findConstructorName(constructor, 'Skip');
var arguments = _parseArguments(constructor);
return arguments.isEmpty ? true : _parseString(arguments.first).stringValue;
@@ -283,9 +283,10 @@
Map<String, Expression> _parseNamedArguments(
NodeList<Expression> arguments) =>
- Map.fromIterable(arguments.whereType<NamedExpression>(),
- key: (a) => (a as NamedExpression).name.label.name,
- value: (a) => (a as NamedExpression).expression);
+ {
+ for (var a in arguments.whereType<NamedExpression>())
+ a.name.label.name: a.expression
+ };
/// Asserts that [existing] is null.
///
@@ -435,7 +436,7 @@
/// By default, returns [Expression] keys and values. These can be overridden
/// with the [key] and [value] parameters.
Map<K, V> _parseMap<K, V>(Expression expression,
- {K key(Expression expression), V value(Expression expression)}) {
+ {K Function(Expression) key, V Function(Expression) value}) {
key ??= (expression) => expression as K;
value ??= (expression) => expression as V;
@@ -505,7 +506,7 @@
/// Runs [fn] and contextualizes any [SourceSpanFormatException]s that occur
/// in it relative to [literal].
- T _contextualize<T>(StringLiteral literal, T fn()) {
+ T _contextualize<T>(StringLiteral literal, T Function() fn) {
try {
return fn();
} on SourceSpanFormatException catch (error) {
diff --git a/test_core/lib/src/runner/plugin/environment.dart b/test_core/lib/src/runner/plugin/environment.dart
index e8cb05f..40e88b2 100644
--- a/test_core/lib/src/runner/plugin/environment.dart
+++ b/test_core/lib/src/runner/plugin/environment.dart
@@ -10,15 +10,20 @@
/// The default environment for platform plugins.
class PluginEnvironment implements Environment {
+ @override
final supportsDebugging = false;
+ @override
Stream get onRestart => StreamController.broadcast().stream;
const PluginEnvironment();
+ @override
Uri get observatoryUrl => null;
+ @override
Uri get remoteDebuggerUrl => null;
+ @override
CancelableOperation displayPause() => throw UnsupportedError(
- "PluginEnvironment.displayPause is not supported.");
+ 'PluginEnvironment.displayPause is not supported.');
}
diff --git a/test_core/lib/src/runner/plugin/platform_helpers.dart b/test_core/lib/src/runner/plugin/platform_helpers.dart
index 442c0c6..bd11058 100644
--- a/test_core/lib/src/runner/plugin/platform_helpers.dart
+++ b/test_core/lib/src/runner/plugin/platform_helpers.dart
@@ -7,19 +7,18 @@
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
-
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports
-import '../runner_suite.dart';
-import '../environment.dart';
-import '../suite.dart';
import '../configuration.dart';
+import '../environment.dart';
import '../load_exception.dart';
+import '../runner_suite.dart';
import '../runner_test.dart';
+import '../suite.dart';
/// A helper method for creating a [RunnerSuiteController] containing tests
/// that communicate over [channel].
@@ -35,13 +34,17 @@
///
/// If [mapper] is passed, it will be used to adjust stack traces for any errors
/// emitted by tests.
+///
+/// [gatherCoverage] is a callback which returns a hit-map containing merged
+/// coverage report suitable for use with `package:coverage`.
RunnerSuiteController deserializeSuite(
String path,
SuitePlatform platform,
SuiteConfiguration suiteConfig,
Environment environment,
StreamChannel channel,
- Object message) {
+ Object message,
+ {Future<Map<String, dynamic>> Function() gatherCoverage}) {
var disconnector = Disconnector();
var suiteChannel = MultiChannel(channel.transform(disconnector));
@@ -51,7 +54,8 @@
'metadata': suiteConfig.metadata.serialize(),
'asciiGlyphs': Platform.isWindows,
'path': path,
- 'collectTraces': Configuration.current.reporter == 'json',
+ 'collectTraces': Configuration.current.reporter == 'json' ||
+ Configuration.current.fileReporters.containsKey('json'),
'noRetry': Configuration.current.noRetry,
'foldTraceExcept': Configuration.current.foldTraceExcept.toList(),
'foldTraceOnly': Configuration.current.foldTraceOnly.toList(),
@@ -60,7 +64,7 @@
var completer = Completer<Group>();
var loadSuiteZone = Zone.current;
- handleError(error, StackTrace stackTrace) {
+ void handleError(error, StackTrace stackTrace) {
disconnector.disconnect();
if (completer.isCompleted) {
@@ -75,26 +79,26 @@
suiteChannel.stream.listen(
(response) {
- switch (response["type"] as String) {
- case "print":
- print(response["line"]);
+ switch (response['type'] as String) {
+ case 'print':
+ print(response['line']);
break;
- case "loadException":
+ case 'loadException':
handleError(
- LoadException(path, response["message"]), Trace.current());
+ LoadException(path, response['message']), Trace.current());
break;
- case "error":
- var asyncError = RemoteException.deserialize(response["error"]);
+ case 'error':
+ var asyncError = RemoteException.deserialize(response['error']);
handleError(
LoadException(path, asyncError.error), asyncError.stackTrace);
break;
- case "success":
+ case 'success':
var deserializer = _Deserializer(suiteChannel);
completer.complete(
- deserializer.deserializeGroup(response["root"] as Map));
+ deserializer.deserializeGroup(response['root'] as Map));
break;
}
},
@@ -102,14 +106,15 @@
onDone: () {
if (completer.isCompleted) return;
completer.completeError(
- LoadException(path, "Connection closed before test suite loaded."),
+ LoadException(path, 'Connection closed before test suite loaded.'),
Trace.current());
});
return RunnerSuiteController(
environment, suiteConfig, suiteChannel, completer.future, platform,
path: path,
- onClose: () => disconnector.disconnect().catchError(handleError));
+ onClose: () => disconnector.disconnect().catchError(handleError),
+ gatherCoverage: gatherCoverage);
}
/// A utility class for storing state while deserializing tests.
diff --git a/test_core/lib/src/runner/plugin/remote_platform_helpers.dart b/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
index 310d0f5..17c6d4c 100644
--- a/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
+++ b/test_core/lib/src/runner/plugin/remote_platform_helpers.dart
@@ -30,8 +30,8 @@
///
/// If [beforeLoad] is passed, it's called before the tests have been declared
/// for this worker.
-StreamChannel serializeSuite(Function getMain(),
- {bool hidePrints = true, Future beforeLoad()}) =>
+StreamChannel serializeSuite(Function Function() getMain,
+ {bool hidePrints = true, Future Function() beforeLoad}) =>
RemoteListener.start(getMain,
hidePrints: hidePrints, beforeLoad: beforeLoad);
diff --git a/test_core/lib/src/runner/reporter/compact.dart b/test_core/lib/src/runner/reporter/compact.dart
index 7827811..4c3e69a 100644
--- a/test_core/lib/src/runner/reporter/compact.dart
+++ b/test_core/lib/src/runner/reporter/compact.dart
@@ -99,7 +99,7 @@
var _paused = false;
/// The set of all subscriptions to various streams.
- final _subscriptions = Set<StreamSubscription>();
+ final _subscriptions = <StreamSubscription>{};
/// Watches the tests run by [engine] and prints their results to the
/// terminal.
@@ -114,6 +114,7 @@
_subscriptions.add(_engine.success.asStream().listen(_onDone));
}
+ @override
void pause() {
if (_paused) return;
_paused = true;
@@ -132,6 +133,7 @@
}
}
+ @override
void resume() {
if (!_paused) return;
_paused = false;
@@ -143,6 +145,7 @@
}
}
+ @override
void cancel() {
for (var subscription in _subscriptions) {
subscription.cancel();
@@ -207,7 +210,7 @@
if (liveTest.state.status != Status.complete) return;
_progressLine(_description(liveTest),
- truncate: false, suffix: " $_bold$_red[E]$_noColor");
+ truncate: false, suffix: ' $_bold$_red[E]$_noColor');
if (!_printedNewline) _sink.writeln('');
_printedNewline = true;
@@ -242,33 +245,33 @@
// shouldn't print summary information, we should just make sure the
// terminal cursor is on its own line.
if (success == null) {
- if (!_printedNewline) _sink.writeln("");
+ if (!_printedNewline) _sink.writeln('');
_printedNewline = true;
return;
}
if (_engine.liveTests.isEmpty) {
- if (!_printedNewline) _sink.write("\r");
- var message = "No tests ran.";
+ if (!_printedNewline) _sink.write('\r');
+ var message = 'No tests ran.';
_sink.write(message);
// Add extra padding to overwrite any load messages.
- if (!_printedNewline) _sink.write(" " * (lineLength - message.length));
+ if (!_printedNewline) _sink.write(' ' * (lineLength - message.length));
_sink.writeln('');
} else if (!success) {
for (var liveTest in _engine.active) {
_progressLine(_description(liveTest),
truncate: false,
- suffix: " - did not complete $_bold$_red[E]$_noColor");
+ suffix: ' - did not complete $_bold$_red[E]$_noColor');
_sink.writeln('');
}
_progressLine('Some tests failed.', color: _red);
_sink.writeln('');
} else if (_engine.passed.isEmpty) {
- _progressLine("All tests skipped.");
+ _progressLine('All tests skipped.');
_sink.writeln('');
} else {
- _progressLine("All tests passed!");
+ _progressLine('All tests passed!');
_sink.writeln('');
}
}
@@ -309,7 +312,7 @@
_lastProgressTruncated = truncate;
if (suffix != null) message += suffix;
- if (color == null) color = '';
+ color ??= '';
var duration = _stopwatch.elapsed;
var buffer = StringBuffer();
@@ -369,15 +372,15 @@
if (_printPath &&
liveTest.suite is! LoadSuite &&
liveTest.suite.path != null) {
- name = "${liveTest.suite.path}: $name";
+ name = '${liveTest.suite.path}: $name';
}
if (_config.suiteDefaults.runtimes.length > 1 &&
liveTest.suite.platform != null) {
- name = "[${liveTest.suite.platform.runtime.name}] $name";
+ name = '[${liveTest.suite.platform.runtime.name}] $name';
}
- if (liveTest.suite is LoadSuite) name = "$_bold$_gray$name$_noColor";
+ if (liveTest.suite is LoadSuite) name = '$_bold$_gray$name$_noColor';
return name;
}
diff --git a/test_core/lib/src/runner/reporter/expanded.dart b/test_core/lib/src/runner/reporter/expanded.dart
index 87588d0..2785ae9 100644
--- a/test_core/lib/src/runner/reporter/expanded.dart
+++ b/test_core/lib/src/runner/reporter/expanded.dart
@@ -82,7 +82,7 @@
var _paused = false;
/// The set of all subscriptions to various streams.
- final _subscriptions = Set<StreamSubscription>();
+ final _subscriptions = <StreamSubscription>{};
final StringSink _sink;
@@ -119,6 +119,7 @@
_subscriptions.add(_engine.success.asStream().listen(_onDone));
}
+ @override
void pause() {
if (_paused) return;
_paused = true;
@@ -130,6 +131,7 @@
}
}
+ @override
void resume() {
if (!_paused) return;
_stopwatch.start();
@@ -139,6 +141,7 @@
}
}
+ @override
void cancel() {
for (var subscription in _subscriptions) {
subscription.cancel();
@@ -162,7 +165,7 @@
.listen((state) => _onStateChange(liveTest, state)));
} else if (_engine.active.length == 1 &&
_engine.active.first == liveTest &&
- liveTest.test.name.startsWith("compiling ")) {
+ liveTest.test.name.startsWith('compiling ')) {
// Print a progress line for load tests that come from compiling JS, since
// that takes a long time.
_progressLine(_description(liveTest));
@@ -194,7 +197,7 @@
void _onError(LiveTest liveTest, error, StackTrace stackTrace) {
if (liveTest.state.status != Status.complete) return;
- _progressLine(_description(liveTest), suffix: " $_bold$_red[E]$_noColor");
+ _progressLine(_description(liveTest), suffix: ' $_bold$_red[E]$_noColor');
if (error is! LoadException) {
_sink..writeln(indent('$error'))..writeln(indent('$stackTrace'));
@@ -221,17 +224,17 @@
if (success == null) return;
if (_engine.liveTests.isEmpty) {
- _sink.writeln("No tests ran.");
+ _sink.writeln('No tests ran.');
} else if (!success) {
for (var liveTest in _engine.active) {
_progressLine(_description(liveTest),
- suffix: " - did not complete $_bold$_red[E]$_noColor");
+ suffix: ' - did not complete $_bold$_red[E]$_noColor');
}
_progressLine('Some tests failed.', color: _red);
} else if (_engine.passed.isEmpty) {
- _progressLine("All tests skipped.");
+ _progressLine('All tests skipped.');
} else {
- _progressLine("All tests passed!");
+ _progressLine('All tests passed!');
}
}
@@ -258,7 +261,7 @@
_lastProgressSuffix = suffix;
if (suffix != null) message += suffix;
- if (color == null) color = '';
+ color ??= '';
var duration = _stopwatch.elapsed;
var buffer = StringBuffer();
@@ -307,14 +310,14 @@
if (_printPath &&
liveTest.suite is! LoadSuite &&
liveTest.suite.path != null) {
- name = "${liveTest.suite.path}: $name";
+ name = '${liveTest.suite.path}: $name';
}
if (_printPlatform) {
- name = "[${liveTest.suite.platform.runtime.name}] $name";
+ name = '[${liveTest.suite.platform.runtime.name}] $name';
}
- if (liveTest.suite is LoadSuite) name = "$_bold$_gray$name$_noColor";
+ if (liveTest.suite is LoadSuite) name = '$_bold$_gray$name$_noColor';
return name;
}
diff --git a/test_core/lib/src/runner/reporter/json.dart b/test_core/lib/src/runner/reporter/json.dart
index eb3c9fb..5edb4a0 100644
--- a/test_core/lib/src/runner/reporter/json.dart
+++ b/test_core/lib/src/runner/reporter/json.dart
@@ -48,16 +48,16 @@
var _paused = false;
/// The set of all subscriptions to various streams.
- final _subscriptions = Set<StreamSubscription>();
+ final _subscriptions = <StreamSubscription>{};
/// An expando that associates unique IDs with [LiveTest]s.
- final _liveTestIDs = Map<LiveTest, int>();
+ final _liveTestIDs = <LiveTest, int>{};
/// An expando that associates unique IDs with [Suite]s.
- final _suiteIDs = Map<Suite, int>();
+ final _suiteIDs = <Suite, int>{};
/// An expando that associates unique IDs with [Group]s.
- final _groupIDs = Map<Group, int>();
+ final _groupIDs = <Group, int>{};
/// The next ID to associate with a [LiveTest].
var _nextID = 0;
@@ -74,13 +74,14 @@
_subscriptions.add(_engine.success.asStream().listen(_onDone));
_subscriptions.add(_engine.onSuiteAdded.listen(null, onDone: () {
- _emit("allSuites", {"count": _engine.addedSuites.length});
+ _emit('allSuites', {'count': _engine.addedSuites.length});
}));
- _emit("start",
- {"protocolVersion": "0.1.1", "runnerVersion": testVersion, "pid": pid});
+ _emit('start',
+ {'protocolVersion': '0.1.1', 'runnerVersion': testVersion, 'pid': pid});
}
+ @override
void pause() {
if (_paused) return;
_paused = true;
@@ -92,6 +93,7 @@
}
}
+ @override
void resume() {
if (!_paused) return;
_paused = false;
@@ -103,6 +105,7 @@
}
}
+ @override
void cancel() {
for (var subscription in _subscriptions) {
subscription.cancel();
@@ -128,15 +131,15 @@
var suiteConfig = _configFor(liveTest.suite);
var id = _nextID++;
_liveTestIDs[liveTest] = id;
- _emit("testStart", {
- "test": _addFrameInfo(
+ _emit('testStart', {
+ 'test': _addFrameInfo(
suiteConfig,
{
- "id": id,
- "name": liveTest.test.name,
- "suiteID": suiteID,
- "groupIDs": groupIDs,
- "metadata": _serializeMetadata(suiteConfig, liveTest.test.metadata)
+ 'id': id,
+ 'name': liveTest.test.name,
+ 'suiteID': suiteID,
+ 'groupIDs': groupIDs,
+ 'metadata': _serializeMetadata(suiteConfig, liveTest.test.metadata)
},
liveTest.test,
liveTest.suite.platform.runtime,
@@ -152,10 +155,10 @@
.listen((error) => _onError(liveTest, error.error, error.stackTrace)));
_subscriptions.add(liveTest.onMessage.listen((message) {
- _emit("print", {
- "testID": id,
- "messageType": message.type.name,
- "message": message.text
+ _emit('print', {
+ 'testID': id,
+ 'messageType': message.type.name,
+ 'message': message.text
});
}));
}
@@ -179,20 +182,20 @@
// TODO(nweiz): test this when we have a library for communicating with
// the Chrome remote debugger, or when we have VM debug support.
- _emit("debug", {
- "suiteID": id,
- "observatory": runnerSuite.environment.observatoryUrl?.toString(),
- "remoteDebugger":
+ _emit('debug', {
+ 'suiteID': id,
+ 'observatory': runnerSuite.environment.observatoryUrl?.toString(),
+ 'remoteDebugger':
runnerSuite.environment.remoteDebuggerUrl?.toString(),
});
});
}
- _emit("suite", {
- "suite": {
- "id": id,
- "platform": suite.platform.runtime.identifier,
- "path": suite.path
+ _emit('suite', {
+ 'suite': {
+ 'id': id,
+ 'platform': suite.platform.runtime.identifier,
+ 'path': suite.path
}
});
return id;
@@ -215,16 +218,16 @@
_groupIDs[group] = id;
var suiteConfig = _configFor(suite);
- _emit("group", {
- "group": _addFrameInfo(
+ _emit('group', {
+ 'group': _addFrameInfo(
suiteConfig,
{
- "id": id,
- "suiteID": _idForSuite(suite),
- "parentID": parentID,
- "name": group.name,
- "metadata": _serializeMetadata(suiteConfig, group.metadata),
- "testCount": group.testCount
+ 'id': id,
+ 'suiteID': _idForSuite(suite),
+ 'parentID': parentID,
+ 'name': group.name,
+ 'metadata': _serializeMetadata(suiteConfig, group.metadata),
+ 'testCount': group.testCount
},
group,
suite.platform.runtime,
@@ -238,29 +241,29 @@
/// Serializes [metadata] into a JSON-protocol-compatible map.
Map _serializeMetadata(SuiteConfiguration suiteConfig, Metadata metadata) =>
suiteConfig.runSkipped
- ? {"skip": false, "skipReason": null}
- : {"skip": metadata.skip, "skipReason": metadata.skipReason};
+ ? {'skip': false, 'skipReason': null}
+ : {'skip': metadata.skip, 'skipReason': metadata.skipReason};
/// A callback called when [liveTest] finishes running.
void _onComplete(LiveTest liveTest) {
- _emit("testDone", {
- "testID": _liveTestIDs[liveTest],
+ _emit('testDone', {
+ 'testID': _liveTestIDs[liveTest],
// For backwards-compatibility, report skipped tests as successes.
- "result": liveTest.state.result == Result.skipped
- ? "success"
+ 'result': liveTest.state.result == Result.skipped
+ ? 'success'
: liveTest.state.result.toString(),
- "skipped": liveTest.state.result == Result.skipped,
- "hidden": !_engine.liveTests.contains(liveTest)
+ 'skipped': liveTest.state.result == Result.skipped,
+ 'hidden': !_engine.liveTests.contains(liveTest)
});
}
/// A callback called when [liveTest] throws [error].
void _onError(LiveTest liveTest, error, StackTrace stackTrace) {
- _emit("error", {
- "testID": _liveTestIDs[liveTest],
- "error": error.toString(),
- "stackTrace": '$stackTrace',
- "isFailure": error is TestFailure
+ _emit('error', {
+ 'testID': _liveTestIDs[liveTest],
+ 'error': error.toString(),
+ 'stackTrace': '$stackTrace',
+ 'isFailure': error is TestFailure
});
}
@@ -272,7 +275,7 @@
cancel();
_stopwatch.stop();
- _emit("done", {"success": success});
+ _emit('done', {'success': success});
}
/// Returns the configuration for [suite].
@@ -284,8 +287,8 @@
/// Emits an event with the given type and attributes.
void _emit(String type, Map attributes) {
- attributes["type"] = type;
- attributes["time"] = _stopwatch.elapsed.inMilliseconds;
+ attributes['type'] = type;
+ attributes['time'] = _stopwatch.elapsed.inMilliseconds;
_sink.writeln(jsonEncode(attributes));
}
@@ -310,13 +313,13 @@
rootFrame = null;
}
- map["line"] = frame?.line;
- map["column"] = frame?.column;
- map["url"] = frame?.uri?.toString();
+ map['line'] = frame?.line;
+ map['column'] = frame?.column;
+ map['url'] = frame?.uri?.toString();
if (rootFrame != null && rootFrame != frame) {
- map["root_line"] = rootFrame.line;
- map["root_column"] = rootFrame.column;
- map["root_url"] = rootFrame.uri.toString();
+ map['root_line'] = rootFrame.line;
+ map['root_column'] = rootFrame.column;
+ map['root_url'] = rootFrame.uri.toString();
}
return map;
}
diff --git a/test_core/lib/src/runner/reporter/multiplex.dart b/test_core/lib/src/runner/reporter/multiplex.dart
new file mode 100644
index 0000000..e13c1b4
--- /dev/null
+++ b/test_core/lib/src/runner/reporter/multiplex.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, 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 '../reporter.dart';
+
+class MultiplexReporter implements Reporter {
+ Iterable<Reporter> delegates;
+
+ MultiplexReporter(this.delegates);
+
+ @override
+ void cancel() {
+ for (var d in delegates) {
+ d.cancel();
+ }
+ }
+
+ @override
+ void pause() {
+ for (var d in delegates) {
+ d.pause();
+ }
+ }
+
+ @override
+ void resume() {
+ for (var d in delegates) {
+ d.resume();
+ }
+ }
+}
diff --git a/test_core/lib/src/runner/runner_suite.dart b/test_core/lib/src/runner/runner_suite.dart
index 4bed418..1b166d3 100644
--- a/test_core/lib/src/runner/runner_suite.dart
+++ b/test_core/lib/src/runner/runner_suite.dart
@@ -6,14 +6,13 @@
import 'package:async/async.dart';
import 'package:stream_channel/stream_channel.dart';
-
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
-import 'suite.dart';
import 'environment.dart';
+import 'suite.dart';
/// A suite produced and consumed by the test runner that has runner-specific
/// logic and lifecycle management.
@@ -68,7 +67,8 @@
this._controller, Group group, String path, SuitePlatform platform)
: super(group, platform, path: path);
- RunnerSuite filter(bool callback(Test test)) {
+ @override
+ RunnerSuite filter(bool Function(Test) callback) {
var filtered = group.filter(callback);
filtered ??= Group.root([], metadata: metadata);
return RunnerSuite._(_controller, filtered, path, platform);
@@ -76,6 +76,13 @@
/// Closes the suite and releases any resources associated with it.
Future close() => _controller._close();
+
+ /// Collects a hit-map containing merged coverage.
+ ///
+ /// Result is suitable for input to the coverage formatters provided by
+ /// `package:coverage`.
+ Future<Map<String, dynamic>> gatherCoverage() async =>
+ (await _controller._gatherCoverage?.call()) ?? {};
}
/// A class that exposes and controls a [RunnerSuite].
@@ -103,12 +110,18 @@
final _onDebuggingController = StreamController<bool>.broadcast();
/// The channel names that have already been used.
- final _channelNames = Set<String>();
+ final _channelNames = <String>{};
+
+ /// Collects a hit-map containing merged coverage.
+ final Future<Map<String, dynamic>> Function() _gatherCoverage;
RunnerSuiteController(this._environment, this._config, this._suiteChannel,
Future<Group> groupFuture, SuitePlatform platform,
- {String path, Function() onClose})
- : _onClose = onClose {
+ {String path,
+ Function() onClose,
+ Future<Map<String, dynamic>> Function() gatherCoverage})
+ : _onClose = onClose,
+ _gatherCoverage = gatherCoverage {
_suite =
groupFuture.then((group) => RunnerSuite._(this, group, path, platform));
}
@@ -116,9 +129,11 @@
/// Used by [new RunnerSuite] to create a runner suite that's not loaded from
/// an external source.
RunnerSuiteController._local(this._environment, this._config,
- {Function() onClose})
+ {Function() onClose,
+ Future<Map<String, dynamic>> Function() gatherCoverage})
: _suiteChannel = null,
- _onClose = onClose;
+ _onClose = onClose,
+ _gatherCoverage = gatherCoverage;
/// Sets whether the suite is paused for debugging.
///
@@ -146,7 +161,7 @@
var channel = _suiteChannel.virtualChannel();
_suiteChannel.sink
- .add({"type": "suiteChannel", "name": name, "id": channel.id});
+ .add({'type': 'suiteChannel', 'name': name, 'id': channel.id});
return channel;
}
diff --git a/test_core/lib/src/runner/runner_test.dart b/test_core/lib/src/runner/runner_test.dart
index f19cad1..44fb3a7 100644
--- a/test_core/lib/src/runner/runner_test.dart
+++ b/test_core/lib/src/runner/runner_test.dart
@@ -2,9 +2,9 @@
// 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:pedantic/pedantic.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
-
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/live_test.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/live_test_controller.dart'; // ignore: implementation_imports
@@ -15,14 +15,16 @@
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports
-import 'package:test_api/src/utils.dart'; // ignore: implementation_imports
import 'spawn_hybrid.dart';
/// A test running remotely, controlled by a stream channel.
class RunnerTest extends Test {
+ @override
final String name;
+ @override
final Metadata metadata;
+ @override
final Trace trace;
/// The channel used to communicate with the test's [IframeListener].
@@ -32,6 +34,7 @@
RunnerTest._(this.name, this.metadata, this.trace, this._channel);
+ @override
LiveTest load(Suite suite, {Iterable<Group> groups}) {
LiveTestController controller;
VirtualChannel testChannel;
@@ -85,18 +88,19 @@
return;
}
- invoke(() async {
+ unawaited(() async {
// If the test is still running, send it a message telling it to shut
// down ASAP. This causes the [Invoker] to eagerly throw exceptions
// whenever the test touches it.
testChannel.sink.add({'command': 'close'});
await controller.completer.future;
await testChannel.sink.close();
- });
+ }());
}, groups: groups);
return controller.liveTest;
}
+ @override
Test forPlatform(SuitePlatform platform) {
if (!metadata.testOn.evaluate(platform)) return null;
return RunnerTest._(name, metadata.forPlatform(platform), trace, _channel);
diff --git a/test_core/lib/src/runner/runtime_selection.dart b/test_core/lib/src/runner/runtime_selection.dart
index 0585a0f..8105dcd 100644
--- a/test_core/lib/src/runner/runtime_selection.dart
+++ b/test_core/lib/src/runner/runtime_selection.dart
@@ -16,7 +16,9 @@
RuntimeSelection(this.name, [this.span]);
+ @override
bool operator ==(other) => other is RuntimeSelection && other.name == name;
+ @override
int get hashCode => name.hashCode;
}
diff --git a/test_core/lib/src/runner/spawn_hybrid.dart b/test_core/lib/src/runner/spawn_hybrid.dart
index 797ba66..1db6769 100644
--- a/test_core/lib/src/runner/spawn_hybrid.dart
+++ b/test_core/lib/src/runner/spawn_hybrid.dart
@@ -24,13 +24,13 @@
var port = ReceivePort();
var onExitPort = ReceivePort();
try {
- var code = """
+ var code = '''
import "package:test_core/src/runner/hybrid_listener.dart";
import "${url.replaceAll(r'$', '%24')}" as lib;
void main(_, List data) => listen(() => lib.hybridMain, data);
- """;
+ ''';
var isolate = await dart.runInIsolate(code, [port.sendPort, message],
onExit: onExitPort.sendPort);
@@ -57,8 +57,8 @@
// Make sure any errors in spawning the isolate are forwarded to the test.
return StreamChannel(
Stream.fromFuture(Future.value({
- "type": "error",
- "error": RemoteException.serialize(error, stackTrace)
+ 'type': 'error',
+ 'error': RemoteException.serialize(error, stackTrace)
})),
NullStreamSink());
}
diff --git a/test_core/lib/src/runner/suite.dart b/test_core/lib/src/runner/suite.dart
index 08c6ab4..c95494a 100644
--- a/test_core/lib/src/runner/suite.dart
+++ b/test_core/lib/src/runner/suite.dart
@@ -55,7 +55,7 @@
/// The set of runtimes on which to run tests.
List<String> get runtimes => _runtimes == null
- ? const ["vm"]
+ ? const ['vm']
: List.unmodifiable(_runtimes.map((runtime) => runtime.name));
final List<RuntimeSelection> _runtimes;
@@ -85,10 +85,9 @@
final Map<PlatformSelector, SuiteConfiguration> onPlatform;
/// The seed with which to shuffle the test order.
- /// Default value is 0 if not provided and will not change the test order.
+ /// Default value is null if not provided and will not change the test order.
/// The same seed will shuffle the tests in the same way every time.
- int get testRandomizeOrderingSeed => _testRandomizeOrderingSeed ?? 0;
- final int _testRandomizeOrderingSeed;
+ final int testRandomizeOrderingSeed;
/// The global test metadata derived from this configuration.
Metadata get metadata {
@@ -196,13 +195,13 @@
: _jsTrace = jsTrace,
_runSkipped = runSkipped,
dart2jsArgs = _list(dart2jsArgs) ?? const [],
- patterns = UnmodifiableSetView(patterns?.toSet() ?? Set()),
+ patterns = UnmodifiableSetView(patterns?.toSet() ?? {}),
_runtimes = _list(runtimes),
includeTags = includeTags ?? BooleanSelector.all,
excludeTags = excludeTags ?? BooleanSelector.none,
tags = _map(tags),
onPlatform = _map(onPlatform),
- _testRandomizeOrderingSeed = testRandomizeOrderingSeed,
+ testRandomizeOrderingSeed = testRandomizeOrderingSeed,
_metadata = metadata ?? Metadata.empty;
/// Creates a new [SuiteConfiguration] that takes its configuration from
@@ -252,7 +251,7 @@
tags: _mergeConfigMaps(tags, other.tags),
onPlatform: _mergeConfigMaps(onPlatform, other.onPlatform),
testRandomizeOrderingSeed:
- other._testRandomizeOrderingSeed ?? _testRandomizeOrderingSeed,
+ other.testRandomizeOrderingSeed ?? testRandomizeOrderingSeed,
metadata: metadata.merge(other.metadata));
return config._resolveTags();
}
@@ -295,7 +294,7 @@
tags: tags ?? this.tags,
onPlatform: onPlatform ?? this.onPlatform,
testRandomizeOrderingSeed:
- testRandomizeOrderingSeed ?? _testRandomizeOrderingSeed,
+ testRandomizeOrderingSeed ?? testRandomizeOrderingSeed,
metadata: _metadata.change(
timeout: timeout,
verboseTrace: verboseTrace,
@@ -364,11 +363,11 @@
// Otherwise, resolve the tag-specific components.
var newTags = Map<BooleanSelector, SuiteConfiguration>.from(tags);
var merged = tags.keys.fold(empty, (SuiteConfiguration merged, selector) {
- if (!selector.evaluate(_metadata.tags)) return merged;
+ if (!selector.evaluate(_metadata.tags.contains)) return merged;
return merged.merge(newTags.remove(selector));
});
if (merged == empty) return this;
- return this.change(tags: newTags).merge(merged);
+ return change(tags: newTags).merge(merged);
}
}
diff --git a/test_core/lib/src/runner/version.dart b/test_core/lib/src/runner/version.dart
index 23d8048..b10aefa 100644
--- a/test_core/lib/src/runner/version.dart
+++ b/test_core/lib/src/runner/version.dart
@@ -13,7 +13,7 @@
final String testVersion = (() {
dynamic lockfile;
try {
- lockfile = loadYaml(File("pubspec.lock").readAsStringSync());
+ lockfile = loadYaml(File('pubspec.lock').readAsStringSync());
} on FormatException catch (_) {
return null;
} on IOException catch (_) {
@@ -21,38 +21,38 @@
}
if (lockfile is! Map) return null;
- var packages = lockfile["packages"];
+ var packages = lockfile['packages'];
if (packages is! Map) return null;
- var package = packages["test"];
+ var package = packages['test'];
if (package is! Map) return null;
- var source = package["source"];
+ var source = package['source'];
if (source is! String) return null;
switch (source as String) {
- case "hosted":
- var version = package["version"];
+ case 'hosted':
+ var version = package['version'];
return (version is String) ? version : null;
- case "git":
- var version = package["version"];
+ case 'git':
+ var version = package['version'];
if (version is! String) return null;
- var description = package["description"];
+ var description = package['description'];
if (description is! Map) return null;
- var ref = description["resolved-ref"];
+ var ref = description['resolved-ref'];
if (ref is! String) return null;
- return "$version (${ref.substring(0, 7)})";
+ return '$version (${ref.substring(0, 7)})';
- case "path":
- var version = package["version"];
+ case 'path':
+ var version = package['version'];
if (version is! String) return null;
- var description = package["description"];
+ var description = package['description'];
if (description is! Map) return null;
- var path = description["path"];
+ var path = description['path'];
if (path is! String) return null;
- return "$version (from $path)";
+ return '$version (from $path)';
default:
return null;
diff --git a/test_core/lib/src/runner/vm/environment.dart b/test_core/lib/src/runner/vm/environment.dart
index 6fedbec..6f919bf 100644
--- a/test_core/lib/src/runner/vm/environment.dart
+++ b/test_core/lib/src/runner/vm/environment.dart
@@ -10,7 +10,9 @@
/// The environment in which VM tests are loaded.
class VMEnvironment implements Environment {
+ @override
final supportsDebugging = true;
+ @override
final Uri observatoryUrl;
/// The VM service isolate object used to control this isolate.
@@ -19,10 +21,13 @@
VMEnvironment(this.observatoryUrl, this._isolate, this._client);
+ @override
Uri get remoteDebuggerUrl => null;
+ @override
Stream get onRestart => StreamController.broadcast().stream;
+ @override
CancelableOperation displayPause() {
var completer =
CancelableCompleter(onCancel: () => _client.resume(_isolate.id));
diff --git a/test_core/lib/src/runner/vm/platform.dart b/test_core/lib/src/runner/vm/platform.dart
index 4f521be..83e4b4f 100644
--- a/test_core/lib/src/runner/vm/platform.dart
+++ b/test_core/lib/src/runner/vm/platform.dart
@@ -7,23 +7,23 @@
import 'dart:io';
import 'dart:isolate';
+import 'package:coverage/coverage.dart';
import 'package:path/path.dart' as p;
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/load_exception.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/platform.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/plugin/environment.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports
-import 'package:test_core/src/util/dart.dart' // ignore: implementation_imports
- as dart;
import 'package:vm_service/vm_service.dart' hide Isolate;
import 'package:vm_service/vm_service_io.dart';
+import '../../runner/configuration.dart';
+import '../../runner/environment.dart';
+import '../../runner/load_exception.dart';
+import '../../runner/platform.dart';
+import '../../runner/plugin/platform_helpers.dart';
+import '../../runner/runner_suite.dart';
+import '../../runner/suite.dart';
+import '../../util/dart.dart' as dart;
import 'environment.dart';
/// A platform that loads tests in isolates spawned within this Dart process.
@@ -33,9 +33,11 @@
VMPlatform();
+ @override
StreamChannel loadChannel(String path, SuitePlatform platform) =>
throw UnimplementedError();
+ @override
Future<RunnerSuite> load(String path, SuitePlatform platform,
SuiteConfiguration suiteConfig, Object message) async {
assert(platform.runtime == Runtime.vm);
@@ -59,7 +61,7 @@
sink.close();
}));
- VMEnvironment environment;
+ Environment environment;
IsolateRef isolateRef;
if (_config.debug) {
// Print an empty line because the VM prints an "Observatory listening on"
@@ -72,7 +74,7 @@
var libraryPath = p.toUri(p.absolute(path)).toString();
client = await vmServiceConnectUri(_wsUriFor(info.serverUri.toString()));
- var isolateNumber = int.parse(isolateID.split("/").last);
+ var isolateNumber = int.parse(isolateID.split('/').last);
isolateRef = (await client.getVM())
.isolates
.firstWhere((isolate) => isolate.number == isolateNumber.toString());
@@ -85,8 +87,11 @@
environment = VMEnvironment(url, isolateRef, client);
}
- var controller = deserializeSuite(path, platform, suiteConfig,
- environment ?? PluginEnvironment(), channel, message);
+ environment ??= PluginEnvironment();
+
+ var controller = deserializeSuite(
+ path, platform, suiteConfig, environment, channel, message,
+ gatherCoverage: () => _gatherCoverage(environment));
if (isolateRef != null) {
await client.streamListen('Debug');
@@ -134,7 +139,7 @@
var channel = serializeSuite(() => test.main);
IsolateChannel.connectSend(message).pipe(channel);
}
- ''', message, checked: true);
+ ''', message);
}
Future<Isolate> _spawnPrecompiledIsolate(
@@ -150,6 +155,13 @@
checked: true);
}
+Future<Map<String, dynamic>> _gatherCoverage(Environment environment) async {
+ final isolateId = Uri.parse(environment.observatoryUrl.fragment)
+ .queryParameters['isolateId'];
+ return await collect(environment.observatoryUrl, false, false, false, {},
+ isolateIds: {isolateId});
+}
+
Future<Isolate> _spawnPubServeIsolate(
String testPath, SendPort message, Uri pubServeUrl) async {
var url = pubServeUrl.resolveUri(
@@ -158,16 +170,16 @@
try {
return await Isolate.spawnUri(url, [], message, checked: true);
} on IsolateSpawnException catch (error) {
- if (error.message.contains("OS Error: Connection refused") ||
- error.message.contains("The remote computer refused")) {
+ if (error.message.contains('OS Error: Connection refused') ||
+ error.message.contains('The remote computer refused')) {
throw LoadException(
testPath,
- "Error getting $url: Connection refused\n"
+ 'Error getting $url: Connection refused\n'
'Make sure "pub serve" is running.');
- } else if (error.message.contains("404 Not Found")) {
+ } else if (error.message.contains('404 Not Found')) {
throw LoadException(
testPath,
- "Error getting $url: 404 Not Found\n"
+ 'Error getting $url: 404 Not Found\n'
'Make sure "pub serve" is serving the test/ directory.');
}
@@ -179,5 +191,5 @@
"ws:${observatoryUrl.split(':').sublist(1).join(':')}ws";
Uri _observatoryUrlFor(String base, String isolateId, String id) =>
- Uri.parse("$base#/inspect?isolateId=${Uri.encodeQueryComponent(isolateId)}&"
- "objectId=${Uri.encodeQueryComponent(id)}");
+ Uri.parse('$base#/inspect?isolateId=${Uri.encodeQueryComponent(isolateId)}&'
+ 'objectId=${Uri.encodeQueryComponent(id)}');
diff --git a/test_core/lib/src/util/dart.dart b/test_core/lib/src/util/dart.dart
index e142dca..bdb39ea 100644
--- a/test_core/lib/src/util/dart.dart
+++ b/test_core/lib/src/util/dart.dart
@@ -8,7 +8,6 @@
// ignore: deprecated_member_use
import 'package:analyzer/analyzer.dart';
-import 'package:package_resolver/package_resolver.dart';
import 'package:source_span/source_span.dart';
import 'string_literal_iterator.dart';
@@ -19,23 +18,16 @@
/// they will be resolved in the same context as the host isolate. [message] is
/// passed to the [main] method of the code being run; the caller is responsible
/// for using this to establish communication with the isolate.
-///
-/// If [resolver] is passed, its package resolution strategy is used to resolve
-/// code in the spawned isolate. It defaults to [PackageResolver.current].
-Future<Isolate> runInIsolate(String code, message,
- {PackageResolver resolver, bool checked, SendPort onExit}) async {
- resolver ??= PackageResolver.current;
- return await Isolate.spawnUri(
- Uri.dataFromString(code, mimeType: 'application/dart', encoding: utf8),
- [],
- message,
- packageConfig: await resolver.packageConfigUri,
- checked: checked,
- onExit: onExit);
-}
+Future<Isolate> runInIsolate(String code, Object message,
+ {SendPort onExit}) async =>
+ Isolate.spawnUri(
+ Uri.dataFromString(code, mimeType: 'application/dart', encoding: utf8),
+ [],
+ message,
+ packageConfig: await Isolate.packageConfig,
+ checked: true,
+ onExit: onExit);
-// TODO(nweiz): Move this into the analyzer once it starts using SourceSpan
-// (issue 22977).
/// Takes a span whose source is the value of a string that has been parsed from
/// a Dart file and returns the corresponding span from within that Dart file.
///
diff --git a/test_core/lib/src/util/io.dart b/test_core/lib/src/util/io.dart
index fafa9b0..c2cc3da 100644
--- a/test_core/lib/src/util/io.dart
+++ b/test_core/lib/src/util/io.dart
@@ -21,7 +21,7 @@
const _defaultLineLength = 200;
/// Whether the test runner is running on Google-internal infrastructure.
-final bool inGoogle = Platform.version.contains("(google3)");
+final bool inGoogle = Platform.version.contains('(google3)');
/// The maximum line length for output.
final int lineLength = () {
@@ -48,9 +48,6 @@
throw UnsupportedError('Unsupported operating system "$name".');
})();
-// TODO(nweiz): Make this `new SuitePlatform.current()` once we only support
-// Dart 2 and we can import `dart:io` from within cross-platform libraries. See
-// commit 4ffda6d2.
/// Returns a [SuitePlatform] with the given [runtime], and with [os] and
/// [inGoogle] determined automatically.
///
@@ -63,15 +60,15 @@
final stdinLines = StreamQueue(lineSplitter.bind(stdin));
/// Whether this is being run as a subprocess in the test package's own tests.
-bool inTestTests = Platform.environment["_DART_TEST_TESTING"] == "true";
+bool inTestTests = Platform.environment['_DART_TEST_TESTING'] == 'true';
/// The root directory below which to nest temporary directories created by the
/// test runner.
///
/// This is configurable so that the test code can validate that the runner
/// cleans up after itself fully.
-final _tempDir = Platform.environment.containsKey("_UNITTEST_TEMP_DIR")
- ? Platform.environment["_UNITTEST_TEMP_DIR"]
+final _tempDir = Platform.environment.containsKey('_UNITTEST_TEMP_DIR')
+ ? Platform.environment['_UNITTEST_TEMP_DIR']
: Directory.systemTemp.path;
/// Whether or not the current terminal supports ansi escape codes.
@@ -92,7 +89,7 @@
///
/// Returns a future that completes to the value that the future returned from
/// [fn] completes to.
-Future withTempDir(Future fn(String path)) {
+Future withTempDir(Future Function(String) fn) {
return Future.sync(() {
var tempDir = createTempDir();
return Future.sync(() => fn(tempDir))
@@ -106,10 +103,10 @@
/// part of a word's length. It only splits words on spaces, not on other sorts
/// of whitespace.
String wordWrap(String text) {
- return text.split("\n").map((originalLine) {
+ return text.split('\n').map((originalLine) {
var buffer = StringBuffer();
var lengthSoFar = 0;
- for (var word in originalLine.split(" ")) {
+ for (var word in originalLine.split(' ')) {
var wordLength = withoutColors(word).length;
if (wordLength > lineLength) {
if (lengthSoFar != 0) buffer.writeln();
@@ -122,12 +119,12 @@
buffer.write(word);
lengthSoFar = wordLength;
} else {
- buffer.write(" $word");
+ buffer.write(' $word');
lengthSoFar += 1 + wordLength;
}
}
return buffer.toString();
- }).join("\n");
+ }).join('\n');
}
/// Print a warning containing [message].
@@ -139,9 +136,9 @@
/// If [print] is `true`, this prints the message using [print] to associate it
/// with the current test. Otherwise, it prints it using [stderr].
void warn(String message, {bool color, bool print = false}) {
- if (color == null) color = canUseSpecialChars;
- var header = color ? "\u001b[33mWarning:\u001b[0m" : "Warning:";
- (print ? core.print : stderr.writeln)(wordWrap("$header $message\n"));
+ color ??= canUseSpecialChars;
+ var header = color ? '\u001b[33mWarning:\u001b[0m' : 'Warning:';
+ (print ? core.print : stderr.writeln)(wordWrap('$header $message\n'));
}
/// Repeatedly finds a probably-unused port on localhost and passes it to
@@ -153,7 +150,7 @@
///
/// This is necessary for ensuring that our port binding isn't flaky for
/// applications that don't print out the bound port.
-Future<T> getUnusedPort<T>(FutureOr<T> tryPort(int port)) async {
+Future<T> getUnusedPort<T>(FutureOr<T> Function(int port) tryPort) async {
T value;
await Future.doWhile(() async {
value = await tryPort(await getUnsafeUnusedPort());
@@ -198,11 +195,11 @@
Future<Uri> getRemoteDebuggerUrl(Uri base) async {
try {
var client = HttpClient();
- var request = await client.getUrl(base.resolve("/json/list"));
+ var request = await client.getUrl(base.resolve('/json/list'));
var response = await request.close();
var jsonObject =
await json.fuse(utf8).decoder.bind(response).single as List;
- return base.resolve(jsonObject.first["devtoolsFrontendUrl"] as String);
+ return base.resolve(jsonObject.first['devtoolsFrontendUrl'] as String);
} catch (_) {
// If we fail to talk to the remote debugger protocol, give up and return
// the raw URL rather than crashing.
diff --git a/test_core/lib/src/util/stack_trace_mapper.dart b/test_core/lib/src/util/stack_trace_mapper.dart
index d99608c..4f4a821 100644
--- a/test_core/lib/src/util/stack_trace_mapper.dart
+++ b/test_core/lib/src/util/stack_trace_mapper.dart
@@ -2,7 +2,6 @@
// 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:package_resolver/package_resolver.dart';
import 'package:source_map_stack_trace/source_map_stack_trace.dart' as mapper;
import 'package:source_maps/source_maps.dart';
import 'package:test_api/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports
@@ -14,8 +13,8 @@
/// This is initialized lazily in `mapStackTrace()`.
Mapping _mapping;
- /// The package resolution information passed to dart2js.
- final SyncPackageResolver _packageResolver;
+ /// The same package resolution information as was passed to dart2js.
+ final Map<String, Uri> _packageMap;
/// The URL of the SDK root from which dart2js loaded its sources.
final Uri _sdkRoot;
@@ -27,26 +26,26 @@
final Uri _mapUrl;
JSStackTraceMapper(this._mapContents,
- {Uri mapUrl, SyncPackageResolver packageResolver, Uri sdkRoot})
+ {Uri mapUrl, Map<String, Uri> packageMap, Uri sdkRoot})
: _mapUrl = mapUrl,
- _packageResolver = packageResolver,
+ _packageMap = packageMap,
_sdkRoot = sdkRoot;
/// Converts [trace] into a Dart stack trace.
+ @override
StackTrace mapStackTrace(StackTrace trace) {
_mapping ??= parseExtended(_mapContents, mapUrl: _mapUrl);
return mapper.mapStackTrace(_mapping, trace,
- packageResolver: _packageResolver, sdkRoot: _sdkRoot);
+ packageMap: _packageMap, sdkRoot: _sdkRoot);
}
/// Returns a Map representation which is suitable for JSON serialization.
+ @override
Map<String, dynamic> serialize() {
return {
'mapContents': _mapContents,
'sdkRoot': _sdkRoot?.toString(),
- 'packageConfigMap':
- _serializePackageConfigMap(_packageResolver.packageConfigMap),
- 'packageRoot': _packageResolver.packageRoot?.toString(),
+ 'packageConfigMap': _serializePackageConfigMap(_packageMap),
'mapUrl': _mapUrl?.toString(),
};
}
@@ -55,15 +54,12 @@
/// representation.
static StackTraceMapper deserialize(Map serialized) {
if (serialized == null) return null;
- String packageRoot = serialized['packageRoot'] as String ?? '';
+ var deserialized = _deserializePackageConfigMap(
+ (serialized['packageConfigMap'] as Map).cast<String, String>());
+
return JSStackTraceMapper(serialized['mapContents'] as String,
sdkRoot: Uri.parse(serialized['sdkRoot'] as String),
- packageResolver: packageRoot.isNotEmpty
- ? SyncPackageResolver.root(
- Uri.parse(serialized['packageRoot'] as String))
- : SyncPackageResolver.config(_deserializePackageConfigMap(
- (serialized['packageConfigMap'] as Map)
- .cast<String, String>())),
+ packageMap: deserialized,
mapUrl: Uri.parse(serialized['mapUrl'] as String));
}
diff --git a/test_core/lib/src/util/string_literal_iterator.dart b/test_core/lib/src/util/string_literal_iterator.dart
index 6b340c2..24caa08 100644
--- a/test_core/lib/src/util/string_literal_iterator.dart
+++ b/test_core/lib/src/util/string_literal_iterator.dart
@@ -37,6 +37,7 @@
/// In addition to exposing the values of the runes themselves, this also
/// exposes the offset of the current rune in the Dart source file.
class StringLiteralIterator extends Iterator<int> {
+ @override
int get current => _current;
int _current;
@@ -96,6 +97,7 @@
_offset = _strings.first.contentsOffset - 1;
}
+ @override
bool moveNext() {
// If we're at beginning of a [SimpleStringLiteral], move forward until
// there's actually text to consume.
diff --git a/test_core/lib/test_core.dart b/test_core/lib/test_core.dart
index 3e937c0..3dc5960 100644
--- a/test_core/lib/test_core.dart
+++ b/test_core/lib/test_core.dart
@@ -10,7 +10,6 @@
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
-import 'package:pedantic/pedantic.dart';
import 'package:test_api/backend.dart'; //ignore: deprecated_member_use
import 'package:test_api/src/backend/declarer.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
@@ -65,10 +64,9 @@
var success = await runZoned(() => Invoker.guard(engine.run),
zoneValues: {#test.declarer: _globalDeclarer});
- // TODO(nweiz): Set the exit code on the VM when issue 6943 is fixed.
if (success) return null;
print('');
- unawaited(Future.error("Dummy exception to set exit code."));
+ unawaited(Future.error('Dummy exception to set exit code.'));
});
return _globalDeclarer;
}
@@ -108,15 +106,15 @@
/// annotation classes: [Timeout], [Skip], or lists of those. These
/// annotations apply only on the given platforms. For example:
///
-/// test("potentially slow test", () {
+/// test('potentially slow test', () {
/// // ...
/// }, onPlatform: {
/// // This test is especially slow on Windows.
-/// "windows": new Timeout.factor(2),
-/// "browser": [
-/// new Skip("TODO: add browser support"),
+/// 'windows': Timeout.factor(2),
+/// 'browser': [
+/// Skip('TODO: add browser support'),
/// // This will be slow on browsers once it works on them.
-/// new Timeout.factor(2)
+/// Timeout.factor(2)
/// ]
/// });
///
@@ -129,7 +127,7 @@
/// avoid this flag if possible and instead use the test runner flag `-n` to
/// filter tests by name.
@isTest
-void test(description, body(),
+void test(description, dynamic Function() body,
{String testOn,
Timeout timeout,
skip,
@@ -186,15 +184,15 @@
/// annotation classes: [Timeout], [Skip], or lists of those. These
/// annotations apply only on the given platforms. For example:
///
-/// group("potentially slow tests", () {
+/// group('potentially slow tests', () {
/// // ...
/// }, onPlatform: {
/// // These tests are especially slow on Windows.
-/// "windows": new Timeout.factor(2),
-/// "browser": [
-/// new Skip("TODO: add browser support"),
+/// 'windows': Timeout.factor(2),
+/// 'browser': [
+/// Skip('TODO: add browser support'),
/// // They'll be slow on browsers once it works on them.
-/// new Timeout.factor(2)
+/// Timeout.factor(2)
/// ]
/// });
///
@@ -207,7 +205,7 @@
/// avoid this flag if possible, and instead use the test runner flag `-n` to
/// filter tests by name.
@isTestGroup
-void group(description, body(),
+void group(description, dynamic Function() body,
{String testOn,
Timeout timeout,
skip,
@@ -242,7 +240,7 @@
///
/// Each callback at the top level or in a given group will be run in the order
/// they were declared.
-void setUp(callback()) => _declarer.setUp(callback);
+void setUp(dynamic Function() callback) => _declarer.setUp(callback);
/// Registers a function to be run after tests.
///
@@ -257,7 +255,7 @@
/// reverse of the order they were declared.
///
/// See also [addTearDown], which adds tear-downs to a running test.
-void tearDown(callback()) => _declarer.tearDown(callback);
+void tearDown(dynamic Function() callback) => _declarer.tearDown(callback);
/// Registers a function to be run once before all tests.
///
@@ -272,7 +270,7 @@
/// dependencies between tests that should be isolated. In general, you should
/// prefer [setUp], and only use [setUpAll] if the callback is prohibitively
/// slow.
-void setUpAll(callback()) => _declarer.setUpAll(callback);
+void setUpAll(dynamic Function() callback) => _declarer.setUpAll(callback);
/// Registers a function to be run once after all tests.
///
@@ -285,4 +283,5 @@
/// dependencies between tests that should be isolated. In general, you should
/// prefer [tearDown], and only use [tearDownAll] if the callback is
/// prohibitively slow.
-void tearDownAll(callback()) => _declarer.tearDownAll(callback);
+void tearDownAll(dynamic Function() callback) =>
+ _declarer.tearDownAll(callback);
diff --git a/test_core/mono_pkg.yaml b/test_core/mono_pkg.yaml
index 995000f..f6da98d 100644
--- a/test_core/mono_pkg.yaml
+++ b/test_core/mono_pkg.yaml
@@ -6,4 +6,4 @@
dart: dev
- group:
- dartanalyzer: --fatal-warnings .
- dart: 2.1.0
+ dart: 2.7.0
diff --git a/test_core/pubspec.yaml b/test_core/pubspec.yaml
index 8c6a1f1..881878a 100644
--- a/test_core/pubspec.yaml
+++ b/test_core/pubspec.yaml
@@ -1,36 +1,33 @@
name: test_core
-version: 0.2.15
-author: Dart Team <misc@dartlang.org>
+version: 0.3.2
description: A basic library for writing tests and running them on the VM.
homepage: https://github.com/dart-lang/test/blob/master/pkgs/test_core
environment:
- sdk: ">=2.2.0 <3.0.0"
+ sdk: ">=2.7.0 <3.0.0"
dependencies:
analyzer: ">=0.36.0 <0.40.0"
async: ^2.0.0
args: ^1.4.0
- boolean_selector: ^1.0.0
+ boolean_selector: ">=1.0.0 <3.0.0"
collection: ^1.8.0
coverage: ^0.13.3
glob: ^1.0.0
io: ^0.3.0
meta: ^1.1.5
- package_resolver: ^1.0.0
path: ^1.2.0
pedantic: ^1.0.0
pool: ^1.3.0
- source_map_stack_trace: ^1.1.4
+ source_map_stack_trace: ^2.0.0
source_maps: ^0.10.2
source_span: ^1.4.0
stack_trace: ^1.9.0
stream_channel: ">=1.7.0 <3.0.0"
- vm_service: '>=1.0.0 <3.0.0'
+ vm_service: '>=1.0.0 <4.0.0'
yaml: ^2.0.0
# Use a tight version constraint to ensure that a constraint on matcher
# properly constrains all features it provides.
matcher: ">=0.12.6 <0.12.7"
# Use an exact version until the test_api package is stable.
- test_api: 0.2.11
-
+ test_api: 0.2.15
diff --git a/timing/.gitignore b/timing/.gitignore
deleted file mode 100644
index 1ddf798..0000000
--- a/timing/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.packages
-/build/
-pubspec.lock
-
-# Files generated by dart tools
-.dart_tool
-doc/
diff --git a/timing/.travis.yml b/timing/.travis.yml
deleted file mode 100644
index 581db89..0000000
--- a/timing/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: dart
-
-dart:
- - 2.2.0
- - dev
-
-dart_task:
-- dartanalyzer: --fatal-infos --fatal-warnings .
-- test
-
-matrix:
- include:
- # Only validate formatting using the dev release
- - dart: dev
- dart_task: dartfmt
-
-branches:
- only:
- - master
-
-cache:
- directories:
- - $HOME/.pub-cache
diff --git a/timing/BUILD.gn b/timing/BUILD.gn
deleted file mode 100644
index d6b6e7e..0000000
--- a/timing/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is generated by importer.py for timing-0.1.1+2
-
-import("//build/dart/dart_library.gni")
-
-dart_library("timing") {
- package_name = "timing"
-
- # This parameter is left empty as we don't care about analysis or exporting
- # these sources outside of the tree.
- sources = []
-
- disable_analysis = true
-
- deps = [
- "//third_party/dart-pkg/pub/json_annotation",
- ]
-}
diff --git a/timing/CHANGELOG.md b/timing/CHANGELOG.md
deleted file mode 100644
index 8cb1627..0000000
--- a/timing/CHANGELOG.md
+++ /dev/null
@@ -1,16 +0,0 @@
-## 0.1.1+2
-
-- Support the latest version of `package:json_annotation`.
-- Require Dart 2.2 or later.
-
-## 0.1.1+1
-
-- Support the latest version of `package:json_annotation`.
-
-## 0.1.1
-
-- Add JSON serialization
-
-## 0.1.0
-
-- Initial release
diff --git a/timing/LICENSE b/timing/LICENSE
deleted file mode 100644
index c4dc9ba..0000000
--- a/timing/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2018, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/timing/README.md b/timing/README.md
deleted file mode 100644
index 400bc4b..0000000
--- a/timing/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# [![Build Status](https://travis-ci.org/dart-lang/timing.svg?branch=master)](https://travis-ci.org/dart-lang/timing)
-
-Timing is a simple package for tracking performance of both async and sync actions
-
-```dart
-var tracker = AsyncTimeTracker();
-await tracker.track(() async {
- // some async code here
-});
-
-// Use results
-print('${tracker.duration} ${tracker.innerDuration} ${tracker.slices}');
-```
-
-
-## Building
-
-Use the following command to re-generate `lib/src/timing.g.dart` file:
-
-```bash
-pub run build_runner build
-```
\ No newline at end of file
diff --git a/timing/analysis_options.yaml b/timing/analysis_options.yaml
deleted file mode 100644
index 210b18f..0000000
--- a/timing/analysis_options.yaml
+++ /dev/null
@@ -1,93 +0,0 @@
-include: package:pedantic/analysis_options.yaml
-analyzer:
- strong-mode:
- implicit-casts: false
-linter:
- rules:
- - always_declare_return_types
- - annotate_overrides
- - avoid_bool_literals_in_conditional_expressions
- - avoid_classes_with_only_static_members
- - avoid_empty_else
- - avoid_function_literals_in_foreach_calls
- - avoid_init_to_null
- - avoid_null_checks_in_equality_operators
- - avoid_relative_lib_imports
- - avoid_renaming_method_parameters
- - avoid_return_types_on_setters
- - avoid_returning_null
- - avoid_returning_null_for_void
- - avoid_returning_this
- - avoid_shadowing_type_parameters
- - avoid_single_cascade_in_expression_statements
- - avoid_types_as_parameter_names
- - avoid_unused_constructor_parameters
- - await_only_futures
- - camel_case_types
- - cancel_subscriptions
- - cascade_invocations
- - comment_references
- - constant_identifier_names
- - control_flow_in_finally
- - curly_braces_in_flow_control_structures
- - directives_ordering
- - empty_catches
- - empty_constructor_bodies
- - empty_statements
- - file_names
- - hash_and_equals
- - implementation_imports
- - invariant_booleans
- - iterable_contains_unrelated_type
- - join_return_with_assignment
- - library_names
- - library_prefixes
- - list_remove_unrelated_type
- - literal_only_boolean_expressions
- - no_duplicate_case_values
- - non_constant_identifier_names
- - null_closures
- - omit_local_variable_types
- - only_throw_errors
- - overridden_fields
- - package_api_docs
- - package_names
- - package_prefixed_library_names
- - prefer_adjacent_string_concatenation
- - prefer_collection_literals
- - prefer_conditional_assignment
- - prefer_const_constructors
- - prefer_contains
- - prefer_equal_for_default_values
- - prefer_final_fields
- - prefer_final_locals
- - prefer_generic_function_type_aliases
- - prefer_initializing_formals
- - prefer_interpolation_to_compose_strings
- - prefer_iterable_whereType
- - prefer_is_empty
- - prefer_is_not_empty
- - prefer_null_aware_operators
- - prefer_single_quotes
- - prefer_typing_uninitialized_variables
- - prefer_void_to_null
- - recursive_getters
- - slash_for_doc_comments
- - test_types_in_equals
- - throw_in_finally
- - type_init_formals
- - unawaited_futures
- - unnecessary_brace_in_string_interps
- - unnecessary_const
- - unnecessary_getters_setters
- - unnecessary_lambdas
- - unnecessary_new
- - unnecessary_null_aware_assignments
- - unnecessary_null_in_if_null_operators
- - unnecessary_parenthesis
- - unnecessary_statements
- - unnecessary_this
- - unrelated_type_equality_checks
- - use_rethrow_when_possible
- - valid_regexps
- - void_checks
diff --git a/timing/lib/src/clock.dart b/timing/lib/src/clock.dart
deleted file mode 100644
index ae1f25f..0000000
--- a/timing/lib/src/clock.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, 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';
-
-/// A function that returns the current [DateTime].
-typedef _Clock = DateTime Function();
-DateTime _defaultClock() => DateTime.now();
-
-const _zoneKey = #timing_Clock;
-
-/// Returns the current [DateTime].
-///
-/// May be overridden for tests using [scopeClock].
-DateTime now() => (Zone.current[_zoneKey] as _Clock ?? _defaultClock)();
-
-/// Runs [f], with [clock] scoped whenever [now] is called.
-T scopeClock<T>(DateTime clock(), T f()) =>
- runZoned(f, zoneValues: {_zoneKey: clock});
diff --git a/timing/lib/src/timing.dart b/timing/lib/src/timing.dart
deleted file mode 100644
index 17e2fb1..0000000
--- a/timing/lib/src/timing.dart
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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 'package:json_annotation/json_annotation.dart';
-
-import 'clock.dart';
-
-part 'timing.g.dart';
-
-/// The timings of an operation, including its [startTime], [stopTime], and
-/// [duration].
-@JsonSerializable(nullable: false)
-class TimeSlice {
- /// The total duration of this operation, equivalent to taking the difference
- /// between [stopTime] and [startTime].
- Duration get duration => stopTime.difference(startTime);
-
- final DateTime startTime;
-
- final DateTime stopTime;
-
- TimeSlice(this.startTime, this.stopTime);
-
- factory TimeSlice.fromJson(Map<String, dynamic> json) =>
- _$TimeSliceFromJson(json);
-
- Map<String, dynamic> toJson() => _$TimeSliceToJson(this);
-
- @override
- String toString() => '($startTime + $duration)';
-}
-
-/// The timings of an async operation, consist of several sync [slices] and
-/// includes total [startTime], [stopTime], and [duration].
-@JsonSerializable(nullable: false)
-class TimeSliceGroup implements TimeSlice {
- final List<TimeSlice> slices;
-
- @override
- DateTime get startTime => slices.first.startTime;
-
- @override
- DateTime get stopTime => slices.last.stopTime;
-
- /// The total duration of this operation, equivalent to taking the difference
- /// between [stopTime] and [startTime].
- @override
- Duration get duration => stopTime.difference(startTime);
-
- /// Sum of [duration]s of all [slices].
- ///
- /// If some of slices implements [TimeSliceGroup] [innerDuration] will be used
- /// to compute sum.
- Duration get innerDuration => slices.fold(
- Duration.zero,
- (duration, slice) =>
- duration +
- (slice is TimeSliceGroup ? slice.innerDuration : slice.duration));
-
- TimeSliceGroup(this.slices);
-
- /// Constructs TimeSliceGroup from JSON representation
- factory TimeSliceGroup.fromJson(Map<String, dynamic> json) =>
- _$TimeSliceGroupFromJson(json);
-
- @override
- Map<String, dynamic> toJson() => _$TimeSliceGroupToJson(this);
-
- @override
- String toString() => slices.toString();
-}
-
-abstract class TimeTracker implements TimeSlice {
- /// Whether tracking is active.
- ///
- /// Tracking is only active after `isStarted` and before `isFinished`.
- bool get isTracking;
-
- /// Whether tracking is finished.
- ///
- /// Tracker can't be used as [TimeSlice] before it is finished
- bool get isFinished;
-
- /// Whether tracking was started.
- ///
- /// Equivalent of `isTracking || isFinished`
- bool get isStarted;
-
- T track<T>(T Function() action);
-}
-
-/// Tracks only sync actions
-class SyncTimeTracker implements TimeTracker {
- /// When this operation started, call [_start] to set this.
- @override
- DateTime get startTime => _startTime;
- DateTime _startTime;
-
- /// When this operation stopped, call [_stop] to set this.
- @override
- DateTime get stopTime => _stopTime;
- DateTime _stopTime;
-
- /// Start tracking this operation, must only be called once, before [_stop].
- void _start() {
- assert(_startTime == null && _stopTime == null);
- _startTime = now();
- }
-
- /// Stop tracking this operation, must only be called once, after [_start].
- void _stop() {
- assert(_startTime != null && _stopTime == null);
- _stopTime = now();
- }
-
- /// Splits tracker into two slices
- ///
- /// Returns new [TimeSlice] started on [startTime] and ended now.
- /// Modifies [startTime] of tracker to current time point
- ///
- /// Don't change state of tracker. Can be called only while [isTracking], and
- /// tracker will sill be tracking after call.
- TimeSlice _split() {
- if (!isTracking) {
- throw StateError('Can be only called while tracking');
- }
- final _now = now();
- final prevSlice = TimeSlice(_startTime, _now);
- _startTime = _now;
- return prevSlice;
- }
-
- @override
- T track<T>(T Function() action) {
- if (isStarted) {
- throw StateError('Can not be tracked twice');
- }
- _start();
- try {
- return action();
- } finally {
- _stop();
- }
- }
-
- @override
- bool get isStarted => startTime != null;
-
- @override
- bool get isTracking => startTime != null && stopTime == null;
-
- @override
- bool get isFinished => startTime != null && stopTime != null;
-
- @override
- Duration get duration => stopTime?.difference(startTime);
-
- /// Converts to JSON representation
- ///
- /// Can't be used before [isFinished]
- @override
- Map<String, dynamic> toJson() => _$TimeSliceToJson(this);
-}
-
-/// Async actions returning [Future] will be tracked as single sync time span
-/// from the beginning of execution till completion of future
-class SimpleAsyncTimeTracker extends SyncTimeTracker {
- @override
- T track<T>(T Function() action) {
- if (isStarted) {
- throw StateError('Can not be tracked twice');
- }
- T result;
- _start();
- try {
- result = action();
- } catch (_) {
- _stop();
- rethrow;
- }
- if (result is Future) {
- return result.whenComplete(_stop) as T;
- } else {
- _stop();
- return result;
- }
- }
-}
-
-/// No-op implementation of [SyncTimeTracker] that does nothing.
-class NoOpTimeTracker implements TimeTracker {
- static final sharedInstance = NoOpTimeTracker();
-
- @override
- Duration get duration =>
- throw UnsupportedError('Unsupported in no-op implementation');
-
- @override
- DateTime get startTime =>
- throw UnsupportedError('Unsupported in no-op implementation');
-
- @override
- DateTime get stopTime =>
- throw UnsupportedError('Unsupported in no-op implementation');
-
- @override
- bool get isStarted =>
- throw UnsupportedError('Unsupported in no-op implementation');
-
- @override
- bool get isTracking =>
- throw UnsupportedError('Unsupported in no-op implementation');
-
- @override
- bool get isFinished =>
- throw UnsupportedError('Unsupported in no-op implementation');
-
- @override
- T track<T>(T Function() action) => action();
-
- @override
- Map<String, dynamic> toJson() =>
- throw UnsupportedError('Unsupported in no-op implementation');
-}
-
-/// Track all async execution as disjoint time [slices] in ascending order.
-///
-/// Can [track] both async and sync actions.
-/// Can exclude time of tested trackers.
-///
-/// If tracked action spawns some dangled async executions behavior is't
-/// defined. Tracked might or might not track time of such executions
-class AsyncTimeTracker extends TimeSliceGroup implements TimeTracker {
- final bool trackNested;
-
- static const _zoneKey = #timing_AsyncTimeTracker;
-
- AsyncTimeTracker({this.trackNested = true}) : super([]);
-
- T _trackSyncSlice<T>(ZoneDelegate parent, Zone zone, T Function() action) {
- // Ignore dangling runs after tracker completes
- if (isFinished) {
- return action();
- }
-
- final isNestedRun = slices.isNotEmpty &&
- slices.last is SyncTimeTracker &&
- (slices.last as SyncTimeTracker).isTracking;
- final isExcludedNestedTrack = !trackNested && zone[_zoneKey] != this;
-
- // Exclude nested sync tracks
- if (isNestedRun && isExcludedNestedTrack) {
- final timer = slices.last as SyncTimeTracker;
- // Split already tracked time into new slice.
- // Replace tracker in slices.last with splitted slice, to indicate for
- // recursive calls that we not tracking.
- slices.last = parent.run(zone, timer._split);
- try {
- return action();
- } finally {
- // Split tracker again and discard slice that was spend in nested tracker
- parent.run(zone, timer._split);
- // Add tracker back to list of slices and continue tracking
- slices.add(timer);
- }
- }
-
- // Exclude nested async tracks
- if (isExcludedNestedTrack) {
- return action();
- }
-
- // Split time slices in nested sync runs
- if (isNestedRun) {
- return action();
- }
-
- final timer = SyncTimeTracker();
- slices.add(timer);
-
- // Pass to parent zone, in case of overwritten clock
- return parent.runUnary(zone, timer.track, action);
- }
-
- static final asyncTimeTrackerZoneSpecification = ZoneSpecification(
- run: <R>(Zone self, ZoneDelegate parent, Zone zone, R Function() f) {
- final tracker = self[_zoneKey] as AsyncTimeTracker;
- return tracker._trackSyncSlice(parent, zone, () => parent.run(zone, f));
- },
- runUnary: <R, T>(Zone self, ZoneDelegate parent, Zone zone, R Function(T) f,
- T arg) {
- final tracker = self[_zoneKey] as AsyncTimeTracker;
- return tracker._trackSyncSlice(
- parent, zone, () => parent.runUnary(zone, f, arg));
- },
- runBinary: <R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone,
- R Function(T1, T2) f, T1 arg1, T2 arg2) {
- final tracker = self[_zoneKey] as AsyncTimeTracker;
- return tracker._trackSyncSlice(
- parent, zone, () => parent.runBinary(zone, f, arg1, arg2));
- },
- );
-
- @override
- T track<T>(T Function() action) {
- if (isStarted) {
- throw StateError('Can not be tracked twice');
- }
- _tracking = true;
- final result = runZoned(action,
- zoneSpecification: asyncTimeTrackerZoneSpecification,
- zoneValues: {_zoneKey: this});
- if (result is Future) {
- return result
- // Break possible sync processing of future completion, so slice trackers can be finished
- .whenComplete(() => Future.value())
- .whenComplete(() => _tracking = false) as T;
- } else {
- _tracking = false;
- return result;
- }
- }
-
- bool _tracking;
-
- @override
- bool get isStarted => _tracking != null;
-
- @override
- bool get isFinished => _tracking == false;
-
- @override
- bool get isTracking => _tracking == true;
-}
diff --git a/timing/lib/src/timing.g.dart b/timing/lib/src/timing.g.dart
deleted file mode 100644
index 91293b2..0000000
--- a/timing/lib/src/timing.g.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'timing.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-TimeSlice _$TimeSliceFromJson(Map<String, dynamic> json) {
- return TimeSlice(
- DateTime.parse(json['startTime'] as String),
- DateTime.parse(json['stopTime'] as String),
- );
-}
-
-Map<String, dynamic> _$TimeSliceToJson(TimeSlice instance) => <String, dynamic>{
- 'startTime': instance.startTime.toIso8601String(),
- 'stopTime': instance.stopTime.toIso8601String(),
- };
-
-TimeSliceGroup _$TimeSliceGroupFromJson(Map<String, dynamic> json) {
- return TimeSliceGroup(
- (json['slices'] as List)
- .map((e) => TimeSlice.fromJson(e as Map<String, dynamic>))
- .toList(),
- );
-}
-
-Map<String, dynamic> _$TimeSliceGroupToJson(TimeSliceGroup instance) =>
- <String, dynamic>{
- 'slices': instance.slices,
- };
diff --git a/timing/lib/timing.dart b/timing/lib/timing.dart
deleted file mode 100644
index 0163e8d..0000000
--- a/timing/lib/timing.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.
-
-export 'src/timing.dart'
- show
- TimeSlice,
- TimeSliceGroup,
- TimeTracker,
- SyncTimeTracker,
- SimpleAsyncTimeTracker,
- AsyncTimeTracker,
- NoOpTimeTracker;
diff --git a/timing/pubspec.yaml b/timing/pubspec.yaml
deleted file mode 100644
index 0b45123..0000000
--- a/timing/pubspec.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: timing
-version: 0.1.1+2
-description: >-
- A simple package for tracking the performance of synchronous and asynchronous
- actions.
-author: Dart Team <misc@dartlang.org>
-homepage: https://github.com/dart-lang/timing
-
-environment:
- sdk: ">=2.2.0 <3.0.0"
-
-dependencies:
- json_annotation: '>=1.0.0 <4.0.0'
-
-dev_dependencies:
- build_runner: ^1.0.0
- json_serializable: ^3.1.0
- pedantic: ^1.1.0
- test: ^1.0.0
diff --git a/url_launcher/BUILD.gn b/url_launcher/BUILD.gn
index 51448e6..ec21259 100644
--- a/url_launcher/BUILD.gn
+++ b/url_launcher/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher-5.4.1
+# This file is generated by importer.py for url_launcher-5.4.2
import("//build/dart/dart_library.gni")
diff --git a/url_launcher/CHANGELOG.md b/url_launcher/CHANGELOG.md
index a38c3eb..0cab101 100644
--- a/url_launcher/CHANGELOG.md
+++ b/url_launcher/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.4.2
+
+* Make the pedantic dev_dependency explicit.
+
## 5.4.1
* Update unit tests to work with the PlatformInterface from package `plugin_platform_interface`.
diff --git a/url_launcher/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/url_launcher/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/url_launcher/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "group:Runner.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/url_launcher/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/url_launcher/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/url_launcher/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IDEDidComputeMac32BitWarning</key>
+ <true/>
+</dict>
+</plist>
diff --git a/url_launcher/example/pubspec.yaml b/url_launcher/example/pubspec.yaml
index 4d9d01a..065693e 100644
--- a/url_launcher/example/pubspec.yaml
+++ b/url_launcher/example/pubspec.yaml
@@ -11,6 +11,7 @@
e2e: "^0.2.0"
flutter_driver:
sdk: flutter
+ pedantic: ^1.8.0
flutter:
uses-material-design: true
diff --git a/url_launcher/pubspec.yaml b/url_launcher/pubspec.yaml
index cd51673..ba92970 100644
--- a/url_launcher/pubspec.yaml
+++ b/url_launcher/pubspec.yaml
@@ -2,7 +2,7 @@
description: Flutter plugin for launching a URL on Android and iOS. Supports
web, phone, SMS, and email schemes.
homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher
-version: 5.4.1
+version: 5.4.2
flutter:
plugin:
@@ -35,6 +35,7 @@
test: ^1.3.0
mockito: ^4.1.1
plugin_platform_interface: ^1.0.0
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/url_launcher_macos/BUILD.gn b/url_launcher_macos/BUILD.gn
index f91dd9d..e4bf2db 100644
--- a/url_launcher_macos/BUILD.gn
+++ b/url_launcher_macos/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher_macos-0.0.1+2
+# This file is generated by importer.py for url_launcher_macos-0.0.1+4
import("//build/dart/dart_library.gni")
diff --git a/url_launcher_macos/CHANGELOG.md b/url_launcher_macos/CHANGELOG.md
index 446b448..6ecac5b 100644
--- a/url_launcher_macos/CHANGELOG.md
+++ b/url_launcher_macos/CHANGELOG.md
@@ -1,3 +1,11 @@
+# 0.0.1+4
+
+* Make the pedantic dev_dependency explicit.
+
+# 0.0.1+3
+
+* Update Gradle version.
+
# 0.0.1+2
* Update README.
diff --git a/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties b/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties
index 019065d..d757f3d 100644
--- a/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties
+++ b/url_launcher_macos/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
diff --git a/url_launcher_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/url_launcher_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/url_launcher_macos/example/macos/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "group:Runner.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/url_launcher_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/url_launcher_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/url_launcher_macos/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IDEDidComputeMac32BitWarning</key>
+ <true/>
+</dict>
+</plist>
diff --git a/url_launcher_macos/example/pubspec.yaml b/url_launcher_macos/example/pubspec.yaml
index 2552786..1125b6d 100644
--- a/url_launcher_macos/example/pubspec.yaml
+++ b/url_launcher_macos/example/pubspec.yaml
@@ -12,6 +12,7 @@
e2e: "^0.2.0"
flutter_driver:
sdk: flutter
+ pedantic: ^1.8.0
flutter:
uses-material-design: true
diff --git a/url_launcher_macos/pubspec.yaml b/url_launcher_macos/pubspec.yaml
index 9e4b200..3f6d5e0 100644
--- a/url_launcher_macos/pubspec.yaml
+++ b/url_launcher_macos/pubspec.yaml
@@ -1,6 +1,6 @@
name: url_launcher_macos
description: macOS implementation of the url_launcher plugin.
-version: 0.0.1+2
+version: 0.0.1+4
homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_macos
flutter:
@@ -17,3 +17,6 @@
dependencies:
flutter:
sdk: flutter
+
+dev_dependencies:
+ pedantic: ^1.8.0
diff --git a/url_launcher_platform_interface/BUILD.gn b/url_launcher_platform_interface/BUILD.gn
index 4564bfc..ac8d95a 100644
--- a/url_launcher_platform_interface/BUILD.gn
+++ b/url_launcher_platform_interface/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher_platform_interface-1.0.5
+# This file is generated by importer.py for url_launcher_platform_interface-1.0.6
import("//build/dart/dart_library.gni")
diff --git a/url_launcher_platform_interface/CHANGELOG.md b/url_launcher_platform_interface/CHANGELOG.md
index f55b4cb..592102f 100644
--- a/url_launcher_platform_interface/CHANGELOG.md
+++ b/url_launcher_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.6
+
+* Make the pedantic dev_dependency explicit.
+
## 1.0.5
* Make the `PlatformInterface` `_token` non `const` (as `const` `Object`s are not unique).
diff --git a/url_launcher_platform_interface/pubspec.yaml b/url_launcher_platform_interface/pubspec.yaml
index aa57b14..806c967 100644
--- a/url_launcher_platform_interface/pubspec.yaml
+++ b/url_launcher_platform_interface/pubspec.yaml
@@ -3,7 +3,7 @@
homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_platform_interface
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 1.0.5
+version: 1.0.6
dependencies:
flutter:
@@ -15,6 +15,7 @@
flutter_test:
sdk: flutter
mockito: ^4.1.1
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/url_launcher_web/BUILD.gn b/url_launcher_web/BUILD.gn
index afe68bd..c277ba0 100644
--- a/url_launcher_web/BUILD.gn
+++ b/url_launcher_web/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for url_launcher_web-0.1.1
+# This file is generated by importer.py for url_launcher_web-0.1.1+1
import("//build/dart/dart_library.gni")
diff --git a/url_launcher_web/CHANGELOG.md b/url_launcher_web/CHANGELOG.md
index df73939..0cb57ef 100644
--- a/url_launcher_web/CHANGELOG.md
+++ b/url_launcher_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.1.1+1
+
+- Make the pedantic dev_dependency explicit.
+
# 0.1.1
- Added support for mailto scheme
diff --git a/url_launcher_web/pubspec.yaml b/url_launcher_web/pubspec.yaml
index d02d250..8e74677 100644
--- a/url_launcher_web/pubspec.yaml
+++ b/url_launcher_web/pubspec.yaml
@@ -1,7 +1,7 @@
name: url_launcher_web
description: Web platform implementation of url_launcher
homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web
-version: 0.1.1
+version: 0.1.1+1
flutter:
plugin:
@@ -22,6 +22,7 @@
flutter_test:
sdk: flutter
url_launcher: ^5.2.5
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/video_player_platform_interface/BUILD.gn b/video_player_platform_interface/BUILD.gn
index c75bc39..a22628c 100644
--- a/video_player_platform_interface/BUILD.gn
+++ b/video_player_platform_interface/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for video_player_platform_interface-1.0.4
+# This file is generated by importer.py for video_player_platform_interface-1.0.5
import("//build/dart/dart_library.gni")
diff --git a/video_player_platform_interface/CHANGELOG.md b/video_player_platform_interface/CHANGELOG.md
index 79be27a..be1b0e3 100644
--- a/video_player_platform_interface/CHANGELOG.md
+++ b/video_player_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.5
+
+* Make the pedantic dev_dependency explicit.
+
## 1.0.4
* Remove the deprecated `author:` field from pubspec.yaml
diff --git a/video_player_platform_interface/pubspec.yaml b/video_player_platform_interface/pubspec.yaml
index 8bae556..2ce3bd1 100644
--- a/video_player_platform_interface/pubspec.yaml
+++ b/video_player_platform_interface/pubspec.yaml
@@ -3,7 +3,7 @@
homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_platform_interface
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 1.0.4
+version: 1.0.5
dependencies:
flutter:
@@ -14,6 +14,7 @@
flutter_test:
sdk: flutter
mockito: ^4.1.1
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/video_player_web/BUILD.gn b/video_player_web/BUILD.gn
index 5a949ae..27d4a7e 100644
--- a/video_player_web/BUILD.gn
+++ b/video_player_web/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for video_player_web-0.1.2
+# This file is generated by importer.py for video_player_web-0.1.2+1
import("//build/dart/dart_library.gni")
diff --git a/video_player_web/CHANGELOG.md b/video_player_web/CHANGELOG.md
index 4c3aaa7..00fc486 100644
--- a/video_player_web/CHANGELOG.md
+++ b/video_player_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.2+1
+
+* Make the pedantic dev_dependency explicit.
+
## 0.1.2
* Add a `PlatformException` to the player's `eventController` when there's a `videoElement.onError`. Fixes https://github.com/flutter/flutter/issues/48884.
diff --git a/video_player_web/pubspec.yaml b/video_player_web/pubspec.yaml
index 4358f82..e1435c8 100644
--- a/video_player_web/pubspec.yaml
+++ b/video_player_web/pubspec.yaml
@@ -1,7 +1,7 @@
name: video_player_web
description: Web platform implementation of video_player
homepage: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_web
-version: 0.1.2
+version: 0.1.2+1
flutter:
plugin:
@@ -23,6 +23,7 @@
sdk: flutter
video_player:
path: ../video_player
+ pedantic: ^1.8.0
environment:
sdk: ">=2.0.0-dev.28.0 <3.0.0"
diff --git a/webdriver/BUILD.gn b/webdriver/BUILD.gn
index 1c2312d..ddb3675 100644
--- a/webdriver/BUILD.gn
+++ b/webdriver/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for webdriver-2.1.1
+# This file is generated by importer.py for webdriver-2.1.2
import("//build/dart/dart_library.gni")
diff --git a/webdriver/CHANGELOG.md b/webdriver/CHANGELOG.md
index db252ae..1b9b0b0 100644
--- a/webdriver/CHANGELOG.md
+++ b/webdriver/CHANGELOG.md
@@ -1,3 +1,7 @@
+## v2.1.2
+
+* Updated to latest version of sync_http.
+
## v2.1.1
* Forward-compatible fix for upcoming Dart SDK breaking change
diff --git a/webdriver/analysis_options.yaml b/webdriver/analysis_options.yaml
index 0b79a58..6f8b463 100644
--- a/webdriver/analysis_options.yaml
+++ b/webdriver/analysis_options.yaml
@@ -1,5 +1,3 @@
-analyzer:
- strong-mode: true
linter:
rules:
- always_declare_return_types
@@ -13,7 +11,6 @@
- cancel_subscriptions
- control_flow_in_finally
- empty_constructor_bodies
- - empty_constructor_bodies
- empty_statements
- hash_and_equals
- implementation_imports
@@ -43,8 +40,6 @@
- prefer_typing_uninitialized_variables
- recursive_getters
- slash_for_doc_comments
- - slash_for_doc_comments
- - super_goes_last
- test_types_in_equals
- throw_in_finally
- type_init_formals
diff --git a/webdriver/lib/async_core.dart b/webdriver/lib/async_core.dart
index ce49382..8013467 100644
--- a/webdriver/lib/async_core.dart
+++ b/webdriver/lib/async_core.dart
@@ -124,5 +124,5 @@
}
return WebDriver(uri, sessionId, UnmodifiableMapView(capabilities),
- createRequestClient(uri.resolve('session/${sessionId}/')), spec);
+ createRequestClient(uri.resolve('session/$sessionId/')), spec);
}
diff --git a/webdriver/lib/src/async/common.dart b/webdriver/lib/src/async/common.dart
index 26f7e9e..d015eb6 100644
--- a/webdriver/lib/src/async/common.dart
+++ b/webdriver/lib/src/async/common.dart
@@ -23,7 +23,7 @@
/// Simple class to provide access to indexed properties such as WebElement
/// attributes or css styles.
class Attributes {
- GetAttribute _getAttribute;
+ final GetAttribute _getAttribute;
Attributes(this._getAttribute);
diff --git a/webdriver/lib/src/handler/json_wire_handler.dart b/webdriver/lib/src/handler/json_wire_handler.dart
index 3bad7bd..4bcd061 100644
--- a/webdriver/lib/src/handler/json_wire_handler.dart
+++ b/webdriver/lib/src/handler/json_wire_handler.dart
@@ -69,5 +69,5 @@
deserialize(parseJsonWireResponse(response), createElement);
@override
- String toString() => "JsonWire";
+ String toString() => 'JsonWire';
}
diff --git a/webdriver/pubspec.yaml b/webdriver/pubspec.yaml
index 8fed1b8..31a5052 100644
--- a/webdriver/pubspec.yaml
+++ b/webdriver/pubspec.yaml
@@ -1,5 +1,5 @@
name: webdriver
-version: 2.1.1
+version: 2.1.2
authors:
- Marc Fisher II <fisherii@google.com>
- Matt Staats<staats@google.com>
@@ -15,6 +15,6 @@
matcher: ^0.12.3
path: ^1.3.0
stack_trace: ^1.3.0
- sync_http: ^0.1.1
+ sync_http: '>=0.1.1 <0.3.0'
dev_dependencies:
test: '^1.0.0'
diff --git a/webkit_inspection_protocol/.travis.yml b/webkit_inspection_protocol/.travis.yml
index ad23559..35e0ab9 100644
--- a/webkit_inspection_protocol/.travis.yml
+++ b/webkit_inspection_protocol/.travis.yml
@@ -1,11 +1,10 @@
language: dart
-sudo: false
dart:
- dev
-before_install:
- - export DISPLAY=:99.0
- - sh -e /etc/init.d/xvfb start
+#before_install:
+# - export DISPLAY=:99.0
+# - sh -e /etc/init.d/xvfb start
script: ./tool/travis.sh
diff --git a/webkit_inspection_protocol/BUILD.gn b/webkit_inspection_protocol/BUILD.gn
index 12419e9..60ef4d0 100644
--- a/webkit_inspection_protocol/BUILD.gn
+++ b/webkit_inspection_protocol/BUILD.gn
@@ -1,4 +1,4 @@
-# This file is generated by importer.py for webkit_inspection_protocol-0.5.0
+# This file is generated by importer.py for webkit_inspection_protocol-0.5.0+1
import("//build/dart/dart_library.gni")
diff --git a/webkit_inspection_protocol/changelog.md b/webkit_inspection_protocol/changelog.md
index 1f1847f..27a9bb7 100644
--- a/webkit_inspection_protocol/changelog.md
+++ b/webkit_inspection_protocol/changelog.md
@@ -1,5 +1,8 @@
# webkit_inspection_protocol.dart
+## 0.5.0+1
+- fixed a bug in reading type of `WipScope`
+
## 0.5.0
- removed the bin/multiplex.dart binary to the example/ directory
- remove dependencies on `package:args`, package:shelf`, and `package:shelf_web_socket`
diff --git a/webkit_inspection_protocol/lib/src/debugger.dart b/webkit_inspection_protocol/lib/src/debugger.dart
index 5c3808b..fa4c428 100644
--- a/webkit_inspection_protocol/lib/src/debugger.dart
+++ b/webkit_inspection_protocol/lib/src/debugger.dart
@@ -160,7 +160,7 @@
WipScope(this._map);
// "catch", "closure", "global", "local", "with"
- String get scope => _map['scope'] as String;
+ String get scope => _map['type'] as String;
/// Object representing the scope. For global and with scopes it represents
/// the actual object; for the rest of the scopes, it is artificial transient
diff --git a/webkit_inspection_protocol/pubspec.yaml b/webkit_inspection_protocol/pubspec.yaml
index 8df358b..1de55da 100644
--- a/webkit_inspection_protocol/pubspec.yaml
+++ b/webkit_inspection_protocol/pubspec.yaml
@@ -1,5 +1,5 @@
name: webkit_inspection_protocol
-version: 0.5.0
+version: 0.5.0+1
description: A client for the Chrome DevTools Protocol (previously called the Webkit Inspection Protocol).
homepage: https://github.com/google/webkit_inspection_protocol.dart