Unverified Commit 0a08f8af authored by Chris Yang's avatar Chris Yang Committed by GitHub

[flutter_tools] Display "no platforms" message based on results when creating...

[flutter_tools] Display "no platforms" message based on results when creating plugins project (#70215)
parent 2b85eeed
...@@ -2,8 +2,6 @@ ...@@ -2,8 +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:yaml/yaml.dart';
import '../android/gradle_utils.dart' as gradle; import '../android/gradle_utils.dart' as gradle;
import '../base/common.dart'; import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
...@@ -17,19 +15,11 @@ import '../features.dart'; ...@@ -17,19 +15,11 @@ import '../features.dart';
import '../flutter_manifest.dart'; import '../flutter_manifest.dart';
import '../flutter_project_metadata.dart'; import '../flutter_project_metadata.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../plugins.dart';
import '../project.dart'; import '../project.dart';
import '../reporting/reporting.dart'; import '../reporting/reporting.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import 'create_base.dart'; import 'create_base.dart';
const String _kNoPlatformsErrorMessage = '''
The plugin project was generated without specifying the `--platforms` flag, no new platforms are added.
To add platforms, run `flutter create -t plugin --platforms <platforms> .` under the same
directory. You can also find detailed instructions on how to add platforms in the `pubspec.yaml`
at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms.
''';
class CreateCommand extends CreateBase { class CreateCommand extends CreateBase {
CreateCommand() { CreateCommand() {
addPlatformsOptions(customHelp: 'The platforms supported by this project. ' addPlatformsOptions(customHelp: 'The platforms supported by this project. '
...@@ -249,7 +239,8 @@ class CreateCommand extends CreateBase { ...@@ -249,7 +239,8 @@ class CreateCommand extends CreateBase {
); );
final String relativeDirPath = globals.fs.path.relative(projectDirPath); final String relativeDirPath = globals.fs.path.relative(projectDirPath);
if (!projectDir.existsSync() || projectDir.listSync().isEmpty) { final bool creatingNewProject = !projectDir.existsSync() || projectDir.listSync().isEmpty;
if (creatingNewProject) {
globals.printStatus('Creating project $relativeDirPath...'); globals.printStatus('Creating project $relativeDirPath...');
} else { } else {
if (sampleCode != null && !overwrite) { if (sampleCode != null && !overwrite) {
...@@ -295,18 +286,24 @@ class CreateCommand extends CreateBase { ...@@ -295,18 +286,24 @@ class CreateCommand extends CreateBase {
'main.dart', 'main.dart',
)); ));
globals.printStatus('Your module code is in $relativeMainPath.'); globals.printStatus('Your module code is in $relativeMainPath.');
} else { } else if (generatePlugin) {
final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath));
final List<String> requestedPlatforms = _getUserRequestedPlatforms();
final String platformsString = requestedPlatforms.join(', ');
_printPluginDirectoryLocationMessage(relativePluginPath, projectName, platformsString);
if (!creatingNewProject && requestedPlatforms.isNotEmpty) {
_printPluginUpdatePubspecMessage(relativePluginPath, platformsString);
} else if (_getSupportedPlatformsInPlugin(projectDir).isEmpty){
globals.printError(_kNoPlatformsArgMessage);
}
} else {
// Tell the user the next steps. // Tell the user the next steps.
final FlutterProject project = FlutterProject.fromPath(projectDirPath); final FlutterProject project = FlutterProject.fromPath(projectDirPath);
final FlutterProject app = project.hasExampleApp ? project.example : project; final FlutterProject app = project.hasExampleApp ? project.example : project;
final String relativeAppPath = globals.fs.path.normalize(globals.fs.path.relative(app.directory.path)); final String relativeAppPath = globals.fs.path.normalize(globals.fs.path.relative(app.directory.path));
final String relativeAppMain = globals.fs.path.join(relativeAppPath, 'lib', 'main.dart'); final String relativeAppMain = globals.fs.path.join(relativeAppPath, 'lib', 'main.dart');
final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath));
final String relativePluginMain = globals.fs.path.join(relativePluginPath, 'lib', '$projectName.dart');
// Let them know a summary of the state of their tooling. // Let them know a summary of the state of their tooling.
final List<String> platforms = _getSupportedPlatformsFromTemplateContext(templateContext);
final String platformsString = platforms.join(', ');
globals.printStatus(''' globals.printStatus('''
In order to run your $application, type: In order to run your $application, type:
...@@ -315,14 +312,6 @@ In order to run your $application, type: ...@@ -315,14 +312,6 @@ In order to run your $application, type:
Your $application code is in $relativeAppMain. Your $application code is in $relativeAppMain.
'''); ''');
if (generatePlugin) {
globals.printStatus('''
Your plugin code is in $relativePluginMain.
Host platform code is in the $platformsString directories under $relativePluginPath.
To edit platform code in an IDE see https://flutter.dev/developing-packages/#edit-plugin-package.
''');
}
} }
return FlutterCommandResult.success(); return FlutterCommandResult.success();
} }
...@@ -378,19 +367,13 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -378,19 +367,13 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
templateContext['linux'] = false; templateContext['linux'] = false;
templateContext['macos'] = false; templateContext['macos'] = false;
templateContext['windows'] = false; templateContext['windows'] = false;
globals.printError(_kNoPlatformsErrorMessage);
} }
final List<String> platformsToAdd = _getSupportedPlatformsFromTemplateContext(templateContext); final List<String> platformsToAdd = _getSupportedPlatformsFromTemplateContext(templateContext);
final String pubspecPath = globals.fs.path.join(directory.absolute.path, 'pubspec.yaml'); final List<String> existingPlatforms = _getSupportedPlatformsInPlugin(directory);
final FlutterManifest manifest = FlutterManifest.createFromPath(pubspecPath, fileSystem: globals.fs, logger: globals.logger); for (final String existingPlatform in existingPlatforms) {
List<String> existingPlatforms = <String>[]; // re-generate files for existing platforms
if (manifest.supportedPlatforms != null) { templateContext[existingPlatform] = true;
existingPlatforms = manifest.supportedPlatforms.keys.toList();
for (final String existingPlatform in existingPlatforms) {
// re-generate files for existing platforms
templateContext[existingPlatform] = true;
}
} }
final bool willAddPlatforms = platformsToAdd.isNotEmpty; final bool willAddPlatforms = platformsToAdd.isNotEmpty;
...@@ -411,35 +394,6 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -411,35 +394,6 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
); );
} }
final bool addPlatformsToExistingPlugin = willAddPlatforms && existingPlatforms.isNotEmpty;
if (addPlatformsToExistingPlugin) {
// If adding new platforms to an existing plugin project, prints
// a help message containing the platforms maps need to be added to the `platforms` key in the pubspec.
platformsToAdd.removeWhere(existingPlatforms.contains);
final YamlMap platformsMapToPrint = Plugin.createPlatformsYamlMap(platformsToAdd, templateContext['pluginClass'] as String, templateContext['androidIdentifier'] as String);
if (platformsMapToPrint.isNotEmpty) {
String prettyYaml = '';
for (final String platform in platformsMapToPrint.keys.toList().cast<String>()) {
prettyYaml += '$platform:\n';
for (final String key in (platformsMapToPrint[platform] as YamlMap).keys.toList().cast<String>()) {
prettyYaml += ' $key: ${platformsMapToPrint[platform][key] as String}\n';
}
}
globals.printStatus('''
The `pubspec.yaml` under the project directory must be updated to support ${platformsToAdd.join(', ')},
Add below lines to under the `platform:` key:
''', emphasis: true);
globals.printStatus(prettyYaml, emphasis: true, color: TerminalColor.blue);
globals.printStatus('''
If the `platforms` key does not exist in the `pubspec.yaml`, it might because that the plugin project does not
use the multi-platforms plugin format. We highly recommend a migration to the multi-platforms plugin format.
For detailed instructions on how to format the pubspec.yaml to support platforms using the multi-platforms format, see:
https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms
''', emphasis: true);
}
}
final FlutterProject project = FlutterProject.fromDirectory(directory); final FlutterProject project = FlutterProject.fromDirectory(directory);
final bool generateAndroid = templateContext['android'] == true; final bool generateAndroid = templateContext['android'] == true;
if (generateAndroid) { if (generateAndroid) {
...@@ -493,4 +447,57 @@ https://flutter.dev/docs/development/packages-and-plugins/developing-packages#pl ...@@ -493,4 +447,57 @@ https://flutter.dev/docs/development/packages-and-plugins/developing-packages#pl
'macos', 'macos',
]; ];
} }
// Returns a list of platforms that are explicitly requested by user via `--platforms`.
List<String> _getUserRequestedPlatforms() {
if (!argResults.wasParsed('platforms')) {
return <String>[];
}
return stringsArg('platforms');
}
}
// Determine what platforms are supported based on generated files.
List<String> _getSupportedPlatformsInPlugin(Directory projectDir) {
final String pubspecPath = globals.fs.path.join(projectDir.absolute.path, 'pubspec.yaml');
final FlutterManifest manifest = FlutterManifest.createFromPath(pubspecPath, fileSystem: globals.fs, logger: globals.logger);
final List<String> platforms = manifest.validSupportedPlatforms == null
? <String>[]
: manifest.validSupportedPlatforms.keys.toList();
return platforms;
} }
void _printPluginDirectoryLocationMessage(String pluginPath, String projectName, String platformsString) {
final String relativePluginMain = globals.fs.path.join(pluginPath, 'lib', '$projectName.dart');
final String relativeExampleMain = globals.fs.path.join(pluginPath, 'example', 'lib', 'main.dart');
globals.printStatus('''
Your plugin code is in $relativePluginMain.
You example app code is in $relativeExampleMain.
''');
if (platformsString != null && platformsString.isNotEmpty) {
globals.printStatus('''
Host platform code is in the $platformsString directories under $pluginPath.
To edit platform code in an IDE see https://flutter.dev/developing-packages/#edit-plugin-package.
''');
}
}
void _printPluginUpdatePubspecMessage(String pluginPath, String platformsString) {
globals.printStatus('''
You need to update $pluginPath/pubspec.yaml to support $platformsString.
For more information, see https://flutter.dev/go/developing-plugins.
''', emphasis: true, color: TerminalColor.red);
}
const String _kNoPlatformsArgMessage = '''
Must specify at least one platform using --platforms.
For more information, see https://flutter.dev/go/developing-plugins.
''';
...@@ -12,6 +12,10 @@ import 'base/user_messages.dart'; ...@@ -12,6 +12,10 @@ import 'base/user_messages.dart';
import 'base/utils.dart'; import 'base/utils.dart';
import 'plugins.dart'; import 'plugins.dart';
const Set<String> _kValidPluginPlatforms = <String>{
'android', 'ios', 'web', 'windows', 'linux', 'macos'
};
/// A wrapper around the `flutter` section in the `pubspec.yaml` file. /// A wrapper around the `flutter` section in the `pubspec.yaml` file.
class FlutterManifest { class FlutterManifest {
FlutterManifest._(this._logger); FlutterManifest._(this._logger);
...@@ -199,6 +203,20 @@ class FlutterManifest { ...@@ -199,6 +203,20 @@ class FlutterManifest {
return null; return null;
} }
/// Like [supportedPlatforms], but only returns the valid platforms that are supported in flutter plugins.
Map<String, dynamic> get validSupportedPlatforms {
final Map<String, dynamic> allPlatforms = supportedPlatforms;
if (allPlatforms == null) {
return null;
}
final Map<String, dynamic> platforms = <String, dynamic>{}..addAll(supportedPlatforms);
platforms.removeWhere((String key, dynamic _) => !_kValidPluginPlatforms.contains(key));
if (platforms.isEmpty) {
return null;
}
return platforms;
}
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();
} }
......
...@@ -33,7 +33,7 @@ flutter: ...@@ -33,7 +33,7 @@ flutter:
platforms: platforms:
{{#no_platforms}} {{#no_platforms}}
# This plugin project was generated without specifying any # This plugin project was generated without specifying any
# platforms with the `--platform` argument. If you see the `fake_platform` map below, remove it and # platforms with the `--platform` argument. If you see the `some_platform` map below, remove it and
# then add platforms following the instruction here: # then add platforms following the instruction here:
# https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms # https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms
# ------------------- # -------------------
......
...@@ -32,6 +32,7 @@ import '../../src/context.dart'; ...@@ -32,6 +32,7 @@ import '../../src/context.dart';
import '../../src/pubspec_schema.dart'; import '../../src/pubspec_schema.dart';
import '../../src/testbed.dart'; import '../../src/testbed.dart';
const String _kNoPlatformsMessage = 'Must specify at least one platform using --platforms.\n';
const String frameworkRevision = '12345678'; const String frameworkRevision = '12345678';
const String frameworkChannel = 'omega'; const String frameworkChannel = 'omega';
// TODO(fujino): replace FakePlatform.fromPlatform() with FakePlatform() // TODO(fujino): replace FakePlatform.fromPlatform() with FakePlatform()
...@@ -390,8 +391,6 @@ void main() { ...@@ -390,8 +391,6 @@ void main() {
'android/src/main/java/com/example/flutter_project/FlutterProjectPlugin.java', 'android/src/main/java/com/example/flutter_project/FlutterProjectPlugin.java',
'example/android/app/src/main/java/com/example/flutter_project_example/MainActivity.java', 'example/android/app/src/main/java/com/example/flutter_project_example/MainActivity.java',
'lib/flutter_project_web.dart', 'lib/flutter_project_web.dart',
// TODO(cyanglaz): no-op iOS folder should be removed after 1.20.0 release
// https://github.com/flutter/flutter/issues/59787
], ],
); );
return _runFlutterTest(projectDir.childDirectory('example')); return _runFlutterTest(projectDir.childDirectory('example'));
...@@ -422,6 +421,7 @@ void main() { ...@@ -422,6 +421,7 @@ void main() {
// The platform is correctly registered // The platform is correctly registered
expect(pubspec.flutter['plugin']['platforms']['web']['pluginClass'], 'FlutterProjectWeb'); expect(pubspec.flutter['plugin']['platforms']['web']['pluginClass'], 'FlutterProjectWeb');
expect(pubspec.flutter['plugin']['platforms']['web']['fileName'], 'flutter_project_web.dart'); expect(pubspec.flutter['plugin']['platforms']['web']['fileName'], 'flutter_project_web.dart');
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true), FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
Pub: () => Pub( Pub: () => Pub(
...@@ -432,6 +432,7 @@ void main() { ...@@ -432,6 +432,7 @@ void main() {
botDetector: globals.botDetector, botDetector: globals.botDetector,
platform: globals.platform, platform: globals.platform,
), ),
Logger: ()=>logger,
}); });
testUsingContext('plugin example app depends on plugin', () async { testUsingContext('plugin example app depends on plugin', () async {
...@@ -661,7 +662,9 @@ void main() { ...@@ -661,7 +662,9 @@ void main() {
// Import for the new embedding class. // Import for the new embedding class.
expect(mainActivity.contains('import io.flutter.embedding.android.FlutterActivity'), true); expect(mainActivity.contains('import io.flutter.embedding.android.FlutterActivity'), true);
expect(testLogger.statusText, isNot(contains('https://flutter.dev/go/android-project-migration'))); expect(logger.statusText, isNot(contains('https://flutter.dev/go/android-project-migration')));
}, overrides: <Type, Generator>{
Logger: () => logger,
}); });
testUsingContext('app does not include desktop or web by default', () async { testUsingContext('app does not include desktop or web by default', () async {
...@@ -732,8 +735,10 @@ void main() { ...@@ -732,8 +735,10 @@ void main() {
expect(projectDir.childDirectory('windows'), isNot(exists)); expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('macos'), isNot(exists)); expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists)); expect(projectDir.childDirectory('web'), isNot(exists));
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true), FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
Logger: () => logger,
}); });
testUsingContext('plugin supports Linux if requested', () async { testUsingContext('plugin supports Linux if requested', () async {
...@@ -767,8 +772,10 @@ void main() { ...@@ -767,8 +772,10 @@ void main() {
], ],
pluginClass: 'FlutterProjectPlugin', pluginClass: 'FlutterProjectPlugin',
unexpectedPlatforms: <String>['some_platform']); unexpectedPlatforms: <String>['some_platform']);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true), FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
Logger: () => logger,
}); });
testUsingContext('app supports macOS if requested', () async { testUsingContext('app supports macOS if requested', () async {
...@@ -794,8 +801,10 @@ void main() { ...@@ -794,8 +801,10 @@ void main() {
expect(projectDir.childDirectory('linux'), isNot(exists)); expect(projectDir.childDirectory('linux'), isNot(exists));
expect(projectDir.childDirectory('windows'), isNot(exists)); expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists)); expect(projectDir.childDirectory('web'), isNot(exists));
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true), FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
Logger: () => logger,
}); });
testUsingContext('plugin supports macOS if requested', () async { testUsingContext('plugin supports macOS if requested', () async {
...@@ -826,8 +835,10 @@ void main() { ...@@ -826,8 +835,10 @@ void main() {
'macos', 'macos',
], pluginClass: 'FlutterProjectPlugin', ], pluginClass: 'FlutterProjectPlugin',
unexpectedPlatforms: <String>['some_platform']); unexpectedPlatforms: <String>['some_platform']);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true), FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
Logger: () => logger,
}); });
testUsingContext('app supports Windows if requested', () async { testUsingContext('app supports Windows if requested', () async {
...@@ -852,8 +863,10 @@ void main() { ...@@ -852,8 +863,10 @@ void main() {
expect(projectDir.childDirectory('linux'), isNot(exists)); expect(projectDir.childDirectory('linux'), isNot(exists));
expect(projectDir.childDirectory('macos'), isNot(exists)); expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists)); expect(projectDir.childDirectory('web'), isNot(exists));
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true), FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
Logger: () => logger,
}); });
testUsingContext('Windows has correct VERSIONINFO', () async { testUsingContext('Windows has correct VERSIONINFO', () async {
...@@ -914,8 +927,10 @@ void main() { ...@@ -914,8 +927,10 @@ void main() {
'windows' 'windows'
], pluginClass: 'FlutterProjectPlugin', ], pluginClass: 'FlutterProjectPlugin',
unexpectedPlatforms: <String>['some_platform']); unexpectedPlatforms: <String>['some_platform']);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true), FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
Logger: () => logger,
}); });
testUsingContext('app supports web if requested', () async { testUsingContext('app supports web if requested', () async {
...@@ -941,8 +956,10 @@ void main() { ...@@ -941,8 +956,10 @@ void main() {
expect(projectDir.childDirectory('linux'), isNot(exists)); expect(projectDir.childDirectory('linux'), isNot(exists));
expect(projectDir.childDirectory('macos'), isNot(exists)); expect(projectDir.childDirectory('macos'), isNot(exists));
expect(projectDir.childDirectory('windows'), isNot(exists)); expect(projectDir.childDirectory('windows'), isNot(exists));
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true), FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
Logger: () => logger,
}); });
testUsingContext('plugin uses new platform schema', () async { testUsingContext('plugin uses new platform schema', () async {
...@@ -1652,8 +1669,6 @@ void main() { ...@@ -1652,8 +1669,6 @@ void main() {
await runner.run(<String>['create', '--no-pub', '--template=plugin', projectDir.path]); await runner.run(<String>['create', '--no-pub', '--template=plugin', projectDir.path]);
// TODO(cyanglaz): no-op iOS folder should be removed after 1.20.0 release
// https://github.com/flutter/flutter/issues/59787
expect(projectDir.childDirectory('ios'), isNot(exists)); expect(projectDir.childDirectory('ios'), isNot(exists));
expect(projectDir.childDirectory('android'), isNot(exists)); expect(projectDir.childDirectory('android'), isNot(exists));
expect(projectDir.childDirectory('web'), isNot(exists)); expect(projectDir.childDirectory('web'), isNot(exists));
...@@ -1661,8 +1676,6 @@ void main() { ...@@ -1661,8 +1676,6 @@ void main() {
expect(projectDir.childDirectory('windows'), isNot(exists)); expect(projectDir.childDirectory('windows'), isNot(exists));
expect(projectDir.childDirectory('macos'), isNot(exists)); expect(projectDir.childDirectory('macos'), isNot(exists));
// TODO(cyanglaz): no-op iOS folder should be removed after 1.20.0 release
// https://github.com/flutter/flutter/issues/59787
expect(projectDir.childDirectory('example').childDirectory('ios'), expect(projectDir.childDirectory('example').childDirectory('ios'),
isNot(exists)); isNot(exists));
expect(projectDir.childDirectory('example').childDirectory('android'), expect(projectDir.childDirectory('example').childDirectory('android'),
...@@ -1683,7 +1696,6 @@ void main() { ...@@ -1683,7 +1696,6 @@ void main() {
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false), FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false),
}); });
testUsingContext('plugin supports ios if requested', () async { testUsingContext('plugin supports ios if requested', () async {
Cache.flutterRoot = '../..'; Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision); when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
...@@ -1700,8 +1712,10 @@ void main() { ...@@ -1700,8 +1712,10 @@ void main() {
'ios', 'ios',
], pluginClass: 'FlutterProjectPlugin', ], pluginClass: 'FlutterProjectPlugin',
unexpectedPlatforms: <String>['some_platform']); unexpectedPlatforms: <String>['some_platform']);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false), FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false),
Logger: () => logger,
}); });
testUsingContext('plugin supports android if requested', () async { testUsingContext('plugin supports android if requested', () async {
...@@ -1722,8 +1736,10 @@ void main() { ...@@ -1722,8 +1736,10 @@ void main() {
], pluginClass: 'FlutterProjectPlugin', ], pluginClass: 'FlutterProjectPlugin',
unexpectedPlatforms: <String>['some_platform'], unexpectedPlatforms: <String>['some_platform'],
androidIdentifier: 'com.example.flutter_project'); androidIdentifier: 'com.example.flutter_project');
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false), FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false),
Logger: () => logger,
}); });
testUsingContext('plugin supports web if requested', () async { testUsingContext('plugin supports web if requested', () async {
...@@ -1744,8 +1760,10 @@ void main() { ...@@ -1744,8 +1760,10 @@ void main() {
unexpectedPlatforms: <String>['some_platform'], unexpectedPlatforms: <String>['some_platform'],
androidIdentifier: 'com.example.flutter_project', androidIdentifier: 'com.example.flutter_project',
webFileName: 'flutter_project_web.dart'); webFileName: 'flutter_project_web.dart');
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true), FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
Logger: () => logger,
}); });
testUsingContext('plugin doe not support web if feature is not enabled', () async { testUsingContext('plugin doe not support web if feature is not enabled', () async {
...@@ -1764,8 +1782,10 @@ void main() { ...@@ -1764,8 +1782,10 @@ void main() {
'some_platform' 'some_platform'
], pluginClass: 'somePluginClass', ], pluginClass: 'somePluginClass',
unexpectedPlatforms: <String>['web']); unexpectedPlatforms: <String>['web']);
expect(logger.errorText, contains(_kNoPlatformsMessage));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWebEnabled: false), FeatureFlags: () => TestFeatureFlags(isWebEnabled: false),
Logger: () => logger,
}); });
testUsingContext('create an empty plugin, then add ios', () async { testUsingContext('create an empty plugin, then add ios', () async {
...@@ -2081,7 +2101,9 @@ void main() { ...@@ -2081,7 +2101,9 @@ void main() {
final CreateCommand command = CreateCommand(); final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=android', projectDir.path]); await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=android', projectDir.path]);
expect(logger.statusText, isNot(contains('The `pubspec.yaml` under the project directory must be updated to support'))); final String projectDirPath = globals.fs.path.normalize(projectDir.absolute.path);
final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath));
expect(logger.statusText, isNot(contains('You need to update $relativePluginPath/pubspec.yaml to support android.\n')));
}, overrides: <Type, Generator> { }, overrides: <Type, Generator> {
Logger: () => logger, Logger: () => logger,
}); });
...@@ -2093,10 +2115,12 @@ void main() { ...@@ -2093,10 +2115,12 @@ void main() {
final CreateCommand command = CreateCommand(); final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command); final CommandRunner<void> runner = createTestCommandRunner(command);
final String projectDirPath = globals.fs.path.normalize(projectDir.absolute.path);
final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath));
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=ios', projectDir.path]); await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=ios', projectDir.path]);
expect(logger.statusText, isNot(contains('The `pubspec.yaml` under the project directory must be updated to support'))); expect(logger.statusText, isNot(contains('You need to update $relativePluginPath/pubspec.yaml to support ios.\n')));
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=android', projectDir.path]); await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=android', projectDir.path]);
expect(logger.statusText, contains('The `pubspec.yaml` under the project directory must be updated to support')); expect(logger.statusText, contains('You need to update $relativePluginPath/pubspec.yaml to support android.\n'));
}, overrides: <Type, Generator> { }, overrides: <Type, Generator> {
Logger: () => logger, Logger: () => logger,
}); });
...@@ -2276,6 +2300,39 @@ void main() { ...@@ -2276,6 +2300,39 @@ void main() {
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true), FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
}); });
testUsingContext('created plugin supports no platforms should print `no platforms` message', () async {
Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', '--no-pub', '--template=plugin', projectDir.path]);
expect(logger.errorText, contains(_kNoPlatformsMessage));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false),
Logger: ()=> logger,
});
testUsingContext('created plugin with no --platforms flag should not print `no platforms` message if the existing plugin supports a platform.', () async {
Cache.flutterRoot = '../..';
when(mockFlutterVersion.frameworkRevision).thenReturn(frameworkRevision);
when(mockFlutterVersion.channel).thenReturn(frameworkChannel);
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['create', '--no-pub', '--template=plugin', '--platforms=ios', projectDir.path]);
await runner.run(<String>['create', '--no-pub', '--template=plugin', projectDir.path]);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: false),
Logger: () => logger,
});
} }
Future<void> _createProject( Future<void> _createProject(
......
...@@ -972,6 +972,49 @@ flutter: ...@@ -972,6 +972,49 @@ flutter:
expect(flutterManifest.supportedPlatforms, null); expect(flutterManifest.supportedPlatforms, null);
}); });
testWithoutContext('FlutterManifest validSupportedPlatforms return null if the platform keys are not valid', () {
const String manifest = '''
name: test
flutter:
plugin:
platforms:
some_platform:
pluginClass: SomeClass
''';
final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest,
logger: logger,
);
expect(flutterManifest.isPlugin, true);
expect(flutterManifest.validSupportedPlatforms, null);
});
testWithoutContext('FlutterManifest validSupportedPlatforms only returns valid platforms', () {
const String manifest = '''
name: test
flutter:
plugin:
platforms:
some_platform:
pluginClass: SomeClass
ios:
pluginClass: SomeClass
''';
final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest,
logger: logger,
);
expect(flutterManifest.isPlugin, true);
expect(flutterManifest.validSupportedPlatforms['ios'],
<String, dynamic>{'pluginClass': 'SomeClass'});
expect(flutterManifest.validSupportedPlatforms['some_platform'],
isNull);
});
testWithoutContext('FlutterManifest getSupportedPlatforms returns valid platforms.', () { testWithoutContext('FlutterManifest getSupportedPlatforms returns valid platforms.', () {
const String manifest = ''' const String manifest = '''
name: test name: test
......
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