mirror of
https://github.com/flutter/packages.git
synced 2025-05-30 21:17:42 +08:00
[ci] Run analysis with older versions of Flutter (#5000)
This commit is contained in:
@ -10,12 +10,9 @@ import 'package:yaml/yaml.dart';
|
||||
|
||||
import 'common/core.dart';
|
||||
import 'common/package_looping_command.dart';
|
||||
import 'common/plugin_command.dart';
|
||||
import 'common/process_runner.dart';
|
||||
import 'common/repository_package.dart';
|
||||
|
||||
const int _exitPackagesGetFailed = 3;
|
||||
|
||||
/// A command to run Dart analysis on packages.
|
||||
class AnalyzeCommand extends PackageLoopingCommand {
|
||||
/// Creates a analysis command instance.
|
||||
@ -84,41 +81,8 @@ class AnalyzeCommand extends PackageLoopingCommand {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Ensures that the dependent packages have been fetched for all packages
|
||||
/// (including their sub-packages) that will be analyzed.
|
||||
Future<bool> _runPackagesGetOnTargetPackages() async {
|
||||
final List<Directory> packageDirectories =
|
||||
await getTargetPackagesAndSubpackages()
|
||||
.map((PackageEnumerationEntry entry) => entry.package.directory)
|
||||
.toList();
|
||||
final Set<String> packagePaths =
|
||||
packageDirectories.map((Directory dir) => dir.path).toSet();
|
||||
packageDirectories.removeWhere((Directory directory) {
|
||||
// Remove the 'example' subdirectories; 'flutter packages get'
|
||||
// automatically runs 'pub get' there as part of handling the parent
|
||||
// directory.
|
||||
return directory.basename == 'example' &&
|
||||
packagePaths.contains(directory.parent.path);
|
||||
});
|
||||
for (final Directory package in packageDirectories) {
|
||||
final int exitCode = await processRunner.runAndStream(
|
||||
flutterCommand, <String>['packages', 'get'],
|
||||
workingDir: package);
|
||||
if (exitCode != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> initializeRun() async {
|
||||
print('Fetching dependencies...');
|
||||
if (!await _runPackagesGetOnTargetPackages()) {
|
||||
printError('Unable to get dependencies.');
|
||||
throw ToolExit(_exitPackagesGetFailed);
|
||||
}
|
||||
|
||||
_allowedCustomAnalysisDirectories =
|
||||
getStringListArg(_customAnalysisFlag).expand<String>((String item) {
|
||||
if (item.endsWith('.yaml')) {
|
||||
@ -138,6 +102,19 @@ class AnalyzeCommand extends PackageLoopingCommand {
|
||||
|
||||
@override
|
||||
Future<PackageResult> runForPackage(RepositoryPackage package) async {
|
||||
// For non-example packages, fetch dependencies. 'flutter packages get'
|
||||
// automatically runs 'pub get' in examples as part of handling the parent
|
||||
// directory, which is guaranteed to come first in the package enumeration.
|
||||
if (package.directory.basename != 'example' ||
|
||||
!RepositoryPackage(package.directory.parent).pubspecFile.existsSync()) {
|
||||
final int exitCode = await processRunner.runAndStream(
|
||||
flutterCommand, <String>['packages', 'get'],
|
||||
workingDir: package.directory);
|
||||
if (exitCode != 0) {
|
||||
return PackageResult.fail(<String>['Unable to get dependencies']);
|
||||
}
|
||||
}
|
||||
|
||||
if (_hasUnexpecetdAnalysisOptions(package)) {
|
||||
return PackageResult.fail(<String>['Unexpected local analysis options']);
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import 'package:file/file.dart';
|
||||
import 'package:git/git.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:pub_semver/pub_semver.dart';
|
||||
import 'package:pubspec_parse/pubspec_parse.dart';
|
||||
|
||||
import 'core.dart';
|
||||
import 'plugin_command.dart';
|
||||
@ -75,7 +77,16 @@ abstract class PackageLoopingCommand extends PluginCommand {
|
||||
Platform platform = const LocalPlatform(),
|
||||
GitDir? gitDir,
|
||||
}) : super(packagesDir,
|
||||
processRunner: processRunner, platform: platform, gitDir: gitDir);
|
||||
processRunner: processRunner, platform: platform, gitDir: gitDir) {
|
||||
argParser.addOption(
|
||||
_skipByFlutterVersionArg,
|
||||
help: 'Skip any packages that require a Flutter version newer than '
|
||||
'the provided version.',
|
||||
);
|
||||
}
|
||||
|
||||
static const String _skipByFlutterVersionArg =
|
||||
'skip-if-not-supporting-flutter-version';
|
||||
|
||||
/// Packages that had at least one [logWarning] call.
|
||||
final Set<PackageEnumerationEntry> _packagesWithWarnings =
|
||||
@ -219,6 +230,11 @@ abstract class PackageLoopingCommand extends PluginCommand {
|
||||
_otherWarningCount = 0;
|
||||
_currentPackageEntry = null;
|
||||
|
||||
final String minFlutterVersionArg = getStringArg(_skipByFlutterVersionArg);
|
||||
final Version? minFlutterVersion = minFlutterVersionArg.isEmpty
|
||||
? null
|
||||
: Version.parse(minFlutterVersionArg);
|
||||
|
||||
final DateTime runStart = DateTime.now();
|
||||
|
||||
await initializeRun();
|
||||
@ -242,7 +258,8 @@ abstract class PackageLoopingCommand extends PluginCommand {
|
||||
|
||||
PackageResult result;
|
||||
try {
|
||||
result = await runForPackage(entry.package);
|
||||
result = await _runForPackageIfSupported(entry.package,
|
||||
minFlutterVersion: minFlutterVersion);
|
||||
} catch (e, stack) {
|
||||
printError(e.toString());
|
||||
printError(stack.toString());
|
||||
@ -285,6 +302,26 @@ abstract class PackageLoopingCommand extends PluginCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Returns the result of running [runForPackage] if the package is supported
|
||||
/// by any run constraints, or a skip result if it is not.
|
||||
Future<PackageResult> _runForPackageIfSupported(
|
||||
RepositoryPackage package, {
|
||||
Version? minFlutterVersion,
|
||||
}) async {
|
||||
if (minFlutterVersion != null) {
|
||||
final Pubspec pubspec = package.parsePubspec();
|
||||
final VersionConstraint? flutterConstraint =
|
||||
pubspec.environment?['flutter'];
|
||||
if (flutterConstraint != null &&
|
||||
!flutterConstraint.allows(minFlutterVersion)) {
|
||||
return PackageResult.skip(
|
||||
'Does not support Flutter ${minFlutterVersion.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
return await runForPackage(package);
|
||||
}
|
||||
|
||||
void _printSuccess(String message) {
|
||||
captureOutput ? print(message) : printSuccess(message);
|
||||
}
|
||||
|
@ -409,6 +409,9 @@ abstract class PluginCommand extends Command<void> {
|
||||
///
|
||||
/// By default, packages excluded via --exclude will not be in the stream, but
|
||||
/// they can be included by passing false for [filterExcluded].
|
||||
///
|
||||
/// Subpackages are guaranteed to be after the containing package in the
|
||||
/// stream.
|
||||
Stream<PackageEnumerationEntry> getTargetPackagesAndSubpackages(
|
||||
{bool filterExcluded = true}) async* {
|
||||
await for (final PackageEnumerationEntry plugin
|
||||
|
Reference in New Issue
Block a user