Flutter doctor detect IntelliJ on Mac (#6262) * cleanup obtaining user home directory path * refactor doctor and detect IntelliJ on Mac * fix detect Flutter plugin for IntelliJ
diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart index ea9c913..e509d6b 100644 --- a/packages/flutter_tools/lib/src/android/android_sdk.dart +++ b/packages/flutter_tools/lib/src/android/android_sdk.dart
@@ -7,6 +7,7 @@ import 'package:path/path.dart' as path; import 'package:pub_semver/pub_semver.dart'; +import '../base/common.dart'; import '../base/os.dart'; import '../globals.dart'; @@ -60,13 +61,11 @@ if (Platform.environment.containsKey('ANDROID_HOME')) { androidHomeDir = Platform.environment['ANDROID_HOME']; } else if (Platform.isLinux) { - String homeDir = Platform.environment['HOME']; - if (homeDir != null) - androidHomeDir = '$homeDir/Android/Sdk'; + if (homeDirPath != null) + androidHomeDir = '$homeDirPath/Android/Sdk'; } else if (Platform.isMacOS) { - String homeDir = Platform.environment['HOME']; - if (homeDir != null) - androidHomeDir = '$homeDir/Library/Android/sdk'; + if (homeDirPath != null) + androidHomeDir = '$homeDirPath/Library/Android/sdk'; } if (androidHomeDir != null) {
diff --git a/packages/flutter_tools/lib/src/base/common.dart b/packages/flutter_tools/lib/src/base/common.dart index b9fef20..4ed265b 100644 --- a/packages/flutter_tools/lib/src/base/common.dart +++ b/packages/flutter_tools/lib/src/base/common.dart
@@ -2,10 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:io'; + +import 'package:path/path.dart' as path; + const int kDefaultObservatoryPort = 8100; const int kDefaultDiagnosticPort = 8101; const int kDefaultDrivePort = 8183; +/// Return the absolute path of the user's home directory +String get homeDirPath { + if (_homeDirPath == null) { + _homeDirPath = Platform.isWindows + ? Platform.environment['USERPROFILE'] + : Platform.environment['HOME']; + if (_homeDirPath != null) + _homeDirPath = path.absolute(_homeDirPath); + } + return _homeDirPath; +} +String _homeDirPath; + /// Specialized exception for expected situations /// where the tool should exit with a clear message to the user /// and no stack trace unless the --verbose option is specified.
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 94b7129..663f207 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -9,6 +9,7 @@ import 'package:path/path.dart' as path; import 'android/android_workflow.dart'; +import 'base/common.dart'; import 'base/context.dart'; import 'base/os.dart'; import 'device.dart'; @@ -41,7 +42,7 @@ List<DoctorValidator> ideValidators = <DoctorValidator>[]; ideValidators.addAll(AtomValidator.installed); - ideValidators.addAll(IntellijValidator.installed); + ideValidators.addAll(IntelliJValidator.installed); if (ideValidators.isNotEmpty) _validators.addAll(ideValidators); else @@ -313,52 +314,25 @@ } } -class IntellijValidator extends DoctorValidator { - IntellijValidator(String title, {this.version, this.pluginsPath}) : super(title); +abstract class IntelliJValidator extends DoctorValidator { + IntelliJValidator(String title) : super(title); - final String version; - final String pluginsPath; + String get version; + String get pluginsPath; + + static final Map<String, String> _idToTitle = <String, String>{ + 'IntelliJIdea' : 'IntelliJ IDEA Ultimate Edition', + 'IdeaIC' : 'IntelliJ IDEA Community Edition', + 'WebStorm' : 'IntelliJ WebStorm', + }; static Iterable<DoctorValidator> get installed { - List<DoctorValidator> validators = <DoctorValidator>[]; - Map<String, String> products = <String, String>{ - 'IntelliJIdea' : 'IntelliJ IDEA Ultimate Edition', - 'IdeaIC' : 'IntelliJ IDEA Community Edition', - 'WebStorm' : 'IntelliJ WebStorm', - }; - String homeDir = Platform.environment['HOME']; - - if (Platform.isLinux && homeDir != null) { - for (FileSystemEntity dir in new Directory(homeDir).listSync()) { - if (dir is Directory) { - String name = path.basename(dir.path); - products.forEach((String id, String title) { - if (name.startsWith('.$id')) { - String version = name.substring(id.length + 1); - String installPath; - try { - installPath = new File(path.join(dir.path, 'system', '.home')).readAsStringSync(); - } catch (e) { - // ignored - } - if (installPath != null && FileSystemEntity.isDirectorySync(installPath)) { - validators.add(new IntellijValidator( - title, - version: version, - pluginsPath: path.join(dir.path, 'config', 'plugins'), - )); - } - } - }); - } - } - } else if (Platform.isMacOS) { - // TODO(danrubel): add support for Mac - - } else { - // TODO(danrubel): add support for Windows - } - return validators; + if (Platform.isLinux) + return IntelliJValidatorOnLinux.installed; + if (Platform.isMacOS) + return IntelliJValidatorOnMac.installed; + // TODO(danrubel): add support for Windows + return <DoctorValidator>[]; } @override @@ -370,7 +344,7 @@ if (_validateHasPackage(messages, 'Dart', 'Dart')) installCount++; - if (_validateHasPackage(messages, 'Flutter', 'Flutter')) + if (_validateHasPackage(messages, 'flutter-intellij.jar', 'Flutter')) installCount++; if (installCount < 2) { @@ -387,23 +361,123 @@ ); } - bool _validateHasPackage(List<ValidationMessage> messages, String packageName, String description) { + bool _validateHasPackage(List<ValidationMessage> messages, String packageName, String title) { if (!hasPackage(packageName)) { messages.add(new ValidationMessage( - '$packageName plugin not installed; this adds $description specific functionality.' + '$title plugin not installed; this adds $title specific functionality.' )); return false; } - messages.add(new ValidationMessage('$packageName plugin installed')); + messages.add(new ValidationMessage('$title plugin installed')); return true; } bool hasPackage(String packageName) { String packagePath = path.join(pluginsPath, packageName); + if (packageName.endsWith('.jar')) + return FileSystemEntity.isFileSync(packagePath); return FileSystemEntity.isDirectorySync(packagePath); } } +class IntelliJValidatorOnLinux extends IntelliJValidator { + IntelliJValidatorOnLinux(String title, this.version, this.pluginsPath) : super(title); + + @override + String version; + + @override + String pluginsPath; + + static Iterable<DoctorValidator> get installed { + List<DoctorValidator> validators = <DoctorValidator>[]; + if (homeDirPath == null) return validators; + for (FileSystemEntity dir in new Directory(homeDirPath).listSync()) { + if (dir is Directory) { + String name = path.basename(dir.path); + IntelliJValidator._idToTitle.forEach((String id, String title) { + if (name.startsWith('.$id')) { + String version = name.substring(id.length + 1); + String installPath; + try { + installPath = new File(path.join(dir.path, 'system', '.home')).readAsStringSync(); + } catch (e) { + // ignored + } + if (installPath != null && FileSystemEntity.isDirectorySync(installPath)) { + String pluginsPath = path.join(dir.path, 'config', 'plugins'); + validators.add(new IntelliJValidatorOnLinux(title, version, pluginsPath)); + } + } + }); + } + } + return validators; + } +} + +class IntelliJValidatorOnMac extends IntelliJValidator { + IntelliJValidatorOnMac(String title, this.id, this.installPath) : super(title); + + final String id; + final String installPath; + + static final Map<String, String> _dirNameToId = <String, String>{ + 'IntelliJ IDEA.app' : 'IntelliJIdea', + 'IntelliJ IDEA CE.app' : 'IdeaIC', + 'WebStorm.app' : 'WebStorm', + }; + + static Iterable<DoctorValidator> get installed { + List<DoctorValidator> validators = <DoctorValidator>[]; + for (FileSystemEntity dir in new Directory('/Applications').listSync()) { + if (dir is Directory) { + String name = path.basename(dir.path); + _dirNameToId.forEach((String dirName, String id) { + if (name == dirName) { + String title = IntelliJValidator._idToTitle[id]; + validators.add(new IntelliJValidatorOnMac(title, id, dir.path)); + } + }); + } + } + return validators; + } + + @override + String get version { + if (_version == null) { + String plist; + try { + plist = new File(path.join(installPath, 'Contents', 'Info.plist')).readAsStringSync(); + int index = plist.indexOf('CFBundleShortVersionString'); + if (index > 0) { + int start = plist.indexOf('<string>', index); + if (start > 0) { + int end = plist.indexOf('</string>', start); + if (end > 0) { + _version = plist.substring(start + 8, end); + } + } + } + } on FileSystemException catch (_) { + // ignored + } + _version ??= 'unknown'; + } + return _version; + } + String _version; + + @override + String get pluginsPath { + List<String> split = version.split('.'); + String major = split[0]; + String minor = split[1]; + return path.join(homeDirPath, 'Library', 'Application Support', '$id$major.$minor'); + } +} + class DeviceValidator extends DoctorValidator { DeviceValidator() : super('Connected devices');
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index ebe9ded..9016171 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -17,8 +17,6 @@ import '../services.dart'; import 'xcodeproj.dart'; -String get homeDirectory => path.absolute(Platform.environment['HOME']); - const int kXcodeRequiredVersionMajor = 7; const int kXcodeRequiredVersionMinor = 0;
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 49201a3..4b18195 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -10,6 +10,7 @@ import 'package:path/path.dart' as path; import '../application_package.dart'; +import '../base/common.dart'; import '../base/context.dart'; import '../base/process.dart'; import '../build_info.dart'; @@ -318,7 +319,7 @@ String get xcrunPath => path.join('/usr', 'bin', 'xcrun'); String _getSimulatorPath() { - return path.join(homeDirectory, 'Library', 'Developer', 'CoreSimulator', 'Devices', id); + return path.join(homeDirPath, 'Library', 'Developer', 'CoreSimulator', 'Devices', id); } String _getSimulatorAppHomeDirectory(ApplicationPackage app) { @@ -544,7 +545,7 @@ } String get logFilePath { - return path.join(homeDirectory, 'Library', 'Logs', 'CoreSimulator', id, 'system.log'); + return path.join(homeDirPath, 'Library', 'Logs', 'CoreSimulator', id, 'system.log'); } @override @@ -587,7 +588,6 @@ @override Future<bool> takeScreenshot(File outputFile) async { - String homeDirPath = Platform.environment['HOME'] ?? Platform.environment['USERPROFILE']; Directory desktopDir = new Directory(path.join(homeDirPath, 'Desktop')); // 'Simulator Screen Shot Mar 25, 2016, 2.59.43 PM.png'