mirror of
https://github.com/flutter/packages.git
synced 2025-05-31 05:30:36 +08:00
[tools] Convert test utils to RepositoryPackage (#5605)
This commit is contained in:
@ -30,14 +30,22 @@ const String platformWindows = 'windows';
|
||||
/// Key for enable experiment.
|
||||
const String kEnableExperiment = 'enable-experiment';
|
||||
|
||||
/// Target platforms supported by Flutter.
|
||||
// ignore: public_member_api_docs
|
||||
enum FlutterPlatform { android, ios, linux, macos, web, windows }
|
||||
|
||||
/// Returns whether the given directory is a Dart package.
|
||||
bool isPackage(FileSystemEntity entity) {
|
||||
if (entity is! Directory) {
|
||||
return false;
|
||||
}
|
||||
// Per https://dart.dev/guides/libraries/create-library-packages#what-makes-a-library-package
|
||||
return entity.childFile('pubspec.yaml').existsSync() &&
|
||||
entity.childDirectory('lib').existsSync();
|
||||
// According to
|
||||
// https://dart.dev/guides/libraries/create-library-packages#what-makes-a-library-package
|
||||
// a package must also have a `lib/` directory, but in practice that's not
|
||||
// always true. flutter/plugins has some special cases (espresso, some
|
||||
// federated implementation packages) that don't have any source, so this
|
||||
// deliberately doesn't check that there's a lib directory.
|
||||
return entity.childFile('pubspec.yaml').existsSync();
|
||||
}
|
||||
|
||||
/// Prints `successMessage` in green.
|
||||
|
@ -6,6 +6,7 @@ import 'package:file/file.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
import 'process_runner.dart';
|
||||
import 'repository_package.dart';
|
||||
|
||||
const String _gradleWrapperWindows = 'gradlew.bat';
|
||||
const String _gradleWrapperNonWindows = 'gradlew';
|
||||
@ -21,7 +22,7 @@ class GradleProject {
|
||||
});
|
||||
|
||||
/// The directory of a Flutter project to run Gradle commands in.
|
||||
final Directory flutterProject;
|
||||
final RepositoryPackage flutterProject;
|
||||
|
||||
/// The [ProcessRunner] used to run commands. Overridable for testing.
|
||||
final ProcessRunner processRunner;
|
||||
@ -30,7 +31,8 @@ class GradleProject {
|
||||
final Platform platform;
|
||||
|
||||
/// The project's 'android' directory.
|
||||
Directory get androidDirectory => flutterProject.childDirectory('android');
|
||||
Directory get androidDirectory =>
|
||||
flutterProject.platformDirectory(FlutterPlatform.android);
|
||||
|
||||
/// The path to the Gradle wrapper file for the project.
|
||||
File get gradleWrapper => androidDirectory.childFile(
|
||||
|
@ -368,7 +368,7 @@ abstract class PluginCommand extends Command<void> {
|
||||
await for (final FileSystemEntity entity
|
||||
in dir.list(followLinks: false)) {
|
||||
// A top-level Dart package is a plugin package.
|
||||
if (_isDartPackage(entity)) {
|
||||
if (isPackage(entity)) {
|
||||
if (packages.isEmpty || packages.contains(p.basename(entity.path))) {
|
||||
yield PackageEnumerationEntry(
|
||||
RepositoryPackage(entity as Directory),
|
||||
@ -378,7 +378,7 @@ abstract class PluginCommand extends Command<void> {
|
||||
// Look for Dart packages under this top-level directory.
|
||||
await for (final FileSystemEntity subdir
|
||||
in entity.list(followLinks: false)) {
|
||||
if (_isDartPackage(subdir)) {
|
||||
if (isPackage(subdir)) {
|
||||
// There are three ways for a federated plugin to match:
|
||||
// - package name (path_provider_android)
|
||||
// - fully specified name (path_provider/path_provider_android)
|
||||
@ -427,9 +427,9 @@ abstract class PluginCommand extends Command<void> {
|
||||
{bool filterExcluded = true}) async* {
|
||||
yield* package.directory
|
||||
.list(recursive: true, followLinks: false)
|
||||
.where(_isDartPackage)
|
||||
.where(isPackage)
|
||||
.map((FileSystemEntity directory) =>
|
||||
// _isDartPackage guarantees that this cast is valid.
|
||||
// isPackage guarantees that this cast is valid.
|
||||
RepositoryPackage(directory as Directory));
|
||||
}
|
||||
|
||||
@ -448,12 +448,6 @@ abstract class PluginCommand extends Command<void> {
|
||||
.cast<File>();
|
||||
}
|
||||
|
||||
/// Returns whether the specified entity is a directory containing a
|
||||
/// `pubspec.yaml` file.
|
||||
bool _isDartPackage(FileSystemEntity entity) {
|
||||
return entity is Directory && entity.childFile('pubspec.yaml').existsSync();
|
||||
}
|
||||
|
||||
/// Retrieve an instance of [GitVersionFinder] based on `_baseShaArg` and [gitDir].
|
||||
///
|
||||
/// Throws tool exit if [gitDir] nor root directory is a git directory.
|
||||
|
@ -9,6 +9,7 @@ import 'package:pubspec_parse/pubspec_parse.dart';
|
||||
import 'core.dart';
|
||||
|
||||
export 'package:pubspec_parse/pubspec_parse.dart' show Pubspec;
|
||||
export 'core.dart' show FlutterPlatform;
|
||||
|
||||
/// A package in the repository.
|
||||
//
|
||||
@ -53,6 +54,44 @@ class RepositoryPackage {
|
||||
/// The package's top-level README.
|
||||
File get readmeFile => directory.childFile('README.md');
|
||||
|
||||
/// The package's top-level README.
|
||||
File get changelogFile => directory.childFile('CHANGELOG.md');
|
||||
|
||||
/// The package's top-level README.
|
||||
File get authorsFile => directory.childFile('AUTHORS');
|
||||
|
||||
/// The lib directory containing the package's code.
|
||||
Directory get libDirectory => directory.childDirectory('lib');
|
||||
|
||||
/// The test directory containing the package's Dart tests.
|
||||
Directory get testDirectory => directory.childDirectory('test');
|
||||
|
||||
/// Returns the directory containing support for [platform].
|
||||
Directory platformDirectory(FlutterPlatform platform) {
|
||||
late final String directoryName;
|
||||
switch (platform) {
|
||||
case FlutterPlatform.android:
|
||||
directoryName = 'android';
|
||||
break;
|
||||
case FlutterPlatform.ios:
|
||||
directoryName = 'ios';
|
||||
break;
|
||||
case FlutterPlatform.linux:
|
||||
directoryName = 'linux';
|
||||
break;
|
||||
case FlutterPlatform.macos:
|
||||
directoryName = 'macos';
|
||||
break;
|
||||
case FlutterPlatform.web:
|
||||
directoryName = 'web';
|
||||
break;
|
||||
case FlutterPlatform.windows:
|
||||
directoryName = 'windows';
|
||||
break;
|
||||
}
|
||||
return directory.childDirectory(directoryName);
|
||||
}
|
||||
|
||||
late final Pubspec _parsedPubspec =
|
||||
Pubspec.parse(pubspecFile.readAsStringSync());
|
||||
|
||||
|
@ -30,11 +30,14 @@ class CreateAllPluginsAppCommand extends PluginCommand {
|
||||
'Defaults to the repository root.');
|
||||
}
|
||||
|
||||
/// The location of the synthesized app project.
|
||||
Directory get appDirectory => packagesDir.fileSystem
|
||||
/// The location to create the synthesized app project.
|
||||
Directory get _appDirectory => packagesDir.fileSystem
|
||||
.directory(getStringArg(_outputDirectoryFlag))
|
||||
.childDirectory('all_plugins');
|
||||
|
||||
/// The synthesized app project.
|
||||
RepositoryPackage get app => RepositoryPackage(_appDirectory);
|
||||
|
||||
@override
|
||||
String get description =>
|
||||
'Generate Flutter app that includes all plugins in packages.';
|
||||
@ -73,7 +76,7 @@ class CreateAllPluginsAppCommand extends PluginCommand {
|
||||
'--template=app',
|
||||
'--project-name=all_plugins',
|
||||
'--android-language=java',
|
||||
appDirectory.path,
|
||||
_appDirectory.path,
|
||||
],
|
||||
);
|
||||
|
||||
@ -83,8 +86,8 @@ class CreateAllPluginsAppCommand extends PluginCommand {
|
||||
}
|
||||
|
||||
Future<void> _updateAppGradle() async {
|
||||
final File gradleFile = appDirectory
|
||||
.childDirectory('android')
|
||||
final File gradleFile = app
|
||||
.platformDirectory(FlutterPlatform.android)
|
||||
.childDirectory('app')
|
||||
.childFile('build.gradle');
|
||||
if (!gradleFile.existsSync()) {
|
||||
@ -119,8 +122,8 @@ class CreateAllPluginsAppCommand extends PluginCommand {
|
||||
}
|
||||
|
||||
Future<void> _updateManifest() async {
|
||||
final File manifestFile = appDirectory
|
||||
.childDirectory('android')
|
||||
final File manifestFile = app
|
||||
.platformDirectory(FlutterPlatform.android)
|
||||
.childDirectory('app')
|
||||
.childDirectory('src')
|
||||
.childDirectory('main')
|
||||
@ -147,12 +150,11 @@ class CreateAllPluginsAppCommand extends PluginCommand {
|
||||
}
|
||||
|
||||
Future<void> _genPubspecWithAllPlugins() async {
|
||||
final RepositoryPackage buildAllApp = RepositoryPackage(appDirectory);
|
||||
// Read the old pubspec file's Dart SDK version, in order to preserve it
|
||||
// in the new file. The template sometimes relies on having opted in to
|
||||
// specific language features via SDK version, so using a different one
|
||||
// can cause compilation failures.
|
||||
final Pubspec originalPubspec = buildAllApp.parsePubspec();
|
||||
final Pubspec originalPubspec = app.parsePubspec();
|
||||
const String dartSdkKey = 'sdk';
|
||||
final VersionConstraint dartSdkConstraint =
|
||||
originalPubspec.environment?[dartSdkKey] ??
|
||||
@ -177,7 +179,7 @@ class CreateAllPluginsAppCommand extends PluginCommand {
|
||||
},
|
||||
dependencyOverrides: pluginDeps,
|
||||
);
|
||||
buildAllApp.pubspecFile.writeAsStringSync(_pubspecToString(pubspec));
|
||||
app.pubspecFile.writeAsStringSync(_pubspecToString(pubspec));
|
||||
}
|
||||
|
||||
Future<Map<String, PathDependency>> _getValidPathDependencies() async {
|
||||
|
@ -146,7 +146,7 @@ class FirebaseTestLabCommand extends PackageLoopingCommand {
|
||||
required RepositoryPackage package,
|
||||
}) async {
|
||||
final Directory androidDirectory =
|
||||
example.directory.childDirectory('android');
|
||||
example.platformDirectory(FlutterPlatform.android);
|
||||
if (!androidDirectory.existsSync()) {
|
||||
return PackageResult.skip(
|
||||
'${example.displayName} does not support Android.');
|
||||
@ -171,7 +171,7 @@ class FirebaseTestLabCommand extends PackageLoopingCommand {
|
||||
}
|
||||
|
||||
// Ensures that gradle wrapper exists
|
||||
final GradleProject project = GradleProject(example.directory,
|
||||
final GradleProject project = GradleProject(example,
|
||||
processRunner: processRunner, platform: platform);
|
||||
if (!await _ensureGradleWrapperExists(project)) {
|
||||
return PackageResult.fail(<String>['Unable to build example apk']);
|
||||
|
@ -40,7 +40,7 @@ class LintAndroidCommand extends PackageLoopingCommand {
|
||||
|
||||
bool failed = false;
|
||||
for (final RepositoryPackage example in package.getExamples()) {
|
||||
final GradleProject project = GradleProject(example.directory,
|
||||
final GradleProject project = GradleProject(example,
|
||||
processRunner: processRunner, platform: platform);
|
||||
|
||||
if (!project.isConfigured()) {
|
||||
|
@ -178,7 +178,7 @@ dependency_overrides:
|
||||
for (final String packageName in packagesToOverride) {
|
||||
// Find the relative path from the common base to the local package.
|
||||
final List<String> repoRelativePathComponents = path.split(
|
||||
path.relative(localDependencies[packageName]!.directory.path,
|
||||
path.relative(localDependencies[packageName]!.path,
|
||||
from: commonBasePath));
|
||||
newPubspecContents += '''
|
||||
$packageName:
|
||||
|
@ -198,22 +198,22 @@ this command.
|
||||
Future<_PlatformResult> _testAndroid(
|
||||
RepositoryPackage plugin, _TestMode mode) async {
|
||||
bool exampleHasUnitTests(RepositoryPackage example) {
|
||||
return example.directory
|
||||
.childDirectory('android')
|
||||
return example
|
||||
.platformDirectory(FlutterPlatform.android)
|
||||
.childDirectory('app')
|
||||
.childDirectory('src')
|
||||
.childDirectory('test')
|
||||
.existsSync() ||
|
||||
example.directory.parent
|
||||
.childDirectory('android')
|
||||
plugin
|
||||
.platformDirectory(FlutterPlatform.android)
|
||||
.childDirectory('src')
|
||||
.childDirectory('test')
|
||||
.existsSync();
|
||||
}
|
||||
|
||||
bool exampleHasNativeIntegrationTests(RepositoryPackage example) {
|
||||
final Directory integrationTestDirectory = example.directory
|
||||
.childDirectory('android')
|
||||
final Directory integrationTestDirectory = example
|
||||
.platformDirectory(FlutterPlatform.android)
|
||||
.childDirectory('app')
|
||||
.childDirectory('src')
|
||||
.childDirectory('androidTest');
|
||||
@ -269,7 +269,7 @@ this command.
|
||||
_printRunningExampleTestsMessage(example, 'Android');
|
||||
|
||||
final GradleProject project = GradleProject(
|
||||
example.directory,
|
||||
example,
|
||||
processRunner: processRunner,
|
||||
platform: platform,
|
||||
);
|
||||
|
@ -246,12 +246,12 @@ HTTP response: ${pubVersionFinderResponse.httpResponse.body}
|
||||
|
||||
bool _passesAuthorsCheck(RepositoryPackage package) {
|
||||
final List<String> pathComponents =
|
||||
package.directory.fileSystem.path.split(package.directory.path);
|
||||
package.directory.fileSystem.path.split(package.path);
|
||||
if (pathComponents.contains('third_party')) {
|
||||
// Third-party packages aren't required to have an AUTHORS file.
|
||||
return true;
|
||||
}
|
||||
return package.directory.childFile('AUTHORS').existsSync();
|
||||
return package.authorsFile.existsSync();
|
||||
}
|
||||
|
||||
void _printImportantStatusMessage(String message, {required bool isError}) {
|
||||
|
@ -41,7 +41,7 @@ class TestCommand extends PackageLoopingCommand {
|
||||
|
||||
@override
|
||||
Future<PackageResult> runForPackage(RepositoryPackage package) async {
|
||||
if (!package.directory.childDirectory('test').existsSync()) {
|
||||
if (!package.testDirectory.existsSync()) {
|
||||
return PackageResult.skip('No test/ directory.');
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,7 @@ ${indentation}HTTP response: ${pubVersionFinderResponse.httpResponse.body}
|
||||
final Version fromPubspec = pubspec.version!;
|
||||
|
||||
// get first version from CHANGELOG
|
||||
final File changelog = package.directory.childFile('CHANGELOG.md');
|
||||
final File changelog = package.changelogFile;
|
||||
final List<String> lines = changelog.readAsLinesSync();
|
||||
String? firstLineWithText;
|
||||
final Iterator<String> iterator = lines.iterator;
|
||||
|
Reference in New Issue
Block a user