Unverified Commit 2e63b7d4 authored by Chris Yang's avatar Chris Yang Committed by GitHub

Add `--platforms` to `flutter create -t plugin` command (#59507)

parent 14992c59
...@@ -41,7 +41,7 @@ Future<void> main() async { ...@@ -41,7 +41,7 @@ Future<void> main() async {
await inDirectory(tempDir, () async { await inDirectory(tempDir, () async {
await flutter( await flutter(
'create', 'create',
options: <String>['--org', 'io.flutter.devicelab', '--template', 'plugin', 'plugin_with_android'], options: <String>['--org', 'io.flutter.devicelab', '--template', 'plugin', '--platforms=android', 'plugin_with_android'],
); );
}); });
...@@ -50,25 +50,10 @@ Future<void> main() async { ...@@ -50,25 +50,10 @@ Future<void> main() async {
await inDirectory(tempDir, () async { await inDirectory(tempDir, () async {
await flutter( await flutter(
'create', 'create',
options: <String>['--org', 'io.flutter.devicelab', '--template', 'plugin', 'plugin_without_android'], options: <String>['--org', 'io.flutter.devicelab', '--template', 'plugin', '--platforms=ios', 'plugin_without_android'],
); );
}); });
// Delete the android/ directory.
File(path.join(
tempDir.path,
'plugin_without_android',
'android'
)).deleteSync(recursive: true);
// Remove Android support from the plugin pubspec.yaml
final File pluginPubspec = File(path.join(tempDir.path, 'plugin_without_android', 'pubspec.yaml'));
pluginPubspec.writeAsStringSync(pluginPubspec.readAsStringSync().replaceFirst('''
android:
package: io.flutter.devicelab.plugin_without_android
pluginClass: PluginWithoutAndroidPlugin
''', ''), flush: true);
section('Add plugins to pubspec.yaml'); section('Add plugins to pubspec.yaml');
final File modulePubspec = File(path.join(projectDir.path, 'pubspec.yaml')); final File modulePubspec = File(path.join(projectDir.path, 'pubspec.yaml'));
......
...@@ -32,6 +32,7 @@ Future<void> main() async { ...@@ -32,6 +32,7 @@ Future<void> main() async {
options: <String>[ options: <String>[
'--org', 'io.flutter.devicelab', '--org', 'io.flutter.devicelab',
'-t', 'plugin', '-t', 'plugin',
'--platforms=ios,android',
'ios_only', 'ios_only',
], ],
); );
......
...@@ -40,6 +40,7 @@ Future<void> main() async { ...@@ -40,6 +40,7 @@ Future<void> main() async {
'--org', '--org',
'io.flutter.devicelab.plugin_a', 'io.flutter.devicelab.plugin_a',
'--template=plugin', '--template=plugin',
'--platforms=android,ios',
pluginADirectory.path, pluginADirectory.path,
], ],
); );
...@@ -55,6 +56,7 @@ Future<void> main() async { ...@@ -55,6 +56,7 @@ Future<void> main() async {
'--org', '--org',
'io.flutter.devicelab.plugin_b', 'io.flutter.devicelab.plugin_b',
'--template=plugin', '--template=plugin',
'--platforms=android,ios',
pluginBDirectory.path, pluginBDirectory.path,
], ],
); );
...@@ -70,6 +72,7 @@ Future<void> main() async { ...@@ -70,6 +72,7 @@ Future<void> main() async {
'--org', '--org',
'io.flutter.devicelab.plugin_c', 'io.flutter.devicelab.plugin_c',
'--template=plugin', '--template=plugin',
'--platforms=ios',
pluginCDirectory.path, pluginCDirectory.path,
], ],
); );
......
...@@ -26,6 +26,7 @@ Future<void> main() async { ...@@ -26,6 +26,7 @@ Future<void> main() async {
'--org', '--org',
'io.flutter.devicelab', 'io.flutter.devicelab',
'--template=plugin', '--template=plugin',
'--platforms=ios,android',
'--ios-language=objc', '--ios-language=objc',
objcPluginName, objcPluginName,
], ],
...@@ -79,6 +80,7 @@ Future<void> main() async { ...@@ -79,6 +80,7 @@ Future<void> main() async {
'--org', '--org',
'io.flutter.devicelab', 'io.flutter.devicelab',
'--template=plugin', '--template=plugin',
'--platforms=ios,android',
'--ios-language=swift', '--ios-language=swift',
swiftPluginName, swiftPluginName,
], ],
......
...@@ -9,14 +9,14 @@ import 'package:flutter_devicelab/framework/framework.dart'; ...@@ -9,14 +9,14 @@ import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async { Future<void> main() async {
await task(combine(<TaskFunction>[ await task(combine(<TaskFunction>[
PluginTest('apk', <String>['-a', 'java']), PluginTest('apk', <String>['-a', 'java', '--platforms=android']),
PluginTest('apk', <String>['-a', 'kotlin']), PluginTest('apk', <String>['-a', 'kotlin', '--platforms=android']),
// These create the plugins using the new v2 plugin templates but create the // These create the plugins using the new v2 plugin templates but create the
// apps using the old v1 embedding app templates to make sure new plugins // apps using the old v1 embedding app templates to make sure new plugins
// are by default backward compatible. // are by default backward compatible.
PluginTest('apk', <String>['-a', 'java'], pluginCreateEnvironment: PluginTest('apk', <String>['-a', 'java', '--platforms=android'], pluginCreateEnvironment:
<String, String>{'ENABLE_ANDROID_EMBEDDING_V2': 'true'}), <String, String>{'ENABLE_ANDROID_EMBEDDING_V2': 'true'}),
PluginTest('apk', <String>['-a', 'kotlin'], pluginCreateEnvironment: PluginTest('apk', <String>['-a', 'kotlin', '--platforms=android'], pluginCreateEnvironment:
<String, String>{'ENABLE_ANDROID_EMBEDDING_V2': 'true'}), <String, String>{'ENABLE_ANDROID_EMBEDDING_V2': 'true'}),
])); ]));
} }
...@@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart'; ...@@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async { Future<void> main() async {
await task(combine(<TaskFunction>[ await task(combine(<TaskFunction>[
PluginTest('ios', <String>['-i', 'objc']), PluginTest('ios', <String>['-i', 'objc', '--platforms=ios']),
PluginTest('ios', <String>['-i', 'swift']), PluginTest('ios', <String>['-i', 'swift', '--platforms=ios']),
])); ]));
} }
...@@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart'; ...@@ -9,7 +9,7 @@ import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async { Future<void> main() async {
await task(combine(<TaskFunction>[ await task(combine(<TaskFunction>[
PluginTest('apk', <String>['-a', 'java']), PluginTest('apk', <String>['-a', 'java', '--platforms=android']),
PluginTest('apk', <String>['-a', 'kotlin']), PluginTest('apk', <String>['-a', 'kotlin', '--platforms=android']),
])); ]));
} }
...@@ -351,7 +351,7 @@ class FlutterPluginProject { ...@@ -351,7 +351,7 @@ class FlutterPluginProject {
static Future<FlutterPluginProject> create(Directory directory, String name) async { static Future<FlutterPluginProject> create(Directory directory, String name) async {
await inDirectory(directory, () async { await inDirectory(directory, () async {
await flutter('create', options: <String>['--template=plugin', name]); await flutter('create', options: <String>['--template=plugin', '--platforms=ios,android', name]);
}); });
return FlutterPluginProject(directory, name); return FlutterPluginProject(directory, name);
} }
......
...@@ -163,17 +163,16 @@ class FlutterManifest { ...@@ -163,17 +163,16 @@ class FlutterManifest {
if (isModule) { if (isModule) {
return _flutterDescriptor['module']['androidPackage'] as String; return _flutterDescriptor['module']['androidPackage'] as String;
} }
if (isPlugin) { if (supportedPlatforms == null) {
final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap; // Pre-multi-platform plugin format
if (plugin.containsKey('platforms')) { if (isPlugin) {
final YamlMap platforms = plugin['platforms'] as YamlMap; final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap;
if (platforms.containsKey('android')) {
return platforms['android']['package'] as String;
}
} else {
return plugin['androidPackage'] as String; return plugin['androidPackage'] as String;
} }
return null;
}
if (supportedPlatforms.containsKey('android')) {
return supportedPlatforms['android']['package'] as String;
} }
return null; return null;
} }
...@@ -187,6 +186,20 @@ class FlutterManifest { ...@@ -187,6 +186,20 @@ class FlutterManifest {
return null; return null;
} }
/// Gets the supported platforms. This only supports the new `platforms` format.
///
/// If the plugin uses the legacy pubspec format, this method returns null.
Map<String, dynamic> get supportedPlatforms {
if (isPlugin) {
final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap;
if (plugin.containsKey('platforms')) {
final YamlMap platformsMap = plugin['platforms'] as YamlMap;
return platformsMap.value.cast<String, dynamic>();
}
}
return null;
}
List<Map<String, dynamic>> get fontsDescriptor { List<Map<String, dynamic>> get fontsDescriptor {
return fonts.map((Font font) => font.descriptor).toList(); return fonts.map((Font font) => font.descriptor).toList();
} }
......
...@@ -174,6 +174,25 @@ class Plugin { ...@@ -174,6 +174,25 @@ class Plugin {
); );
} }
/// Create a YamlMap that represents the supported platforms.
///
/// For example, if the `platforms` contains 'ios' and 'android', the return map looks like:
/// android:
/// package: io.flutter.plugins.sample
/// pluginClass: SamplePlugin
/// ios:
/// pluginClass: SamplePlugin
static YamlMap createPlatformsYamlMap(List<String> platforms, String pluginClass, String androidPackage) {
final Map<String, dynamic> map = <String, dynamic>{};
for (final String platform in platforms) {
map[platform] = <String, String>{
'pluginClass': pluginClass,
...platform == 'android' ? <String, String>{'package': androidPackage} : <String, String>{},
};
}
return YamlMap.wrap(map);
}
static List<String> validatePluginYaml(YamlMap yaml) { static List<String> validatePluginYaml(YamlMap yaml) {
if (yaml == null) { if (yaml == null) {
return <String>['Invalid "plugin" specification.']; return <String>['Invalid "plugin" specification.'];
......
...@@ -225,6 +225,9 @@ class FlutterProject { ...@@ -225,6 +225,9 @@ class FlutterProject {
/// Generates project files necessary to make Gradle builds work on Android /// Generates project files necessary to make Gradle builds work on Android
/// and CocoaPods+Xcode work on iOS, for app and module projects only. /// and CocoaPods+Xcode work on iOS, for app and module projects only.
// TODO(cyanglaz): The param `checkProjects` is confusing. We should give it a better name
// or add some documentation explaining what it does, or both.
// https://github.com/flutter/flutter/issues/60023
Future<void> ensureReadyForPlatformSpecificTooling({bool checkProjects = false}) async { Future<void> ensureReadyForPlatformSpecificTooling({bool checkProjects = false}) async {
if (!directory.existsSync() || hasExampleApp) { if (!directory.existsSync() || hasExampleApp) {
return; return;
...@@ -648,6 +651,7 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { ...@@ -648,6 +651,7 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
template.render( template.render(
target, target,
<String, dynamic>{ <String, dynamic>{
'ios': true,
'projectName': parent.manifest.appName, 'projectName': parent.manifest.appName,
'iosIdentifier': parent.manifest.iosBundleIdentifier, 'iosIdentifier': parent.manifest.iosBundleIdentifier,
}, },
...@@ -797,6 +801,7 @@ class AndroidProject extends FlutterProjectPlatform { ...@@ -797,6 +801,7 @@ class AndroidProject extends FlutterProjectPlatform {
template.render( template.render(
target, target,
<String, dynamic>{ <String, dynamic>{
'android': true,
'projectName': parent.manifest.appName, 'projectName': parent.manifest.appName,
'androidIdentifier': parent.manifest.androidPackage, 'androidIdentifier': parent.manifest.androidPackage,
'androidX': usesAndroidX, 'androidX': usesAndroidX,
......
...@@ -108,6 +108,16 @@ class Template { ...@@ -108,6 +108,16 @@ class Template {
} }
relativeDestinationPath = relativeDestinationPath.replaceAll('$platform-$language.tmpl', platform); relativeDestinationPath = relativeDestinationPath.replaceAll('$platform-$language.tmpl', platform);
} }
final bool android = context['android'] as bool;
if (relativeDestinationPath.contains('android') && !android) {
return null;
}
// TODO(cyanglaz): do not add iOS folder by default when 1.20.0 is released.
// Also need to update the flutter SDK min constraint in the pubspec.yaml to 1.20.0.
// https://github.com/flutter/flutter/issues/59787
// Only build a web project if explicitly asked. // Only build a web project if explicitly asked.
final bool web = context['web'] as bool; final bool web = context['web'] as bool;
if (relativeDestinationPath.contains('web') && !web) { if (relativeDestinationPath.contains('web') && !web) {
...@@ -128,6 +138,7 @@ class Template { ...@@ -128,6 +138,7 @@ class Template {
if (relativeDestinationPath.startsWith('windows.tmpl') && !windows) { if (relativeDestinationPath.startsWith('windows.tmpl') && !windows) {
return null; return null;
} }
final String projectName = context['projectName'] as String; final String projectName = context['projectName'] as String;
final String androidIdentifier = context['androidIdentifier'] as String; final String androidIdentifier = context['androidIdentifier'] as String;
final String pluginClass = context['pluginClass'] as String; final String pluginClass = context['pluginClass'] as String;
...@@ -139,7 +150,7 @@ class Template { ...@@ -139,7 +150,7 @@ class Template {
.replaceAll(imageTemplateExtension, '') .replaceAll(imageTemplateExtension, '')
.replaceAll(templateExtension, ''); .replaceAll(templateExtension, '');
if (androidIdentifier != null) { if (android != null && android && androidIdentifier != null) {
finalDestinationPath = finalDestinationPath finalDestinationPath = finalDestinationPath
.replaceAll('androidIdentifier', androidIdentifier.replaceAll('.', pathSeparator)); .replaceAll('androidIdentifier', androidIdentifier.replaceAll('.', pathSeparator));
} }
......
...@@ -9,6 +9,12 @@ This project is a starting point for a Flutter ...@@ -9,6 +9,12 @@ This project is a starting point for a Flutter
a specialized package that includes platform-specific implementation code for a specialized package that includes platform-specific implementation code for
Android and/or iOS. Android and/or iOS.
For help getting started with Flutter, view our For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials, [online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference. samples, guidance on mobile development, and a full API reference.
{{#no_platforms}}
The plugin project was generated without specifying the `--platforms` flag, no platforms are currently supported.
To add platforms, run `flutter create -t plugin --platforms <platforms> .` under the same
directory. You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms.
{{/no_platforms}}
{{#no_platforms}}
// You have generated a new plugin project without
// specifying the `--platforms` flag. A plugin project supports no platforms is generated.
// To add platforms, run `flutter create -t plugin --platforms <platforms> .` under the same
// directory. You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms.
{{/no_platforms}}
import 'dart:async'; import 'dart:async';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
......
...@@ -31,11 +31,25 @@ flutter: ...@@ -31,11 +31,25 @@ flutter:
# adding or updating assets for this project. # adding or updating assets for this project.
plugin: plugin:
platforms: platforms:
{{#no_platforms}}
# This plugin project was generated without specifying any
# platforms with the `--platform` argument. If you see the `fake_platform` map below, remove it and
# then add platforms following the instruction here:
# https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms
# -------------------
some_platform:
pluginClass: somePluginClass
# -------------------
{{/no_platforms}}
{{#android}}
android: android:
package: {{androidIdentifier}} package: {{androidIdentifier}}
pluginClass: {{pluginClass}} pluginClass: {{pluginClass}}
{{/android}}
{{#ios}}
ios: ios:
pluginClass: {{pluginClass}} pluginClass: {{pluginClass}}
{{/ios}}
{{#linux}} {{#linux}}
linux: linux:
pluginClass: {{pluginClass}} pluginClass: {{pluginClass}}
...@@ -44,6 +58,10 @@ flutter: ...@@ -44,6 +58,10 @@ flutter:
macos: macos:
pluginClass: {{pluginClass}} pluginClass: {{pluginClass}}
{{/macos}} {{/macos}}
{{#windows}}
windows:
pluginClass: {{pluginClass}}
{{/windows}}
{{#web}} {{#web}}
web: web:
pluginClass: {{pluginDartClass}}Web pluginClass: {{pluginDartClass}}Web
......
...@@ -375,7 +375,7 @@ void main() { ...@@ -375,7 +375,7 @@ void main() {
testUsingContext('get fetches packages and injects plugin in plugin project', () async { testUsingContext('get fetches packages and injects plugin in plugin project', () async {
final String projectPath = await createProject( final String projectPath = await createProject(
tempDir, tempDir,
arguments: <String>['--template=plugin', '--no-pub'], arguments: <String>['--template=plugin', '--no-pub', '--platforms=ios,android'],
); );
final String exampleProjectPath = globals.fs.path.join(projectPath, 'example'); final String exampleProjectPath = globals.fs.path.join(projectPath, 'example');
removeGeneratedFiles(projectPath); removeGeneratedFiles(projectPath);
......
...@@ -900,6 +900,49 @@ flutter: ...@@ -900,6 +900,49 @@ flutter:
expect(flutterManifest.isEmpty, false); expect(flutterManifest.isEmpty, false);
}); });
testWithoutContext('FlutterManifest getSupportedPlatforms return null if runs on legacy format', () {
const String manifest = '''
name: test
flutter:
plugin:
androidPackage: com.example
''';
final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest,
logger: logger,
);
expect(flutterManifest.isPlugin, true);
expect(flutterManifest.supportedPlatforms, null);
});
testWithoutContext('FlutterManifest getSupportedPlatforms returns valid platforms.', () {
const String manifest = '''
name: test
flutter:
plugin:
platforms:
android:
package: com.example
pluginClass: SomeClass
ios:
pluginClass: SomeClass
''';
final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest,
logger: logger,
);
expect(flutterManifest.isPlugin, true);
expect(flutterManifest.supportedPlatforms['ios'],
<String, dynamic>{'pluginClass': 'SomeClass'});
expect(flutterManifest.supportedPlatforms['android'],
<String, dynamic>{'pluginClass': 'SomeClass',
'package': 'com.example'});
});
} }
Matcher matchesManifest({ Matcher matchesManifest({
......
...@@ -10,15 +10,18 @@ import 'package:file_testing/file_testing.dart'; ...@@ -10,15 +10,18 @@ import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/time.dart'; import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/dart/package_map.dart'; import 'package:flutter_tools/src/dart/package_map.dart';
import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/xcodeproj.dart'; import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/plugins.dart'; import 'package:flutter_tools/src/plugins.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/version.dart'; import 'package:flutter_tools/src/version.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:yaml/yaml.dart';
import '../src/common.dart'; import '../src/common.dart';
import '../src/context.dart'; import '../src/context.dart';
import '../src/pubspec_schema.dart';
void main() { void main() {
group('plugins', () { group('plugins', () {
...@@ -109,16 +112,14 @@ void main() { ...@@ -109,16 +112,14 @@ void main() {
..writeAsStringSync('apackage:file://${dummyPackageDirectory.path}\n'); ..writeAsStringSync('apackage:file://${dummyPackageDirectory.path}\n');
}); });
// Makes the dummy package pointed to by packagesFile look like a plugin. const String _pluginYaml = '''
void configureDummyPackageAsPlugin() {
dummyPackageDirectory.parent.childFile('pubspec.yaml')..createSync(recursive: true)..writeAsStringSync('''
flutter: flutter:
plugin: plugin:
platforms: platforms:
ios: ios:
pluginClass: FLESomePlugin pluginClass: SomePlugin
macos: macos:
pluginClass: FLESomePlugin pluginClass: SomePlugin
windows: windows:
pluginClass: SomePlugin pluginClass: SomePlugin
linux: linux:
...@@ -129,7 +130,10 @@ void main() { ...@@ -129,7 +130,10 @@ void main() {
android: android:
pluginClass: SomePlugin pluginClass: SomePlugin
package: AndroidPackage package: AndroidPackage
'''); ''';
// Makes the dummy package pointed to by packagesFile look like a plugin.
void configureDummyPackageAsPlugin() {
dummyPackageDirectory.parent.childFile('pubspec.yaml')..createSync(recursive: true)..writeAsStringSync(_pluginYaml);
} }
void createNewJavaPlugin1() { void createNewJavaPlugin1() {
...@@ -1298,6 +1302,51 @@ flutter: ...@@ -1298,6 +1302,51 @@ flutter:
FeatureFlags: () => featureFlags, FeatureFlags: () => featureFlags,
}); });
}); });
group('pubspec', () {
Directory projectDir;
Directory tempDir;
setUp(() {
tempDir = globals.fs.systemTempDirectory.createTempSync('plugin_test.');
projectDir = tempDir.childDirectory('flutter_project');
});
tearDown(() {
tryToDelete(tempDir);
});
void _createPubspecFile(String yamlString) {
projectDir.childFile('pubspec.yaml')..createSync(recursive: true)..writeAsStringSync(yamlString);
}
test('validatePubspecForPlugin works', () async {
_createPubspecFile(_pluginYaml);
validatePubspecForPlugin(projectDir: projectDir.absolute.path, pluginClass: 'SomePlugin', expectedPlatforms: <String>[
'ios', 'macos', 'windows', 'linux', 'android', 'web'
], androidIdentifier: 'AndroidPackage', webFileName: 'lib/SomeFile.dart');
});
test('createPlatformsYamlMap should create the correct map', () async {
final YamlMap map = Plugin.createPlatformsYamlMap(<String>['ios', 'android', 'linux'], 'PluginClass', 'some.android.package');
expect(map['ios'], <String, String> {
'pluginClass' : 'PluginClass'
});
expect(map['android'], <String, String> {
'pluginClass' : 'PluginClass',
'package': 'some.android.package',
});
expect(map['linux'], <String, String> {
'pluginClass' : 'PluginClass'
});
});
test('createPlatformsYamlMap should create empty map', () async {
final YamlMap map = Plugin.createPlatformsYamlMap(<String>[], null, null);
expect(map.isEmpty, true);
});
});
}); });
} }
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/flutter_manifest.dart'; import 'package:flutter_tools/src/flutter_manifest.dart';
import 'package:meta/meta.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:yaml/yaml.dart';
import 'common.dart';
/// Writes a schemaData used for validating pubspec.yaml files when parsing /// Writes a schemaData used for validating pubspec.yaml files when parsing
/// asset information. /// asset information.
...@@ -22,3 +26,22 @@ void writeSchemaFile(FileSystem filesystem, String schemaData) { ...@@ -22,3 +26,22 @@ void writeSchemaFile(FileSystem filesystem, String schemaData) {
void writeEmptySchemaFile(FileSystem filesystem) { void writeEmptySchemaFile(FileSystem filesystem) {
writeSchemaFile(filesystem, '{}'); writeSchemaFile(filesystem, '{}');
} }
/// Check if the pubspec.yaml file under the `projectDir` is valid for a plugin project.
void validatePubspecForPlugin({@required String projectDir, @required String pluginClass, @required List<String> expectedPlatforms, List<String> unexpectedPlatforms = const <String>[], String androidIdentifier, String webFileName}) {
final FlutterManifest manifest = FlutterManifest.createFromPath(projectDir+'/pubspec.yaml', fileSystem: globals.fs, logger: globals.logger);
final YamlMap platformsMap = YamlMap.wrap(manifest.supportedPlatforms);
for (final String platform in expectedPlatforms) {
expect(platformsMap[platform], isNotNull);
expect(platformsMap[platform]['pluginClass'], pluginClass);
if (platform == 'android') {
expect(platformsMap[platform]['package'], androidIdentifier);
}
if (platform == 'web') {
expect(platformsMap[platform]['fileName'], webFileName);
}
}
for (final String platform in unexpectedPlatforms) {
expect(platformsMap[platform], isNull);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment