From a5cb81c52a6dd3360dfbef02df12a46dbd5a6813 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 5 May 2021 11:37:17 -0400 Subject: [PATCH 1/6] Upgrade all dependencies to null-safe versions (and sort them) --- .../lib/src/firebase_test_lab_command.dart | 2 +- script/tool/lib/src/format_command.dart | 4 +- script/tool/pubspec.yaml | 40 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index ff7d05bf4e89..7083343ff5fb 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -30,7 +30,7 @@ class FirebaseTestLabCommand extends PluginCommand { defaultsTo: p.join(io.Platform.environment['HOME'], 'gcloud-service-key.json')); argParser.addOption('test-run-id', - defaultsTo: Uuid().v4(), + defaultsTo: const Uuid().v4(), help: 'Optional string to append to the results path, to avoid conflicts. ' 'Randomly chosen on each invocation if none is provided. ' diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index 9c29f0f8c684..e7b7e15fc1c9 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -13,8 +13,8 @@ import 'package:quiver/iterables.dart'; import 'common.dart'; -const String _googleFormatterUrl = - 'https://github.com/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar'; +final Uri _googleFormatterUrl = Uri.https('github.com', + '/google/google-java-format/releases/download/google-java-format-1.3/google-java-format-1.3-all-deps.jar'); /// A command to format all package code. class FormatCommand extends PluginCommand { diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index 18631fef02d7..fc1fd2255efe 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -4,28 +4,28 @@ repository: https://github.com/flutter/plugins/tree/master/script/tool version: 0.1.0+1 dependencies: - args: "^1.4.3" - path: "^1.6.1" - http: "^0.12.1" - async: "^2.0.7" - yaml: "^2.1.15" - quiver: "^2.0.2" - pub_semver: ^1.4.2 - colorize: ^2.0.0 - git: ^1.0.0 - platform: ^2.2.0 - pubspec_parse: "^0.1.4" - test: ^1.6.4 - meta: ^1.1.7 - file: ^5.0.10 - uuid: ^2.0.4 - http_multi_server: ^2.2.0 - collection: ^1.14.13 + args: ^2.1.0 + async: ^2.6.1 + collection: ^1.15.0 + colorize: ^3.0.0 + file: ^6.1.0 + git: ^2.0.0 + http: ^0.13.3 + http_multi_server: ^3.0.1 + meta: ^1.3.0 + path: ^1.8.0 + platform: ^3.0.0 + pub_semver: ^2.0.0 + pubspec_parse: ^1.0.0 + quiver: ^3.0.1 + test: ^1.17.3 + uuid: ^3.0.4 + yaml: ^3.1.0 dev_dependencies: - matcher: ^0.12.6 - mockito: ^4.1.1 - pedantic: ^1.8.0 + matcher: ^0.12.10 + mockito: ^5.0.7 + pedantic: ^1.11.0 environment: sdk: ">=2.3.0 <3.0.0" From 0529a3af89b3c651e9694cb2ced9700633fef338 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 5 May 2021 14:08:19 -0400 Subject: [PATCH 2/6] Introduce convenience methods for arg access --- script/tool/lib/src/analyze_command.dart | 8 ++--- .../tool/lib/src/build_examples_command.dart | 4 +-- script/tool/lib/src/common.dart | 29 ++++++++++++++----- .../tool/lib/src/drive_examples_command.dart | 23 +++++++-------- .../lib/src/firebase_test_lab_command.dart | 12 ++++---- script/tool/lib/src/format_command.dart | 4 +-- .../tool/lib/src/lint_podspecs_command.dart | 4 +-- script/tool/lib/src/list_command.dart | 2 +- .../tool/lib/src/publish_check_command.dart | 2 +- .../tool/lib/src/publish_plugin_command.dart | 24 +++++++-------- script/tool/lib/src/test_command.dart | 2 +- script/tool/lib/src/xctest_command.dart | 4 +-- 12 files changed, 65 insertions(+), 53 deletions(-) diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index e17400fa8871..53ba6229cdc1 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -42,8 +42,8 @@ class AnalyzeCommand extends PluginCommand { continue; } - final bool allowed = (argResults[_customAnalysisFlag] as List) - .any((String directory) => + final bool allowed = (getStringListArg(_customAnalysisFlag)).any( + (String directory) => directory != null && directory.isNotEmpty && p.isWithin(p.join(packagesDir.path, directory), file.path)); @@ -69,8 +69,8 @@ class AnalyzeCommand extends PluginCommand { final List failingPackages = []; await for (final Directory package in getPlugins()) { - final int exitCode = await processRunner.runAndStream( - 'dart', ['analyze'], workingDir: package); + final int exitCode = await processRunner + .runAndStream('dart', ['analyze'], workingDir: package); if (exitCode != 0) { failingPackages.add(p.basename(package.path)); } diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 0069c0586810..1be861255774 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -52,7 +52,7 @@ class BuildExamplesCommand extends PluginCommand { ]; final Map platforms = { for (final String platform in platformSwitches) - platform: argResults[platform] as bool + platform: getBoolArg(platform) }; if (!platforms.values.any((bool enabled) => enabled)) { print( @@ -63,7 +63,7 @@ class BuildExamplesCommand extends PluginCommand { final String flutterCommand = const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; - final String enableExperiment = argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); final List failingPackages = []; await for (final Directory plugin in getPlugins()) { diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index c16ba8e957e0..f2d4ab49c146 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -255,9 +255,24 @@ abstract class PluginCommand extends Command { return _shardCount; } + /// Convenience accessor for boolean arguments. + bool getBoolArg(String key) { + return (argResults[key] as bool) ?? false; + } + + /// Convenience accessor for String arguments. + String getStringArg(String key) { + return (argResults[key] as String) ?? ''; + } + + /// Convenience accessor for List arguments. + List getStringListArg(String key) { + return (argResults[key] as List) ?? []; + } + void _checkSharding() { - final int shardIndex = int.tryParse(argResults[_shardIndexArg] as String); - final int shardCount = int.tryParse(argResults[_shardCountArg] as String); + final int shardIndex = int.tryParse(getStringArg(_shardIndexArg)); + final int shardCount = int.tryParse(getStringArg(_shardCountArg)); if (shardIndex == null) { usageException('$_shardIndexArg must be an integer'); } @@ -312,12 +327,10 @@ abstract class PluginCommand extends Command { /// "client library" package, which declares the API for the plugin, as /// well as one or more platform-specific implementations. Stream _getAllPlugins() async* { - Set plugins = - Set.from(argResults[_pluginsArg] as List); + Set plugins = Set.from(getStringListArg(_pluginsArg)); final Set excludedPlugins = - Set.from(argResults[_excludeArg] as List); - final bool runOnChangedPackages = - argResults[_runOnChangedPackagesArg] as bool; + Set.from(getStringListArg(_excludeArg)); + final bool runOnChangedPackages = getBoolArg(_runOnChangedPackagesArg); if (plugins.isEmpty && runOnChangedPackages) { plugins = await _getChangedPackages(); } @@ -415,7 +428,7 @@ abstract class PluginCommand extends Command { /// Throws tool exit if [gitDir] nor root directory is a git directory. Future retrieveVersionFinder() async { final String rootDir = packagesDir.parent.absolute.path; - final String baseSha = argResults[_kBaseSha] as String; + final String baseSha = getStringArg(_kBaseSha); GitDir baseGitDir = gitDir; if (baseGitDir == null) { diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index e52052a49ae6..e5e8ca0ee02f 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -52,10 +52,10 @@ class DriveExamplesCommand extends PluginCommand { @override Future run() async { final List failingTests = []; - final bool isLinux = argResults[kLinux] == true; - final bool isMacos = argResults[kMacos] == true; - final bool isWeb = argResults[kWeb] == true; - final bool isWindows = argResults[kWindows] == true; + final bool isLinux = getBoolArg(kLinux); + final bool isMacos = getBoolArg(kMacos); + final bool isWeb = getBoolArg(kWeb); + final bool isWindows = getBoolArg(kWindows); await for (final Directory plugin in getPlugins()) { final String flutterCommand = const LocalPlatform().isWindows ? 'flutter.bat' : 'flutter'; @@ -126,8 +126,7 @@ Tried searching for the following: final List driveArgs = ['drive']; - final String enableExperiment = - argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); if (enableExperiment.isNotEmpty) { driveArgs.add('--enable-experiment=$enableExperiment'); } @@ -193,12 +192,12 @@ Tried searching for the following: Future _pluginSupportedOnCurrentPlatform( FileSystemEntity plugin, FileSystem fileSystem) async { - final bool isAndroid = argResults[kAndroid] == true; - final bool isIOS = argResults[kIos] == true; - final bool isLinux = argResults[kLinux] == true; - final bool isMacos = argResults[kMacos] == true; - final bool isWeb = argResults[kWeb] == true; - final bool isWindows = argResults[kWindows] == true; + final bool isAndroid = getBoolArg(kAndroid); + final bool isIOS = getBoolArg(kIos); + final bool isLinux = getBoolArg(kLinux); + final bool isMacos = getBoolArg(kMacos); + final bool isWeb = getBoolArg(kWeb); + final bool isWindows = getBoolArg(kWindows); if (isAndroid) { return isAndroidPlugin(plugin, fileSystem); } diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index 7083343ff5fb..2cf84ae35200 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -78,7 +78,7 @@ class FirebaseTestLabCommand extends PluginCommand { [ 'auth', 'activate-service-account', - '--key-file=${argResults['service-key']}', + '--key-file=${getStringArg('service-key')}', ], exitOnError: true, logOnError: true, @@ -87,7 +87,7 @@ class FirebaseTestLabCommand extends PluginCommand { 'config', 'set', 'project', - argResults['project'] as String, + getStringArg('project'), ]); if (exitCode == 0) { _print('\nFirebase project configured.'); @@ -125,7 +125,7 @@ class FirebaseTestLabCommand extends PluginCommand { final Directory androidDirectory = fileSystem.directory(p.join(exampleDirectory.path, 'android')); - final String enableExperiment = argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); final String encodedEnableExperiment = Uri.encodeComponent('--enable-experiment=$enableExperiment'); @@ -213,7 +213,7 @@ class FirebaseTestLabCommand extends PluginCommand { continue; } final String buildId = io.Platform.environment['CIRRUS_BUILD_ID']; - final String testRunId = argResults['test-run-id'] as String; + final String testRunId = getStringArg('test-run-id'); final String resultsDir = 'plugins_android_test/$packageName/$buildId/$testRunId/${resultsCounter++}/'; final List args = [ @@ -229,10 +229,10 @@ class FirebaseTestLabCommand extends PluginCommand { 'build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk', '--timeout', '5m', - '--results-bucket=${argResults['results-bucket']}', + '--results-bucket=${getStringArg('results-bucket')}', '--results-dir=$resultsDir', ]; - for (final String device in argResults['device'] as List) { + for (final String device in getStringListArg('device')) { args.addAll(['--device', device]); } exitCode = await processRunner.runAndStream('gcloud', args, diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index e7b7e15fc1c9..51ab7957d883 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -47,7 +47,7 @@ class FormatCommand extends PluginCommand { await _formatJava(googleFormatterPath); await _formatCppAndObjectiveC(); - if (argResults['fail-on-change'] == true) { + if (getBoolArg('fail-on-change')) { final bool modified = await _didModifyAnything(); if (modified) { throw ToolExit(1); @@ -105,7 +105,7 @@ class FormatCommand extends PluginCommand { // 'ProcessException: Argument list too long'. final Iterable> batches = partition(allFiles, 100); for (final List batch in batches) { - await processRunner.runAndStream(argResults['clang-format'] as String, + await processRunner.runAndStream(getStringArg('clang-format'), ['-i', '--style=Google', ...batch], workingDir: packagesDir, exitOnError: true); } diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index ebcefd6c2343..42d8e813c2b7 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -89,7 +89,7 @@ class LintPodspecsCommand extends PluginCommand { final List podspecs = await getFiles().where((File entity) { final String filePath = entity.path; return p.extension(filePath) == '.podspec' && - !(argResults['skip'] as List) + !getStringListArg('skip') .contains(p.basenameWithoutExtension(filePath)); }).toList(); @@ -122,7 +122,7 @@ class LintPodspecsCommand extends PluginCommand { Future _runPodLint(String podspecPath, {bool libraryLint}) async { - final bool allowWarnings = (argResults['ignore-warnings'] as List) + final bool allowWarnings = (getStringListArg('ignore-warnings')) .contains(p.basenameWithoutExtension(podspecPath)); final List arguments = [ 'lib', diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart index 49302a91ad27..f834c8aa502e 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -36,7 +36,7 @@ class ListCommand extends PluginCommand { @override Future run() async { - switch (argResults[_type] as String) { + switch (getStringArg(_type)) { case _plugin: await for (final Directory package in getPlugins()) { print(package.path); diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index 0fb9dbad60a8..99ef1249f56d 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -108,7 +108,7 @@ class PublishCheckCommand extends PluginCommand { return true; } - if (!(argResults[_allowPrereleaseFlag] as bool)) { + if (!getBoolArg(_allowPrereleaseFlag)) { return false; } diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index 9bfa0e71743a..6b2570471f9f 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -111,8 +111,8 @@ class PublishPluginCommand extends PluginCommand { @override Future run() async { - final String package = argResults[_packageOption] as String; - final bool publishAllChanged = argResults[_allChangedFlag] as bool; + final String package = getStringArg(_packageOption); + final bool publishAllChanged = getBoolArg(_allChangedFlag); if (package == null && !publishAllChanged) { _print( 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); @@ -127,14 +127,14 @@ class PublishPluginCommand extends PluginCommand { final GitDir baseGitDir = await GitDir.fromExisting(packagesDir.path, allowSubdirectory: true); - final bool shouldPushTag = argResults[_pushTagsOption] == true; - final String remote = argResults[_remoteOption] as String; + final bool shouldPushTag = getBoolArg(_pushTagsOption); + final String remote = getStringArg(_remoteOption); String remoteUrl; if (shouldPushTag) { remoteUrl = await _verifyRemote(remote); } _print('Local repo is ready!'); - if (argResults[_dryRunFlag] as bool) { + if (getBoolArg(_dryRunFlag)) { _print('=============== DRY RUN ==============='); } @@ -233,7 +233,7 @@ class PublishPluginCommand extends PluginCommand { if (!await _publishPlugin(packageDir: packageDir)) { return false; } - if (argResults[_tagReleaseOption] as bool) { + if (getBoolArg(_tagReleaseOption)) { if (!await _tagRelease( packageDir: packageDir, remote: remote, @@ -267,7 +267,8 @@ Safe to ignore if the package is deleted in this commit. } if (pubspec.version == null) { - _print('No version found. A package that intentionally has no version should be marked "publish_to: none"'); + _print( + 'No version found. A package that intentionally has no version should be marked "publish_to: none"'); return _CheckNeedsReleaseResult.failure; } @@ -321,7 +322,7 @@ Safe to ignore if the package is deleted in this commit. }) async { final String tag = _getTag(packageDir); _print('Tagging release $tag...'); - if (!(argResults[_dryRunFlag] as bool)) { + if (!getBoolArg(_dryRunFlag)) { final io.ProcessResult result = await processRunner.run( 'git', ['tag', tag], @@ -404,11 +405,10 @@ Safe to ignore if the package is deleted in this commit. } Future _publish(Directory packageDir) async { - final List publishFlags = - argResults[_pubFlagsOption] as List; + final List publishFlags = getStringListArg(_pubFlagsOption); _print( 'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n'); - if (!(argResults[_dryRunFlag] as bool)) { + if (!getBoolArg(_dryRunFlag)) { final io.Process publish = await processRunner.start( 'flutter', ['pub', 'publish'] + publishFlags, workingDirectory: packageDir); @@ -459,7 +459,7 @@ Safe to ignore if the package is deleted in this commit. _print('Tag push canceled.'); return false; } - if (!(argResults[_dryRunFlag] as bool)) { + if (!getBoolArg(_dryRunFlag)) { final io.ProcessResult result = await processRunner.run( 'git', ['push', remote, tag], diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index bb4f9c12a77f..7455095effcf 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -44,7 +44,7 @@ class TestCommand extends PluginCommand { print('RUNNING $packageName tests...'); - final String enableExperiment = argResults[kEnableExperiment] as String; + final String enableExperiment = getStringArg(kEnableExperiment); // `flutter test` automatically gets packages. `pub run test` does not. :( int exitCode = 0; diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index 64f85577dbce..b0435999cb88 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -48,7 +48,7 @@ class XCTestCommand extends PluginCommand { @override Future run() async { - String destination = argResults[_kiOSDestination] as String; + String destination = getStringArg(_kiOSDestination); if (destination == null) { final String simulatorId = await _findAvailableIphoneSimulator(); if (simulatorId == null) { @@ -58,7 +58,7 @@ class XCTestCommand extends PluginCommand { destination = 'id=$simulatorId'; } - final List skipped = argResults[_kSkip] as List; + final List skipped = getStringListArg(_kSkip); final List failingPackages = []; await for (final Directory plugin in getPlugins()) { From ba38415dcccabd00ba15771ea17ab50e918c429c Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 14 May 2021 13:48:39 -0400 Subject: [PATCH 3/6] Run migration and do minor fixup --- script/tool/bin/flutter_plugin_tools.dart | 2 + script/tool/lib/src/analyze_command.dart | 2 + .../tool/lib/src/build_examples_command.dart | 2 + script/tool/lib/src/common.dart | 80 +++++----- .../src/create_all_plugins_app_command.dart | 2 + .../tool/lib/src/drive_examples_command.dart | 2 + .../lib/src/firebase_test_lab_command.dart | 2 + script/tool/lib/src/format_command.dart | 2 + script/tool/lib/src/java_test_command.dart | 2 + .../tool/lib/src/license_check_command.dart | 2 + .../tool/lib/src/lint_podspecs_command.dart | 2 + script/tool/lib/src/list_command.dart | 2 + script/tool/lib/src/main.dart | 2 + .../tool/lib/src/publish_check_command.dart | 2 + .../tool/lib/src/publish_plugin_command.dart | 4 +- script/tool/lib/src/test_command.dart | 2 + .../tool/lib/src/version_check_command.dart | 2 + script/tool/lib/src/xctest_command.dart | 4 +- script/tool/pubspec.yaml | 3 +- script/tool/test/analyze_command_test.dart | 2 + .../test/build_examples_command_test.dart | 2 + script/tool/test/common_test.dart | 64 ++++---- script/tool/test/common_test.mocks.dart | 143 ++++++++++++++++++ .../create_all_plugins_app_command_test.dart | 2 + .../test/drive_examples_command_test.dart | 2 + script/tool/test/firebase_test_lab_test.dart | 2 + script/tool/test/java_test_command_test.dart | 2 + .../tool/test/license_check_command_test.dart | 2 + .../tool/test/lint_podspecs_command_test.dart | 2 + script/tool/test/list_command_test.dart | 2 + script/tool/test/mocks.dart | 2 + .../tool/test/publish_check_command_test.dart | 2 + .../test/publish_plugin_command_test.dart | 2 + script/tool/test/test_command_test.dart | 2 + script/tool/test/util.dart | 46 +++--- script/tool/test/version_check_test.dart | 2 + script/tool/test/xctest_command_test.dart | 2 + 37 files changed, 305 insertions(+), 99 deletions(-) create mode 100644 script/tool/test/common_test.mocks.dart diff --git a/script/tool/bin/flutter_plugin_tools.dart b/script/tool/bin/flutter_plugin_tools.dart index 0f30bee0d258..eea0db5a7f01 100644 --- a/script/tool/bin/flutter_plugin_tools.dart +++ b/script/tool/bin/flutter_plugin_tools.dart @@ -2,4 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + export 'package:flutter_plugin_tools/src/main.dart'; diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart index 0ed6c2caa5ce..ec22e0683924 100644 --- a/script/tool/lib/src/analyze_command.dart +++ b/script/tool/lib/src/analyze_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/build_examples_command.dart b/script/tool/lib/src/build_examples_command.dart index 1be861255774..f7129865630d 100644 --- a/script/tool/lib/src/build_examples_command.dart +++ b/script/tool/lib/src/build_examples_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 4c183a65eda5..59ea6176cb34 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -12,14 +12,13 @@ import 'package:colorize/colorize.dart'; import 'package:file/file.dart'; import 'package:git/git.dart'; import 'package:http/http.dart' as http; -import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; /// The signature for a print handler for commands that allow overriding the /// print destination. -typedef Print = void Function(Object object); +typedef Print = void Function(Object? object); /// Key for windows platform. const String kWindows = 'windows'; @@ -50,7 +49,7 @@ const String kEnableExperiment = 'enable-experiment'; /// Returns whether the given directory contains a Flutter package. bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { - if (entity == null || entity is! Directory) { + if (entity is! Directory) { return false; } @@ -59,7 +58,7 @@ bool isFlutterPackage(FileSystemEntity entity, FileSystem fileSystem) { fileSystem.file(p.join(entity.path, 'pubspec.yaml')); final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap; - final YamlMap dependencies = pubspecYaml['dependencies'] as YamlMap; + final YamlMap? dependencies = pubspecYaml['dependencies'] as YamlMap?; if (dependencies == null) { return false; } @@ -87,7 +86,7 @@ bool pluginSupportsPlatform( platform == kMacos || platform == kWindows || platform == kLinux); - if (entity == null || entity is! Directory) { + if (entity is! Directory) { return false; } @@ -96,15 +95,15 @@ bool pluginSupportsPlatform( fileSystem.file(p.join(entity.path, 'pubspec.yaml')); final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap; - final YamlMap flutterSection = pubspecYaml['flutter'] as YamlMap; + final YamlMap? flutterSection = pubspecYaml['flutter'] as YamlMap?; if (flutterSection == null) { return false; } - final YamlMap pluginSection = flutterSection['plugin'] as YamlMap; + final YamlMap? pluginSection = flutterSection['plugin'] as YamlMap?; if (pluginSection == null) { return false; } - final YamlMap platforms = pluginSection['platforms'] as YamlMap; + final YamlMap? platforms = pluginSection['platforms'] as YamlMap?; if (platforms == null) { // Legacy plugin specs are assumed to support iOS and Android. if (!pluginSection.containsKey('platforms')) { @@ -151,7 +150,7 @@ bool isLinuxPlugin(FileSystemEntity entity, FileSystem fileSystem) { } /// Throws a [ToolExit] with `exitCode` and log the `errorMessage` in red. -void printErrorAndExit({@required String errorMessage, int exitCode = 1}) { +void printErrorAndExit({required String errorMessage, int exitCode = 1}) { final Colorize redError = Colorize(errorMessage)..red(); print(redError); throw ToolExit(exitCode); @@ -236,17 +235,17 @@ abstract class PluginCommand extends Command { /// The git directory to use. By default it uses the parent directory. /// /// This can be mocked for testing. - final GitDir gitDir; + final GitDir? gitDir; - int _shardIndex; - int _shardCount; + int? _shardIndex; + int? _shardCount; /// The shard of the overall command execution that this instance should run. int get shardIndex { if (_shardIndex == null) { _checkSharding(); } - return _shardIndex; + return _shardIndex!; } /// The number of shards this command is divided into. @@ -254,27 +253,27 @@ abstract class PluginCommand extends Command { if (_shardCount == null) { _checkSharding(); } - return _shardCount; + return _shardCount!; } /// Convenience accessor for boolean arguments. bool getBoolArg(String key) { - return (argResults[key] as bool) ?? false; + return (argResults![key] as bool?) ?? false; } /// Convenience accessor for String arguments. String getStringArg(String key) { - return (argResults[key] as String) ?? ''; + return (argResults![key] as String?) ?? ''; } /// Convenience accessor for List arguments. List getStringListArg(String key) { - return (argResults[key] as List) ?? []; + return (argResults![key] as List?) ?? []; } void _checkSharding() { - final int shardIndex = int.tryParse(getStringArg(_shardIndexArg)); - final int shardCount = int.tryParse(getStringArg(_shardCountArg)); + final int? shardIndex = int.tryParse(getStringArg(_shardIndexArg)); + final int? shardCount = int.tryParse(getStringArg(_shardCountArg)); if (shardIndex == null) { usageException('$_shardIndexArg must be an integer'); } @@ -444,7 +443,7 @@ abstract class PluginCommand extends Command { final String rootDir = packagesDir.parent.absolute.path; final String baseSha = getStringArg(_kBaseSha); - GitDir baseGitDir = gitDir; + GitDir? baseGitDir = gitDir; if (baseGitDir == null) { if (!await GitDir.isGitDir(rootDir)) { printErrorAndExit( @@ -503,7 +502,7 @@ class ProcessRunner { Future runAndStream( String executable, List args, { - Directory workingDir, + Directory? workingDir, bool exitOnError = false, }) async { print( @@ -535,7 +534,7 @@ class ProcessRunner { /// /// Returns the [io.ProcessResult] of the [executable]. Future run(String executable, List args, - {Directory workingDir, + {Directory? workingDir, bool exitOnError = false, bool logOnError = false, Encoding stdoutEncoding = io.systemEncoding, @@ -563,15 +562,15 @@ class ProcessRunner { /// passing [workingDir]. /// /// Returns the started [io.Process]. - Future start(String executable, List args, - {Directory workingDirectory}) async { + Future start(String executable, List args, + {Directory? workingDirectory}) async { final io.Process process = await io.Process.start(executable, args, workingDirectory: workingDirectory?.path); return process; } String _getErrorString(String executable, List args, - {Directory workingDir}) { + {Directory? workingDir}) { final String workdir = workingDir == null ? '' : ' in ${workingDir.path}'; return 'ERROR: Unable to execute "$executable ${args.join(' ')}"$workdir.'; } @@ -582,7 +581,7 @@ class PubVersionFinder { /// Constructor. /// /// Note: you should manually close the [httpClient] when done using the finder. - PubVersionFinder({this.pubHost = defaultPubHost, @required this.httpClient}); + PubVersionFinder({this.pubHost = defaultPubHost, required this.httpClient}); /// The default pub host to use. static const String defaultPubHost = 'https://pub.dev'; @@ -597,7 +596,7 @@ class PubVersionFinder { /// Get the package version on pub. Future getPackageVersion( - {@required String package}) async { + {required String? package}) async { assert(package != null && package.isNotEmpty); final Uri pubHostUri = Uri.parse(pubHost); final Uri url = pubHostUri.replace(path: '/packages/$package.json'); @@ -631,8 +630,8 @@ class PubVersionFinder { class PubVersionFinderResponse { /// Constructor. PubVersionFinderResponse({this.versions, this.result, this.httpResponse}) { - if (versions != null && versions.isNotEmpty) { - versions.sort((Version a, Version b) { + if (versions != null && versions!.isNotEmpty) { + versions!.sort((Version a, Version b) { // TODO(cyanglaz): Think about how to handle pre-release version with [Version.prioritize]. // https://github.com/flutter/flutter/issues/82222 return b.compareTo(a); @@ -644,13 +643,13 @@ class PubVersionFinderResponse { /// /// This is sorted by largest to smallest, so the first element in the list is the largest version. /// Might be `null` if the [result] is not [PubVersionFinderResult.success]. - final List versions; + final List? versions; /// The result of the version finder. - final PubVersionFinderResult result; + final PubVersionFinderResult? result; /// The response object of the http request. - final http.Response httpResponse; + final http.Response? httpResponse; } /// An enum representing the result of [PubVersionFinder]. @@ -680,7 +679,7 @@ class GitVersionFinder { final GitDir baseGitDir; /// The base sha used to get diff. - final String baseSha; + final String? baseSha; static bool _isPubspec(String file) { return file.trim().endsWith('pubspec.yaml'); @@ -697,8 +696,7 @@ class GitVersionFinder { final io.ProcessResult changedFilesCommand = await baseGitDir .runCommand(['diff', '--name-only', baseSha, 'HEAD']); print('Determine diff with base sha: $baseSha'); - final String changedFilesStdout = - changedFilesCommand.stdout.toString() ?? ''; + final String changedFilesStdout = changedFilesCommand.stdout.toString(); if (changedFilesStdout.isEmpty) { return []; } @@ -709,7 +707,8 @@ class GitVersionFinder { /// Get the package version specified in the pubspec file in `pubspecPath` and /// at the revision of `gitRef` (defaulting to the base if not provided). - Future getPackageVersion(String pubspecPath, {String gitRef}) async { + Future getPackageVersion(String pubspecPath, + {String? gitRef}) async { final String ref = gitRef ?? (await _getBaseSha()); io.ProcessResult gitShow; @@ -720,20 +719,19 @@ class GitVersionFinder { return null; } final String fileContent = gitShow.stdout as String; - final String versionString = loadYaml(fileContent)['version'] as String; + final String? versionString = loadYaml(fileContent)['version'] as String?; return versionString == null ? null : Version.parse(versionString); } Future _getBaseSha() async { - if (baseSha != null && baseSha.isNotEmpty) { - return baseSha; + if (baseSha != null && baseSha!.isNotEmpty) { + return baseSha!; } io.ProcessResult baseShaFromMergeBase = await baseGitDir.runCommand( ['merge-base', '--fork-point', 'FETCH_HEAD', 'HEAD'], throwOnError: false); - if (baseShaFromMergeBase == null || - baseShaFromMergeBase.stderr != null || + if (baseShaFromMergeBase.stderr != null || baseShaFromMergeBase.stdout == null) { baseShaFromMergeBase = await baseGitDir .runCommand(['merge-base', 'FETCH_HEAD', 'HEAD']); diff --git a/script/tool/lib/src/create_all_plugins_app_command.dart b/script/tool/lib/src/create_all_plugins_app_command.dart index 4b5b4c6b8df4..d825703f1731 100644 --- a/script/tool/lib/src/create_all_plugins_app_command.dart +++ b/script/tool/lib/src/create_all_plugins_app_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 15f465f53591..76ba8205e177 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; import 'package:path/path.dart' as p; diff --git a/script/tool/lib/src/firebase_test_lab_command.dart b/script/tool/lib/src/firebase_test_lab_command.dart index 2cf84ae35200..2d91deffa2c4 100644 --- a/script/tool/lib/src/firebase_test_lab_command.dart +++ b/script/tool/lib/src/firebase_test_lab_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/lib/src/format_command.dart b/script/tool/lib/src/format_command.dart index 51ab7957d883..b3a8bd04edb5 100644 --- a/script/tool/lib/src/format_command.dart +++ b/script/tool/lib/src/format_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/lib/src/java_test_command.dart b/script/tool/lib/src/java_test_command.dart index 5df97627cecd..dff83d37315f 100644 --- a/script/tool/lib/src/java_test_command.dart +++ b/script/tool/lib/src/java_test_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index a6528640b828..cc4eb96fac39 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/lint_podspecs_command.dart b/script/tool/lib/src/lint_podspecs_command.dart index 42d8e813c2b7..0bf4c69b24f4 100644 --- a/script/tool/lib/src/lint_podspecs_command.dart +++ b/script/tool/lib/src/lint_podspecs_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io'; diff --git a/script/tool/lib/src/list_command.dart b/script/tool/lib/src/list_command.dart index f834c8aa502e..cac6cfcf352e 100644 --- a/script/tool/lib/src/list_command.dart +++ b/script/tool/lib/src/list_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/main.dart b/script/tool/lib/src/main.dart index 6fba3b34b955..4b0e85704b24 100644 --- a/script/tool/lib/src/main.dart +++ b/script/tool/lib/src/main.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:io' as io; import 'package:args/command_runner.dart'; diff --git a/script/tool/lib/src/publish_check_command.dart b/script/tool/lib/src/publish_check_command.dart index bd74a3516383..3f90465d4f7d 100644 --- a/script/tool/lib/src/publish_check_command.dart +++ b/script/tool/lib/src/publish_check_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index b365391e244c..cb72c1897215 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -124,7 +126,7 @@ class PublishPluginCommand extends PluginCommand { Future run() async { final String package = getStringArg(_packageOption); final bool publishAllChanged = getBoolArg(_allChangedFlag); - if (package == null && !publishAllChanged) { + if (package.isEmpty && !publishAllChanged) { _print( 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); throw ToolExit(1); diff --git a/script/tool/lib/src/test_command.dart b/script/tool/lib/src/test_command.dart index 7455095effcf..c4aeab7022b8 100644 --- a/script/tool/lib/src/test_command.dart +++ b/script/tool/lib/src/test_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/version_check_command.dart b/script/tool/lib/src/version_check_command.dart index 67c7a22f34ab..a802c4d425ee 100644 --- a/script/tool/lib/src/version_check_command.dart +++ b/script/tool/lib/src/version_check_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'package:file/file.dart'; diff --git a/script/tool/lib/src/xctest_command.dart b/script/tool/lib/src/xctest_command.dart index b0435999cb88..335e0054fc05 100644 --- a/script/tool/lib/src/xctest_command.dart +++ b/script/tool/lib/src/xctest_command.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -49,7 +51,7 @@ class XCTestCommand extends PluginCommand { @override Future run() async { String destination = getStringArg(_kiOSDestination); - if (destination == null) { + if (destination.isEmpty) { final String simulatorId = await _findAvailableIphoneSimulator(); if (simulatorId == null) { print(_kFoundNoSimulatorsMessage); diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml index 6e58d8c4bf6c..725c8395b819 100644 --- a/script/tool/pubspec.yaml +++ b/script/tool/pubspec.yaml @@ -23,9 +23,10 @@ dependencies: yaml: ^3.1.0 dev_dependencies: + build_runner: ^2.0.3 matcher: ^0.12.10 mockito: ^5.0.7 pedantic: ^1.11.0 environment: - sdk: ">=2.3.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart index 11acb59a474d..1e656b4f75e4 100644 --- a/script/tool/test/analyze_command_test.dart +++ b/script/tool/test/analyze_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/analyze_command.dart'; diff --git a/script/tool/test/build_examples_command_test.dart b/script/tool/test/build_examples_command_test.dart index 40da27d44923..7b488879f3be 100644 --- a/script/tool/test/build_examples_command_test.dart +++ b/script/tool/test/build_examples_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/build_examples_command.dart'; diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index d6ac449e7fd3..8a708ef60e88 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -2,6 +2,7 @@ // 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'; @@ -12,21 +13,24 @@ import 'package:flutter_plugin_tools/src/common.dart'; import 'package:git/git.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; +import 'common_test.mocks.dart'; import 'util.dart'; +@GenerateMocks([GitDir]) void main() { - RecordingProcessRunner processRunner; - CommandRunner runner; - FileSystem fileSystem; - Directory packagesDir; - Directory thirdPartyPackagesDir; - List plugins; - List> gitDirCommands; - String gitDiffResponse; + late RecordingProcessRunner processRunner; + late CommandRunner runner; + late FileSystem fileSystem; + late Directory packagesDir; + late Directory thirdPartyPackagesDir; + late List plugins; + late List?> gitDirCommands; + late String gitDiffResponse; setUp(() { fileSystem = MemoryFileSystem(); @@ -35,14 +39,14 @@ void main() { .childDirectory('third_party') .childDirectory('packages'); - gitDirCommands = >[]; + gitDirCommands = ?>[]; gitDiffResponse = ''; final MockGitDir gitDir = MockGitDir(); when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0] as List); + gitDirCommands.add(invocation.positionalArguments[0] as List?); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout as String) + when(mockProcessResult.stdout as String?) .thenReturn(gitDiffResponse); } return Future.value(mockProcessResult); @@ -255,23 +259,24 @@ packages/plugin3/plugin3.dart }); group('$GitVersionFinder', () { - List> gitDirCommands; - String gitDiffResponse; - String mergeBaseResponse; - MockGitDir gitDir; + late List?> gitDirCommands; + late String gitDiffResponse; + String? mergeBaseResponse; + late MockGitDir gitDir; setUp(() { - gitDirCommands = >[]; + gitDirCommands = ?>[]; gitDiffResponse = ''; gitDir = MockGitDir(); - when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { - gitDirCommands.add(invocation.positionalArguments[0] as List); + when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) + .thenAnswer((Invocation invocation) { + gitDirCommands.add(invocation.positionalArguments[0] as List?); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { - when(mockProcessResult.stdout as String) + when(mockProcessResult.stdout as String?) .thenReturn(gitDiffResponse); } else if (invocation.positionalArguments[0][0] == 'merge-base') { - when(mockProcessResult.stdout as String) + when(mockProcessResult.stdout as String?) .thenReturn(mergeBaseResponse); } return Future.value(mockProcessResult); @@ -320,10 +325,11 @@ file2/file2.cc file1/pubspec.yaml file2/file2.cc '''; + final GitVersionFinder finder = GitVersionFinder(gitDir, null); await finder.getChangedFiles(); verify(gitDir.runCommand( - ['diff', '--name-only', mergeBaseResponse, 'HEAD'])); + ['diff', '--name-only', mergeBaseResponse!, 'HEAD'])); }); test('use correct base sha if specified', () async { @@ -350,8 +356,8 @@ file2/file2.cc expect(response.versions, isNull); expect(response.result, PubVersionFinderResult.noPackageFound); - expect(response.httpResponse.statusCode, 404); - expect(response.httpResponse.body, ''); + expect(response.httpResponse!.statusCode, 404); + expect(response.httpResponse!.body, ''); }); test('HTTP error when getting versions from pub', () async { @@ -364,8 +370,8 @@ file2/file2.cc expect(response.versions, isNull); expect(response.result, PubVersionFinderResult.fail); - expect(response.httpResponse.statusCode, 400); - expect(response.httpResponse.body, ''); + expect(response.httpResponse!.statusCode, 400); + expect(response.httpResponse!.body, ''); }); test('Get a correct list of versions when http response is OK.', () async { @@ -408,8 +414,8 @@ file2/file2.cc Version.parse('0.0.1'), ]); expect(response.result, PubVersionFinderResult.success); - expect(response.httpResponse.statusCode, 200); - expect(response.httpResponse.body, json.encode(httpResponse)); + expect(response.httpResponse!.statusCode, 200); + expect(response.httpResponse!.body, json.encode(httpResponse)); }); }); } @@ -420,7 +426,7 @@ class SamplePluginCommand extends PluginCommand { Directory packagesDir, FileSystem fileSystem, { ProcessRunner processRunner = const ProcessRunner(), - GitDir gitDir, + GitDir? gitDir, }) : super(packagesDir, fileSystem, processRunner: processRunner, gitDir: gitDir); @@ -440,6 +446,4 @@ class SamplePluginCommand extends PluginCommand { } } -class MockGitDir extends Mock implements GitDir {} - class MockProcessResult extends Mock implements ProcessResult {} diff --git a/script/tool/test/common_test.mocks.dart b/script/tool/test/common_test.mocks.dart new file mode 100644 index 000000000000..b7f7807b3b05 --- /dev/null +++ b/script/tool/test/common_test.mocks.dart @@ -0,0 +1,143 @@ +// Mocks generated by Mockito 5.0.7 from annotations +// in flutter_plugin_tools/test/common_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i6; +import 'dart:io' as _i4; + +import 'package:git/src/branch_reference.dart' as _i3; +import 'package:git/src/commit.dart' as _i2; +import 'package:git/src/commit_reference.dart' as _i8; +import 'package:git/src/git_dir.dart' as _i5; +import 'package:git/src/tag.dart' as _i7; +import 'package:git/src/tree_entry.dart' as _i9; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: comment_references +// ignore_for_file: unnecessary_parenthesis + +// ignore_for_file: prefer_const_constructors + +// ignore_for_file: avoid_redundant_argument_values + +class _FakeCommit extends _i1.Fake implements _i2.Commit {} + +class _FakeBranchReference extends _i1.Fake implements _i3.BranchReference {} + +class _FakeProcessResult extends _i1.Fake implements _i4.ProcessResult {} + +/// A class which mocks [GitDir]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGitDir extends _i1.Mock implements _i5.GitDir { + MockGitDir() { + _i1.throwOnMissingStub(this); + } + + @override + String get path => + (super.noSuchMethod(Invocation.getter(#path), returnValue: '') as String); + @override + _i6.Future commitCount([String? branchName = r'HEAD']) => + (super.noSuchMethod(Invocation.method(#commitCount, [branchName]), + returnValue: Future.value(0)) as _i6.Future); + @override + _i6.Future<_i2.Commit> commitFromRevision(String? revision) => + (super.noSuchMethod(Invocation.method(#commitFromRevision, [revision]), + returnValue: Future<_i2.Commit>.value(_FakeCommit())) + as _i6.Future<_i2.Commit>); + @override + _i6.Future> commits([String? branchName = r'HEAD']) => + (super.noSuchMethod(Invocation.method(#commits, [branchName]), + returnValue: + Future>.value({})) + as _i6.Future>); + @override + _i6.Future<_i3.BranchReference?> branchReference(String? branchName) => + (super.noSuchMethod(Invocation.method(#branchReference, [branchName]), + returnValue: + Future<_i3.BranchReference?>.value(_FakeBranchReference())) + as _i6.Future<_i3.BranchReference?>); + @override + _i6.Future> branches() => (super.noSuchMethod( + Invocation.method(#branches, []), + returnValue: + Future>.value(<_i3.BranchReference>[])) + as _i6.Future>); + @override + _i6.Stream<_i7.Tag> tags() => + (super.noSuchMethod(Invocation.method(#tags, []), + returnValue: Stream<_i7.Tag>.empty()) as _i6.Stream<_i7.Tag>); + @override + _i6.Future> showRef( + {bool? heads = false, bool? tags = false}) => + (super.noSuchMethod( + Invocation.method(#showRef, [], {#heads: heads, #tags: tags}), + returnValue: Future>.value( + <_i8.CommitReference>[])) + as _i6.Future>); + @override + _i6.Future<_i3.BranchReference> currentBranch() => + (super.noSuchMethod(Invocation.method(#currentBranch, []), + returnValue: + Future<_i3.BranchReference>.value(_FakeBranchReference())) + as _i6.Future<_i3.BranchReference>); + @override + _i6.Future> lsTree(String? treeish, + {bool? subTreesOnly = false, String? path}) => + (super.noSuchMethod( + Invocation.method(#lsTree, [treeish], + {#subTreesOnly: subTreesOnly, #path: path}), + returnValue: Future>.value(<_i9.TreeEntry>[])) + as _i6.Future>); + @override + _i6.Future createOrUpdateBranch( + String? branchName, String? treeSha, String? commitMessage) => + (super.noSuchMethod( + Invocation.method( + #createOrUpdateBranch, [branchName, treeSha, commitMessage]), + returnValue: Future.value('')) as _i6.Future); + @override + _i6.Future commitTree(String? treeSha, String? commitMessage, + {List? parentCommitShas}) => + (super.noSuchMethod( + Invocation.method(#commitTree, [treeSha, commitMessage], + {#parentCommitShas: parentCommitShas}), + returnValue: Future.value('')) as _i6.Future); + @override + _i6.Future> writeObjects(List? paths) => + (super.noSuchMethod(Invocation.method(#writeObjects, [paths]), + returnValue: + Future>.value({})) + as _i6.Future>); + @override + _i6.Future<_i4.ProcessResult> runCommand(Iterable? args, + {bool? throwOnError = true}) => + (super.noSuchMethod( + Invocation.method(#runCommand, [args], {#throwOnError: throwOnError}), + returnValue: + Future<_i4.ProcessResult>.value(_FakeProcessResult())) as _i6 + .Future<_i4.ProcessResult>); + @override + _i6.Future isWorkingTreeClean() => + (super.noSuchMethod(Invocation.method(#isWorkingTreeClean, []), + returnValue: Future.value(false)) as _i6.Future); + @override + _i6.Future<_i2.Commit?> updateBranch( + String? branchName, + _i6.Future Function(_i4.Directory)? populater, + String? commitMessage) => + (super.noSuchMethod( + Invocation.method( + #updateBranch, [branchName, populater, commitMessage]), + returnValue: Future<_i2.Commit?>.value(_FakeCommit())) + as _i6.Future<_i2.Commit?>); + @override + _i6.Future<_i2.Commit?> updateBranchWithDirectoryContents(String? branchName, + String? sourceDirectoryPath, String? commitMessage) => + (super.noSuchMethod( + Invocation.method(#updateBranchWithDirectoryContents, + [branchName, sourceDirectoryPath, commitMessage]), + returnValue: Future<_i2.Commit?>.value(_FakeCommit())) + as _i6.Future<_i2.Commit?>); +} diff --git a/script/tool/test/create_all_plugins_app_command_test.dart b/script/tool/test/create_all_plugins_app_command_test.dart index fedc04684631..caf4218dc161 100644 --- a/script/tool/test/create_all_plugins_app_command_test.dart +++ b/script/tool/test/create_all_plugins_app_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/local.dart'; diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index 5ba8d8af25ff..7905bb279f4a 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/common.dart'; diff --git a/script/tool/test/firebase_test_lab_test.dart b/script/tool/test/firebase_test_lab_test.dart index d6068691d549..b4e5b5b8c723 100644 --- a/script/tool/test/firebase_test_lab_test.dart +++ b/script/tool/test/firebase_test_lab_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:io'; import 'package:args/command_runner.dart'; diff --git a/script/tool/test/java_test_command_test.dart b/script/tool/test/java_test_command_test.dart index ba016915223d..cfa8d448f374 100644 --- a/script/tool/test/java_test_command_test.dart +++ b/script/tool/test/java_test_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/java_test_command.dart'; diff --git a/script/tool/test/license_check_command_test.dart b/script/tool/test/license_check_command_test.dart index 23de2581b9be..a0c74fc6acd6 100644 --- a/script/tool/test/license_check_command_test.dart +++ b/script/tool/test/license_check_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:file/memory.dart'; diff --git a/script/tool/test/lint_podspecs_command_test.dart b/script/tool/test/lint_podspecs_command_test.dart index a1fa1f7c7743..13bb1cc8d32f 100644 --- a/script/tool/test/lint_podspecs_command_test.dart +++ b/script/tool/test/lint_podspecs_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/lint_podspecs_command.dart'; diff --git a/script/tool/test/list_command_test.dart b/script/tool/test/list_command_test.dart index e7fcfe7a7c4b..a767671be5c2 100644 --- a/script/tool/test/list_command_test.dart +++ b/script/tool/test/list_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/list_command.dart'; diff --git a/script/tool/test/mocks.dart b/script/tool/test/mocks.dart index ad1f357fb472..a83ca754380f 100644 --- a/script/tool/test/mocks.dart +++ b/script/tool/test/mocks.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:io' as io; diff --git a/script/tool/test/publish_check_command_test.dart b/script/tool/test/publish_check_command_test.dart index eca7caf53403..8c34b3313a07 100644 --- a/script/tool/test/publish_check_command_test.dart +++ b/script/tool/test/publish_check_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:collection'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index b622e05861fa..357e72efa004 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/test/test_command_test.dart b/script/tool/test/test_command_test.dart index 1dd0c158293a..550249169b9b 100644 --- a/script/tool/test/test_command_test.dart +++ b/script/tool/test/test_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'package:args/command_runner.dart'; import 'package:file/file.dart'; import 'package:flutter_plugin_tools/src/test_command.dart'; diff --git a/script/tool/test/util.dart b/script/tool/test/util.dart index d708dc71bef7..7d4278f68cc9 100644 --- a/script/tool/test/util.dart +++ b/script/tool/test/util.dart @@ -21,13 +21,13 @@ FileSystem mockFileSystem = MemoryFileSystem( style: const LocalPlatform().isWindows ? FileSystemStyle.windows : FileSystemStyle.posix); -Directory mockPackagesDir; +late Directory mockPackagesDir; /// Creates a mock packages directory in the mock file system. /// /// If [parentDir] is set the mock packages dir will be creates as a child of /// it. If not [mockFileSystem] will be used instead. -void initializeFakePackages({Directory parentDir}) { +void initializeFakePackages({Directory? parentDir}) { mockPackagesDir = (parentDir ?? mockFileSystem.currentDirectory).childDirectory('packages'); mockPackagesDir.createSync(); @@ -51,7 +51,7 @@ Directory createFakePlugin( bool includeVersion = false, String version = '0.0.1', String parentDirectoryName = '', - Directory packagesDirectory, + Directory? packagesDirectory, }) { assert(!(withSingleExample && withExamples.isNotEmpty), 'cannot pass withSingleExample and withExamples simultaneously'); @@ -211,7 +211,8 @@ typedef _ErrorHandler = void Function(Error error); /// what was printed. /// A custom [errorHandler] can be used to handle the runner error as desired without throwing. Future> runCapturingPrint( - CommandRunner runner, List args, {_ErrorHandler errorHandler}) async { + CommandRunner runner, List args, + {_ErrorHandler? errorHandler}) async { final List prints = []; final ZoneSpecification spec = ZoneSpecification( print: (_, __, ___, String message) { @@ -220,8 +221,8 @@ Future> runCapturingPrint( ); try { await Zone.current - .fork(specification: spec) - .run>(() => runner.run(args)); + .fork(specification: spec) + .run>(() => runner.run(args)); } on Error catch (e) { if (errorHandler == null) { rethrow; @@ -234,25 +235,25 @@ Future> runCapturingPrint( /// A mock [ProcessRunner] which records process calls. class RecordingProcessRunner extends ProcessRunner { - io.Process processToReturn; + io.Process? processToReturn; final List recordedCalls = []; /// Populate for [io.ProcessResult] to use a String [stdout] instead of a [List] of [int]. - String resultStdout; + String? resultStdout; /// Populate for [io.ProcessResult] to use a String [stderr] instead of a [List] of [int]. - String resultStderr; + String? resultStderr; @override Future runAndStream( String executable, List args, { - Directory workingDir, + Directory? workingDir, bool exitOnError = false, }) async { recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); return Future.value( - processToReturn == null ? 0 : await processToReturn.exitCode); + processToReturn == null ? 0 : await processToReturn!.exitCode); } /// Returns [io.ProcessResult] created from [processToReturn], [resultStdout], and [resultStderr]. @@ -260,28 +261,26 @@ class RecordingProcessRunner extends ProcessRunner { Future run( String executable, List args, { - Directory workingDir, + Directory? workingDir, bool exitOnError = false, bool logOnError = false, Encoding stdoutEncoding = io.systemEncoding, Encoding stderrEncoding = io.systemEncoding, }) async { recordedCalls.add(ProcessCall(executable, args, workingDir?.path)); - io.ProcessResult result; + io.ProcessResult? result; - if (processToReturn != null) { - result = io.ProcessResult( - processToReturn.pid, - await processToReturn.exitCode, - resultStdout ?? processToReturn.stdout, - resultStderr ?? processToReturn.stderr); + final io.Process? process = processToReturn; + if (process != null) { + result = io.ProcessResult(process.pid, await process.exitCode, + resultStdout ?? process.stdout, resultStderr ?? process.stderr); } return Future.value(result); } @override Future start(String executable, List args, - {Directory workingDirectory}) async { + {Directory? workingDirectory}) async { recordedCalls.add(ProcessCall(executable, args, workingDirectory?.path)); return Future.value(processToReturn); } @@ -299,7 +298,7 @@ class ProcessCall { final List args; /// The working directory this process was called from. - final String workingDir; + final String? workingDir; @override bool operator ==(dynamic other) { @@ -311,10 +310,7 @@ class ProcessCall { @override int get hashCode => - executable?.hashCode ?? - 0 ^ args?.hashCode ?? - 0 ^ workingDir?.hashCode ?? - 0; + (executable.hashCode) ^ (args.hashCode) ^ (workingDir?.hashCode ?? 0); @override String toString() { diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index d67103f716a1..73e9aa7caa41 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; diff --git a/script/tool/test/xctest_command_test.dart b/script/tool/test/xctest_command_test.dart index 1707dc8cfb8d..53e82ac623e8 100644 --- a/script/tool/test/xctest_command_test.dart +++ b/script/tool/test/xctest_command_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// @dart=2.9 + import 'dart:convert'; import 'package:args/command_runner.dart'; From 95fab439bc7a84205a4a2f522b1d17280ce9aeb1 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 14 May 2021 16:05:26 -0400 Subject: [PATCH 4/6] Fix unnecessary nullable --- script/tool/lib/src/common.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 59ea6176cb34..e975ec1ebeb5 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -596,8 +596,8 @@ class PubVersionFinder { /// Get the package version on pub. Future getPackageVersion( - {required String? package}) async { - assert(package != null && package.isNotEmpty); + {required String package}) async { + assert(package.isNotEmpty); final Uri pubHostUri = Uri.parse(pubHost); final Uri url = pubHostUri.replace(path: '/packages/$package.json'); final http.Response response = await httpClient.get(url); From 208eba8e4a0a4b271fd44e2f08e0d85e585333fb Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 14 May 2021 16:28:05 -0400 Subject: [PATCH 5/6] Fix mock matchers to work on all calls --- script/tool/test/common_test.dart | 3 ++- script/tool/test/version_check_test.dart | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/script/tool/test/common_test.dart b/script/tool/test/common_test.dart index 8a708ef60e88..477e186aa24b 100644 --- a/script/tool/test/common_test.dart +++ b/script/tool/test/common_test.dart @@ -42,7 +42,8 @@ void main() { gitDirCommands = ?>[]; gitDiffResponse = ''; final MockGitDir gitDir = MockGitDir(); - when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { + when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) + .thenAnswer((Invocation invocation) { gitDirCommands.add(invocation.positionalArguments[0] as List?); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { diff --git a/script/tool/test/version_check_test.dart b/script/tool/test/version_check_test.dart index 73e9aa7caa41..cef2ab1cfad3 100644 --- a/script/tool/test/version_check_test.dart +++ b/script/tool/test/version_check_test.dart @@ -67,7 +67,8 @@ void main() { gitDiffResponse = ''; gitShowResponses = {}; gitDir = MockGitDir(); - when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) { + when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) + .thenAnswer((Invocation invocation) { gitDirCommands.add(invocation.positionalArguments[0] as List); final MockProcessResult mockProcessResult = MockProcessResult(); if (invocation.positionalArguments[0][0] == 'diff') { From 36da02c49aaa21696524ccdae738d98b55c2bd19 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 14 May 2021 16:36:00 -0400 Subject: [PATCH 6/6] Don't skip Flutter upgrade for podspect lint task --- .cirrus.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index e3d6f7881382..2598bfe7e426 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -194,6 +194,12 @@ task: << : *MACOS_TEMPLATE << : *FLUTTER_UPGRADE_TEMPLATE matrix: + ### iOS+macOS tasks *** + - name: lint_darwin_plugins + script: + # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. + - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm + - ./script/tool_runner.sh podspecs ### iOS tasks ### - name: build_all_plugins_ipa env: @@ -251,14 +257,3 @@ task: - ./script/tool_runner.sh build-examples --macos --no-ipa drive_script: - ./script/tool_runner.sh drive-examples --macos - -task: - # Don't use FLUTTER_UPGRADE_TEMPLATE, Flutter tooling not needed. - << : *MACOS_TEMPLATE - << : *TOOL_SETUP_TEMPLATE - matrix: - - name: lint_darwin_plugins - script: - # TODO(jmagman): Lint macOS podspecs but skip any that fail library validation. - - find . -name "*.podspec" | xargs grep -l "osx" | xargs rm - - ./script/tool_runner.sh podspecs