Version 2.17.0-159.0.dev
Merge commit '59b6e9dcd0d8194442c67fc5d28f68008bc3138a' into 'dev'
diff --git a/pkg/analysis_server/test/verify_sorted_test.dart b/pkg/analysis_server/test/verify_sorted_test.dart
index bcde125..37de909 100644
--- a/pkg/analysis_server/test/verify_sorted_test.dart
+++ b/pkg/analysis_server/test/verify_sorted_test.dart
@@ -27,6 +27,10 @@
group('analyzer_plugin', () {
buildTestsForAnalyzerPlugin();
});
+
+ group('nnbd_migration', () {
+ buildTestsForNnbdMigration();
+ });
}
void buildTests({
@@ -116,6 +120,12 @@
);
}
+void buildTestsForNnbdMigration() {
+ buildTests(
+ packagePath: 'nnbd_migration',
+ excludedPaths: ['lib/src/front_end/resources/resources.g.dart']);
+}
+
void buildTestsIn(AnalysisSession session, String testDirPath,
List<String> excludedPath, Folder directory) {
var pathContext = session.resourceProvider.pathContext;
diff --git a/pkg/nnbd_migration/lib/src/edit_plan.dart b/pkg/nnbd_migration/lib/src/edit_plan.dart
index 76d2703..b3757c8 100644
--- a/pkg/nnbd_migration/lib/src/edit_plan.dart
+++ b/pkg/nnbd_migration/lib/src/edit_plan.dart
@@ -1713,6 +1713,26 @@
/// [AtomicEdit]s. This data structure is used by [EditPlan]s to accumulate
/// source file changes.
extension AtomicEditMap on Map<int?, List<AtomicEdit>>? {
+ /// Destructively combines two change representations. If one or the other
+ /// input is null, the other input is returned unchanged for efficiency.
+ Map<int?, List<AtomicEdit>>? operator +(
+ Map<int?, List<AtomicEdit>>? newChanges) {
+ if (newChanges == null) return this;
+ if (this == null) {
+ return newChanges;
+ } else {
+ for (var entry in newChanges.entries) {
+ var currentValue = this![entry.key];
+ if (currentValue == null) {
+ this![entry.key] = entry.value;
+ } else {
+ currentValue.addAll(entry.value);
+ }
+ }
+ return this;
+ }
+ }
+
/// Applies the changes to source file text.
///
/// If [includeInformative] is `true`, informative edits are included;
@@ -1734,26 +1754,6 @@
.toSourceEdit(offset!, includeInformative: includeInformative)
];
}
-
- /// Destructively combines two change representations. If one or the other
- /// input is null, the other input is returned unchanged for efficiency.
- Map<int?, List<AtomicEdit>>? operator +(
- Map<int?, List<AtomicEdit>>? newChanges) {
- if (newChanges == null) return this;
- if (this == null) {
- return newChanges;
- } else {
- for (var entry in newChanges.entries) {
- var currentValue = this![entry.key];
- if (currentValue == null) {
- this![entry.key] = entry.value;
- } else {
- currentValue.addAll(entry.value);
- }
- }
- return this;
- }
- }
}
/// Extension allowing an AstNode to be queried to see if it ends in a casade
diff --git a/pkg/nnbd_migration/lib/src/front_end/charcodes.dart b/pkg/nnbd_migration/lib/src/front_end/charcodes.dart
index aba601f..72c75cc 100644
--- a/pkg/nnbd_migration/lib/src/front_end/charcodes.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/charcodes.dart
@@ -2,11 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/// "Line feed" control character.
-const int $lf = 0x0a;
-
/// "Carriage return" control character.
const int $cr = 0x0d;
+/// "Line feed" control character.
+const int $lf = 0x0a;
+
/// Space character.
const int $space = 0x20;
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
index bde8b46..0fec61f 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
@@ -81,14 +81,14 @@
String absolutePathFromRoot(String? path) =>
pathContext.join(includedRoot!, path);
- /// Returns the relative path of [path] from [includedRoot].
- String relativePathFromRoot(String path) =>
- pathContext.relative(path, from: includedRoot);
-
/// Return the path to [unit] from [includedRoot], to be used as a display
/// name for a library.
String computeName(UnitInfo unit) => relativePathFromRoot(unit.path!);
+ /// Returns the relative path of [path] from [includedRoot].
+ String relativePathFromRoot(String path) =>
+ pathContext.relative(path, from: includedRoot);
+
List<UnitLink> unitLinks() {
var links = <UnitLink>[];
for (var unit in units!) {
diff --git a/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
index ab64227..2b7e6d2 100644
--- a/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/annotation_tracker.dart
@@ -9,9 +9,8 @@
class AnnotationTracker extends RecursiveAstVisitor<void> {
final Set<Annotation> _nodes = {};
- @override
- void visitAnnotation(Annotation node) {
- _nodes.add(node);
+ void finalize() {
+ assert(_nodes.isEmpty, 'Annotation nodes not visited: $_nodes');
}
void nodeVisited(Annotation node) {
@@ -20,7 +19,8 @@
}
}
- void finalize() {
- assert(_nodes.isEmpty, 'Annotation nodes not visited: $_nodes');
+ @override
+ void visitAnnotation(Annotation node) {
+ _nodes.add(node);
}
}
diff --git a/pkg/nnbd_migration/lib/src/utilities/multi_future_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/multi_future_tracker.dart
index 94176c2..d40da27 100644
--- a/pkg/nnbd_migration/lib/src/utilities/multi_future_tracker.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/multi_future_tracker.dart
@@ -37,14 +37,6 @@
MultiFutureTracker(this.parallel);
- /// Wait until fewer or equal to this many Futures are outstanding.
- Future<void> _waitUntil(int max) async {
- assert(_trackedFutures.length <= parallel);
- while (_trackedFutures.length > max) {
- await Future.any(_trackedFutures);
- }
- }
-
/// Generates a [Future] from the given closure and adds it to the queue,
/// once the queue is sufficiently empty. The returned future completes
/// when the generated [Future] has been added to the queue.
@@ -73,4 +65,12 @@
/// Wait until all futures added so far have completed.
Future<void> wait() => _waitUntil(0);
+
+ /// Wait until fewer or equal to this many Futures are outstanding.
+ Future<void> _waitUntil(int max) async {
+ assert(_trackedFutures.length <= parallel);
+ while (_trackedFutures.length > max) {
+ await Future.any(_trackedFutures);
+ }
+ }
}
diff --git a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart b/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
index 672840e..ff6fb77 100644
--- a/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/subprocess_launcher.dart
@@ -9,7 +9,6 @@
/// This is a modified version of dartdoc's
/// SubprocessLauncher from test/src/utils.dart, for use with the
/// nnbd_migration script.
-
import 'dart:convert';
import 'dart:io';
@@ -34,20 +33,6 @@
final String context;
final Map<String, String> environmentDefaults;
- /// From flutter:dev/tools/dartdoc.dart, modified.
- static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
- {String prefix = '', Iterable<String> Function(String line)? filter}) {
- filter ??= (line) => [line];
- return stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .expand(filter)
- .listen((String line) {
- output.write('$prefix$line'.trim());
- output.write('\n');
- }).asFuture();
- }
-
SubprocessLauncher(this.context, [Map<String, String>? environment])
: environmentDefaults = environment ?? <String, String>{};
@@ -192,4 +177,18 @@
}
return jsonObjects;
}
+
+ /// From flutter:dev/tools/dartdoc.dart, modified.
+ static Future<void> _printStream(Stream<List<int>> stream, Stdout output,
+ {String prefix = '', Iterable<String> Function(String line)? filter}) {
+ filter ??= (line) => [line];
+ return stream
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .expand(filter)
+ .listen((String line) {
+ output.write('$prefix$line'.trim());
+ output.write('\n');
+ }).asFuture();
+ }
}
diff --git a/pkg/nnbd_migration/test/front_end/info_builder_test.dart b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
index 23a7900..f434cf2 100644
--- a/pkg/nnbd_migration/test/front_end/info_builder_test.dart
+++ b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
@@ -798,34 +798,6 @@
edits: isEmpty);
}
- Future<void> test_insertedRequired_fieldFormal_hint() async {
- var unit = await buildInfoForSingleTestFile('''
-class C {
- int level;
- int level2;
- C({this.level}) : this.level2 = level + 1;
-}
-''', migratedContent: '''
-class C {
- int level;
- int level2;
- C({required this.level}) : this.level2 = level + 1;
-}
-''');
- var regions = unit.fixRegions;
- expect(regions, hasLength(1));
- var region = regions[0];
- var edits = region.edits;
- assertRegion(
- region: region,
- offset: 44,
- length: 9,
- explanation: "Add 'required' keyword to parameter 'level' in 'C.'",
- kind: NullabilityFixKind.addRequired);
- assertEdit(
- edit: edits[0], offset: 42, length: 0, replacement: '/*required*/ ');
- }
-
Future<void> test_insertedRequired_fieldFormal() async {
addMetaPackage();
var unit = await buildInfoForSingleTestFile('''
@@ -857,6 +829,63 @@
edit: edits[0], offset: 75, length: 0, replacement: '@required ');
}
+ Future<void> test_insertedRequired_fieldFormal_hint() async {
+ var unit = await buildInfoForSingleTestFile('''
+class C {
+ int level;
+ int level2;
+ C({this.level}) : this.level2 = level + 1;
+}
+''', migratedContent: '''
+class C {
+ int level;
+ int level2;
+ C({required this.level}) : this.level2 = level + 1;
+}
+''');
+ var regions = unit.fixRegions;
+ expect(regions, hasLength(1));
+ var region = regions[0];
+ var edits = region.edits;
+ assertRegion(
+ region: region,
+ offset: 44,
+ length: 9,
+ explanation: "Add 'required' keyword to parameter 'level' in 'C.'",
+ kind: NullabilityFixKind.addRequired);
+ assertEdit(
+ edit: edits[0], offset: 42, length: 0, replacement: '/*required*/ ');
+ }
+
+ Future<void> test_insertedRequired_parameter() async {
+ addMetaPackage();
+ var unit = await buildInfoForSingleTestFile('''
+import 'package:meta/meta.dart';
+class C {
+ int level = 0;
+ bool f({int lvl}) => lvl >= level;
+}
+''', migratedContent: '''
+import 'package:meta/meta.dart';
+class C {
+ int level = 0;
+ bool f({required int lvl}) => lvl >= level;
+}
+''');
+ var regions = unit.fixRegions;
+ expect(regions, hasLength(1));
+ var region = regions[0];
+ var edits = region.edits;
+ assertRegion(
+ region: region,
+ offset: 72,
+ length: 9,
+ explanation: "Add 'required' keyword to parameter 'lvl' in 'C.f'",
+ kind: NullabilityFixKind.addRequired);
+ assertEdit(
+ edit: edits[0], offset: 70, length: 0, replacement: '@required ');
+ }
+
Future<void> test_insertedRequired_parameter_hint() async {
var unit = await buildInfoForSingleTestFile('''
class C {
@@ -906,35 +935,6 @@
edit: edits[0], offset: 78, length: 0, replacement: '@meta.required ');
}
- Future<void> test_insertedRequired_parameter() async {
- addMetaPackage();
- var unit = await buildInfoForSingleTestFile('''
-import 'package:meta/meta.dart';
-class C {
- int level = 0;
- bool f({int lvl}) => lvl >= level;
-}
-''', migratedContent: '''
-import 'package:meta/meta.dart';
-class C {
- int level = 0;
- bool f({required int lvl}) => lvl >= level;
-}
-''');
- var regions = unit.fixRegions;
- expect(regions, hasLength(1));
- var region = regions[0];
- var edits = region.edits;
- assertRegion(
- region: region,
- offset: 72,
- length: 9,
- explanation: "Add 'required' keyword to parameter 'lvl' in 'C.f'",
- kind: NullabilityFixKind.addRequired);
- assertEdit(
- edit: edits[0], offset: 70, length: 0, replacement: '@required ');
- }
-
Future<void> test_insertParens() async {
var originalContent = '''
class C {
diff --git a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
index 54a5e39..536560f 100644
--- a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
@@ -330,11 +330,11 @@
}
extension<T extends NavigationTreeNode> on TypeMatcher<T> {
- TypeMatcher<T> named(dynamic matcher) =>
- having((node) => node.name, 'name', matcher);
-
TypeMatcher<T> havingMigrationStatus(dynamic matcher) =>
having((node) => node.migrationStatus, 'migrationStatus', matcher);
+
+ TypeMatcher<T> named(dynamic matcher) =>
+ having((node) => node.name, 'name', matcher);
}
extension on TypeMatcher<NavigationTreeDirectoryNode> {
diff --git a/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart b/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart
index 634a347..18d7c67 100644
--- a/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart
+++ b/pkg/nnbd_migration/test/utilities/multi_future_tracker_test.dart
@@ -24,6 +24,22 @@
testTracker = null;
}
+ Future<void> test_doesNotBlockWithoutLimit() async {
+ var completer1 = Completer();
+
+ // Limit is set above the number of futures we are adding.
+ testTracker = MultiFutureTracker(10);
+ await testTracker!.addFutureFromClosure(() => completer1.future);
+ // The second future added should be executing even though the first
+ // future is not complete. A test failure will time out.
+ await testTracker!.addFutureFromClosure(() async {
+ expect(completer1.isCompleted, isFalse);
+ completer1.complete();
+ });
+
+ return await testTracker!.wait();
+ }
+
Future<void> test_multiFutureBlocksOnLimit() async {
var completer1 = Completer();
@@ -40,20 +56,12 @@
return await testTracker!.wait();
}
- Future<void> test_doesNotBlockWithoutLimit() async {
- var completer1 = Completer();
-
- // Limit is set above the number of futures we are adding.
- testTracker = MultiFutureTracker(10);
- await testTracker!.addFutureFromClosure(() => completer1.future);
- // The second future added should be executing even though the first
- // future is not complete. A test failure will time out.
- await testTracker!.addFutureFromClosure(() async {
- expect(completer1.isCompleted, isFalse);
- completer1.complete();
- });
-
- return await testTracker!.wait();
+ Future<void> test_returnsValueFromRun() async {
+ testTracker = MultiFutureTracker(1);
+ await expectLater(await testTracker!.runFutureFromClosure(() async => true),
+ equals(true));
+ await expectLater(
+ await testTracker!.runFutureFromClosure(() => true), equals(true));
}
Future<void> test_runsSeriallyAtLowLimit() async {
@@ -76,12 +84,4 @@
await runFuture1;
await runFuture2;
}
-
- Future<void> test_returnsValueFromRun() async {
- testTracker = MultiFutureTracker(1);
- await expectLater(await testTracker!.runFutureFromClosure(() async => true),
- equals(true));
- await expectLater(
- await testTracker!.runFutureFromClosure(() => true), equals(true));
- }
}
diff --git a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart b/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
index 7b05cfa..5c6babb 100644
--- a/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
+++ b/pkg/nnbd_migration/test/utilities/subprocess_launcher_test.dart
@@ -31,25 +31,6 @@
await tempDir.delete(recursive: true);
}
- Future<void> test_subprocessWorksViaParallelSubprocessLimit() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessWorksViaParallelSubprocessLimit');
-
- await launcher.runStreamed(Platform.resolvedExecutable, ['--version'],
- perLine: outputCallback);
- expect(output, anyElement(contains('Dart')));
- }
-
- Future<void> test_subprocessRunsValidExecutable() async {
- SubprocessLauncher launcher =
- SubprocessLauncher('test_subprocessRunsValidExecutable');
-
- await launcher.runStreamedImmediate(
- Platform.resolvedExecutable, ['--version'],
- perLine: outputCallback);
- expect(output, anyElement(contains('Dart')));
- }
-
Future<void> test_subprocessPassesArgs() async {
SubprocessLauncher launcher =
SubprocessLauncher('test_subprocessPassesArgs');
@@ -90,6 +71,16 @@
'^environment: .*__SUBPROCESS_PASSES_ENVIRONMENT_TEST: yes'))));
}
+ Future<void> test_subprocessRunsValidExecutable() async {
+ SubprocessLauncher launcher =
+ SubprocessLauncher('test_subprocessRunsValidExecutable');
+
+ await launcher.runStreamedImmediate(
+ Platform.resolvedExecutable, ['--version'],
+ perLine: outputCallback);
+ expect(output, anyElement(contains('Dart')));
+ }
+
Future<void> test_subprocessSetsWorkingDirectory() async {
SubprocessLauncher launcher =
SubprocessLauncher('test_subprocessSetsWorkingDirectory');
@@ -128,4 +119,13 @@
perLine: outputCallback),
throwsA(TypeMatcher<ProcessException>()));
}
+
+ Future<void> test_subprocessWorksViaParallelSubprocessLimit() async {
+ SubprocessLauncher launcher =
+ SubprocessLauncher('test_subprocessWorksViaParallelSubprocessLimit');
+
+ await launcher.runStreamed(Platform.resolvedExecutable, ['--version'],
+ perLine: outputCallback);
+ expect(output, anyElement(contains('Dart')));
+ }
}
diff --git a/pkg/nnbd_migration/test/verify_tests_test.dart b/pkg/nnbd_migration/test/verify_tests_test.dart
index 654c634..cd08ec6 100644
--- a/pkg/nnbd_migration/test/verify_tests_test.dart
+++ b/pkg/nnbd_migration/test/verify_tests_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:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer_utilities/package_root.dart' as package_root;
import 'package:analyzer_utilities/verify_tests.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
void main() {
var provider = PhysicalResourceProvider.INSTANCE;
diff --git a/pkg/nnbd_migration/tool/codegen/generate_resources.dart b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
index 3dab62f..83cfd8c 100644
--- a/pkg/nnbd_migration/tool/codegen/generate_resources.dart
+++ b/pkg/nnbd_migration/tool/codegen/generate_resources.dart
@@ -54,17 +54,6 @@
}
}
-/// Returns the dart2jsPath, either from [argResults] or the Platform.
-String? dart2jsPath(ArgResults argResults) {
- if (argResults.wasParsed('dart2js_path')) {
- return argResults['dart2js_path'] as String?;
- } else {
- var sdkBinDir = path.dirname(Platform.resolvedExecutable);
- var dart2jsBinary = Platform.isWindows ? 'dart2js.bat' : 'dart2js';
- return path.join(sdkBinDir, dart2jsBinary);
- }
-}
-
final File dartSources = File(path.join('pkg', 'nnbd_migration', 'lib', 'src',
'front_end', 'web', 'migration.dart'));
@@ -131,6 +120,17 @@
resourcesFile.writeAsStringSync(content);
}
+/// Returns the dart2jsPath, either from [argResults] or the Platform.
+String? dart2jsPath(ArgResults argResults) {
+ if (argResults.wasParsed('dart2js_path')) {
+ return argResults['dart2js_path'] as String?;
+ } else {
+ var sdkBinDir = path.dirname(Platform.resolvedExecutable);
+ var dart2jsBinary = Platform.isWindows ? 'dart2js.bat' : 'dart2js';
+ return path.join(sdkBinDir, dart2jsBinary);
+ }
+}
+
void fail(String message) {
stderr.writeln(message);
exit(1);
diff --git a/pkg/nnbd_migration/tool/src/package.dart b/pkg/nnbd_migration/tool/src/package.dart
index a50b8c3..dc4dec4 100644
--- a/pkg/nnbd_migration/tool/src/package.dart
+++ b/pkg/nnbd_migration/tool/src/package.dart
@@ -3,12 +3,33 @@
// BSD-style license that can be found in the LICENSE file.
/// Abstractions for the different sources of truth for different packages.
-
import 'dart:io';
import 'package:nnbd_migration/src/utilities/subprocess_launcher.dart';
import 'package:path/path.dart' as path;
+final String defaultPlaygroundPath =
+ Platform.environment['TRIAL_MIGRATION_PLAYGROUND'] ??
+ resolveTildePath('~/.nnbd_trial_migration');
+
+/// The pub cache inherited by this process.
+final String defaultPubCache =
+ Platform.environment['PUB_CACHE'] ?? resolveTildePath('~/.pub-cache');
+
+/// Returns the path to the SDK repository this script is a part of.
+final String thisSdkRepo = () {
+ var maybeSdkRepoDir = Platform.script.toFilePath();
+ while (maybeSdkRepoDir != path.dirname(maybeSdkRepoDir)) {
+ maybeSdkRepoDir = path.dirname(maybeSdkRepoDir);
+ if (File(path.join(maybeSdkRepoDir, 'README.dart-sdk')).existsSync()) {
+ return maybeSdkRepoDir;
+ }
+ }
+ throw UnsupportedError(
+ 'Script ${Platform.script} using this library must be within the SDK repository');
+}();
+Uri get thisSdkUri => Uri.file(thisSdkRepo);
+
/// Return a resolved path including the home directory in place of tilde
/// references.
String resolveTildePath(String originalPath) {
@@ -27,93 +48,36 @@
return path.join(homeDir, originalPath.substring(2));
}
-/// The pub cache inherited by this process.
-final String defaultPubCache =
- Platform.environment['PUB_CACHE'] ?? resolveTildePath('~/.pub-cache');
-final String defaultPlaygroundPath =
- Platform.environment['TRIAL_MIGRATION_PLAYGROUND'] ??
- resolveTildePath('~/.nnbd_trial_migration');
-Uri get thisSdkUri => Uri.file(thisSdkRepo);
-
-class Playground {
- final String playgroundPath;
-
- /// If [clean] is true, this will delete the playground. Otherwise,
- /// if it exists it will assume it is properly constructed.
- Playground(this.playgroundPath, bool clean) {
- Directory playground = Directory(playgroundPath);
- if (clean) {
- if (playground.existsSync()) {
- playground.deleteSync(recursive: true);
- }
- }
- if (!playground.existsSync()) playground.createSync();
- }
-
- /// Build an environment for subprocesses.
- Map<String, String> get env => {'PUB_CACHE': pubCachePath};
-
- String get pubCachePath => path.join(playgroundPath, '.pub-cache');
-}
-
-/// Returns the path to the SDK repository this script is a part of.
-final String thisSdkRepo = () {
- var maybeSdkRepoDir = Platform.script.toFilePath();
- while (maybeSdkRepoDir != path.dirname(maybeSdkRepoDir)) {
- maybeSdkRepoDir = path.dirname(maybeSdkRepoDir);
- if (File(path.join(maybeSdkRepoDir, 'README.dart-sdk')).existsSync()) {
- return maybeSdkRepoDir;
- }
- }
- throw UnsupportedError(
- 'Script ${Platform.script} using this library must be within the SDK repository');
-}();
-
-/// Abstraction for an unmanaged package.
-class ManualPackage extends Package {
- final String _packagePath;
- ManualPackage(this._packagePath) : super(_packagePath);
-
- @override
- List<String> get migrationPaths => [_packagePath];
-}
-
/// Abstraction for a package fetched via Git.
class GitPackage extends Package {
+ static final RegExp _pathAndPeriodSplitter = RegExp('[\\/.]');
final String _clonePath;
final bool? _keepUpdated;
final String label;
+
final Playground _playground;
+ SubprocessLauncher? _launcher;
+
+ String? _packagePath;
+
GitPackage._(this._clonePath, this._playground, this._keepUpdated,
{String? name, this.label = 'master'})
: super(name ?? _buildName(_clonePath));
- static Future<GitPackage> gitPackageFactory(
- String clonePath, Playground playground, bool? keepUpdated,
- {String? name, String label = 'master'}) async {
- GitPackage gitPackage = GitPackage._(clonePath, playground, keepUpdated,
- name: name, label: label);
- await gitPackage._init();
- return gitPackage;
- }
+ SubprocessLauncher get launcher =>
+ _launcher ??= SubprocessLauncher('$name-$label', _playground.env);
- /// Calculate the "humanish" name of the clone (see `git help clone`).
- static String _buildName(String clonePath) {
- if (Directory(clonePath).existsSync()) {
- // assume we are cloning locally
- return path.basename(clonePath);
- }
- List<String> pathParts = clonePath.split(_pathAndPeriodSplitter);
- int indexOfName = pathParts.lastIndexOf('git') - 1;
- if (indexOfName < 0) {
- throw ArgumentError(
- 'GitPackage can not figure out the name for $clonePath, pass it in manually?');
- }
- return pathParts[indexOfName];
- }
+ @override
+ List<String?> get migrationPaths => [_packagePath];
+ String get packagePath =>
+ // TODO(jcollins-g): allow packages from subdirectories of clones
+ _packagePath ??= path.join(_playground.playgroundPath, '$name-$label');
- static final RegExp _pathAndPeriodSplitter = RegExp('[\\/.]');
+ @override
+ String toString() {
+ return '$_clonePath ($label)' + (_keepUpdated! ? ' [synced]' : '');
+ }
/// Initialize the package with a shallow clone. Run only once per
/// [GitPackage] instance.
@@ -139,58 +103,38 @@
}
}
- SubprocessLauncher? _launcher;
- SubprocessLauncher get launcher =>
- _launcher ??= SubprocessLauncher('$name-$label', _playground.env);
-
- String? _packagePath;
- String get packagePath =>
- // TODO(jcollins-g): allow packages from subdirectories of clones
- _packagePath ??= path.join(_playground.playgroundPath, '$name-$label');
-
- @override
- List<String?> get migrationPaths => [_packagePath];
-
- @override
- String toString() {
- return '$_clonePath ($label)' + (_keepUpdated! ? ' [synced]' : '');
- }
-}
-
-/// Abstraction for a package fetched via pub.
-class PubPackage extends Package {
- PubPackage(String name, [String? version]) : super(name) {
- throw UnimplementedError();
+ static Future<GitPackage> gitPackageFactory(
+ String clonePath, Playground playground, bool? keepUpdated,
+ {String? name, String label = 'master'}) async {
+ GitPackage gitPackage = GitPackage._(clonePath, playground, keepUpdated,
+ name: name, label: label);
+ await gitPackage._init();
+ return gitPackage;
}
- @override
- // TODO: implement packagePath
- List<String> get migrationPaths => throw UnimplementedError();
-}
-
-/// Abstraction for a package located within pkg or third_party/pkg.
-class SdkPackage extends Package {
- /// Where to find packages. Constructor searches in-order.
- static final List<String> _searchPaths = [
- 'pkg',
- path.join('third_party', 'pkg'),
- ];
-
- SdkPackage(String name) : super(name) {
- for (String potentialPath
- in _searchPaths.map((p) => path.join(thisSdkRepo, p, name))) {
- if (Directory(potentialPath).existsSync()) {
- _packagePath = potentialPath;
- }
+ /// Calculate the "humanish" name of the clone (see `git help clone`).
+ static String _buildName(String clonePath) {
+ if (Directory(clonePath).existsSync()) {
+ // assume we are cloning locally
+ return path.basename(clonePath);
}
+ List<String> pathParts = clonePath.split(_pathAndPeriodSplitter);
+ int indexOfName = pathParts.lastIndexOf('git') - 1;
+ if (indexOfName < 0) {
+ throw ArgumentError(
+ 'GitPackage can not figure out the name for $clonePath, pass it in manually?');
+ }
+ return pathParts[indexOfName];
}
+}
- late final String _packagePath;
+/// Abstraction for an unmanaged package.
+class ManualPackage extends Package {
+ final String _packagePath;
+ ManualPackage(this._packagePath) : super(_packagePath);
+
@override
List<String> get migrationPaths => [_packagePath];
-
- @override
- String toString() => path.relative(_packagePath, from: thisSdkRepo);
}
/// Base class for pub, github, SDK, or possibly other package sources.
@@ -206,6 +150,38 @@
String toString() => name;
}
+class Playground {
+ final String playgroundPath;
+
+ /// If [clean] is true, this will delete the playground. Otherwise,
+ /// if it exists it will assume it is properly constructed.
+ Playground(this.playgroundPath, bool clean) {
+ Directory playground = Directory(playgroundPath);
+ if (clean) {
+ if (playground.existsSync()) {
+ playground.deleteSync(recursive: true);
+ }
+ }
+ if (!playground.existsSync()) playground.createSync();
+ }
+
+ /// Build an environment for subprocesses.
+ Map<String, String> get env => {'PUB_CACHE': pubCachePath};
+
+ String get pubCachePath => path.join(playgroundPath, '.pub-cache');
+}
+
+/// Abstraction for a package fetched via pub.
+class PubPackage extends Package {
+ PubPackage(String name, [String? version]) : super(name) {
+ throw UnimplementedError();
+ }
+
+ @override
+ // TODO: implement packagePath
+ List<String> get migrationPaths => throw UnimplementedError();
+}
+
/// Abstraction for compiled Dart SDKs (not this repository).
class Sdk {
/// The root of the compiled SDK.
@@ -215,3 +191,28 @@
this.sdkPath = path.canonicalize(sdkPath);
}
}
+
+/// Abstraction for a package located within pkg or third_party/pkg.
+class SdkPackage extends Package {
+ /// Where to find packages. Constructor searches in-order.
+ static final List<String> _searchPaths = [
+ 'pkg',
+ path.join('third_party', 'pkg'),
+ ];
+
+ late final String _packagePath;
+
+ SdkPackage(String name) : super(name) {
+ for (String potentialPath
+ in _searchPaths.map((p) => path.join(thisSdkRepo, p, name))) {
+ if (Directory(potentialPath).existsSync()) {
+ _packagePath = potentialPath;
+ }
+ }
+ }
+ @override
+ List<String> get migrationPaths => [_packagePath];
+
+ @override
+ String toString() => path.relative(_packagePath, from: thisSdkRepo);
+}
diff --git a/tools/VERSION b/tools/VERSION
index f27b5c8..b2afca5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 158
+PRERELEASE 159
PRERELEASE_PATCH 0
\ No newline at end of file