Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tool] Add a package inclusion filter #4904

Merged
merged 1 commit into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 37 additions & 10 deletions script/tool/lib/src/common/package_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ abstract class PackageCommand extends Command<void> {
'Cannot be combined with $_packagesArg.\n\n'
'This is intended for use in CI.\n',
hide: true);
argParser.addMultiOption(_filterPackagesArg,
help: 'Filters any selected packages to only those included in this '
'list. This is intended for use in CI with flags such as '
'--$_packagesForBranchArg.\n\n'
'Entries can be package names or YAML files that contain a list '
'of package names.',
defaultsTo: <String>[],
hide: true);
argParser.addFlag(_currentPackageArg,
negatable: false,
help:
Expand Down Expand Up @@ -129,6 +137,7 @@ abstract class PackageCommand extends Command<void> {
static const String _runOnChangedPackagesArg = 'run-on-changed-packages';
static const String _runOnDirtyPackagesArg = 'run-on-dirty-packages';
static const String _excludeArg = 'exclude';
static const String _filterPackagesArg = 'filter-packages-to';
// Diff base selection.
static const String _baseBranchArg = 'base-branch';
static const String _baseShaArg = 'base-sha';
Expand Down Expand Up @@ -255,18 +264,25 @@ abstract class PackageCommand extends Command<void> {
_shardCount = shardCount;
}

/// Converts a list of items which are either package names or yaml files
/// containing a list of package names to a flat list of package names by
/// reading all the file contents.
Set<String> _expandYamlInPackageList(List<String> items) {
return items.expand<String>((String item) {
if (item.endsWith('.yaml')) {
final File file = packagesDir.fileSystem.file(item);
return (loadYaml(file.readAsStringSync()) as YamlList)
.toList()
.cast<String>();
}
return <String>[item];
}).toSet();
}

/// Returns the set of packages to exclude based on the `--exclude` argument.
Set<String> getExcludedPackageNames() {
final Set<String> excludedPackages = _excludedPackages ??
getStringListArg(_excludeArg).expand<String>((String item) {
if (item.endsWith('.yaml')) {
final File file = packagesDir.fileSystem.file(item);
return (loadYaml(file.readAsStringSync()) as YamlList)
.toList()
.cast<String>();
}
return <String>[item];
}).toSet();
_expandYamlInPackageList(getStringListArg(_excludeArg));
// Cache for future calls.
_excludedPackages = excludedPackages;
return excludedPackages;
Expand Down Expand Up @@ -420,7 +436,18 @@ abstract class PackageCommand extends Command<void> {
packages = <String>{currentPackageName};
}

final Set<String> excludedPackageNames = getExcludedPackageNames();
Set<String> excludedPackageNames = getExcludedPackageNames();

final Set<String> filter =
_expandYamlInPackageList(getStringListArg(_filterPackagesArg));
if (filter.isNotEmpty) {
final List<String> sortedList = filter.toList()..sort();
print('--$_filterPackagesArg is excluding packages that are not '
'included in: ${sortedList.join(',')}');
excludedPackageNames =
excludedPackageNames.union(packages.difference(filter));
}

for (final Directory dir in <Directory>[
packagesDir,
if (thirdPartyPackagesDir.existsSync()) thirdPartyPackagesDir,
Expand Down
40 changes: 39 additions & 1 deletion script/tool/test/common/package_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,21 @@ void main() {
expect(command.plugins, unorderedEquals(<String>[]));
});

test('filter-packages-to accepts config files', () async {
final RepositoryPackage plugin1 =
createFakePlugin('plugin1', packagesDir);
createFakePlugin('plugin2', packagesDir);
final File configFile = packagesDir.childFile('exclude.yaml');
configFile.writeAsStringSync('- plugin1');

await runCapturingPrint(runner, <String>[
'sample',
'--packages=plugin1,plugin2',
'--filter-packages-to=${configFile.path}'
]);
expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
});

test(
'explicitly specifying the plugin (group) name of a federated plugin '
'should include all plugins in the group', () async {
Expand Down Expand Up @@ -765,7 +780,7 @@ packages/plugin1/plugin1/plugin1.dart
expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
});

test('--exclude flag works with --run-on-changed-packages', () async {
test('honors --exclude flag', () async {
processRunner.mockProcessesForExecutable['git-diff'] =
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(stdout: '''
Expand All @@ -787,6 +802,29 @@ packages/plugin3/plugin3.dart

expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
});

test('honors --filter-packages-to flag', () async {
processRunner.mockProcessesForExecutable['git-diff'] =
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(stdout: '''
packages/plugin1/plugin1.dart
packages/plugin2/ios/plugin2.m
packages/plugin3/plugin3.dart
''')),
];
final RepositoryPackage plugin1 =
createFakePlugin('plugin1', packagesDir.childDirectory('plugin1'));
createFakePlugin('plugin2', packagesDir);
createFakePlugin('plugin3', packagesDir);
await runCapturingPrint(runner, <String>[
'sample',
'--filter-packages-to=plugin1',
'--base-sha=main',
'--run-on-changed-packages'
]);

expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
});
});

group('test run-on-dirty-packages', () {
Expand Down