mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Flutter doctor error message lookup (#23889)
This commit is contained in:
parent
29bab6c023
commit
f8ab72657e
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import '../globals.dart';
|
||||
@ -34,9 +35,9 @@ class AndroidStudioValidator extends DoctorValidator {
|
||||
|
||||
final String studioVersionText = _studio.version == Version.unknown
|
||||
? null
|
||||
: 'version ${_studio.version}';
|
||||
: userMessages.androidStudioVersion(_studio.version.toString());
|
||||
messages
|
||||
.add(ValidationMessage('Android Studio at ${_studio.directory}'));
|
||||
.add(ValidationMessage(userMessages.androidStudioLocation(_studio.directory)));
|
||||
|
||||
final IntelliJPlugins plugins = IntelliJPlugins(_studio.pluginsPath);
|
||||
plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'],
|
||||
@ -51,11 +52,9 @@ class AndroidStudioValidator extends DoctorValidator {
|
||||
type = ValidationType.partial;
|
||||
messages.addAll(_studio.validationMessages
|
||||
.map<ValidationMessage>((String m) => ValidationMessage.error(m)));
|
||||
messages.add(ValidationMessage(
|
||||
'Try updating or re-installing Android Studio.'));
|
||||
messages.add(ValidationMessage(userMessages.androidStudioNeedsUpdate));
|
||||
if (_studio.configured != null) {
|
||||
messages.add(ValidationMessage(
|
||||
'Consider removing your android-studio-dir setting by running:\nflutter config --android-studio-dir='));
|
||||
messages.add(ValidationMessage(userMessages.androidStudioResetDir));
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,13 +75,9 @@ class NoAndroidStudioValidator extends DoctorValidator {
|
||||
|
||||
final String cfgAndroidStudio = config.getValue('android-studio-dir');
|
||||
if (cfgAndroidStudio != null) {
|
||||
messages.add(
|
||||
ValidationMessage.error('android-studio-dir = $cfgAndroidStudio\n'
|
||||
'but Android Studio not found at this location.'));
|
||||
messages.add(ValidationMessage.error(userMessages.androidStudioMissing(cfgAndroidStudio)));
|
||||
}
|
||||
messages.add(ValidationMessage(
|
||||
'Android Studio not found; download from https://developer.android.com/studio/index.html\n'
|
||||
'(or visit https://flutter.io/setup/#android-setup for detailed instructions).'));
|
||||
messages.add(ValidationMessage(userMessages.androidStudioInstallation));
|
||||
|
||||
return ValidationResult(ValidationType.notAvailable, messages,
|
||||
statusInfo: 'not installed');
|
||||
|
@ -11,6 +11,7 @@ import '../base/io.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/process.dart';
|
||||
import '../base/process_manager.dart';
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
@ -49,13 +50,11 @@ class AndroidWorkflow implements Workflow {
|
||||
class AndroidValidator extends DoctorValidator {
|
||||
AndroidValidator(): super('Android toolchain - develop for Android devices',);
|
||||
|
||||
static const String _jdkDownload = 'https://www.oracle.com/technetwork/java/javase/downloads/';
|
||||
|
||||
/// Returns false if we cannot determine the Java version or if the version
|
||||
/// is not compatible.
|
||||
Future<bool> _checkJavaVersion(String javaBinary, List<ValidationMessage> messages) async {
|
||||
if (!processManager.canRun(javaBinary)) {
|
||||
messages.add(ValidationMessage.error('Cannot execute $javaBinary to determine the version'));
|
||||
messages.add(ValidationMessage.error(userMessages.androidCantRunJavaBinary(javaBinary)));
|
||||
return false;
|
||||
}
|
||||
String javaVersion;
|
||||
@ -71,10 +70,10 @@ class AndroidValidator extends DoctorValidator {
|
||||
}
|
||||
if (javaVersion == null) {
|
||||
// Could not determine the java version.
|
||||
messages.add(ValidationMessage.error('Could not determine java version'));
|
||||
messages.add(ValidationMessage.error(userMessages.androidUnknownJavaVersion));
|
||||
return false;
|
||||
}
|
||||
messages.add(ValidationMessage('Java version $javaVersion'));
|
||||
messages.add(ValidationMessage(userMessages.androidJavaVersion(javaVersion)));
|
||||
// TODO(johnmccutchan): Validate version.
|
||||
return true;
|
||||
}
|
||||
@ -87,38 +86,26 @@ class AndroidValidator extends DoctorValidator {
|
||||
// No Android SDK found.
|
||||
if (platform.environment.containsKey(kAndroidHome)) {
|
||||
final String androidHomeDir = platform.environment[kAndroidHome];
|
||||
messages.add(ValidationMessage.error(
|
||||
'$kAndroidHome = $androidHomeDir\n'
|
||||
'but Android SDK not found at this location.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.androidBadSdkDir(kAndroidHome, androidHomeDir)));
|
||||
} else {
|
||||
messages.add(ValidationMessage.error(
|
||||
'Unable to locate Android SDK.\n'
|
||||
'Install Android Studio from: https://developer.android.com/studio/index.html\n'
|
||||
'On first launch it will assist you in installing the Android SDK components.\n'
|
||||
'(or visit https://flutter.io/setup/#android-setup for detailed instructions).\n'
|
||||
'If Android SDK has been installed to a custom location, set \$$kAndroidHome to that location.\n'
|
||||
'You may also want to add it to your PATH environment variable.\n'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.androidMissingSdkInstructions(kAndroidHome)));
|
||||
}
|
||||
|
||||
return ValidationResult(ValidationType.missing, messages);
|
||||
}
|
||||
|
||||
messages.add(ValidationMessage('Android SDK at ${androidSdk.directory}'));
|
||||
messages.add(ValidationMessage(userMessages.androidSdkLocation(androidSdk.directory)));
|
||||
|
||||
messages.add(ValidationMessage(androidSdk.ndk == null
|
||||
? 'Android NDK location not configured (optional; useful for native profiling support)'
|
||||
: 'Android NDK at ${androidSdk.ndk.directory}'));
|
||||
? userMessages.androidMissingNdk
|
||||
: userMessages.androidNdkLocation(androidSdk.ndk.directory)));
|
||||
|
||||
String sdkVersionText;
|
||||
if (androidSdk.latestVersion != null) {
|
||||
sdkVersionText = 'Android SDK ${androidSdk.latestVersion.buildToolsVersionName}';
|
||||
sdkVersionText = userMessages.androidStatusInfo(androidSdk.latestVersion.buildToolsVersionName);
|
||||
|
||||
messages.add(ValidationMessage(
|
||||
'Platform ${androidSdk.latestVersion.platformName}, '
|
||||
'build-tools ${androidSdk.latestVersion.buildToolsVersionName}'
|
||||
));
|
||||
messages.add(ValidationMessage(userMessages.androidSdkPlatformToolsVersion(
|
||||
androidSdk.latestVersion.platformName,
|
||||
androidSdk.latestVersion.buildToolsVersionName)));
|
||||
}
|
||||
|
||||
if (platform.environment.containsKey(kAndroidHome)) {
|
||||
@ -137,22 +124,17 @@ class AndroidValidator extends DoctorValidator {
|
||||
messages.addAll(validationResult.map<ValidationMessage>((String message) {
|
||||
return ValidationMessage.error(message);
|
||||
}));
|
||||
messages.add(ValidationMessage(
|
||||
'Try re-installing or updating your Android SDK,\n'
|
||||
'visit https://flutter.io/setup/#android-setup for detailed instructions.'));
|
||||
messages.add(ValidationMessage(userMessages.androidSdkInstallHelp));
|
||||
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
|
||||
}
|
||||
|
||||
// Now check for the JDK.
|
||||
final String javaBinary = AndroidSdk.findJavaBinary();
|
||||
if (javaBinary == null) {
|
||||
messages.add(ValidationMessage.error(
|
||||
'No Java Development Kit (JDK) found; You must have the environment '
|
||||
'variable JAVA_HOME set and the java binary in your PATH. '
|
||||
'You can download the JDK from $_jdkDownload.'));
|
||||
messages.add(ValidationMessage.error(userMessages.androidMissingJdk));
|
||||
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
|
||||
}
|
||||
messages.add(ValidationMessage('Java binary at: $javaBinary'));
|
||||
messages.add(ValidationMessage(userMessages.androidJdkLocation(javaBinary)));
|
||||
|
||||
// Check JDK version.
|
||||
if (! await _checkJavaVersion(javaBinary, messages)) {
|
||||
@ -178,21 +160,21 @@ class AndroidLicenseValidator extends DoctorValidator {
|
||||
return ValidationResult(ValidationType.missing, messages);
|
||||
}
|
||||
|
||||
final String sdkVersionText = 'Android SDK ${androidSdk.latestVersion.buildToolsVersionName}';
|
||||
final String sdkVersionText = userMessages.androidStatusInfo(androidSdk.latestVersion.buildToolsVersionName);
|
||||
|
||||
// Check for licenses.
|
||||
switch (await licensesAccepted) {
|
||||
case LicensesAccepted.all:
|
||||
messages.add(ValidationMessage('All Android licenses accepted.'));
|
||||
messages.add(ValidationMessage(userMessages.androidLicensesAll));
|
||||
break;
|
||||
case LicensesAccepted.some:
|
||||
messages.add(ValidationMessage.hint('Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses'));
|
||||
messages.add(ValidationMessage.hint(userMessages.androidLicensesSome));
|
||||
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
|
||||
case LicensesAccepted.none:
|
||||
messages.add(ValidationMessage.error('Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses'));
|
||||
messages.add(ValidationMessage.error(userMessages.androidLicensesNone));
|
||||
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
|
||||
case LicensesAccepted.unknown:
|
||||
messages.add(ValidationMessage.error('Android license status unknown.'));
|
||||
messages.add(ValidationMessage.error(userMessages.androidLicensesUnknown));
|
||||
return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText);
|
||||
}
|
||||
return ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText);
|
||||
@ -263,7 +245,7 @@ class AndroidLicenseValidator extends DoctorValidator {
|
||||
try {
|
||||
await Future.wait<void>(<Future<void>>[output, errors]).timeout(const Duration(seconds: 30));
|
||||
} catch (TimeoutException) {
|
||||
printTrace('Intentionally killing ${androidSdk.sdkManagerPath}');
|
||||
printTrace(userMessages.androidLicensesTimeout(androidSdk.sdkManagerPath));
|
||||
processManager.killPid(process.pid);
|
||||
}
|
||||
return status ?? LicensesAccepted.unknown;
|
||||
@ -272,7 +254,7 @@ class AndroidLicenseValidator extends DoctorValidator {
|
||||
/// Run the Android SDK manager tool in order to accept SDK licenses.
|
||||
static Future<bool> runLicenseManager() async {
|
||||
if (androidSdk == null) {
|
||||
printStatus('Unable to locate Android SDK.');
|
||||
printStatus(userMessages.androidSdkShort);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -281,10 +263,7 @@ class AndroidLicenseValidator extends DoctorValidator {
|
||||
final Version sdkManagerVersion = Version.parse(androidSdk.sdkManagerVersion);
|
||||
if (sdkManagerVersion == null || sdkManagerVersion.major < 26)
|
||||
// SDK manager is found, but needs to be updated.
|
||||
throwToolExit(
|
||||
'A newer version of the Android SDK is required. To update, run:\n'
|
||||
'${androidSdk.sdkManagerPath} --update\n'
|
||||
);
|
||||
throwToolExit(userMessages.androidSdkOutdated(androidSdk.sdkManagerPath));
|
||||
|
||||
final Process process = await runCommand(
|
||||
<String>[androidSdk.sdkManagerPath, '--licenses'],
|
||||
@ -309,10 +288,6 @@ class AndroidLicenseValidator extends DoctorValidator {
|
||||
assert(androidSdk != null);
|
||||
final String sdkManagerPath = androidSdk.sdkManagerPath;
|
||||
if (!processManager.canRun(sdkManagerPath))
|
||||
throwToolExit(
|
||||
'Android sdkmanager tool not found ($sdkManagerPath).\n'
|
||||
'Try re-installing or updating your Android SDK,\n'
|
||||
'visit https://flutter.io/setup/#android-setup for detailed instructions.'
|
||||
);
|
||||
throwToolExit(userMessages.androidMissingSdkManager(sdkManagerPath));
|
||||
}
|
||||
}
|
||||
|
183
packages/flutter_tools/lib/src/base/user_messages.dart
Normal file
183
packages/flutter_tools/lib/src/base/user_messages.dart
Normal file
@ -0,0 +1,183 @@
|
||||
import 'context.dart';
|
||||
|
||||
UserMessages get userMessages => context[UserMessages];
|
||||
|
||||
/// Class containing message strings that can be produced by Flutter tools.
|
||||
class UserMessages {
|
||||
// Messages used in FlutterValidator
|
||||
String flutterStatusInfo(String channel, String version, String os, String locale) =>
|
||||
'Channel $channel, v$version, on $os, locale $locale';
|
||||
String flutterVersion(String version, String flutterRoot) =>
|
||||
'Flutter version $version at $flutterRoot';
|
||||
String flutterRevision(String revision, String age, String date) =>
|
||||
'Framework revision $revision ($age), $date';
|
||||
String engineRevision(String revision) => 'Engine revision $revision';
|
||||
String dartRevision(String revision) => 'Dart version $revision';
|
||||
String get flutterBinariesDoNotRun =>
|
||||
'Downloaded executables cannot execute on host.\n'
|
||||
'See https://github.com/flutter/flutter/issues/6207 for more information';
|
||||
String get flutterBinariesLinuxRepairCommands =>
|
||||
'On Debian/Ubuntu/Mint: sudo apt-get install lib32stdc++6\n'
|
||||
'On Fedora: dnf install libstdc++.i686\n'
|
||||
'On Arch: pacman -S lib32-libstdc++5';
|
||||
|
||||
// Messages used in NoIdeValidator
|
||||
String get noIdeStatusInfo => 'No supported IDEs installed';
|
||||
String get noIdeInstallationInfo => 'IntelliJ - https://www.jetbrains.com/idea/';
|
||||
|
||||
// Messages used in IntellijValidator
|
||||
String intellijStatusInfo(String version) => 'version $version';
|
||||
String get intellijPluginInfo =>
|
||||
'For information about installing plugins, see\n'
|
||||
'https://flutter.io/intellij-setup/#installing-the-plugins';
|
||||
String intellijMinimumVersion(String minVersion) =>
|
||||
'This install is older than the minimum recommended version of $minVersion.';
|
||||
String intellijLocation(String installPath) => 'IntelliJ at $installPath';
|
||||
|
||||
// Message used in IntellijValidatorOnMac
|
||||
String get intellijMacUnknownResult => 'Cannot determine if IntelliJ is installed';
|
||||
|
||||
// Messages used in DeviceValidator
|
||||
String get devicesMissing => 'No devices available';
|
||||
String devicesAvailable(int devices) => '$devices available';
|
||||
|
||||
// Messages used in AndroidValidator
|
||||
String androidCantRunJavaBinary(String javaBinary) => 'Cannot execute $javaBinary to determine the version';
|
||||
String get androidUnknownJavaVersion => 'Could not determine java version';
|
||||
String androidJavaVersion(String javaVersion) => 'Java version $javaVersion';
|
||||
String androidBadSdkDir(String envKey, String homeDir) =>
|
||||
'$envKey = $homeDir\n'
|
||||
'but Android SDK not found at this location.';
|
||||
String androidMissingSdkInstructions(String envKey) =>
|
||||
'Unable to locate Android SDK.\n'
|
||||
'Install Android Studio from: https://developer.android.com/studio/index.html\n'
|
||||
'On first launch it will assist you in installing the Android SDK components.\n'
|
||||
'(or visit https://flutter.io/setup/#android-setup for detailed instructions).\n'
|
||||
'If Android SDK has been installed to a custom location, set $envKey to that location.\n'
|
||||
'You may also want to add it to your PATH environment variable.\n';
|
||||
String androidSdkLocation(String directory) => 'Android SDK at $directory';
|
||||
String androidSdkPlatformToolsVersion(String platform, String tools) =>
|
||||
'Platform $platform, build-tools $tools';
|
||||
String get androidSdkInstallHelp =>
|
||||
'Try re-installing or updating your Android SDK,\n'
|
||||
'visit https://flutter.io/setup/#android-setup for detailed instructions.';
|
||||
String get androidMissingNdk => 'Android NDK location not configured (optional; useful for native profiling support)';
|
||||
String androidNdkLocation(String directory) => 'Android NDK at $directory';
|
||||
// Also occurs in AndroidLicenseValidator
|
||||
String androidStatusInfo(String version) => 'Android SDK version $version';
|
||||
|
||||
// Messages used in AndroidLicenseValidator
|
||||
String get androidMissingJdk =>
|
||||
'No Java Development Kit (JDK) found; You must have the environment '
|
||||
'variable JAVA_HOME set and the java binary in your PATH. '
|
||||
'You can download the JDK from https://www.oracle.com/technetwork/java/javase/downloads/.';
|
||||
String androidJdkLocation(String location) => 'Java binary at: $location';
|
||||
String get androidLicensesAll => 'All Android licenses accepted.';
|
||||
String get androidLicensesSome => 'Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses';
|
||||
String get androidLicensesNone => 'Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses';
|
||||
String get androidLicensesUnknown => 'Android license status unknown.';
|
||||
String androidSdkOutdated(String managerPath) =>
|
||||
'A newer version of the Android SDK is required. To update, run:\n'
|
||||
'$managerPath --update\n';
|
||||
String androidLicensesTimeout(String managerPath) => 'Intentionally killing $managerPath';
|
||||
String get androidSdkShort => 'Unable to locate Android SDK.';
|
||||
String androidMissingSdkManager(String sdkManagerPath) =>
|
||||
'Android sdkmanager tool not found ($sdkManagerPath).\n'
|
||||
'Try re-installing or updating your Android SDK,\n'
|
||||
'visit https://flutter.io/setup/#android-setup for detailed instructions.';
|
||||
|
||||
// Messages used in AndroidStudioValidator
|
||||
String androidStudioVersion(String version) => 'version $version';
|
||||
String androidStudioLocation(String location) => 'Android Studio at $location';
|
||||
String get androidStudioNeedsUpdate => 'Try updating or re-installing Android Studio.';
|
||||
String get androidStudioResetDir =>
|
||||
'Consider removing your android-studio-dir setting by running:\n'
|
||||
'flutter config --android-studio-dir=';
|
||||
|
||||
// Messages used in NoAndroidStudioValidator
|
||||
String androidStudioMissing(String location) =>
|
||||
'android-studio-dir = $location\n'
|
||||
'but Android Studio not found at this location.';
|
||||
String get androidStudioInstallation =>
|
||||
'Android Studio not found; download from https://developer.android.com/studio/index.html\n'
|
||||
'(or visit https://flutter.io/setup/#android-setup for detailed instructions).';
|
||||
|
||||
// Messages used in IOSValidator
|
||||
String iOSXcodeLocation(String location) => 'Xcode at $location';
|
||||
String iOSXcodeOutdated(int versionMajor, int versionMinor) =>
|
||||
'Flutter requires a minimum Xcode version of $versionMajor.$versionMinor.0.\n'
|
||||
'Download the latest version or update via the Mac App Store.';
|
||||
String get iOSXcodeEula => 'Xcode end user license agreement not signed; open Xcode or run the command \'sudo xcodebuild -license\'.';
|
||||
String get iOSXcodeMissingSimct =>
|
||||
'Xcode requires additional components to be installed in order to run.\n'
|
||||
'Launch Xcode and install additional required components when prompted.';
|
||||
String get iOSXcodeMissing =>
|
||||
'Xcode not installed; this is necessary for iOS development.\n'
|
||||
'Download at https://developer.apple.com/xcode/download/.';
|
||||
String get iOSXcodeIncomplete =>
|
||||
'Xcode installation is incomplete; a full installation is necessary for iOS development.\n'
|
||||
'Download at: https://developer.apple.com/xcode/download/\n'
|
||||
'Or install Xcode via the App Store.\n'
|
||||
'Once installed, run:\n'
|
||||
' sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer';
|
||||
String get iOSIMobileDeviceMissing =>
|
||||
'libimobiledevice and ideviceinstaller are not installed. To install with Brew, run:\n'
|
||||
' brew update\n'
|
||||
' brew install --HEAD usbmuxd\n'
|
||||
' brew link usbmuxd\n'
|
||||
' brew install --HEAD libimobiledevice\n'
|
||||
' brew install ideviceinstaller';
|
||||
String get iOSIMobileDeviceBroken =>
|
||||
'Verify that all connected devices have been paired with this computer in Xcode.\n'
|
||||
'If all devices have been paired, libimobiledevice and ideviceinstaller may require updating.\n'
|
||||
'To update with Brew, run:\n'
|
||||
' brew update\n'
|
||||
' brew uninstall --ignore-dependencies libimobiledevice\n'
|
||||
' brew uninstall --ignore-dependencies usbmuxd\n'
|
||||
' brew install --HEAD usbmuxd\n'
|
||||
' brew unlink usbmuxd\n'
|
||||
' brew link usbmuxd\n'
|
||||
' brew install --HEAD libimobiledevice\n'
|
||||
' brew install ideviceinstaller';
|
||||
String get iOSDeviceInstallerMissing =>
|
||||
'ideviceinstaller is not installed; this is used to discover connected iOS devices.\n'
|
||||
'To install with Brew, run:\n'
|
||||
' brew install --HEAD usbmuxd\n'
|
||||
' brew link usbmuxd\n'
|
||||
' brew install --HEAD libimobiledevice\n'
|
||||
' brew install ideviceinstaller';
|
||||
String iOSDeployVersion(String version) => 'ios-deploy $version';
|
||||
String iOSDeployOutdated(String minVersion) =>
|
||||
'ios-deploy out of date ($minVersion is required). To upgrade with Brew:\n'
|
||||
' brew upgrade ios-deploy';
|
||||
String get iOSDeployMissing =>
|
||||
'ios-deploy not installed. To install:\n'
|
||||
' brew install ios-deploy';
|
||||
String get iOSBrewMissing =>
|
||||
'Brew can be used to install tools for iOS device development.\n'
|
||||
'Download brew at https://brew.sh/.';
|
||||
|
||||
// Messages used in CocoaPodsValidator
|
||||
String cocoaPodsVersion(String version) => 'CocoaPods version $version';
|
||||
String cocoaPodsUninitialized(String consequence) =>
|
||||
'CocoaPods installed but not initialized.\n'
|
||||
'$consequence\n'
|
||||
'To initialize CocoaPods, run:\n'
|
||||
' pod setup\n'
|
||||
'once to finalize CocoaPods\' installation.';
|
||||
String cocoaPodsMissing(String consequence, String installInstructions) =>
|
||||
'CocoaPods not installed.\n'
|
||||
'$consequence\n'
|
||||
'To install:\n'
|
||||
'$installInstructions';
|
||||
String cocoaPodsOutdated(String recVersion, String consequence, String upgradeInstructions) =>
|
||||
'CocoaPods out of date ($recVersion is recommended).\n'
|
||||
'$consequence\n'
|
||||
'To upgrade:\n'
|
||||
'$upgradeInstructions';
|
||||
|
||||
// Messages used in VsCodeValidator
|
||||
String vsCodeVersion(String version) => 'version $version';
|
||||
String vsCodeLocation(String location) => 'VS Code at $location';
|
||||
String vsCodeFlutterExtensionMissing(String url) => 'Flutter extension not installed; install from\n$url';
|
||||
}
|
@ -18,6 +18,7 @@ import 'base/logger.dart';
|
||||
import 'base/os.dart';
|
||||
import 'base/platform.dart';
|
||||
import 'base/time.dart';
|
||||
import 'base/user_messages.dart';
|
||||
import 'base/utils.dart';
|
||||
import 'cache.dart';
|
||||
import 'compile.dart';
|
||||
@ -81,6 +82,7 @@ Future<T> runInContext<T>(
|
||||
SystemClock: () => const SystemClock(),
|
||||
Stdio: () => const Stdio(),
|
||||
Usage: () => Usage(),
|
||||
UserMessages: () => UserMessages(),
|
||||
Xcode: () => Xcode(),
|
||||
XcodeProjectInterpreter: () => XcodeProjectInterpreter(),
|
||||
},
|
||||
|
@ -15,6 +15,7 @@ import 'base/os.dart';
|
||||
import 'base/platform.dart';
|
||||
import 'base/process_manager.dart';
|
||||
import 'base/terminal.dart';
|
||||
import 'base/user_messages.dart';
|
||||
import 'base/utils.dart';
|
||||
import 'base/version.dart';
|
||||
import 'cache.dart';
|
||||
@ -432,32 +433,26 @@ class _FlutterValidator extends DoctorValidator {
|
||||
|
||||
final FlutterVersion version = FlutterVersion.instance;
|
||||
|
||||
messages.add(ValidationMessage('Flutter version ${version.frameworkVersion} at ${Cache.flutterRoot}'));
|
||||
messages.add(ValidationMessage(
|
||||
'Framework revision ${version.frameworkRevisionShort} '
|
||||
'(${version.frameworkAge}), ${version.frameworkDate}'
|
||||
));
|
||||
messages.add(ValidationMessage('Engine revision ${version.engineRevisionShort}'));
|
||||
messages.add(ValidationMessage('Dart version ${version.dartSdkVersion}'));
|
||||
messages.add(ValidationMessage(userMessages.flutterVersion(version.frameworkVersion, Cache.flutterRoot)));
|
||||
messages.add(ValidationMessage(userMessages.flutterRevision(version.frameworkRevisionShort, version.frameworkAge, version.frameworkDate)));
|
||||
messages.add(ValidationMessage(userMessages.engineRevision(version.engineRevisionShort)));
|
||||
messages.add(ValidationMessage(userMessages.dartRevision(version.dartSdkVersion)));
|
||||
final String genSnapshotPath =
|
||||
artifacts.getArtifactPath(Artifact.genSnapshot);
|
||||
|
||||
// Check that the binaries we downloaded for this platform actually run on it.
|
||||
if (!_genSnapshotRuns(genSnapshotPath)) {
|
||||
final StringBuffer buf = StringBuffer();
|
||||
buf.writeln('Downloaded executables cannot execute on host.');
|
||||
buf.writeln('See https://github.com/flutter/flutter/issues/6207 for more information');
|
||||
buf.writeln(userMessages.flutterBinariesDoNotRun);
|
||||
if (platform.isLinux) {
|
||||
buf.writeln('On Debian/Ubuntu/Mint: sudo apt-get install lib32stdc++6');
|
||||
buf.writeln('On Fedora: dnf install libstdc++.i686');
|
||||
buf.writeln('On Arch: pacman -S lib32-libstdc++5');
|
||||
buf.writeln(userMessages.flutterBinariesLinuxRepairCommands);
|
||||
}
|
||||
messages.add(ValidationMessage.error(buf.toString()));
|
||||
valid = ValidationType.partial;
|
||||
}
|
||||
|
||||
return ValidationResult(valid, messages,
|
||||
statusInfo: 'Channel ${version.channel}, v${version.frameworkVersion}, on ${os.name}, locale ${platform.localeName}'
|
||||
statusInfo: userMessages.flutterStatusInfo(version.channel, version.frameworkVersion, os.name, platform.localeName)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -477,8 +472,8 @@ class NoIdeValidator extends DoctorValidator {
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
return ValidationResult(ValidationType.missing, <ValidationMessage>[
|
||||
ValidationMessage('IntelliJ - https://www.jetbrains.com/idea/'),
|
||||
], statusInfo: 'No supported IDEs installed');
|
||||
ValidationMessage(userMessages.noIdeInstallationInfo),
|
||||
], statusInfo: userMessages.noIdeStatusInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,7 +504,7 @@ abstract class IntelliJValidator extends DoctorValidator {
|
||||
Future<ValidationResult> validate() async {
|
||||
final List<ValidationMessage> messages = <ValidationMessage>[];
|
||||
|
||||
messages.add(ValidationMessage('IntelliJ at $installPath'));
|
||||
messages.add(ValidationMessage(userMessages.intellijLocation(installPath)));
|
||||
|
||||
final IntelliJPlugins plugins = IntelliJPlugins(pluginsPath);
|
||||
plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'],
|
||||
@ -517,10 +512,7 @@ abstract class IntelliJValidator extends DoctorValidator {
|
||||
plugins.validatePackage(messages, <String>['Dart'], 'Dart');
|
||||
|
||||
if (_hasIssues(messages)) {
|
||||
messages.add(ValidationMessage(
|
||||
'For information about installing plugins, see\n'
|
||||
'https://flutter.io/intellij-setup/#installing-the-plugins'
|
||||
));
|
||||
messages.add(ValidationMessage(userMessages.intellijPluginInfo));
|
||||
}
|
||||
|
||||
_validateIntelliJVersion(messages, kMinIdeaVersion);
|
||||
@ -528,8 +520,7 @@ abstract class IntelliJValidator extends DoctorValidator {
|
||||
return ValidationResult(
|
||||
_hasIssues(messages) ? ValidationType.partial : ValidationType.installed,
|
||||
messages,
|
||||
statusInfo: 'version $version'
|
||||
);
|
||||
statusInfo: userMessages.intellijStatusInfo(version));
|
||||
}
|
||||
|
||||
bool _hasIssues(List<ValidationMessage> messages) {
|
||||
@ -546,9 +537,7 @@ abstract class IntelliJValidator extends DoctorValidator {
|
||||
return;
|
||||
|
||||
if (installedVersion < minVersion) {
|
||||
messages.add(ValidationMessage.error(
|
||||
'This install is older than the minimum recommended version of $minVersion.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.intellijMinimumVersion(minVersion.toString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -648,7 +637,7 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
|
||||
}
|
||||
} on FileSystemException catch (e) {
|
||||
validators.add(ValidatorWithResult(
|
||||
'Cannot determine if IntelliJ is installed',
|
||||
userMessages.intellijMacUnknownResult,
|
||||
ValidationResult(ValidationType.missing, <ValidationMessage>[
|
||||
ValidationMessage.error(e.message),
|
||||
]),
|
||||
@ -691,7 +680,7 @@ class DeviceValidator extends DoctorValidator {
|
||||
if (diagnostics.isNotEmpty) {
|
||||
messages = diagnostics.map<ValidationMessage>((String message) => ValidationMessage(message)).toList();
|
||||
} else {
|
||||
messages = <ValidationMessage>[ValidationMessage.hint('No devices available')];
|
||||
messages = <ValidationMessage>[ValidationMessage.hint(userMessages.devicesMissing)];
|
||||
}
|
||||
} else {
|
||||
messages = await Device.descriptions(devices)
|
||||
@ -701,7 +690,7 @@ class DeviceValidator extends DoctorValidator {
|
||||
if (devices.isEmpty) {
|
||||
return ValidationResult(ValidationType.notAvailable, messages);
|
||||
} else {
|
||||
return ValidationResult(ValidationType.installed, messages, statusInfo: '${devices.length} available');
|
||||
return ValidationResult(ValidationType.installed, messages, statusInfo: userMessages.devicesAvailable(devices.length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import '../base/context.dart';
|
||||
import '../base/os.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/process.dart';
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import 'cocoapods.dart';
|
||||
@ -81,7 +82,7 @@ class IOSValidator extends DoctorValidator {
|
||||
if (xcode.isInstalled) {
|
||||
xcodeStatus = ValidationType.installed;
|
||||
|
||||
messages.add(ValidationMessage('Xcode at ${xcode.xcodeSelectPath}'));
|
||||
messages.add(ValidationMessage(userMessages.iOSXcodeLocation(xcode.xcodeSelectPath)));
|
||||
|
||||
xcodeVersionInfo = xcode.versionText;
|
||||
if (xcodeVersionInfo.contains(','))
|
||||
@ -91,40 +92,25 @@ class IOSValidator extends DoctorValidator {
|
||||
if (!xcode.isInstalledAndMeetsVersionCheck) {
|
||||
xcodeStatus = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'Flutter requires a minimum Xcode version of $kXcodeRequiredVersionMajor.$kXcodeRequiredVersionMinor.0.\n'
|
||||
'Download the latest version or update via the Mac App Store.'
|
||||
userMessages.iOSXcodeOutdated(kXcodeRequiredVersionMajor, kXcodeRequiredVersionMinor)
|
||||
));
|
||||
}
|
||||
|
||||
if (!xcode.eulaSigned) {
|
||||
xcodeStatus = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'Xcode end user license agreement not signed; open Xcode or run the command \'sudo xcodebuild -license\'.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSXcodeEula));
|
||||
}
|
||||
if (!xcode.isSimctlInstalled) {
|
||||
xcodeStatus = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'Xcode requires additional components to be installed in order to run.\n'
|
||||
'Launch Xcode and install additional required components when prompted.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSXcodeMissingSimct));
|
||||
}
|
||||
|
||||
} else {
|
||||
xcodeStatus = ValidationType.missing;
|
||||
if (xcode.xcodeSelectPath == null || xcode.xcodeSelectPath.isEmpty) {
|
||||
messages.add(ValidationMessage.error(
|
||||
'Xcode not installed; this is necessary for iOS development.\n'
|
||||
'Download at https://developer.apple.com/xcode/download/.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSXcodeMissing));
|
||||
} else {
|
||||
messages.add(ValidationMessage.error(
|
||||
'Xcode installation is incomplete; a full installation is necessary for iOS development.\n'
|
||||
'Download at: https://developer.apple.com/xcode/download/\n'
|
||||
'Or install Xcode via the App Store.\n'
|
||||
'Once installed, run:\n'
|
||||
' sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSXcodeIncomplete));
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,63 +119,30 @@ class IOSValidator extends DoctorValidator {
|
||||
if (!iMobileDevice.isInstalled) {
|
||||
checksFailed += 3;
|
||||
packageManagerStatus = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'libimobiledevice and ideviceinstaller are not installed. To install with Brew, run:\n'
|
||||
' brew update\n'
|
||||
' brew install --HEAD usbmuxd\n'
|
||||
' brew link usbmuxd\n'
|
||||
' brew install --HEAD libimobiledevice\n'
|
||||
' brew install ideviceinstaller'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSIMobileDeviceMissing));
|
||||
} else if (!await iMobileDevice.isWorking) {
|
||||
checksFailed += 2;
|
||||
packageManagerStatus = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'Verify that all connected devices have been paired with this computer in Xcode.\n'
|
||||
'If all devices have been paired, libimobiledevice and ideviceinstaller may require updating.\n'
|
||||
'To update with Brew, run:\n'
|
||||
' brew update\n'
|
||||
' brew uninstall --ignore-dependencies libimobiledevice\n'
|
||||
' brew uninstall --ignore-dependencies usbmuxd\n'
|
||||
' brew install --HEAD usbmuxd\n'
|
||||
' brew unlink usbmuxd\n'
|
||||
' brew link usbmuxd\n'
|
||||
' brew install --HEAD libimobiledevice\n'
|
||||
' brew install ideviceinstaller'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSIMobileDeviceBroken));
|
||||
} else if (!await hasIDeviceInstaller) {
|
||||
checksFailed += 1;
|
||||
packageManagerStatus = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'ideviceinstaller is not installed; this is used to discover connected iOS devices.\n'
|
||||
'To install with Brew, run:\n'
|
||||
' brew install --HEAD usbmuxd\n'
|
||||
' brew link usbmuxd\n'
|
||||
' brew install --HEAD libimobiledevice\n'
|
||||
' brew install ideviceinstaller'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSDeviceInstallerMissing));
|
||||
}
|
||||
|
||||
final bool iHasIosDeploy = await hasIosDeploy;
|
||||
|
||||
// Check ios-deploy is installed at meets version requirements.
|
||||
if (iHasIosDeploy) {
|
||||
messages.add(
|
||||
ValidationMessage('ios-deploy ${await iosDeployVersionText}'));
|
||||
messages.add(ValidationMessage(userMessages.iOSDeployVersion(await iosDeployVersionText)));
|
||||
}
|
||||
if (!await _iosDeployIsInstalledAndMeetsVersionCheck) {
|
||||
packageManagerStatus = ValidationType.partial;
|
||||
if (iHasIosDeploy) {
|
||||
messages.add(ValidationMessage.error(
|
||||
'ios-deploy out of date ($iosDeployMinimumVersion is required). To upgrade with Brew:\n'
|
||||
' brew upgrade ios-deploy'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSDeployOutdated(iosDeployMinimumVersion)));
|
||||
} else {
|
||||
checksFailed += 1;
|
||||
messages.add(ValidationMessage.error(
|
||||
'ios-deploy not installed. To install with Brew:\n'
|
||||
' brew install ios-deploy'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSDeployMissing));
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,10 +151,7 @@ class IOSValidator extends DoctorValidator {
|
||||
if (checksFailed == totalChecks)
|
||||
packageManagerStatus = ValidationType.missing;
|
||||
if (checksFailed > 0 && !hasHomebrew) {
|
||||
messages.add(ValidationMessage.error(
|
||||
'Brew can be used to install tools for iOS device development.\n'
|
||||
'Download brew at https://brew.sh/.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.iOSBrewMissing));
|
||||
}
|
||||
|
||||
return ValidationResult(
|
||||
@ -232,34 +182,20 @@ class CocoaPodsValidator extends DoctorValidator {
|
||||
|
||||
if (cocoaPodsStatus == CocoaPodsStatus.recommended) {
|
||||
if (await cocoaPods.isCocoaPodsInitialized) {
|
||||
messages.add(ValidationMessage('CocoaPods version ${await cocoaPods.cocoaPodsVersionText}'));
|
||||
messages.add(ValidationMessage(userMessages.cocoaPodsVersion(await cocoaPods.cocoaPodsVersionText)));
|
||||
} else {
|
||||
status = ValidationType.partial;
|
||||
messages.add(ValidationMessage.error(
|
||||
'CocoaPods installed but not initialized.\n'
|
||||
'$noCocoaPodsConsequence\n'
|
||||
'To initialize CocoaPods, run:\n'
|
||||
' pod setup\n'
|
||||
'once to finalize CocoaPods\' installation.'
|
||||
));
|
||||
messages.add(ValidationMessage.error(userMessages.cocoaPodsUninitialized(noCocoaPodsConsequence)));
|
||||
}
|
||||
} else {
|
||||
if (cocoaPodsStatus == CocoaPodsStatus.notInstalled) {
|
||||
status = ValidationType.missing;
|
||||
messages.add(ValidationMessage.error(
|
||||
'CocoaPods not installed.\n'
|
||||
'$noCocoaPodsConsequence\n'
|
||||
'To install:\n'
|
||||
'$cocoaPodsInstallInstructions'
|
||||
));
|
||||
userMessages.cocoaPodsMissing(noCocoaPodsConsequence, cocoaPodsInstallInstructions)));
|
||||
} else {
|
||||
status = ValidationType.partial;
|
||||
messages.add(ValidationMessage.hint(
|
||||
'CocoaPods out of date (${cocoaPods.cocoaPodsRecommendedVersion} is recommended).\n'
|
||||
'$noCocoaPodsConsequence\n'
|
||||
'To upgrade:\n'
|
||||
'$cocoaPodsUpgradeInstructions'
|
||||
));
|
||||
userMessages.cocoaPodsOutdated(cocoaPods.cocoaPodsRecommendedVersion, noCocoaPodsConsequence, cocoaPodsUpgradeInstructions)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import 'vscode.dart';
|
||||
@ -24,7 +25,7 @@ class VsCodeValidator extends DoctorValidator {
|
||||
Future<ValidationResult> validate() async {
|
||||
final String vsCodeVersionText = _vsCode.version == Version.unknown
|
||||
? null
|
||||
: 'version ${_vsCode.version}';
|
||||
: userMessages.vsCodeVersion(_vsCode.version.toString());
|
||||
|
||||
final ValidationType validationType = _vsCode.isValid
|
||||
? ValidationType.installed
|
||||
|
Loading…
Reference in New Issue
Block a user