Commit e20ee045 authored by Dan Rubel's avatar Dan Rubel Committed by GitHub

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
parent 3f19b2db
...@@ -7,6 +7,7 @@ import 'dart:io'; ...@@ -7,6 +7,7 @@ import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import '../base/common.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../globals.dart'; import '../globals.dart';
...@@ -60,13 +61,11 @@ class AndroidSdk { ...@@ -60,13 +61,11 @@ class AndroidSdk {
if (Platform.environment.containsKey('ANDROID_HOME')) { if (Platform.environment.containsKey('ANDROID_HOME')) {
androidHomeDir = Platform.environment['ANDROID_HOME']; androidHomeDir = Platform.environment['ANDROID_HOME'];
} else if (Platform.isLinux) { } else if (Platform.isLinux) {
String homeDir = Platform.environment['HOME']; if (homeDirPath != null)
if (homeDir != null) androidHomeDir = '$homeDirPath/Android/Sdk';
androidHomeDir = '$homeDir/Android/Sdk';
} else if (Platform.isMacOS) { } else if (Platform.isMacOS) {
String homeDir = Platform.environment['HOME']; if (homeDirPath != null)
if (homeDir != null) androidHomeDir = '$homeDirPath/Library/Android/sdk';
androidHomeDir = '$homeDir/Library/Android/sdk';
} }
if (androidHomeDir != null) { if (androidHomeDir != null) {
......
...@@ -2,10 +2,27 @@ ...@@ -2,10 +2,27 @@
// 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 'dart:io';
import 'package:path/path.dart' as path;
const int kDefaultObservatoryPort = 8100; const int kDefaultObservatoryPort = 8100;
const int kDefaultDiagnosticPort = 8101; const int kDefaultDiagnosticPort = 8101;
const int kDefaultDrivePort = 8183; 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 /// Specialized exception for expected situations
/// where the tool should exit with a clear message to the user /// where the tool should exit with a clear message to the user
/// and no stack trace unless the --verbose option is specified. /// and no stack trace unless the --verbose option is specified.
......
...@@ -9,6 +9,7 @@ import 'dart:io'; ...@@ -9,6 +9,7 @@ import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'android/android_workflow.dart'; import 'android/android_workflow.dart';
import 'base/common.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/os.dart'; import 'base/os.dart';
import 'device.dart'; import 'device.dart';
...@@ -41,7 +42,7 @@ class Doctor { ...@@ -41,7 +42,7 @@ class Doctor {
List<DoctorValidator> ideValidators = <DoctorValidator>[]; List<DoctorValidator> ideValidators = <DoctorValidator>[];
ideValidators.addAll(AtomValidator.installed); ideValidators.addAll(AtomValidator.installed);
ideValidators.addAll(IntellijValidator.installed); ideValidators.addAll(IntelliJValidator.installed);
if (ideValidators.isNotEmpty) if (ideValidators.isNotEmpty)
_validators.addAll(ideValidators); _validators.addAll(ideValidators);
else else
...@@ -313,52 +314,25 @@ class AtomValidator extends DoctorValidator { ...@@ -313,52 +314,25 @@ class AtomValidator extends DoctorValidator {
} }
} }
class IntellijValidator extends DoctorValidator { abstract class IntelliJValidator extends DoctorValidator {
IntellijValidator(String title, {this.version, this.pluginsPath}) : super(title); IntelliJValidator(String title) : super(title);
final String version; String get version;
final String pluginsPath; String get pluginsPath;
static Iterable<DoctorValidator> get installed { static final Map<String, String> _idToTitle = <String, String>{
List<DoctorValidator> validators = <DoctorValidator>[]; 'IntelliJIdea' : 'IntelliJ IDEA Ultimate Edition',
Map<String, String> products = <String, String>{ 'IdeaIC' : 'IntelliJ IDEA Community Edition',
'IntelliJIdea' : 'IntelliJ IDEA Ultimate Edition', 'WebStorm' : 'IntelliJ WebStorm',
'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 { static Iterable<DoctorValidator> get installed {
// TODO(danrubel): add support for Windows if (Platform.isLinux)
} return IntelliJValidatorOnLinux.installed;
return validators; if (Platform.isMacOS)
return IntelliJValidatorOnMac.installed;
// TODO(danrubel): add support for Windows
return <DoctorValidator>[];
} }
@override @override
...@@ -370,7 +344,7 @@ class IntellijValidator extends DoctorValidator { ...@@ -370,7 +344,7 @@ class IntellijValidator extends DoctorValidator {
if (_validateHasPackage(messages, 'Dart', 'Dart')) if (_validateHasPackage(messages, 'Dart', 'Dart'))
installCount++; installCount++;
if (_validateHasPackage(messages, 'Flutter', 'Flutter')) if (_validateHasPackage(messages, 'flutter-intellij.jar', 'Flutter'))
installCount++; installCount++;
if (installCount < 2) { if (installCount < 2) {
...@@ -387,23 +361,123 @@ class IntellijValidator extends DoctorValidator { ...@@ -387,23 +361,123 @@ class IntellijValidator extends DoctorValidator {
); );
} }
bool _validateHasPackage(List<ValidationMessage> messages, String packageName, String description) { bool _validateHasPackage(List<ValidationMessage> messages, String packageName, String title) {
if (!hasPackage(packageName)) { if (!hasPackage(packageName)) {
messages.add(new ValidationMessage( messages.add(new ValidationMessage(
'$packageName plugin not installed; this adds $description specific functionality.' '$title plugin not installed; this adds $title specific functionality.'
)); ));
return false; return false;
} }
messages.add(new ValidationMessage('$packageName plugin installed')); messages.add(new ValidationMessage('$title plugin installed'));
return true; return true;
} }
bool hasPackage(String packageName) { bool hasPackage(String packageName) {
String packagePath = path.join(pluginsPath, packageName); String packagePath = path.join(pluginsPath, packageName);
if (packageName.endsWith('.jar'))
return FileSystemEntity.isFileSync(packagePath);
return FileSystemEntity.isDirectorySync(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 { class DeviceValidator extends DoctorValidator {
DeviceValidator() : super('Connected devices'); DeviceValidator() : super('Connected devices');
......
...@@ -17,8 +17,6 @@ import '../globals.dart'; ...@@ -17,8 +17,6 @@ import '../globals.dart';
import '../services.dart'; import '../services.dart';
import 'xcodeproj.dart'; import 'xcodeproj.dart';
String get homeDirectory => path.absolute(Platform.environment['HOME']);
const int kXcodeRequiredVersionMajor = 7; const int kXcodeRequiredVersionMajor = 7;
const int kXcodeRequiredVersionMinor = 0; const int kXcodeRequiredVersionMinor = 0;
......
...@@ -10,6 +10,7 @@ import 'dart:math' as math; ...@@ -10,6 +10,7 @@ import 'dart:math' as math;
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../build_info.dart'; import '../build_info.dart';
...@@ -318,7 +319,7 @@ class IOSSimulator extends Device { ...@@ -318,7 +319,7 @@ class IOSSimulator extends Device {
String get xcrunPath => path.join('/usr', 'bin', 'xcrun'); String get xcrunPath => path.join('/usr', 'bin', 'xcrun');
String _getSimulatorPath() { String _getSimulatorPath() {
return path.join(homeDirectory, 'Library', 'Developer', 'CoreSimulator', 'Devices', id); return path.join(homeDirPath, 'Library', 'Developer', 'CoreSimulator', 'Devices', id);
} }
String _getSimulatorAppHomeDirectory(ApplicationPackage app) { String _getSimulatorAppHomeDirectory(ApplicationPackage app) {
...@@ -544,7 +545,7 @@ class IOSSimulator extends Device { ...@@ -544,7 +545,7 @@ class IOSSimulator extends Device {
} }
String get logFilePath { String get logFilePath {
return path.join(homeDirectory, 'Library', 'Logs', 'CoreSimulator', id, 'system.log'); return path.join(homeDirPath, 'Library', 'Logs', 'CoreSimulator', id, 'system.log');
} }
@override @override
...@@ -587,7 +588,6 @@ class IOSSimulator extends Device { ...@@ -587,7 +588,6 @@ class IOSSimulator extends Device {
@override @override
Future<bool> takeScreenshot(File outputFile) async { Future<bool> takeScreenshot(File outputFile) async {
String homeDirPath = Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
Directory desktopDir = new Directory(path.join(homeDirPath, 'Desktop')); Directory desktopDir = new Directory(path.join(homeDirPath, 'Desktop'));
// 'Simulator Screen Shot Mar 25, 2016, 2.59.43 PM.png' // 'Simulator Screen Shot Mar 25, 2016, 2.59.43 PM.png'
......
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