[flutter_plugin_tools] Introduce a class for packages (#4252)

Packages are the primary conceptual object in the tool, but currently they are represented simply as Directory (or occasionally a path string). This introduces an object for packages and:
- moves a number of existing utility methods into it
- sweeps the code for the obvious cases of using `Directory` to represent a package, especially in method signatures and migrates them
- notes a few places where we should migrate later, to avoid ballooning the size of the PR

There are no doubt other cases not caught in the sweep, but this gives us a foundation both for new code, and to migrate incrementally toward as we find existing code that was missed.
This commit is contained in:
stuartmorgan
2021-08-24 16:29:56 -04:00
committed by GitHub
parent 74cf0287f9
commit 41f1c806f2
27 changed files with 440 additions and 334 deletions

View File

@ -11,6 +11,7 @@ import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/common/package_looping_command.dart';
import 'package:flutter_plugin_tools/src/common/process_runner.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:git/git.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
@ -578,64 +579,6 @@ void main() {
]));
});
});
group('utility', () {
test('getPackageDescription prints packageDir-relative paths by default',
() async {
final TestPackageLoopingCommand command =
TestPackageLoopingCommand(packagesDir, platform: mockPlatform);
expect(
command.getPackageDescription(packagesDir.childDirectory('foo')),
'foo',
);
expect(
command.getPackageDescription(packagesDir
.childDirectory('foo')
.childDirectory('bar')
.childDirectory('baz')),
'foo/bar/baz',
);
});
test('getPackageDescription always uses Posix-style paths', () async {
mockPlatform.isWindows = true;
final TestPackageLoopingCommand command =
TestPackageLoopingCommand(packagesDir, platform: mockPlatform);
expect(
command.getPackageDescription(packagesDir.childDirectory('foo')),
'foo',
);
expect(
command.getPackageDescription(packagesDir
.childDirectory('foo')
.childDirectory('bar')
.childDirectory('baz')),
'foo/bar/baz',
);
});
test(
'getPackageDescription elides group name in grouped federated plugin structure',
() async {
final TestPackageLoopingCommand command =
TestPackageLoopingCommand(packagesDir, platform: mockPlatform);
expect(
command.getPackageDescription(packagesDir
.childDirectory('a_plugin')
.childDirectory('a_plugin_platform_interface')),
'a_plugin_platform_interface',
);
expect(
command.getPackageDescription(packagesDir
.childDirectory('a_plugin')
.childDirectory('a_plugin_web')),
'a_plugin_web',
);
});
});
}
class TestPackageLoopingCommand extends PackageLoopingCommand {
@ -699,18 +642,18 @@ class TestPackageLoopingCommand extends PackageLoopingCommand {
}
@override
Future<PackageResult> runForPackage(Directory package) async {
Future<PackageResult> runForPackage(RepositoryPackage package) async {
checkedPackages.add(package.path);
final File warningFile = package.childFile(_warningFile);
final File warningFile = package.directory.childFile(_warningFile);
if (warningFile.existsSync()) {
final List<String> warnings = warningFile.readAsLinesSync();
warnings.forEach(logWarning);
}
final File skipFile = package.childFile(_skipFile);
final File skipFile = package.directory.childFile(_skipFile);
if (skipFile.existsSync()) {
return PackageResult.skip(skipFile.readAsStringSync());
}
final File errorFile = package.childFile(_errorFile);
final File errorFile = package.directory.childFile(_errorFile);
if (errorFile.existsSync()) {
return PackageResult.fail(errorFile.readAsLinesSync());
}

View File

@ -498,7 +498,7 @@ packages/plugin3/plugin3.dart
expect(
localCommand.plugins,
unorderedEquals(expectedShards[i]
.map((Directory package) => package.path)
.map((Directory packageDir) => packageDir.path)
.toList()));
}
});
@ -541,7 +541,7 @@ packages/plugin3/plugin3.dart
expect(
localCommand.plugins,
unorderedEquals(expectedShards[i]
.map((Directory package) => package.path)
.map((Directory packageDir) => packageDir.path)
.toList()));
}
});
@ -594,7 +594,7 @@ packages/plugin3/plugin3.dart
expect(
localCommand.plugins,
unorderedEquals(expectedShards[i]
.map((Directory package) => package.path)
.map((Directory packageDir) => packageDir.path)
.toList()));
}
});
@ -620,8 +620,8 @@ class SamplePluginCommand extends PluginCommand {
@override
Future<void> run() async {
await for (final PackageEnumerationEntry package in getTargetPackages()) {
plugins.add(package.directory.path);
await for (final PackageEnumerationEntry entry in getTargetPackages()) {
plugins.add(entry.package.path);
}
}
}

View File

@ -6,6 +6,7 @@ import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/common/plugin_utils.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:test/test.dart';
import '../util.dart';
@ -21,7 +22,8 @@ void main() {
group('pluginSupportsPlatform', () {
test('no platforms', () async {
final Directory plugin = createFakePlugin('plugin', packagesDir);
final RepositoryPackage plugin =
RepositoryPackage(createFakePlugin('plugin', packagesDir));
expect(pluginSupportsPlatform(kPlatformAndroid, plugin), isFalse);
expect(pluginSupportsPlatform(kPlatformIos, plugin), isFalse);
@ -32,7 +34,8 @@ void main() {
});
test('all platforms', () async {
final Directory plugin = createFakePlugin('plugin', packagesDir,
final RepositoryPackage plugin = RepositoryPackage(createFakePlugin(
'plugin', packagesDir,
platformSupport: <String, PlatformSupport>{
kPlatformAndroid: PlatformSupport.inline,
kPlatformIos: PlatformSupport.inline,
@ -40,7 +43,7 @@ void main() {
kPlatformMacos: PlatformSupport.inline,
kPlatformWeb: PlatformSupport.inline,
kPlatformWindows: PlatformSupport.inline,
});
}));
expect(pluginSupportsPlatform(kPlatformAndroid, plugin), isTrue);
expect(pluginSupportsPlatform(kPlatformIos, plugin), isTrue);
@ -51,7 +54,7 @@ void main() {
});
test('some platforms', () async {
final Directory plugin = createFakePlugin(
final RepositoryPackage plugin = RepositoryPackage(createFakePlugin(
'plugin',
packagesDir,
platformSupport: <String, PlatformSupport>{
@ -59,7 +62,7 @@ void main() {
kPlatformLinux: PlatformSupport.inline,
kPlatformWeb: PlatformSupport.inline,
},
);
));
expect(pluginSupportsPlatform(kPlatformAndroid, plugin), isTrue);
expect(pluginSupportsPlatform(kPlatformIos, plugin), isFalse);
@ -70,7 +73,7 @@ void main() {
});
test('inline plugins are only detected as inline', () async {
final Directory plugin = createFakePlugin(
final RepositoryPackage plugin = RepositoryPackage(createFakePlugin(
'plugin',
packagesDir,
platformSupport: <String, PlatformSupport>{
@ -81,7 +84,7 @@ void main() {
kPlatformWeb: PlatformSupport.inline,
kPlatformWindows: PlatformSupport.inline,
},
);
));
expect(
pluginSupportsPlatform(kPlatformAndroid, plugin,
@ -135,7 +138,7 @@ void main() {
test('federated plugins are only detected as federated', () async {
const String pluginName = 'plugin';
final Directory plugin = createFakePlugin(
final RepositoryPackage plugin = RepositoryPackage(createFakePlugin(
pluginName,
packagesDir,
platformSupport: <String, PlatformSupport>{
@ -146,7 +149,7 @@ void main() {
kPlatformWeb: PlatformSupport.federated,
kPlatformWindows: PlatformSupport.federated,
},
);
));
expect(
pluginSupportsPlatform(kPlatformAndroid, plugin,

View File

@ -19,7 +19,7 @@ void main() {
});
final PubVersionFinder finder = PubVersionFinder(httpClient: mockClient);
final PubVersionFinderResponse response =
await finder.getPackageVersion(package: 'some_package');
await finder.getPackageVersion(packageName: 'some_package');
expect(response.versions, isEmpty);
expect(response.result, PubVersionFinderResult.noPackageFound);
@ -33,7 +33,7 @@ void main() {
});
final PubVersionFinder finder = PubVersionFinder(httpClient: mockClient);
final PubVersionFinderResponse response =
await finder.getPackageVersion(package: 'some_package');
await finder.getPackageVersion(packageName: 'some_package');
expect(response.versions, isEmpty);
expect(response.result, PubVersionFinderResult.fail);
@ -64,7 +64,7 @@ void main() {
});
final PubVersionFinder finder = PubVersionFinder(httpClient: mockClient);
final PubVersionFinderResponse response =
await finder.getPackageVersion(package: 'some_package');
await finder.getPackageVersion(packageName: 'some_package');
expect(response.versions, <Version>[
Version.parse('2.0.0'),

View File

@ -0,0 +1,123 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:test/test.dart';
import '../util.dart';
void main() {
late FileSystem fileSystem;
late Directory packagesDir;
setUp(() {
fileSystem = MemoryFileSystem();
packagesDir = createPackagesDirectory(fileSystem: fileSystem);
});
group('displayName', () {
test('prints packageDir-relative paths by default', () async {
expect(
RepositoryPackage(packagesDir.childDirectory('foo')).displayName,
'foo',
);
expect(
RepositoryPackage(packagesDir
.childDirectory('foo')
.childDirectory('bar')
.childDirectory('baz'))
.displayName,
'foo/bar/baz',
);
});
test('handles third_party/packages/', () async {
expect(
RepositoryPackage(packagesDir.parent
.childDirectory('third_party')
.childDirectory('packages')
.childDirectory('foo')
.childDirectory('bar')
.childDirectory('baz'))
.displayName,
'foo/bar/baz',
);
});
test('always uses Posix-style paths', () async {
final Directory windowsPackagesDir = createPackagesDirectory(
fileSystem: MemoryFileSystem(style: FileSystemStyle.windows));
expect(
RepositoryPackage(windowsPackagesDir.childDirectory('foo')).displayName,
'foo',
);
expect(
RepositoryPackage(windowsPackagesDir
.childDirectory('foo')
.childDirectory('bar')
.childDirectory('baz'))
.displayName,
'foo/bar/baz',
);
});
test('elides group name in grouped federated plugin structure', () async {
expect(
RepositoryPackage(packagesDir
.childDirectory('a_plugin')
.childDirectory('a_plugin_platform_interface'))
.displayName,
'a_plugin_platform_interface',
);
expect(
RepositoryPackage(packagesDir
.childDirectory('a_plugin')
.childDirectory('a_plugin_platform_web'))
.displayName,
'a_plugin_platform_web',
);
});
// The app-facing package doesn't get elided to avoid potential confusion
// with the group folder itself.
test('does not elide group name for app-facing packages', () async {
expect(
RepositoryPackage(packagesDir
.childDirectory('a_plugin')
.childDirectory('a_plugin'))
.displayName,
'a_plugin/a_plugin',
);
});
});
group('getExamples', () {
test('handles a single example', () async {
final Directory plugin = createFakePlugin('a_plugin', packagesDir);
final List<RepositoryPackage> examples =
RepositoryPackage(plugin).getExamples().toList();
expect(examples.length, 1);
expect(examples[0].path, plugin.childDirectory('example').path);
});
test('handles multiple examples', () async {
final Directory plugin = createFakePlugin('a_plugin', packagesDir,
examples: <String>['example1', 'example2']);
final List<RepositoryPackage> examples =
RepositoryPackage(plugin).getExamples().toList();
expect(examples.length, 2);
expect(examples[0].path,
plugin.childDirectory('example').childDirectory('example1').path);
expect(examples[1].path,
plugin.childDirectory('example').childDirectory('example2').path);
});
});
}