mirror of
https://github.com/flutter/packages.git
synced 2025-05-30 21:17:42 +08:00
Begin migrating tools to NNBD (#3891)
- Updates dependencies to null-safe versions - Migrates common.dart (which doesn't depend on anything) - Migrates common_tests.dart and its one dependency, utils.dart - Adds build_runner for Mockito mock generation - Adds a new utility methods for getting arguments that handle both the casting and the removal of nullability to address a common problematic pattern while migrating code. - Converts all files, not just the migrated ones, to those new helpers. Migrating common.dart and utils.dart should unblock a command-by-command migration to null safety. Reverts the separate of podspect lints into a step that doesn't do a Flutter upgrade (https://github.com/flutter/plugins/pull/3700) because without that step we had a version of Dart too old to run null-safe tooling. First step of https://github.com/flutter/flutter/issues/81912
This commit is contained in:
@ -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';
|
||||
|
@ -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';
|
||||
@ -42,8 +44,8 @@ class AnalyzeCommand extends PluginCommand {
|
||||
continue;
|
||||
}
|
||||
|
||||
final bool allowed = (argResults[_customAnalysisFlag] as List<String>)
|
||||
.any((String directory) =>
|
||||
final bool allowed = (getStringListArg(_customAnalysisFlag)).any(
|
||||
(String directory) =>
|
||||
directory != null &&
|
||||
directory.isNotEmpty &&
|
||||
p.isWithin(p.join(packagesDir.path, directory), file.path));
|
||||
|
@ -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;
|
||||
|
||||
@ -52,7 +54,7 @@ class BuildExamplesCommand extends PluginCommand {
|
||||
];
|
||||
final Map<String, bool> platforms = <String, bool>{
|
||||
for (final String platform in platformSwitches)
|
||||
platform: argResults[platform] as bool
|
||||
platform: getBoolArg(platform)
|
||||
};
|
||||
if (!platforms.values.any((bool enabled) => enabled)) {
|
||||
print(
|
||||
@ -63,7 +65,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<String> failingPackages = <String>[];
|
||||
await for (final Directory plugin in getPlugins()) {
|
||||
|
@ -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<void> {
|
||||
/// 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,12 +253,27 @@ abstract class PluginCommand extends Command<void> {
|
||||
if (_shardCount == null) {
|
||||
_checkSharding();
|
||||
}
|
||||
return _shardCount;
|
||||
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<String> arguments.
|
||||
List<String> getStringListArg(String key) {
|
||||
return (argResults![key] as List<String>?) ?? <String>[];
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
@ -317,12 +331,10 @@ abstract class PluginCommand extends Command<void> {
|
||||
/// is a sibling of the packages directory. This is used for a small number
|
||||
/// of packages in the flutter/packages repository.
|
||||
Stream<Directory> _getAllPlugins() async* {
|
||||
Set<String> plugins =
|
||||
Set<String>.from(argResults[_pluginsArg] as List<String>);
|
||||
Set<String> plugins = Set<String>.from(getStringListArg(_pluginsArg));
|
||||
final Set<String> excludedPlugins =
|
||||
Set<String>.from(argResults[_excludeArg] as List<String>);
|
||||
final bool runOnChangedPackages =
|
||||
argResults[_runOnChangedPackagesArg] as bool;
|
||||
Set<String>.from(getStringListArg(_excludeArg));
|
||||
final bool runOnChangedPackages = getBoolArg(_runOnChangedPackagesArg);
|
||||
if (plugins.isEmpty && runOnChangedPackages) {
|
||||
plugins = await _getChangedPackages();
|
||||
}
|
||||
@ -429,9 +441,9 @@ abstract class PluginCommand extends Command<void> {
|
||||
/// Throws tool exit if [gitDir] nor root directory is a git directory.
|
||||
Future<GitVersionFinder> retrieveVersionFinder() async {
|
||||
final String rootDir = packagesDir.parent.absolute.path;
|
||||
final String baseSha = argResults[_kBaseSha] as String;
|
||||
final String baseSha = getStringArg(_kBaseSha);
|
||||
|
||||
GitDir baseGitDir = gitDir;
|
||||
GitDir? baseGitDir = gitDir;
|
||||
if (baseGitDir == null) {
|
||||
if (!await GitDir.isGitDir(rootDir)) {
|
||||
printErrorAndExit(
|
||||
@ -490,7 +502,7 @@ class ProcessRunner {
|
||||
Future<int> runAndStream(
|
||||
String executable,
|
||||
List<String> args, {
|
||||
Directory workingDir,
|
||||
Directory? workingDir,
|
||||
bool exitOnError = false,
|
||||
}) async {
|
||||
print(
|
||||
@ -522,7 +534,7 @@ class ProcessRunner {
|
||||
///
|
||||
/// Returns the [io.ProcessResult] of the [executable].
|
||||
Future<io.ProcessResult> run(String executable, List<String> args,
|
||||
{Directory workingDir,
|
||||
{Directory? workingDir,
|
||||
bool exitOnError = false,
|
||||
bool logOnError = false,
|
||||
Encoding stdoutEncoding = io.systemEncoding,
|
||||
@ -550,15 +562,15 @@ class ProcessRunner {
|
||||
/// passing [workingDir].
|
||||
///
|
||||
/// Returns the started [io.Process].
|
||||
Future<io.Process> start(String executable, List<String> args,
|
||||
{Directory workingDirectory}) async {
|
||||
Future<io.Process?> start(String executable, List<String> args,
|
||||
{Directory? workingDirectory}) async {
|
||||
final io.Process process = await io.Process.start(executable, args,
|
||||
workingDirectory: workingDirectory?.path);
|
||||
return process;
|
||||
}
|
||||
|
||||
String _getErrorString(String executable, List<String> args,
|
||||
{Directory workingDir}) {
|
||||
{Directory? workingDir}) {
|
||||
final String workdir = workingDir == null ? '' : ' in ${workingDir.path}';
|
||||
return 'ERROR: Unable to execute "$executable ${args.join(' ')}"$workdir.';
|
||||
}
|
||||
@ -569,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';
|
||||
@ -584,8 +596,8 @@ class PubVersionFinder {
|
||||
|
||||
/// Get the package version on pub.
|
||||
Future<PubVersionFinderResponse> 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);
|
||||
@ -618,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);
|
||||
@ -631,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<Version> versions;
|
||||
final List<Version>? 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].
|
||||
@ -667,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');
|
||||
@ -684,8 +696,7 @@ class GitVersionFinder {
|
||||
final io.ProcessResult changedFilesCommand = await baseGitDir
|
||||
.runCommand(<String>['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 <String>[];
|
||||
}
|
||||
@ -696,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<Version> getPackageVersion(String pubspecPath, {String gitRef}) async {
|
||||
Future<Version?> getPackageVersion(String pubspecPath,
|
||||
{String? gitRef}) async {
|
||||
final String ref = gitRef ?? (await _getBaseSha());
|
||||
|
||||
io.ProcessResult gitShow;
|
||||
@ -707,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<String> _getBaseSha() async {
|
||||
if (baseSha != null && baseSha.isNotEmpty) {
|
||||
return baseSha;
|
||||
if (baseSha != null && baseSha!.isNotEmpty) {
|
||||
return baseSha!;
|
||||
}
|
||||
|
||||
io.ProcessResult baseShaFromMergeBase = await baseGitDir.runCommand(
|
||||
<String>['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(<String>['merge-base', 'FETCH_HEAD', 'HEAD']);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
@ -53,10 +55,10 @@ class DriveExamplesCommand extends PluginCommand {
|
||||
Future<void> run() async {
|
||||
final List<String> failingTests = <String>[];
|
||||
final List<String> pluginsWithoutTests = <String>[];
|
||||
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 pluginName = plugin.basename;
|
||||
if (pluginName.endsWith('_platform_interface') &&
|
||||
@ -140,8 +142,7 @@ Tried searching for the following:
|
||||
|
||||
final List<String> driveArgs = <String>['drive'];
|
||||
|
||||
final String enableExperiment =
|
||||
argResults[kEnableExperiment] as String;
|
||||
final String enableExperiment = getStringArg(kEnableExperiment);
|
||||
if (enableExperiment.isNotEmpty) {
|
||||
driveArgs.add('--enable-experiment=$enableExperiment');
|
||||
}
|
||||
@ -222,12 +223,12 @@ Tried searching for the following:
|
||||
|
||||
Future<bool> _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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
@ -30,7 +32,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. '
|
||||
@ -78,7 +80,7 @@ class FirebaseTestLabCommand extends PluginCommand {
|
||||
<String>[
|
||||
'auth',
|
||||
'activate-service-account',
|
||||
'--key-file=${argResults['service-key']}',
|
||||
'--key-file=${getStringArg('service-key')}',
|
||||
],
|
||||
exitOnError: true,
|
||||
logOnError: true,
|
||||
@ -87,7 +89,7 @@ class FirebaseTestLabCommand extends PluginCommand {
|
||||
'config',
|
||||
'set',
|
||||
'project',
|
||||
argResults['project'] as String,
|
||||
getStringArg('project'),
|
||||
]);
|
||||
if (exitCode == 0) {
|
||||
_print('\nFirebase project configured.');
|
||||
@ -125,7 +127,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 +215,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<String> args = <String>[
|
||||
@ -229,10 +231,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<String>) {
|
||||
for (final String device in getStringListArg('device')) {
|
||||
args.addAll(<String>['--device', device]);
|
||||
}
|
||||
exitCode = await processRunner.runAndStream('gcloud', args,
|
||||
|
@ -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;
|
||||
@ -13,8 +15,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 {
|
||||
@ -47,7 +49,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 +107,7 @@ class FormatCommand extends PluginCommand {
|
||||
// 'ProcessException: Argument list too long'.
|
||||
final Iterable<List<String>> batches = partition(allFiles, 100);
|
||||
for (final List<String> batch in batches) {
|
||||
await processRunner.runAndStream(argResults['clang-format'] as String,
|
||||
await processRunner.runAndStream(getStringArg('clang-format'),
|
||||
<String>['-i', '--style=Google', ...batch],
|
||||
workingDir: packagesDir, exitOnError: true);
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
@ -89,7 +91,7 @@ class LintPodspecsCommand extends PluginCommand {
|
||||
final List<File> podspecs = await getFiles().where((File entity) {
|
||||
final String filePath = entity.path;
|
||||
return p.extension(filePath) == '.podspec' &&
|
||||
!(argResults['skip'] as List<String>)
|
||||
!getStringListArg('skip')
|
||||
.contains(p.basenameWithoutExtension(filePath));
|
||||
}).toList();
|
||||
|
||||
@ -122,7 +124,7 @@ class LintPodspecsCommand extends PluginCommand {
|
||||
|
||||
Future<ProcessResult> _runPodLint(String podspecPath,
|
||||
{bool libraryLint}) async {
|
||||
final bool allowWarnings = (argResults['ignore-warnings'] as List<String>)
|
||||
final bool allowWarnings = (getStringListArg('ignore-warnings'))
|
||||
.contains(p.basenameWithoutExtension(podspecPath));
|
||||
final List<String> arguments = <String>[
|
||||
'lib',
|
||||
|
@ -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';
|
||||
@ -36,7 +38,7 @@ class ListCommand extends PluginCommand {
|
||||
|
||||
@override
|
||||
Future<void> run() async {
|
||||
switch (argResults[_type] as String) {
|
||||
switch (getStringArg(_type)) {
|
||||
case _plugin:
|
||||
await for (final Directory package in getPlugins()) {
|
||||
print(package.path);
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
@ -78,7 +80,7 @@ class PublishCheckCommand extends PluginCommand {
|
||||
Future<void> run() async {
|
||||
final ZoneSpecification logSwitchSpecification = ZoneSpecification(
|
||||
print: (Zone self, ZoneDelegate parent, Zone zone, String message) {
|
||||
final bool logMachineMessage = argResults[_machineFlag] as bool;
|
||||
final bool logMachineMessage = getBoolArg(_machineFlag);
|
||||
if (logMachineMessage && message != _prettyJson(_machineOutput)) {
|
||||
_humanMessages.add(message);
|
||||
} else {
|
||||
@ -123,7 +125,7 @@ class PublishCheckCommand extends PluginCommand {
|
||||
isError: false);
|
||||
}
|
||||
|
||||
if (argResults[_machineFlag] as bool) {
|
||||
if (getBoolArg(_machineFlag)) {
|
||||
_setStatus(status);
|
||||
_machineOutput[_humanMessageKey] = _humanMessages;
|
||||
print(_prettyJson(_machineOutput));
|
||||
@ -184,7 +186,7 @@ class PublishCheckCommand extends PluginCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(argResults[_allowPrereleaseFlag] as bool)) {
|
||||
if (!getBoolArg(_allowPrereleaseFlag)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -270,7 +272,7 @@ HTTP response: ${pubVersionFinderResponse.httpResponse.body}
|
||||
|
||||
void _printImportantStatusMessage(String message, {@required bool isError}) {
|
||||
final String statusMessage = '${isError ? 'ERROR' : 'SUCCESS'}: $message';
|
||||
if (argResults[_machineFlag] as bool) {
|
||||
if (getBoolArg(_machineFlag)) {
|
||||
print(statusMessage);
|
||||
} else {
|
||||
final Colorize colorizedMessage = Colorize(statusMessage);
|
||||
|
@ -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;
|
||||
@ -122,9 +124,9 @@ class PublishPluginCommand extends PluginCommand {
|
||||
|
||||
@override
|
||||
Future<void> run() async {
|
||||
final String package = argResults[_packageOption] as String;
|
||||
final bool publishAllChanged = argResults[_allChangedFlag] as bool;
|
||||
if (package == null && !publishAllChanged) {
|
||||
final String package = getStringArg(_packageOption);
|
||||
final bool publishAllChanged = getBoolArg(_allChangedFlag);
|
||||
if (package.isEmpty && !publishAllChanged) {
|
||||
_print(
|
||||
'Must specify a package to publish. See `plugin_tools help publish-plugin`.');
|
||||
throw ToolExit(1);
|
||||
@ -138,14 +140,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 ===============');
|
||||
}
|
||||
|
||||
@ -244,7 +246,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,
|
||||
@ -333,7 +335,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',
|
||||
<String>['tag', tag],
|
||||
@ -416,15 +418,14 @@ Safe to ignore if the package is deleted in this commit.
|
||||
}
|
||||
|
||||
Future<bool> _publish(Directory packageDir) async {
|
||||
final List<String> publishFlags =
|
||||
argResults[_pubFlagsOption] as List<String>;
|
||||
final List<String> publishFlags = getStringListArg(_pubFlagsOption);
|
||||
_print(
|
||||
'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n');
|
||||
if (argResults[_dryRunFlag] as bool) {
|
||||
if (getBoolArg(_dryRunFlag)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argResults[_skipConfirmationFlag] as bool) {
|
||||
if (getBoolArg(_skipConfirmationFlag)) {
|
||||
publishFlags.add('--force');
|
||||
}
|
||||
if (publishFlags.contains('--force')) {
|
||||
@ -474,7 +475,7 @@ Safe to ignore if the package is deleted in this commit.
|
||||
@required String remoteUrl,
|
||||
}) async {
|
||||
assert(remote != null && tag != null && remoteUrl != null);
|
||||
if (!(argResults[_skipConfirmationFlag] as bool)) {
|
||||
if (!getBoolArg(_skipConfirmationFlag)) {
|
||||
_print('Ready to push $tag to $remoteUrl (y/n)?');
|
||||
final String input = _stdin.readLineSync();
|
||||
if (input.toLowerCase() != 'y') {
|
||||
@ -482,7 +483,7 @@ Safe to ignore if the package is deleted in this commit.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!(argResults[_dryRunFlag] as bool)) {
|
||||
if (!getBoolArg(_dryRunFlag)) {
|
||||
final io.ProcessResult result = await processRunner.run(
|
||||
'git',
|
||||
<String>['push', remote, tag],
|
||||
|
@ -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';
|
||||
@ -44,7 +46,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;
|
||||
|
@ -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';
|
||||
@ -135,7 +137,7 @@ class VersionCheckCommand extends PluginCommand {
|
||||
'"publish_to: none".');
|
||||
}
|
||||
Version sourceVersion;
|
||||
if (argResults[_againstPubFlag] as bool) {
|
||||
if (getBoolArg(_againstPubFlag)) {
|
||||
final String packageName = pubspecFile.parent.basename;
|
||||
final PubVersionFinderResponse pubVersionFinderResponse =
|
||||
await _pubVersionFinder.getPackageVersion(package: packageName);
|
||||
@ -161,7 +163,7 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body}
|
||||
}
|
||||
if (sourceVersion == null) {
|
||||
String safeToIgnoreMessage;
|
||||
if (argResults[_againstPubFlag] as bool) {
|
||||
if (getBoolArg(_againstPubFlag)) {
|
||||
safeToIgnoreMessage =
|
||||
'${indentation}Unable to find package on pub server.';
|
||||
} else {
|
||||
@ -181,8 +183,7 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body}
|
||||
getAllowedNextVersions(sourceVersion, headVersion);
|
||||
|
||||
if (!allowedNextVersions.containsKey(headVersion)) {
|
||||
final String source =
|
||||
(argResults[_againstPubFlag] as bool) ? 'pub' : 'master';
|
||||
final String source = (getBoolArg(_againstPubFlag)) ? 'pub' : 'master';
|
||||
final String error = '${indentation}Incorrectly updated version.\n'
|
||||
'${indentation}HEAD: $headVersion, $source: $sourceVersion.\n'
|
||||
'${indentation}Allowed versions: $allowedNextVersions';
|
||||
|
@ -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;
|
||||
@ -48,8 +50,8 @@ class XCTestCommand extends PluginCommand {
|
||||
|
||||
@override
|
||||
Future<void> run() async {
|
||||
String destination = argResults[_kiOSDestination] as String;
|
||||
if (destination == null) {
|
||||
String destination = getStringArg(_kiOSDestination);
|
||||
if (destination.isEmpty) {
|
||||
final String simulatorId = await _findAvailableIphoneSimulator();
|
||||
if (simulatorId == null) {
|
||||
print(_kFoundNoSimulatorsMessage);
|
||||
@ -58,7 +60,7 @@ class XCTestCommand extends PluginCommand {
|
||||
destination = 'id=$simulatorId';
|
||||
}
|
||||
|
||||
final List<String> skipped = argResults[_kSkip] as List<String>;
|
||||
final List<String> skipped = getStringListArg(_kSkip);
|
||||
|
||||
final List<String> failingPackages = <String>[];
|
||||
await for (final Directory plugin in getPlugins()) {
|
||||
|
@ -4,28 +4,29 @@ repository: https://github.com/flutter/plugins/tree/master/script/tool
|
||||
version: 0.1.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
|
||||
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'
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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(<Type>[GitDir])
|
||||
void main() {
|
||||
RecordingProcessRunner processRunner;
|
||||
CommandRunner<void> runner;
|
||||
FileSystem fileSystem;
|
||||
Directory packagesDir;
|
||||
Directory thirdPartyPackagesDir;
|
||||
List<String> plugins;
|
||||
List<List<String>> gitDirCommands;
|
||||
String gitDiffResponse;
|
||||
late RecordingProcessRunner processRunner;
|
||||
late CommandRunner<void> runner;
|
||||
late FileSystem fileSystem;
|
||||
late Directory packagesDir;
|
||||
late Directory thirdPartyPackagesDir;
|
||||
late List<String> plugins;
|
||||
late List<List<String>?> gitDirCommands;
|
||||
late String gitDiffResponse;
|
||||
|
||||
setUp(() {
|
||||
fileSystem = MemoryFileSystem();
|
||||
@ -35,14 +39,15 @@ void main() {
|
||||
.childDirectory('third_party')
|
||||
.childDirectory('packages');
|
||||
|
||||
gitDirCommands = <List<String>>[];
|
||||
gitDirCommands = <List<String>?>[];
|
||||
gitDiffResponse = '';
|
||||
final MockGitDir gitDir = MockGitDir();
|
||||
when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) {
|
||||
gitDirCommands.add(invocation.positionalArguments[0] as List<String>);
|
||||
when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError')))
|
||||
.thenAnswer((Invocation invocation) {
|
||||
gitDirCommands.add(invocation.positionalArguments[0] as List<String>?);
|
||||
final MockProcessResult mockProcessResult = MockProcessResult();
|
||||
if (invocation.positionalArguments[0][0] == 'diff') {
|
||||
when<String>(mockProcessResult.stdout as String)
|
||||
when<String?>(mockProcessResult.stdout as String?)
|
||||
.thenReturn(gitDiffResponse);
|
||||
}
|
||||
return Future<ProcessResult>.value(mockProcessResult);
|
||||
@ -255,23 +260,24 @@ packages/plugin3/plugin3.dart
|
||||
});
|
||||
|
||||
group('$GitVersionFinder', () {
|
||||
List<List<String>> gitDirCommands;
|
||||
String gitDiffResponse;
|
||||
String mergeBaseResponse;
|
||||
MockGitDir gitDir;
|
||||
late List<List<String>?> gitDirCommands;
|
||||
late String gitDiffResponse;
|
||||
String? mergeBaseResponse;
|
||||
late MockGitDir gitDir;
|
||||
|
||||
setUp(() {
|
||||
gitDirCommands = <List<String>>[];
|
||||
gitDirCommands = <List<String>?>[];
|
||||
gitDiffResponse = '';
|
||||
gitDir = MockGitDir();
|
||||
when(gitDir.runCommand(any)).thenAnswer((Invocation invocation) {
|
||||
gitDirCommands.add(invocation.positionalArguments[0] as List<String>);
|
||||
when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError')))
|
||||
.thenAnswer((Invocation invocation) {
|
||||
gitDirCommands.add(invocation.positionalArguments[0] as List<String>?);
|
||||
final MockProcessResult mockProcessResult = MockProcessResult();
|
||||
if (invocation.positionalArguments[0][0] == 'diff') {
|
||||
when<String>(mockProcessResult.stdout as String)
|
||||
when<String?>(mockProcessResult.stdout as String?)
|
||||
.thenReturn(gitDiffResponse);
|
||||
} else if (invocation.positionalArguments[0][0] == 'merge-base') {
|
||||
when<String>(mockProcessResult.stdout as String)
|
||||
when<String?>(mockProcessResult.stdout as String?)
|
||||
.thenReturn(mergeBaseResponse);
|
||||
}
|
||||
return Future<ProcessResult>.value(mockProcessResult);
|
||||
@ -320,10 +326,11 @@ file2/file2.cc
|
||||
file1/pubspec.yaml
|
||||
file2/file2.cc
|
||||
''';
|
||||
|
||||
final GitVersionFinder finder = GitVersionFinder(gitDir, null);
|
||||
await finder.getChangedFiles();
|
||||
verify(gitDir.runCommand(
|
||||
<String>['diff', '--name-only', mergeBaseResponse, 'HEAD']));
|
||||
<String>['diff', '--name-only', mergeBaseResponse!, 'HEAD']));
|
||||
});
|
||||
|
||||
test('use correct base sha if specified', () async {
|
||||
@ -350,8 +357,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 +371,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 +415,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 +427,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 +447,4 @@ class SamplePluginCommand extends PluginCommand {
|
||||
}
|
||||
}
|
||||
|
||||
class MockGitDir extends Mock implements GitDir {}
|
||||
|
||||
class MockProcessResult extends Mock implements ProcessResult {}
|
||||
|
143
script/tool/test/common_test.mocks.dart
Normal file
143
script/tool/test/common_test.mocks.dart
Normal file
@ -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<int> commitCount([String? branchName = r'HEAD']) =>
|
||||
(super.noSuchMethod(Invocation.method(#commitCount, [branchName]),
|
||||
returnValue: Future<int>.value(0)) as _i6.Future<int>);
|
||||
@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<Map<String, _i2.Commit>> commits([String? branchName = r'HEAD']) =>
|
||||
(super.noSuchMethod(Invocation.method(#commits, [branchName]),
|
||||
returnValue:
|
||||
Future<Map<String, _i2.Commit>>.value(<String, _i2.Commit>{}))
|
||||
as _i6.Future<Map<String, _i2.Commit>>);
|
||||
@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<List<_i3.BranchReference>> branches() => (super.noSuchMethod(
|
||||
Invocation.method(#branches, []),
|
||||
returnValue:
|
||||
Future<List<_i3.BranchReference>>.value(<_i3.BranchReference>[]))
|
||||
as _i6.Future<List<_i3.BranchReference>>);
|
||||
@override
|
||||
_i6.Stream<_i7.Tag> tags() =>
|
||||
(super.noSuchMethod(Invocation.method(#tags, []),
|
||||
returnValue: Stream<_i7.Tag>.empty()) as _i6.Stream<_i7.Tag>);
|
||||
@override
|
||||
_i6.Future<List<_i8.CommitReference>> showRef(
|
||||
{bool? heads = false, bool? tags = false}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#showRef, [], {#heads: heads, #tags: tags}),
|
||||
returnValue: Future<List<_i8.CommitReference>>.value(
|
||||
<_i8.CommitReference>[]))
|
||||
as _i6.Future<List<_i8.CommitReference>>);
|
||||
@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<List<_i9.TreeEntry>> lsTree(String? treeish,
|
||||
{bool? subTreesOnly = false, String? path}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#lsTree, [treeish],
|
||||
{#subTreesOnly: subTreesOnly, #path: path}),
|
||||
returnValue: Future<List<_i9.TreeEntry>>.value(<_i9.TreeEntry>[]))
|
||||
as _i6.Future<List<_i9.TreeEntry>>);
|
||||
@override
|
||||
_i6.Future<String?> createOrUpdateBranch(
|
||||
String? branchName, String? treeSha, String? commitMessage) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createOrUpdateBranch, [branchName, treeSha, commitMessage]),
|
||||
returnValue: Future<String?>.value('')) as _i6.Future<String?>);
|
||||
@override
|
||||
_i6.Future<String> commitTree(String? treeSha, String? commitMessage,
|
||||
{List<String>? parentCommitShas}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#commitTree, [treeSha, commitMessage],
|
||||
{#parentCommitShas: parentCommitShas}),
|
||||
returnValue: Future<String>.value('')) as _i6.Future<String>);
|
||||
@override
|
||||
_i6.Future<Map<String, String>> writeObjects(List<String>? paths) =>
|
||||
(super.noSuchMethod(Invocation.method(#writeObjects, [paths]),
|
||||
returnValue:
|
||||
Future<Map<String, String>>.value(<String, String>{}))
|
||||
as _i6.Future<Map<String, String>>);
|
||||
@override
|
||||
_i6.Future<_i4.ProcessResult> runCommand(Iterable<String>? 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<bool> isWorkingTreeClean() =>
|
||||
(super.noSuchMethod(Invocation.method(#isWorkingTreeClean, []),
|
||||
returnValue: Future<bool>.value(false)) as _i6.Future<bool>);
|
||||
@override
|
||||
_i6.Future<_i2.Commit?> updateBranch(
|
||||
String? branchName,
|
||||
_i6.Future<dynamic> 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?>);
|
||||
}
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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';
|
||||
|
@ -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<List<String>> runCapturingPrint(
|
||||
CommandRunner<void> runner, List<String> args, {_ErrorHandler errorHandler}) async {
|
||||
CommandRunner<void> runner, List<String> args,
|
||||
{_ErrorHandler? errorHandler}) async {
|
||||
final List<String> prints = <String>[];
|
||||
final ZoneSpecification spec = ZoneSpecification(
|
||||
print: (_, __, ___, String message) {
|
||||
@ -220,8 +221,8 @@ Future<List<String>> runCapturingPrint(
|
||||
);
|
||||
try {
|
||||
await Zone.current
|
||||
.fork(specification: spec)
|
||||
.run<Future<void>>(() => runner.run(args));
|
||||
.fork(specification: spec)
|
||||
.run<Future<void>>(() => runner.run(args));
|
||||
} on Error catch (e) {
|
||||
if (errorHandler == null) {
|
||||
rethrow;
|
||||
@ -234,25 +235,25 @@ Future<List<String>> runCapturingPrint(
|
||||
|
||||
/// A mock [ProcessRunner] which records process calls.
|
||||
class RecordingProcessRunner extends ProcessRunner {
|
||||
io.Process processToReturn;
|
||||
io.Process? processToReturn;
|
||||
final List<ProcessCall> recordedCalls = <ProcessCall>[];
|
||||
|
||||
/// 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<int> runAndStream(
|
||||
String executable,
|
||||
List<String> args, {
|
||||
Directory workingDir,
|
||||
Directory? workingDir,
|
||||
bool exitOnError = false,
|
||||
}) async {
|
||||
recordedCalls.add(ProcessCall(executable, args, workingDir?.path));
|
||||
return Future<int>.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<io.ProcessResult> run(
|
||||
String executable,
|
||||
List<String> 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<io.ProcessResult>.value(result);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<io.Process> start(String executable, List<String> args,
|
||||
{Directory workingDirectory}) async {
|
||||
{Directory? workingDirectory}) async {
|
||||
recordedCalls.add(ProcessCall(executable, args, workingDirectory?.path));
|
||||
return Future<io.Process>.value(processToReturn);
|
||||
}
|
||||
@ -299,7 +298,7 @@ class ProcessCall {
|
||||
final List<String> 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() {
|
||||
|
@ -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;
|
||||
@ -65,7 +67,8 @@ void main() {
|
||||
gitDiffResponse = '';
|
||||
gitShowResponses = <String, String>{};
|
||||
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<String>);
|
||||
final MockProcessResult mockProcessResult = MockProcessResult();
|
||||
if (invocation.positionalArguments[0][0] == 'diff') {
|
||||
|
@ -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';
|
||||
|
Reference in New Issue
Block a user