Skip to content
34 changes: 29 additions & 5 deletions script/tool/lib/src/pubspec_check_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ class PubspecCheckCommand extends PackageLoopingCommand {
'a topic. Add "$topicName" to the "topics" section.';
}
}

// Validates topic names according to https://dart.dev/tools/pub/pubspec#topics
final RegExp expectedTopicFormat = RegExp(r'^[a-z](?:-?[a-z0-9]+)*$');
final Iterable<String> invalidTopics = topics.where((String topic) =>
Expand Down Expand Up @@ -542,17 +542,25 @@ class PubspecCheckCommand extends PackageLoopingCommand {
// there are any that aren't allowed.
String? _checkDependencies(Pubspec pubspec) {
final Set<String> badDependencies = <String>{};
// Shipped dependencies.
for (final Map<String, Dependency> dependencies
in <Map<String, Dependency>>[
pubspec.dependencies,
pubspec.devDependencies
]) {
in <Map<String, Dependency>>[pubspec.dependencies]) {
dependencies.forEach((String name, Dependency dependency) {
if (!_shouldAllowDependency(name, dependency)) {
badDependencies.add(name);
}
});
}
// Dev dependencies
for (final Map<String, Dependency> dependencies
in <Map<String, Dependency>>[pubspec.devDependencies]) {
dependencies.forEach((String name, Dependency dependency) {
if (!_shouldAllowDevDependency(name, dependency)) {
badDependencies.add(name);
}
});
}

if (badDependencies.isEmpty) {
return null;
}
Expand All @@ -563,7 +571,23 @@ class PubspecCheckCommand extends PackageLoopingCommand {
}

// Checks whether a given dependency is allowed.
// Defaults to false.
bool _shouldAllowDependency(String name, Dependency dependency) {
const List<String> disallowedSdkDependencies = <String>['integration_test'];
if (dependency is SdkDependency &&
disallowedSdkDependencies.contains(name)) {
return false;
}
return _shouldAllowBaselineDependency(name, dependency);
}

// Checks whether a given dependency is allowed as a dev dependency.
bool _shouldAllowDevDependency(String name, Dependency dependency) {
return _shouldAllowBaselineDependency(name, dependency);
}

// Shared enforcement between dev and non dev dependencies.
bool _shouldAllowBaselineDependency(String name, Dependency dependency) {
if (dependency is PathDependency || dependency is SdkDependency) {
return true;
}
Expand Down
33 changes: 33 additions & 0 deletions script/tool/test/pubspec_check_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,39 @@ ${_topicsSection()}
]),
);
});

test('fails when integration_test is used in non dev dependency',
() async {
final RepositoryPackage package =
createFakePackage('a_package', packagesDir, examples: <String>[]);

package.pubspecFile.writeAsStringSync('''
${_headerSection('a_package')}
${_environmentSection()}
${_dependenciesSection(<String>['integration_test: \n sdk: flutter'])}
${_devDependenciesSection()}
${_topicsSection()}
''');

Error? commandError;
final List<String> output = await runCapturingPrint(runner, <String>[
'pubspec-check',
], errorHandler: (Error e) {
commandError = e;
});

expect(commandError, isA<ToolExit>());
expect(
output,
containsAllInOrder(<Matcher>[
contains(
'The following unexpected non-local dependencies were found:\n'
' integration_test\n'
'Please see https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#Dependencies '
'for more information and next steps.'),
]),
);
});
});
});

Expand Down