From 2243c42ebc143960ecb6fe1bd433ebabd6cb32b9 Mon Sep 17 00:00:00 2001 From: Lynn Date: Thu, 27 Feb 2020 05:41:03 +0800 Subject: [PATCH] Fix flutter doctor (pluginsPath) check for Mac (#50324) --- packages/flutter_tools/lib/src/doctor.dart | 56 ++++++++++++++----- .../commands.shard/hermetic/doctor_test.dart | 14 +++++ .../mac_not_via_toolbox/Contents/Info.plist | 38 +++++++++++++ .../mac_via_toolbox/Contents/Info.plist | 40 +++++++++++++ 4 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist create mode 100644 packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index da35d54ccf..f5a8a2c91d 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -4,6 +4,8 @@ import 'dart:async'; +import 'package:meta/meta.dart'; + import 'android/android_studio_validator.dart'; import 'android/android_workflow.dart'; import 'artifacts.dart'; @@ -699,19 +701,23 @@ abstract class IntelliJValidator extends DoctorValidator { Future validate() async { final List messages = []; - messages.add(ValidationMessage(userMessages.intellijLocation(installPath))); + if (pluginsPath == null) { + messages.add(ValidationMessage.error('Invalid IntelliJ version number.')); + } else { + messages.add(ValidationMessage(userMessages.intellijLocation(installPath))); - final IntelliJPlugins plugins = IntelliJPlugins(pluginsPath); - plugins.validatePackage(messages, ['flutter-intellij', 'flutter-intellij.jar'], - 'Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion); - plugins.validatePackage(messages, ['Dart'], 'Dart'); + final IntelliJPlugins plugins = IntelliJPlugins(pluginsPath); + plugins.validatePackage(messages, ['flutter-intellij', 'flutter-intellij.jar'], + 'Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion); + plugins.validatePackage(messages, ['Dart'], 'Dart'); - if (_hasIssues(messages)) { - messages.add(ValidationMessage(userMessages.intellijPluginInfo)); + if (_hasIssues(messages)) { + messages.add(ValidationMessage(userMessages.intellijPluginInfo)); + } + + _validateIntelliJVersion(messages, kMinIdeaVersion); } - _validateIntelliJVersion(messages, kMinIdeaVersion); - return ValidationResult( _hasIssues(messages) ? ValidationType.partial : ValidationType.installed, messages, @@ -847,31 +853,53 @@ class IntelliJValidatorOnMac extends IntelliJValidator { return validators; } + @visibleForTesting + String get plistFile { + _plistFile ??= globals.fs.path.join(installPath, 'Contents', 'Info.plist'); + return _plistFile; + } + String _plistFile; + @override String get version { - if (_version == null) { - final String plistFile = globals.fs.path.join(installPath, 'Contents', 'Info.plist'); - _version = PlistParser.instance.getValueFromFile( + _version ??= PlistParser.instance.getValueFromFile( plistFile, PlistParser.kCFBundleShortVersionStringKey, ) ?? 'unknown'; - } return _version; } String _version; @override String get pluginsPath { + if (_pluginsPath != null) { + return _pluginsPath; + } + + final String altLocation = PlistParser.instance.getValueFromFile(plistFile, 'JetBrainsToolboxApp'); + + if (altLocation != null) { + _pluginsPath = altLocation + '.plugins'; + return _pluginsPath; + } + final List split = version.split('.'); + + if (split.length < 2) { + return null; + } + final String major = split[0]; final String minor = split[1]; - return globals.fs.path.join( + _pluginsPath = globals.fs.path.join( globals.fsUtils.homeDirPath, 'Library', 'Application Support', '$id$major.$minor', ); + return _pluginsPath; } + String _pluginsPath; } class DeviceValidator extends DoctorValidator { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart index a6ec89b821..b8b253b2e1 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart @@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/globals.dart' as globals; +import 'package:flutter_tools/src/ios/plist_parser.dart'; import 'package:flutter_tools/src/proxy_validator.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/vscode/vscode.dart'; @@ -67,6 +68,19 @@ void main() { expect(message.message, contains('recommended minimum version')); }, overrides: noColorTerminalOverride); + testUsingContext('intellij plugins path checking on mac', () async { + final String pathViaToolbox = globals.fs.path.join('test', 'data', 'intellij', 'mac_via_toolbox'); + final String pathNotViaToolbox = globals.fs.path.join('test', 'data', 'intellij', 'mac_not_via_toolbox'); + + final IntelliJValidatorOnMac validatorViaToolbox = IntelliJValidatorOnMac('Test', 'Test', pathViaToolbox); + expect(validatorViaToolbox.plistFile, 'test/data/intellij/mac_via_toolbox/Contents/Info.plist'); + + final IntelliJValidatorOnMac validatorNotViaToolbox = IntelliJValidatorOnMac('Test', 'Test', pathNotViaToolbox); + expect(validatorNotViaToolbox.plistFile, 'test/data/intellij/mac_not_via_toolbox/Contents/Info.plist'); + }, overrides: { + PlistParser: () => const PlistParser(), + }); + testUsingContext('vs code validator when both installed', () async { final ValidationResult result = await VsCodeValidatorTestTargets.installedWithExtension.validate(); expect(result.type, ValidationType.installed); diff --git a/packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist b/packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist new file mode 100644 index 0000000000..087127f913 --- /dev/null +++ b/packages/flutter_tools/test/data/intellij/mac_not_via_toolbox/Contents/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + jetbrains-toolbox-launcher + CFBundleGetInfoString + + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + NSHumanReadableCopyright + Copyright (c) JetBrains s.r.o. + NSHighResolutionCapable + + NSUIElement + + LSUIElement + + CFBundleName + IntelliJ IDEA Ultimate 2019.3.3 + CFBundleIdentifier + com.jetbrains.apps.activator.linkapp.pcom.jetbrains.apps.activator__ntelli_ltimate_2019_3_3 + CFBundleVersion + 2019.3.3 + CFBundleLongVersionString + 2019.3.3 + CFBundleShortVersionString + 2019.3.3 + CFBundleIconFile + icon.icns + + diff --git a/packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist b/packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist new file mode 100644 index 0000000000..0700e061cd --- /dev/null +++ b/packages/flutter_tools/test/data/intellij/mac_via_toolbox/Contents/Info.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + jetbrains-toolbox-launcher + CFBundleGetInfoString + + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + NSHumanReadableCopyright + Copyright (c) JetBrains s.r.o. + NSHighResolutionCapable + + NSUIElement + + LSUIElement + + CFBundleName + IntelliJ IDEA Ultimate 2019.3.3 + CFBundleIdentifier + com.jetbrains.apps.activator.linkapp.pcom.jetbrains.apps.activator__ntelli_ltimate_2019_3_3 + CFBundleVersion + 2019.3.3 + CFBundleLongVersionString + 2019.3.3 + CFBundleShortVersionString + 2019.3.3 + CFBundleIconFile + icon.icns + JetBrainsToolboxApp + /Users/lynn/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/193.6494.35/IntelliJ IDEA.app + +