[flutter_plugin_tools] Support non-plugin packages for drive-examples (#5468)

This commit is contained in:
stuartmorgan
2022-05-02 17:44:12 -04:00
committed by GitHub
parent d43fae6fb4
commit fbf53f284b
20 changed files with 398 additions and 112 deletions

View File

@ -1,3 +1,8 @@
## NEXT
- `drive-examples` now supports non-plugin packages.
- Commands that iterate over examples now include non-Flutter example packages.
## 0.8.4 ## 0.8.4
- `readme-check` now validates that there's a info tag on code blocks to - `readme-check` now validates that there's a info tag on code blocks to

View File

@ -4,7 +4,6 @@
import 'package:colorize/colorize.dart'; import 'package:colorize/colorize.dart';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:yaml/yaml.dart';
/// The signature for a print handler for commands that allow overriding the /// The signature for a print handler for commands that allow overriding the
/// print destination. /// print destination.
@ -31,26 +30,14 @@ const String platformWindows = 'windows';
/// Key for enable experiment. /// Key for enable experiment.
const String kEnableExperiment = 'enable-experiment'; const String kEnableExperiment = 'enable-experiment';
/// Returns whether the given directory contains a Flutter package. /// Returns whether the given directory is a Dart package.
bool isFlutterPackage(FileSystemEntity entity) { bool isPackage(FileSystemEntity entity) {
if (entity is! Directory) { if (entity is! Directory) {
return false; return false;
} }
// Per https://dart.dev/guides/libraries/create-library-packages#what-makes-a-library-package
try { return entity.childFile('pubspec.yaml').existsSync() &&
final File pubspecFile = entity.childFile('pubspec.yaml'); entity.childDirectory('lib').existsSync();
final YamlMap pubspecYaml =
loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
final YamlMap? dependencies = pubspecYaml['dependencies'] as YamlMap?;
if (dependencies == null) {
return false;
}
return dependencies.containsKey('flutter');
} on FileSystemException {
return false;
} on YamlException {
return false;
}
} }
/// Prints `successMessage` in green. /// Prints `successMessage` in green.

View File

@ -10,7 +10,6 @@ import 'package:git/git.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'core.dart'; import 'core.dart';
import 'plugin_command.dart'; import 'plugin_command.dart';

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:file/file.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart'; import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
@ -111,13 +110,8 @@ YamlMap? _readPlatformPubspecSectionForPlugin(
/// section from [plugin]'s pubspec.yaml, or null if either it is not present, /// section from [plugin]'s pubspec.yaml, or null if either it is not present,
/// or the pubspec couldn't be read. /// or the pubspec couldn't be read.
YamlMap? _readPluginPubspecSection(RepositoryPackage package) { YamlMap? _readPluginPubspecSection(RepositoryPackage package) {
final File pubspecFile = package.pubspecFile; final Pubspec pubspec = package.parsePubspec();
if (!pubspecFile.existsSync()) { final Map<String, dynamic>? flutterSection = pubspec.flutter;
return null;
}
final YamlMap pubspecYaml =
loadYaml(pubspecFile.readAsStringSync()) as YamlMap;
final YamlMap? flutterSection = pubspecYaml['flutter'] as YamlMap?;
if (flutterSection == null) { if (flutterSection == null) {
return null; return null;
} }

View File

@ -8,6 +8,8 @@ import 'package:pubspec_parse/pubspec_parse.dart';
import 'core.dart'; import 'core.dart';
export 'package:pubspec_parse/pubspec_parse.dart' show Pubspec;
/// A package in the repository. /// A package in the repository.
// //
// TODO(stuartmorgan): Add more package-related info here, such as an on-demand // TODO(stuartmorgan): Add more package-related info here, such as an on-demand
@ -59,6 +61,12 @@ class RepositoryPackage {
/// Caches for future use. /// Caches for future use.
Pubspec parsePubspec() => _parsedPubspec; Pubspec parsePubspec() => _parsedPubspec;
/// Returns true if the package depends on Flutter.
bool requiresFlutter() {
final Pubspec pubspec = parsePubspec();
return pubspec.dependencies.containsKey('flutter');
}
/// True if this appears to be a federated plugin package, according to /// True if this appears to be a federated plugin package, according to
/// repository conventions. /// repository conventions.
bool get isFederated => bool get isFederated =>
@ -91,7 +99,7 @@ class RepositoryPackage {
if (!exampleDirectory.existsSync()) { if (!exampleDirectory.existsSync()) {
return <RepositoryPackage>[]; return <RepositoryPackage>[];
} }
if (isFlutterPackage(exampleDirectory)) { if (isPackage(exampleDirectory)) {
return <RepositoryPackage>[RepositoryPackage(exampleDirectory)]; return <RepositoryPackage>[RepositoryPackage(exampleDirectory)];
} }
// Only look at the subdirectories of the example directory if the example // Only look at the subdirectories of the example directory if the example
@ -99,8 +107,8 @@ class RepositoryPackage {
// example directory for other Dart packages. // example directory for other Dart packages.
return exampleDirectory return exampleDirectory
.listSync() .listSync()
.where((FileSystemEntity entity) => isFlutterPackage(entity)) .where((FileSystemEntity entity) => isPackage(entity))
// isFlutterPackage guarantees that the cast to Directory is safe. // isPackage guarantees that the cast to Directory is safe.
.map((FileSystemEntity entity) => .map((FileSystemEntity entity) =>
RepositoryPackage(entity as Directory)); RepositoryPackage(entity as Directory));
} }

View File

@ -123,6 +123,8 @@ class DriveExamplesCommand extends PackageLoopingCommand {
@override @override
Future<PackageResult> runForPackage(RepositoryPackage package) async { Future<PackageResult> runForPackage(RepositoryPackage package) async {
final bool isPlugin = isFlutterPlugin(package);
if (package.isPlatformInterface && if (package.isPlatformInterface &&
!package.getSingleExampleDeprecated().directory.existsSync()) { !package.getSingleExampleDeprecated().directory.existsSync()) {
// Platform interface packages generally aren't intended to have // Platform interface packages generally aren't intended to have
@ -131,23 +133,23 @@ class DriveExamplesCommand extends PackageLoopingCommand {
'Platform interfaces are not expected to have integration tests.'); 'Platform interfaces are not expected to have integration tests.');
} }
final List<String> deviceFlags = <String>[]; // For plugin packages, skip if the plugin itself doesn't support any
for (final MapEntry<String, List<String>> entry // requested platform(s).
in _targetDeviceFlags.entries) { if (isPlugin) {
final String platform = entry.key; final Iterable<String> requestedPlatforms = _targetDeviceFlags.keys;
if (pluginSupportsPlatform(platform, package)) { final Iterable<String> unsupportedPlatforms = requestedPlatforms.where(
deviceFlags.addAll(entry.value); (String platform) => !pluginSupportsPlatform(platform, package));
} else { for (final String platform in unsupportedPlatforms) {
print('Skipping unsupported platform ${entry.key}...'); print('Skipping unsupported platform $platform...');
}
if (unsupportedPlatforms.length == requestedPlatforms.length) {
return PackageResult.skip(
'${package.displayName} does not support any requested platform.');
} }
}
// If there is no supported target platform, skip the plugin.
if (deviceFlags.isEmpty) {
return PackageResult.skip(
'${package.displayName} does not support any requested platform.');
} }
int examplesFound = 0; int examplesFound = 0;
int supportedExamplesFound = 0;
bool testsRan = false; bool testsRan = false;
final List<String> errors = <String>[]; final List<String> errors = <String>[];
for (final RepositoryPackage example in package.getExamples()) { for (final RepositoryPackage example in package.getExamples()) {
@ -155,6 +157,15 @@ class DriveExamplesCommand extends PackageLoopingCommand {
final String exampleName = final String exampleName =
getRelativePosixPath(example.directory, from: packagesDir); getRelativePosixPath(example.directory, from: packagesDir);
// Skip examples that don't support any requested platform(s).
final List<String> deviceFlags = _deviceFlagsForExample(example);
if (deviceFlags.isEmpty) {
print(
'Skipping $exampleName; does not support any requested platforms.');
continue;
}
++supportedExamplesFound;
final List<File> drivers = await _getDrivers(example); final List<File> drivers = await _getDrivers(example);
if (drivers.isEmpty) { if (drivers.isEmpty) {
print('No driver tests found for $exampleName'); print('No driver tests found for $exampleName');
@ -195,14 +206,41 @@ class DriveExamplesCommand extends PackageLoopingCommand {
} }
} }
if (!testsRan) { if (!testsRan) {
printError('No driver tests were run ($examplesFound example(s) found).'); // It is an error for a plugin not to have integration tests, because that
errors.add('No tests ran (use --exclude if this is intentional).'); // is the only way to test the method channel communication.
if (isPlugin) {
printError(
'No driver tests were run ($examplesFound example(s) found).');
errors.add('No tests ran (use --exclude if this is intentional).');
} else {
return PackageResult.skip(supportedExamplesFound == 0
? 'No example supports requested platform(s).'
: 'No example is configured for driver tests.');
}
} }
return errors.isEmpty return errors.isEmpty
? PackageResult.success() ? PackageResult.success()
: PackageResult.fail(errors); : PackageResult.fail(errors);
} }
/// Returns the device flags for the intersection of the requested platforms
/// and the platforms supported by [example].
List<String> _deviceFlagsForExample(RepositoryPackage example) {
final List<String> deviceFlags = <String>[];
for (final MapEntry<String, List<String>> entry
in _targetDeviceFlags.entries) {
final String platform = entry.key;
if (example.directory.childDirectory(platform).existsSync()) {
deviceFlags.addAll(entry.value);
} else {
final String exampleName =
getRelativePosixPath(example.directory, from: packagesDir);
print('Skipping unsupported platform $platform for $exampleName');
}
}
return deviceFlags;
}
Future<List<String>> _getDevicesForPlatform(String platform) async { Future<List<String>> _getDevicesForPlatform(String platform) async {
final List<String> deviceIds = <String>[]; final List<String> deviceIds = <String>[];

View File

@ -8,7 +8,6 @@ import 'package:git/git.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'common/core.dart'; import 'common/core.dart';
import 'common/file_utils.dart'; import 'common/file_utils.dart';

View File

@ -3,15 +3,14 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:git/git.dart'; import 'package:git/git.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'common/core.dart'; import 'common/core.dart';
import 'common/git_version_finder.dart'; import 'common/git_version_finder.dart';
import 'common/plugin_command.dart'; import 'common/plugin_command.dart';
import 'common/repository_package.dart';
const int _exitPackageNotFound = 3; const int _exitPackageNotFound = 3;
const int _exitCannotUpdatePubspec = 4; const int _exitCannotUpdatePubspec = 4;

View File

@ -10,7 +10,6 @@ import 'package:file/file.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'common/core.dart'; import 'common/core.dart';
import 'common/package_looping_command.dart'; import 'common/package_looping_command.dart';

View File

@ -13,7 +13,6 @@ import 'package:meta/meta.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
import 'common/core.dart'; import 'common/core.dart';

View File

@ -5,7 +5,6 @@
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:git/git.dart'; import 'package:git/git.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
import 'common/core.dart'; import 'common/core.dart';

View File

@ -5,7 +5,6 @@
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:git/git.dart'; import 'package:git/git.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
import 'common/core.dart'; import 'common/core.dart';

View File

@ -43,7 +43,7 @@ class TestCommand extends PackageLoopingCommand {
} }
bool passed; bool passed;
if (isFlutterPackage(package.directory)) { if (package.requiresFlutter()) {
passed = await _runFlutterTests(package); passed = await _runFlutterTests(package);
} else { } else {
passed = await _runDartTests(package); passed = await _runDartTests(package);

View File

@ -9,7 +9,6 @@ import 'package:meta/meta.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'common/core.dart'; import 'common/core.dart';
import 'common/git_version_finder.dart'; import 'common/git_version_finder.dart';

View File

@ -5,7 +5,6 @@
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart'; import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import '../util.dart'; import '../util.dart';
@ -97,7 +96,7 @@ void main() {
}); });
group('getExamples', () { group('getExamples', () {
test('handles a single example', () async { test('handles a single Flutter example', () async {
final Directory plugin = createFakePlugin('a_plugin', packagesDir); final Directory plugin = createFakePlugin('a_plugin', packagesDir);
final List<RepositoryPackage> examples = final List<RepositoryPackage> examples =
@ -107,7 +106,7 @@ void main() {
expect(examples[0].path, plugin.childDirectory('example').path); expect(examples[0].path, plugin.childDirectory('example').path);
}); });
test('handles multiple examples', () async { test('handles multiple Flutter examples', () async {
final Directory plugin = createFakePlugin('a_plugin', packagesDir, final Directory plugin = createFakePlugin('a_plugin', packagesDir,
examples: <String>['example1', 'example2']); examples: <String>['example1', 'example2']);
@ -120,6 +119,30 @@ void main() {
expect(examples[1].path, expect(examples[1].path,
plugin.childDirectory('example').childDirectory('example2').path); plugin.childDirectory('example').childDirectory('example2').path);
}); });
test('handles a single non-Flutter example', () async {
final Directory package = createFakePackage('a_package', packagesDir);
final List<RepositoryPackage> examples =
RepositoryPackage(package).getExamples().toList();
expect(examples.length, 1);
expect(examples[0].path, package.childDirectory('example').path);
});
test('handles multiple non-Flutter examples', () async {
final Directory package = createFakePackage('a_package', packagesDir,
examples: <String>['example1', 'example2']);
final List<RepositoryPackage> examples =
RepositoryPackage(package).getExamples().toList();
expect(examples.length, 2);
expect(examples[0].path,
package.childDirectory('example').childDirectory('example1').path);
expect(examples[1].path,
package.childDirectory('example').childDirectory('example2').path);
});
}); });
group('federated plugin queries', () { group('federated plugin queries', () {
@ -179,4 +202,18 @@ void main() {
expect(pubspec.name, 'a_plugin'); expect(pubspec.name, 'a_plugin');
}); });
}); });
group('requiresFlutter', () {
test('returns true for Flutter package', () async {
final Directory package =
createFakePackage('a_package', packagesDir, isFlutter: true);
expect(RepositoryPackage(package).requiresFlutter(), true);
});
test('returns false for non-Flutter package', () async {
final Directory package =
createFakePackage('a_package', packagesDir, isFlutter: false);
expect(RepositoryPackage(package).requiresFlutter(), false);
});
});
} }

View File

@ -10,7 +10,6 @@ import 'package:file/local.dart';
import 'package:flutter_plugin_tools/src/common/repository_package.dart'; import 'package:flutter_plugin_tools/src/common/repository_package.dart';
import 'package:flutter_plugin_tools/src/create_all_plugins_app_command.dart'; import 'package:flutter_plugin_tools/src/create_all_plugins_app_command.dart';
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'util.dart'; import 'util.dart';

View File

@ -128,6 +128,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/integration_test.dart', 'example/test_driver/integration_test.dart',
'example/integration_test/foo_test.dart', 'example/integration_test/foo_test.dart',
'example/ios/ios.m',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformIOS: const PlatformDetails(PlatformSupport.inline), platformIOS: const PlatformDetails(PlatformSupport.inline),
@ -193,6 +194,8 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/android/android.java',
'example/ios/ios.m',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformAndroid: const PlatformDetails(PlatformSupport.inline), platformAndroid: const PlatformDetails(PlatformSupport.inline),
@ -243,6 +246,8 @@ void main() {
packagesDir, packagesDir,
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/android/android.java',
'example/ios/ios.m',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformAndroid: const PlatformDetails(PlatformSupport.inline), platformAndroid: const PlatformDetails(PlatformSupport.inline),
@ -276,6 +281,8 @@ void main() {
packagesDir, packagesDir,
extraFiles: <String>[ extraFiles: <String>[
'example/lib/main.dart', 'example/lib/main.dart',
'example/android/android.java',
'example/ios/ios.m',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformAndroid: const PlatformDetails(PlatformSupport.inline), platformAndroid: const PlatformDetails(PlatformSupport.inline),
@ -312,6 +319,8 @@ void main() {
'example/integration_test/bar_test.dart', 'example/integration_test/bar_test.dart',
'example/integration_test/foo_test.dart', 'example/integration_test/foo_test.dart',
'example/integration_test/ignore_me.dart', 'example/integration_test/ignore_me.dart',
'example/android/android.java',
'example/ios/ios.m',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformAndroid: const PlatformDetails(PlatformSupport.inline), platformAndroid: const PlatformDetails(PlatformSupport.inline),
@ -398,6 +407,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/linux/linux.cc',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformLinux: const PlatformDetails(PlatformSupport.inline), platformLinux: const PlatformDetails(PlatformSupport.inline),
@ -542,6 +552,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/web/index.html',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformWeb: const PlatformDetails(PlatformSupport.inline), platformWeb: const PlatformDetails(PlatformSupport.inline),
@ -591,6 +602,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/web/index.html',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformWeb: const PlatformDetails(PlatformSupport.inline), platformWeb: const PlatformDetails(PlatformSupport.inline),
@ -668,6 +680,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/windows/windows.cpp',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformWindows: const PlatformDetails(PlatformSupport.inline), platformWindows: const PlatformDetails(PlatformSupport.inline),
@ -715,6 +728,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/android/android.java',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformAndroid: const PlatformDetails(PlatformSupport.inline), platformAndroid: const PlatformDetails(PlatformSupport.inline),
@ -853,6 +867,8 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/plugin_test.dart', 'example/test_driver/plugin_test.dart',
'example/test_driver/plugin.dart', 'example/test_driver/plugin.dart',
'example/android/android.java',
'example/ios/ios.m',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformAndroid: const PlatformDetails(PlatformSupport.inline), platformAndroid: const PlatformDetails(PlatformSupport.inline),
@ -927,6 +943,7 @@ void main() {
extraFiles: <String>[ extraFiles: <String>[
'example/integration_test/bar_test.dart', 'example/integration_test/bar_test.dart',
'example/integration_test/foo_test.dart', 'example/integration_test/foo_test.dart',
'example/web/index.html',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformWeb: const PlatformDetails(PlatformSupport.inline), platformWeb: const PlatformDetails(PlatformSupport.inline),
@ -959,6 +976,7 @@ void main() {
packagesDir, packagesDir,
extraFiles: <String>[ extraFiles: <String>[
'example/test_driver/integration_test.dart', 'example/test_driver/integration_test.dart',
'example/web/index.html',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformWeb: const PlatformDetails(PlatformSupport.inline), platformWeb: const PlatformDetails(PlatformSupport.inline),
@ -995,6 +1013,7 @@ void main() {
'example/test_driver/integration_test.dart', 'example/test_driver/integration_test.dart',
'example/integration_test/bar_test.dart', 'example/integration_test/bar_test.dart',
'example/integration_test/foo_test.dart', 'example/integration_test/foo_test.dart',
'example/macos/macos.swift',
], ],
platformSupport: <String, PlatformDetails>{ platformSupport: <String, PlatformDetails>{
platformMacOS: const PlatformDetails(PlatformSupport.inline), platformMacOS: const PlatformDetails(PlatformSupport.inline),
@ -1060,5 +1079,147 @@ void main() {
pluginExampleDirectory.path), pluginExampleDirectory.path),
])); ]));
}); });
group('packages', () {
test('can be driven', () async {
final Directory package =
createFakePackage('a_package', packagesDir, extraFiles: <String>[
'example/integration_test/foo_test.dart',
'example/test_driver/integration_test.dart',
'example/web/index.html',
]);
final Directory exampleDirectory = package.childDirectory('example');
final List<String> output = await runCapturingPrint(runner, <String>[
'drive-examples',
'--web',
]);
expect(
output,
containsAllInOrder(<Matcher>[
contains('Running for a_package'),
contains('No issues found!'),
]),
);
expect(
processRunner.recordedCalls,
orderedEquals(<ProcessCall>[
ProcessCall(
getFlutterCommand(mockPlatform),
const <String>[
'drive',
'-d',
'web-server',
'--web-port=7357',
'--browser-name=chrome',
'--driver',
'test_driver/integration_test.dart',
'--target',
'integration_test/foo_test.dart'
],
exampleDirectory.path),
]));
});
test('are skipped when example does not support platform', () async {
createFakePackage('a_package', packagesDir,
isFlutter: true,
extraFiles: <String>[
'example/integration_test/foo_test.dart',
'example/test_driver/integration_test.dart',
]);
final List<String> output = await runCapturingPrint(runner, <String>[
'drive-examples',
'--web',
]);
expect(
output,
containsAllInOrder(<Matcher>[
contains('Running for a_package'),
contains('Skipping a_package/example; does not support any '
'requested platforms'),
contains('SKIPPING: No example supports requested platform(s).'),
]),
);
expect(processRunner.recordedCalls.isEmpty, true);
});
test('drive only supported examples if there is more than one', () async {
final Directory package = createFakePackage('a_package', packagesDir,
isFlutter: true,
examples: <String>[
'with_web',
'without_web'
],
extraFiles: <String>[
'example/with_web/integration_test/foo_test.dart',
'example/with_web/test_driver/integration_test.dart',
'example/with_web/web/index.html',
'example/without_web/integration_test/foo_test.dart',
'example/without_web/test_driver/integration_test.dart',
]);
final Directory supportedExampleDirectory =
package.childDirectory('example').childDirectory('with_web');
final List<String> output = await runCapturingPrint(runner, <String>[
'drive-examples',
'--web',
]);
expect(
output,
containsAllInOrder(<Matcher>[
contains('Running for a_package'),
contains(
'Skipping a_package/example/without_web; does not support any requested platforms.'),
contains('No issues found!'),
]),
);
expect(
processRunner.recordedCalls,
orderedEquals(<ProcessCall>[
ProcessCall(
getFlutterCommand(mockPlatform),
const <String>[
'drive',
'-d',
'web-server',
'--web-port=7357',
'--browser-name=chrome',
'--driver',
'test_driver/integration_test.dart',
'--target',
'integration_test/foo_test.dart'
],
supportedExampleDirectory.path),
]));
});
test('are skipped when there is no integration testing', () async {
createFakePackage('a_package', packagesDir,
isFlutter: true, extraFiles: <String>['example/web/index.html']);
final List<String> output = await runCapturingPrint(runner, <String>[
'drive-examples',
'--web',
]);
expect(
output,
containsAllInOrder(<Matcher>[
contains('Running for a_package'),
contains('SKIPPING: No example is configured for driver tests.'),
]),
);
expect(processRunner.recordedCalls.isEmpty, true);
});
});
}); });
} }

View File

@ -12,7 +12,7 @@ import 'mocks.dart';
import 'util.dart'; import 'util.dart';
void main() { void main() {
group('$ListCommand', () { group('ListCommand', () {
late FileSystem fileSystem; late FileSystem fileSystem;
late MockPlatform mockPlatform; late MockPlatform mockPlatform;
late Directory packagesDir; late Directory packagesDir;

View File

@ -155,6 +155,21 @@ ${_flutterSection(isPlugin: true)}
${_dependenciesSection()} ${_dependenciesSection()}
${_devDependenciesSection()} ${_devDependenciesSection()}
${_falseSecretsSection()} ${_falseSecretsSection()}
''');
pluginDirectory
.childDirectory('example')
.childFile('pubspec.yaml')
.writeAsStringSync('''
${_headerSection(
'plugin_example',
publishable: false,
includeRepository: false,
includeIssueTracker: false,
)}
${_environmentSection()}
${_dependenciesSection()}
${_flutterSection()}
'''); ''');
final List<String> output = await runCapturingPrint(runner, <String>[ final List<String> output = await runCapturingPrint(runner, <String>[
@ -172,15 +187,31 @@ ${_falseSecretsSection()}
}); });
test('passes for a Flutter package following conventions', () async { test('passes for a Flutter package following conventions', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory packageDirectory =
createFakePackage('a_package', packagesDir);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' packageDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin')} ${_headerSection('a_package')}
${_environmentSection()} ${_environmentSection()}
${_dependenciesSection()} ${_dependenciesSection()}
${_devDependenciesSection()} ${_devDependenciesSection()}
${_flutterSection()} ${_flutterSection()}
${_falseSecretsSection()} ${_falseSecretsSection()}
''');
packageDirectory
.childDirectory('example')
.childFile('pubspec.yaml')
.writeAsStringSync('''
${_headerSection(
'a_package',
publishable: false,
includeRepository: false,
includeIssueTracker: false,
)}
${_environmentSection()}
${_dependenciesSection()}
${_flutterSection()}
'''); ''');
final List<String> output = await runCapturingPrint(runner, <String>[ final List<String> output = await runCapturingPrint(runner, <String>[
@ -190,8 +221,8 @@ ${_falseSecretsSection()}
expect( expect(
output, output,
containsAllInOrder(<Matcher>[ containsAllInOrder(<Matcher>[
contains('Running for plugin...'), contains('Running for a_package...'),
contains('Running for plugin/example...'), contains('Running for a_package/example...'),
contains('No issues found!'), contains('No issues found!'),
]), ]),
); );
@ -221,7 +252,8 @@ ${_dependenciesSection()}
}); });
test('fails when homepage is included', () async { test('fails when homepage is included', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, includeHomepage: true)} ${_headerSection('plugin', isPlugin: true, includeHomepage: true)}
@ -248,7 +280,8 @@ ${_devDependenciesSection()}
}); });
test('fails when repository is missing', () async { test('fails when repository is missing', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, includeRepository: false)} ${_headerSection('plugin', isPlugin: true, includeRepository: false)}
@ -274,7 +307,8 @@ ${_devDependenciesSection()}
}); });
test('fails when homepage is given instead of repository', () async { test('fails when homepage is given instead of repository', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, includeHomepage: true, includeRepository: false)} ${_headerSection('plugin', isPlugin: true, includeHomepage: true, includeRepository: false)}
@ -301,7 +335,8 @@ ${_devDependenciesSection()}
}); });
test('fails when repository is incorrect', () async { test('fails when repository is incorrect', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, repositoryPackagesDirRelativePath: 'different_plugin')} ${_headerSection('plugin', isPlugin: true, repositoryPackagesDirRelativePath: 'different_plugin')}
@ -327,7 +362,8 @@ ${_devDependenciesSection()}
}); });
test('fails when issue tracker is missing', () async { test('fails when issue tracker is missing', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, includeIssueTracker: false)} ${_headerSection('plugin', isPlugin: true, includeIssueTracker: false)}
@ -353,8 +389,9 @@ ${_devDependenciesSection()}
}); });
test('fails when description is too short', () async { test('fails when description is too short', () async {
final Directory pluginDirectory = final Directory pluginDirectory = createFakePlugin(
createFakePlugin('a_plugin', packagesDir.childDirectory('a_plugin')); 'a_plugin', packagesDir.childDirectory('a_plugin'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, description: 'Too short')} ${_headerSection('plugin', isPlugin: true, description: 'Too short')}
@ -383,7 +420,8 @@ ${_devDependenciesSection()}
test( test(
'allows short descriptions for non-app-facing parts of federated plugins', 'allows short descriptions for non-app-facing parts of federated plugins',
() async { () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true, description: 'Too short')} ${_headerSection('plugin', isPlugin: true, description: 'Too short')}
@ -410,7 +448,8 @@ ${_devDependenciesSection()}
}); });
test('fails when description is too long', () async { test('fails when description is too long', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
const String description = 'This description is too long. It just goes ' const String description = 'This description is too long. It just goes '
'on and on and on and on and on. pub.dev will down-score it because ' 'on and on and on and on and on. pub.dev will down-score it because '
@ -442,7 +481,8 @@ ${_devDependenciesSection()}
}); });
test('fails when environment section is out of order', () async { test('fails when environment section is out of order', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true)} ${_headerSection('plugin', isPlugin: true)}
@ -469,7 +509,8 @@ ${_environmentSection()}
}); });
test('fails when flutter section is out of order', () async { test('fails when flutter section is out of order', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true)} ${_headerSection('plugin', isPlugin: true)}
@ -496,7 +537,8 @@ ${_devDependenciesSection()}
}); });
test('fails when dependencies section is out of order', () async { test('fails when dependencies section is out of order', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true)} ${_headerSection('plugin', isPlugin: true)}
@ -550,7 +592,8 @@ ${_dependenciesSection()}
}); });
test('fails when false_secrets section is out of order', () async { test('fails when false_secrets section is out of order', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin', isPlugin: true)} ${_headerSection('plugin', isPlugin: true)}
@ -580,7 +623,8 @@ ${_devDependenciesSection()}
test('fails when an implemenation package is missing "implements"', test('fails when an implemenation package is missing "implements"',
() async { () async {
final Directory pluginDirectory = createFakePlugin( final Directory pluginDirectory = createFakePlugin(
'plugin_a_foo', packagesDir.childDirectory('plugin_a')); 'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin_a_foo', isPlugin: true)} ${_headerSection('plugin_a_foo', isPlugin: true)}
@ -608,7 +652,8 @@ ${_devDependenciesSection()}
test('fails when an implemenation package has the wrong "implements"', test('fails when an implemenation package has the wrong "implements"',
() async { () async {
final Directory pluginDirectory = createFakePlugin( final Directory pluginDirectory = createFakePlugin(
'plugin_a_foo', packagesDir.childDirectory('plugin_a')); 'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('plugin_a_foo', isPlugin: true)} ${_headerSection('plugin_a_foo', isPlugin: true)}
@ -636,7 +681,8 @@ ${_devDependenciesSection()}
test('passes for a correct implemenation package', () async { test('passes for a correct implemenation package', () async {
final Directory pluginDirectory = createFakePlugin( final Directory pluginDirectory = createFakePlugin(
'plugin_a_foo', packagesDir.childDirectory('plugin_a')); 'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection( ${_headerSection(
@ -663,8 +709,9 @@ ${_devDependenciesSection()}
}); });
test('fails when a "default_package" looks incorrect', () async { test('fails when a "default_package" looks incorrect', () async {
final Directory pluginDirectory = final Directory pluginDirectory = createFakePlugin(
createFakePlugin('plugin_a', packagesDir.childDirectory('plugin_a')); 'plugin_a', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection( ${_headerSection(
@ -702,8 +749,9 @@ ${_devDependenciesSection()}
test( test(
'fails when a "default_package" does not have a corresponding dependency', 'fails when a "default_package" does not have a corresponding dependency',
() async { () async {
final Directory pluginDirectory = final Directory pluginDirectory = createFakePlugin(
createFakePlugin('plugin_a', packagesDir.childDirectory('plugin_a')); 'plugin_a', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection( ${_headerSection(
@ -739,8 +787,9 @@ ${_devDependenciesSection()}
}); });
test('passes for an app-facing package without "implements"', () async { test('passes for an app-facing package without "implements"', () async {
final Directory pluginDirectory = final Directory pluginDirectory = createFakePlugin(
createFakePlugin('plugin_a', packagesDir.childDirectory('plugin_a')); 'plugin_a', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection( ${_headerSection(
@ -769,8 +818,8 @@ ${_devDependenciesSection()}
test('passes for a platform interface package without "implements"', test('passes for a platform interface package without "implements"',
() async { () async {
final Directory pluginDirectory = createFakePlugin( final Directory pluginDirectory = createFakePlugin(
'plugin_a_platform_interface', 'plugin_a_platform_interface', packagesDir.childDirectory('plugin_a'),
packagesDir.childDirectory('plugin_a')); examples: <String>[]);
pluginDirectory.childFile('pubspec.yaml').writeAsStringSync(''' pluginDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection( ${_headerSection(
@ -799,7 +848,8 @@ ${_devDependenciesSection()}
test('validates some properties even for unpublished packages', () async { test('validates some properties even for unpublished packages', () async {
final Directory pluginDirectory = createFakePlugin( final Directory pluginDirectory = createFakePlugin(
'plugin_a_foo', packagesDir.childDirectory('plugin_a')); 'plugin_a_foo', packagesDir.childDirectory('plugin_a'),
examples: <String>[]);
// Environment section is in the wrong location. // Environment section is in the wrong location.
// Missing 'implements'. // Missing 'implements'.
@ -829,7 +879,8 @@ ${_environmentSection()}
}); });
test('ignores some checks for unpublished packages', () async { test('ignores some checks for unpublished packages', () async {
final Directory pluginDirectory = createFakePlugin('plugin', packagesDir); final Directory pluginDirectory =
createFakePlugin('plugin', packagesDir, examples: <String>[]);
// Missing metadata that is only useful for published packages, such as // Missing metadata that is only useful for published packages, such as
// repository and issue tracker. // repository and issue tracker.
@ -886,7 +937,7 @@ ${_devDependenciesSection()}
test('repository check works', () async { test('repository check works', () async {
final Directory packageDirectory = final Directory packageDirectory =
createFakePackage('package', packagesDir); createFakePackage('package', packagesDir, examples: <String>[]);
packageDirectory.childFile('pubspec.yaml').writeAsStringSync(''' packageDirectory.childFile('pubspec.yaml').writeAsStringSync('''
${_headerSection('package')} ${_headerSection('package')}

View File

@ -107,6 +107,12 @@ Directory createFakePlugin(
/// ///
/// [extraFiles] is an optional list of package-relative paths, using unix-style /// [extraFiles] is an optional list of package-relative paths, using unix-style
/// separators, of extra files to create in the package. /// separators, of extra files to create in the package.
///
/// If [includeCommonFiles] is true, common but non-critical files like
/// CHANGELOG.md and AUTHORS will be included.
///
/// If non-null, [directoryName] will be used for the directory instead of
/// [name].
// TODO(stuartmorgan): Convert the return to a RepositoryPackage. // TODO(stuartmorgan): Convert the return to a RepositoryPackage.
Directory createFakePackage( Directory createFakePackage(
String name, String name,
@ -116,37 +122,43 @@ Directory createFakePackage(
bool isFlutter = false, bool isFlutter = false,
String? version = '0.0.1', String? version = '0.0.1',
String flutterConstraint = '>=2.5.0', String flutterConstraint = '>=2.5.0',
bool includeCommonFiles = true,
String? directoryName,
String? publishTo,
}) { }) {
final Directory packageDirectory = parentDirectory.childDirectory(name); final Directory packageDirectory =
parentDirectory.childDirectory(directoryName ?? name);
packageDirectory.createSync(recursive: true); packageDirectory.createSync(recursive: true);
packageDirectory.childDirectory('lib').createSync();
createFakePubspec(packageDirectory, createFakePubspec(packageDirectory,
name: name, name: name,
isFlutter: isFlutter, isFlutter: isFlutter,
version: version, version: version,
flutterConstraint: flutterConstraint); flutterConstraint: flutterConstraint);
createFakeCHANGELOG(packageDirectory, ''' if (includeCommonFiles) {
createFakeCHANGELOG(packageDirectory, '''
## $version ## $version
* Some changes. * Some changes.
'''); ''');
createFakeAuthors(packageDirectory); createFakeAuthors(packageDirectory);
}
if (examples.length == 1) { if (examples.length == 1) {
final Directory exampleDir = packageDirectory.childDirectory(examples.first) createFakePackage('${name}_example', packageDirectory,
..createSync(); directoryName: examples.first,
createFakePubspec(exampleDir, examples: <String>[],
name: '${name}_example', includeCommonFiles: false,
isFlutter: isFlutter, isFlutter: isFlutter,
publishTo: 'none', publishTo: 'none',
flutterConstraint: flutterConstraint); flutterConstraint: flutterConstraint);
} else if (examples.isNotEmpty) { } else if (examples.isNotEmpty) {
final Directory exampleDir = packageDirectory.childDirectory('example') final Directory examplesDirectory =
..createSync(); packageDirectory.childDirectory('example')..createSync();
for (final String example in examples) { for (final String exampleName in examples) {
final Directory currentExample = exampleDir.childDirectory(example) createFakePackage(exampleName, examplesDirectory,
..createSync(); examples: <String>[],
createFakePubspec(currentExample, includeCommonFiles: false,
name: example,
isFlutter: isFlutter, isFlutter: isFlutter,
publishTo: 'none', publishTo: 'none',
flutterConstraint: flutterConstraint); flutterConstraint: flutterConstraint);
@ -179,7 +191,7 @@ void createFakePubspec(
bool isPlugin = false, bool isPlugin = false,
Map<String, PlatformDetails> platformSupport = Map<String, PlatformDetails> platformSupport =
const <String, PlatformDetails>{}, const <String, PlatformDetails>{},
String publishTo = 'http://no_pub_server.com', String? publishTo,
String? version, String? version,
String dartConstraint = '>=2.0.0 <3.0.0', String dartConstraint = '>=2.0.0 <3.0.0',
String flutterConstraint = '>=2.5.0', String flutterConstraint = '>=2.5.0',
@ -219,9 +231,16 @@ flutter:
} }
} }
String yaml = ''' // Default to a fake server to avoid ever accidentally publishing something
// from a test. Does not use 'none' since that changes the behavior of some
// commands.
final String publishToSection =
'publish_to: ${publishTo ?? 'http://no_pub_server.com'}';
final String yaml = '''
name: $name name: $name
${(version != null) ? 'version: $version' : ''} ${(version != null) ? 'version: $version' : ''}
$publishToSection
$environmentSection $environmentSection
@ -230,11 +249,6 @@ $dependenciesSection
$pluginSection $pluginSection
'''; ''';
if (publishTo.isNotEmpty) {
yaml += '''
publish_to: $publishTo # Hardcoded safeguard to prevent this from somehow being published by a broken test.
''';
}
parent.childFile('pubspec.yaml').createSync(); parent.childFile('pubspec.yaml').createSync();
parent.childFile('pubspec.yaml').writeAsStringSync(yaml); parent.childFile('pubspec.yaml').writeAsStringSync(yaml);
} }