Migrate doctor_validator to null safety (#79682)
This commit is contained in:
parent
90c0e3e875
commit
79f1689f6a
@ -11,7 +11,7 @@ import '../base/file_system.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../intellij/intellij.dart';
|
||||
import 'android_studio.dart';
|
||||
|
||||
|
@ -17,7 +17,7 @@ import '../base/platform.dart';
|
||||
import '../base/user_messages.dart' hide userMessages;
|
||||
import '../base/version.dart';
|
||||
import '../convert.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
import 'android_sdk.dart';
|
||||
import 'android_studio.dart';
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
import '../base/common.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../emulator.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../runner/flutter_command.dart';
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
|
||||
/// The custom-devices-specific implementation of a [Workflow].
|
||||
|
@ -21,6 +21,7 @@ import 'base/user_messages.dart';
|
||||
import 'base/utils.dart';
|
||||
import 'cache.dart';
|
||||
import 'device.dart';
|
||||
import 'doctor_validator.dart';
|
||||
import 'features.dart';
|
||||
import 'fuchsia/fuchsia_workflow.dart';
|
||||
import 'globals.dart' as globals;
|
||||
@ -172,13 +173,6 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider {
|
||||
}
|
||||
return _workflows;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ValidatorTask {
|
||||
ValidatorTask(this.validator, this.result);
|
||||
final DoctorValidator validator;
|
||||
final Future<ValidationResult> result;
|
||||
}
|
||||
|
||||
class Doctor {
|
||||
@ -393,278 +387,6 @@ class Doctor {
|
||||
}
|
||||
}
|
||||
|
||||
/// A series of tools and required install steps for a target platform (iOS or Android).
|
||||
abstract class Workflow {
|
||||
const Workflow();
|
||||
|
||||
/// Whether the workflow applies to this platform (as in, should we ever try and use it).
|
||||
bool get appliesToHostPlatform;
|
||||
|
||||
/// Are we functional enough to list devices?
|
||||
bool get canListDevices;
|
||||
|
||||
/// Could this thing launch *something*? It may still have minor issues.
|
||||
bool get canLaunchDevices;
|
||||
|
||||
/// Are we functional enough to list emulators?
|
||||
bool get canListEmulators;
|
||||
}
|
||||
|
||||
enum ValidationType {
|
||||
crash,
|
||||
missing,
|
||||
partial,
|
||||
notAvailable,
|
||||
installed,
|
||||
}
|
||||
|
||||
enum ValidationMessageType {
|
||||
error,
|
||||
hint,
|
||||
information,
|
||||
}
|
||||
|
||||
abstract class DoctorValidator {
|
||||
const DoctorValidator(this.title);
|
||||
|
||||
/// This is displayed in the CLI.
|
||||
final String title;
|
||||
|
||||
String get slowWarning => 'This is taking an unexpectedly long time...';
|
||||
|
||||
Future<ValidationResult> validate();
|
||||
}
|
||||
|
||||
/// A validator that runs other [DoctorValidator]s and combines their output
|
||||
/// into a single [ValidationResult]. It uses the title of the first validator
|
||||
/// passed to the constructor and reports the statusInfo of the first validator
|
||||
/// that provides one. Other titles and statusInfo strings are discarded.
|
||||
class GroupedValidator extends DoctorValidator {
|
||||
GroupedValidator(this.subValidators) : super(subValidators[0].title);
|
||||
|
||||
final List<DoctorValidator> subValidators;
|
||||
|
||||
List<ValidationResult> _subResults;
|
||||
|
||||
/// Sub-validator results.
|
||||
///
|
||||
/// To avoid losing information when results are merged, the sub-results are
|
||||
/// cached on this field when they are available. The results are in the same
|
||||
/// order as the sub-validator list.
|
||||
List<ValidationResult> get subResults => _subResults;
|
||||
|
||||
@override
|
||||
String get slowWarning => _currentSlowWarning;
|
||||
String _currentSlowWarning = 'Initializing...';
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
final List<ValidatorTask> tasks = <ValidatorTask>[
|
||||
for (final DoctorValidator validator in subValidators)
|
||||
ValidatorTask(
|
||||
validator,
|
||||
asyncGuard<ValidationResult>(() => validator.validate()),
|
||||
),
|
||||
];
|
||||
|
||||
final List<ValidationResult> results = <ValidationResult>[];
|
||||
for (final ValidatorTask subValidator in tasks) {
|
||||
_currentSlowWarning = subValidator.validator.slowWarning;
|
||||
try {
|
||||
results.add(await subValidator.result);
|
||||
} on Exception catch (exception, stackTrace) {
|
||||
results.add(ValidationResult.crash(exception, stackTrace));
|
||||
}
|
||||
}
|
||||
_currentSlowWarning = 'Merging results...';
|
||||
return _mergeValidationResults(results);
|
||||
}
|
||||
|
||||
ValidationResult _mergeValidationResults(List<ValidationResult> results) {
|
||||
assert(results.isNotEmpty, 'Validation results should not be empty');
|
||||
_subResults = results;
|
||||
ValidationType mergedType = results[0].type;
|
||||
final List<ValidationMessage> mergedMessages = <ValidationMessage>[];
|
||||
String statusInfo;
|
||||
|
||||
for (final ValidationResult result in results) {
|
||||
statusInfo ??= result.statusInfo;
|
||||
switch (result.type) {
|
||||
case ValidationType.installed:
|
||||
if (mergedType == ValidationType.missing) {
|
||||
mergedType = ValidationType.partial;
|
||||
}
|
||||
break;
|
||||
case ValidationType.notAvailable:
|
||||
case ValidationType.partial:
|
||||
mergedType = ValidationType.partial;
|
||||
break;
|
||||
case ValidationType.crash:
|
||||
case ValidationType.missing:
|
||||
if (mergedType == ValidationType.installed) {
|
||||
mergedType = ValidationType.partial;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 'Unrecognized validation type: ' + result.type.toString();
|
||||
}
|
||||
mergedMessages.addAll(result.messages);
|
||||
}
|
||||
|
||||
return ValidationResult(mergedType, mergedMessages,
|
||||
statusInfo: statusInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ValidationResult {
|
||||
/// [ValidationResult.type] should only equal [ValidationResult.installed]
|
||||
/// if no [messages] are hints or errors.
|
||||
const ValidationResult(this.type, this.messages, { this.statusInfo });
|
||||
|
||||
factory ValidationResult.crash(Object error, [StackTrace stackTrace]) {
|
||||
return ValidationResult(ValidationType.crash, <ValidationMessage>[
|
||||
const ValidationMessage.error(
|
||||
'Due to an error, the doctor check did not complete. '
|
||||
'If the error message below is not helpful, '
|
||||
'please let us know about this issue at https://github.com/flutter/flutter/issues.'),
|
||||
ValidationMessage.error('$error'),
|
||||
if (stackTrace != null)
|
||||
// Stacktrace is informational. Printed in verbose mode only.
|
||||
ValidationMessage('$stackTrace'),
|
||||
], statusInfo: 'the doctor check crashed');
|
||||
}
|
||||
|
||||
final ValidationType type;
|
||||
// A short message about the status.
|
||||
final String statusInfo;
|
||||
final List<ValidationMessage> messages;
|
||||
|
||||
String get leadingBox {
|
||||
assert(type != null);
|
||||
switch (type) {
|
||||
case ValidationType.crash:
|
||||
return '[☠]';
|
||||
case ValidationType.missing:
|
||||
return '[✗]';
|
||||
case ValidationType.installed:
|
||||
return '[✓]';
|
||||
case ValidationType.notAvailable:
|
||||
case ValidationType.partial:
|
||||
return '[!]';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String get coloredLeadingBox {
|
||||
assert(type != null);
|
||||
switch (type) {
|
||||
case ValidationType.crash:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.red);
|
||||
case ValidationType.missing:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.red);
|
||||
case ValidationType.installed:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.green);
|
||||
case ValidationType.notAvailable:
|
||||
case ValidationType.partial:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.yellow);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The string representation of the type.
|
||||
String get typeStr {
|
||||
assert(type != null);
|
||||
switch (type) {
|
||||
case ValidationType.crash:
|
||||
return 'crash';
|
||||
case ValidationType.missing:
|
||||
return 'missing';
|
||||
case ValidationType.installed:
|
||||
return 'installed';
|
||||
case ValidationType.notAvailable:
|
||||
return 'notAvailable';
|
||||
case ValidationType.partial:
|
||||
return 'partial';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// A status line for the flutter doctor validation to display.
|
||||
///
|
||||
/// The [message] is required and represents either an informational statement
|
||||
/// about the particular doctor validation that passed, or more context
|
||||
/// on the cause and/or solution to the validation failure.
|
||||
@immutable
|
||||
class ValidationMessage {
|
||||
/// Create a validation message with information for a passing validator.
|
||||
///
|
||||
/// By default this is not displayed unless the doctor is run in
|
||||
/// verbose mode.
|
||||
///
|
||||
/// The [contextUrl] may be supplied to link to external resources. This
|
||||
/// is displayed after the informative message in verbose modes.
|
||||
const ValidationMessage(this.message, {this.contextUrl}) : type = ValidationMessageType.information;
|
||||
|
||||
/// Create a validation message with information for a failing validator.
|
||||
const ValidationMessage.error(this.message)
|
||||
: type = ValidationMessageType.error,
|
||||
contextUrl = null;
|
||||
|
||||
/// Create a validation message with information for a partially failing
|
||||
/// validator.
|
||||
const ValidationMessage.hint(this.message)
|
||||
: type = ValidationMessageType.hint,
|
||||
contextUrl = null;
|
||||
|
||||
final ValidationMessageType type;
|
||||
final String contextUrl;
|
||||
final String message;
|
||||
|
||||
bool get isError => type == ValidationMessageType.error;
|
||||
|
||||
bool get isHint => type == ValidationMessageType.hint;
|
||||
|
||||
String get indicator {
|
||||
switch (type) {
|
||||
case ValidationMessageType.error:
|
||||
return '✗';
|
||||
case ValidationMessageType.hint:
|
||||
return '!';
|
||||
case ValidationMessageType.information:
|
||||
return '•';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String get coloredIndicator {
|
||||
switch (type) {
|
||||
case ValidationMessageType.error:
|
||||
return globals.terminal.color(indicator, TerminalColor.red);
|
||||
case ValidationMessageType.hint:
|
||||
return globals.terminal.color(indicator, TerminalColor.yellow);
|
||||
case ValidationMessageType.information:
|
||||
return globals.terminal.color(indicator, TerminalColor.green);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => message;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is ValidationMessage
|
||||
&& other.message == message
|
||||
&& other.type == type
|
||||
&& other.contextUrl == contextUrl;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => type.hashCode ^ message.hashCode ^ contextUrl.hashCode;
|
||||
}
|
||||
|
||||
/// A validator that checks the version of Flutter, as well as some auxiliary information
|
||||
/// such as the pub or Flutter cache overrides.
|
||||
///
|
||||
@ -768,19 +490,6 @@ class FlutterValidator extends DoctorValidator {
|
||||
}
|
||||
}
|
||||
|
||||
class NoIdeValidator extends DoctorValidator {
|
||||
NoIdeValidator() : super('Flutter IDE Support');
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
return ValidationResult(
|
||||
ValidationType.missing,
|
||||
userMessages.noIdeInstallationInfo.map((String ideInfo) => ValidationMessage(ideInfo)).toList(),
|
||||
statusInfo: userMessages.noIdeStatusInfo,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DeviceValidator extends DoctorValidator {
|
||||
// TODO(jmagman): Make required once g3 rolls and is updated.
|
||||
DeviceValidator({
|
||||
@ -831,12 +540,3 @@ class DeviceValidator extends DoctorValidator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ValidatorWithResult extends DoctorValidator {
|
||||
ValidatorWithResult(String title, this.result) : super(title);
|
||||
|
||||
final ValidationResult result;
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async => result;
|
||||
}
|
||||
|
304
packages/flutter_tools/lib/src/doctor_validator.dart
Normal file
304
packages/flutter_tools/lib/src/doctor_validator.dart
Normal file
@ -0,0 +1,304 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'base/async_guard.dart';
|
||||
import 'base/terminal.dart';
|
||||
import 'globals_null_migrated.dart' as globals;
|
||||
|
||||
class ValidatorTask {
|
||||
ValidatorTask(this.validator, this.result);
|
||||
final DoctorValidator validator;
|
||||
final Future<ValidationResult> result;
|
||||
}
|
||||
|
||||
/// A series of tools and required install steps for a target platform (iOS or Android).
|
||||
abstract class Workflow {
|
||||
const Workflow();
|
||||
|
||||
/// Whether the workflow applies to this platform (as in, should we ever try and use it).
|
||||
bool get appliesToHostPlatform;
|
||||
|
||||
/// Are we functional enough to list devices?
|
||||
bool get canListDevices;
|
||||
|
||||
/// Could this thing launch *something*? It may still have minor issues.
|
||||
bool get canLaunchDevices;
|
||||
|
||||
/// Are we functional enough to list emulators?
|
||||
bool get canListEmulators;
|
||||
}
|
||||
|
||||
enum ValidationType {
|
||||
crash,
|
||||
missing,
|
||||
partial,
|
||||
notAvailable,
|
||||
installed,
|
||||
}
|
||||
|
||||
enum ValidationMessageType {
|
||||
error,
|
||||
hint,
|
||||
information,
|
||||
}
|
||||
|
||||
abstract class DoctorValidator {
|
||||
const DoctorValidator(this.title);
|
||||
|
||||
/// This is displayed in the CLI.
|
||||
final String title;
|
||||
|
||||
String get slowWarning => 'This is taking an unexpectedly long time...';
|
||||
|
||||
Future<ValidationResult> validate();
|
||||
}
|
||||
|
||||
/// A validator that runs other [DoctorValidator]s and combines their output
|
||||
/// into a single [ValidationResult]. It uses the title of the first validator
|
||||
/// passed to the constructor and reports the statusInfo of the first validator
|
||||
/// that provides one. Other titles and statusInfo strings are discarded.
|
||||
class GroupedValidator extends DoctorValidator {
|
||||
GroupedValidator(this.subValidators) : super(subValidators[0].title);
|
||||
|
||||
final List<DoctorValidator> subValidators;
|
||||
|
||||
List<ValidationResult> _subResults = <ValidationResult>[];
|
||||
|
||||
/// Sub-validator results.
|
||||
///
|
||||
/// To avoid losing information when results are merged, the sub-results are
|
||||
/// cached on this field when they are available. The results are in the same
|
||||
/// order as the sub-validator list.
|
||||
List<ValidationResult> get subResults => _subResults;
|
||||
|
||||
@override
|
||||
String get slowWarning => _currentSlowWarning;
|
||||
String _currentSlowWarning = 'Initializing...';
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
final List<ValidatorTask> tasks = <ValidatorTask>[
|
||||
for (final DoctorValidator validator in subValidators)
|
||||
ValidatorTask(
|
||||
validator,
|
||||
asyncGuard<ValidationResult>(() => validator.validate()),
|
||||
),
|
||||
];
|
||||
|
||||
final List<ValidationResult> results = <ValidationResult>[];
|
||||
for (final ValidatorTask subValidator in tasks) {
|
||||
_currentSlowWarning = subValidator.validator.slowWarning;
|
||||
try {
|
||||
results.add(await subValidator.result);
|
||||
} on Exception catch (exception, stackTrace) {
|
||||
results.add(ValidationResult.crash(exception, stackTrace));
|
||||
}
|
||||
}
|
||||
_currentSlowWarning = 'Merging results...';
|
||||
return _mergeValidationResults(results);
|
||||
}
|
||||
|
||||
ValidationResult _mergeValidationResults(List<ValidationResult> results) {
|
||||
assert(results.isNotEmpty, 'Validation results should not be empty');
|
||||
_subResults = results;
|
||||
ValidationType mergedType = results[0].type;
|
||||
final List<ValidationMessage> mergedMessages = <ValidationMessage>[];
|
||||
String? statusInfo;
|
||||
|
||||
for (final ValidationResult result in results) {
|
||||
statusInfo ??= result.statusInfo;
|
||||
switch (result.type) {
|
||||
case ValidationType.installed:
|
||||
if (mergedType == ValidationType.missing) {
|
||||
mergedType = ValidationType.partial;
|
||||
}
|
||||
break;
|
||||
case ValidationType.notAvailable:
|
||||
case ValidationType.partial:
|
||||
mergedType = ValidationType.partial;
|
||||
break;
|
||||
case ValidationType.crash:
|
||||
case ValidationType.missing:
|
||||
if (mergedType == ValidationType.installed) {
|
||||
mergedType = ValidationType.partial;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 'Unrecognized validation type: ' + result.type.toString();
|
||||
}
|
||||
mergedMessages.addAll(result.messages);
|
||||
}
|
||||
|
||||
return ValidationResult(mergedType, mergedMessages,
|
||||
statusInfo: statusInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class ValidationResult {
|
||||
/// [ValidationResult.type] should only equal [ValidationResult.installed]
|
||||
/// if no [messages] are hints or errors.
|
||||
const ValidationResult(this.type, this.messages, { this.statusInfo });
|
||||
|
||||
factory ValidationResult.crash(Object error, [StackTrace? stackTrace]) {
|
||||
return ValidationResult(ValidationType.crash, <ValidationMessage>[
|
||||
const ValidationMessage.error(
|
||||
'Due to an error, the doctor check did not complete. '
|
||||
'If the error message below is not helpful, '
|
||||
'please let us know about this issue at https://github.com/flutter/flutter/issues.'),
|
||||
ValidationMessage.error('$error'),
|
||||
if (stackTrace != null)
|
||||
// Stacktrace is informational. Printed in verbose mode only.
|
||||
ValidationMessage('$stackTrace'),
|
||||
], statusInfo: 'the doctor check crashed');
|
||||
}
|
||||
|
||||
final ValidationType type;
|
||||
// A short message about the status.
|
||||
final String? statusInfo;
|
||||
final List<ValidationMessage> messages;
|
||||
|
||||
String get leadingBox {
|
||||
assert(type != null);
|
||||
switch (type) {
|
||||
case ValidationType.crash:
|
||||
return '[☠]';
|
||||
case ValidationType.missing:
|
||||
return '[✗]';
|
||||
case ValidationType.installed:
|
||||
return '[✓]';
|
||||
case ValidationType.notAvailable:
|
||||
case ValidationType.partial:
|
||||
return '[!]';
|
||||
}
|
||||
}
|
||||
|
||||
String get coloredLeadingBox {
|
||||
assert(type != null);
|
||||
switch (type) {
|
||||
case ValidationType.crash:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.red);
|
||||
case ValidationType.missing:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.red);
|
||||
case ValidationType.installed:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.green);
|
||||
case ValidationType.notAvailable:
|
||||
case ValidationType.partial:
|
||||
return globals.terminal.color(leadingBox, TerminalColor.yellow);
|
||||
}
|
||||
}
|
||||
|
||||
/// The string representation of the type.
|
||||
String get typeStr {
|
||||
assert(type != null);
|
||||
switch (type) {
|
||||
case ValidationType.crash:
|
||||
return 'crash';
|
||||
case ValidationType.missing:
|
||||
return 'missing';
|
||||
case ValidationType.installed:
|
||||
return 'installed';
|
||||
case ValidationType.notAvailable:
|
||||
return 'notAvailable';
|
||||
case ValidationType.partial:
|
||||
return 'partial';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A status line for the flutter doctor validation to display.
|
||||
///
|
||||
/// The [message] is required and represents either an informational statement
|
||||
/// about the particular doctor validation that passed, or more context
|
||||
/// on the cause and/or solution to the validation failure.
|
||||
@immutable
|
||||
class ValidationMessage {
|
||||
/// Create a validation message with information for a passing validator.
|
||||
///
|
||||
/// By default this is not displayed unless the doctor is run in
|
||||
/// verbose mode.
|
||||
///
|
||||
/// The [contextUrl] may be supplied to link to external resources. This
|
||||
/// is displayed after the informative message in verbose modes.
|
||||
const ValidationMessage(this.message, {this.contextUrl}) : type = ValidationMessageType.information;
|
||||
|
||||
/// Create a validation message with information for a failing validator.
|
||||
const ValidationMessage.error(this.message)
|
||||
: type = ValidationMessageType.error,
|
||||
contextUrl = null;
|
||||
|
||||
/// Create a validation message with information for a partially failing
|
||||
/// validator.
|
||||
const ValidationMessage.hint(this.message)
|
||||
: type = ValidationMessageType.hint,
|
||||
contextUrl = null;
|
||||
|
||||
final ValidationMessageType type;
|
||||
final String? contextUrl;
|
||||
final String message;
|
||||
|
||||
bool get isError => type == ValidationMessageType.error;
|
||||
|
||||
bool get isHint => type == ValidationMessageType.hint;
|
||||
|
||||
String get indicator {
|
||||
switch (type) {
|
||||
case ValidationMessageType.error:
|
||||
return '✗';
|
||||
case ValidationMessageType.hint:
|
||||
return '!';
|
||||
case ValidationMessageType.information:
|
||||
return '•';
|
||||
}
|
||||
}
|
||||
|
||||
String get coloredIndicator {
|
||||
switch (type) {
|
||||
case ValidationMessageType.error:
|
||||
return globals.terminal.color(indicator, TerminalColor.red);
|
||||
case ValidationMessageType.hint:
|
||||
return globals.terminal.color(indicator, TerminalColor.yellow);
|
||||
case ValidationMessageType.information:
|
||||
return globals.terminal.color(indicator, TerminalColor.green);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => message;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is ValidationMessage
|
||||
&& other.message == message
|
||||
&& other.type == type
|
||||
&& other.contextUrl == contextUrl;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => type.hashCode ^ message.hashCode ^ contextUrl.hashCode;
|
||||
}
|
||||
|
||||
class NoIdeValidator extends DoctorValidator {
|
||||
NoIdeValidator() : super('Flutter IDE Support');
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async {
|
||||
return ValidationResult(
|
||||
ValidationType.missing,
|
||||
globals.userMessages.noIdeInstallationInfo.map((String ideInfo) => ValidationMessage(ideInfo)).toList(),
|
||||
statusInfo: globals.userMessages.noIdeStatusInfo,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ValidatorWithResult extends DoctorValidator {
|
||||
ValidatorWithResult(String title, this.result) : super(title);
|
||||
|
||||
final ValidationResult result;
|
||||
|
||||
@override
|
||||
Future<ValidationResult> validate() async => result;
|
||||
}
|
@ -8,7 +8,7 @@ import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/context.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
import 'fuchsia_sdk.dart';
|
||||
|
||||
|
@ -10,7 +10,7 @@ import 'package:meta/meta.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/version.dart';
|
||||
import '../convert.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
|
||||
/// A parser for the Intellij and Android Studio plugin JAR files.
|
||||
///
|
||||
|
@ -10,7 +10,7 @@ import '../base/file_system.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/user_messages.dart' hide userMessages;
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../ios/plist_parser.dart';
|
||||
import 'intellij.dart';
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
import '../macos/xcode.dart';
|
||||
|
||||
|
@ -10,7 +10,7 @@ import 'package:process/process.dart';
|
||||
import '../base/io.dart';
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
|
||||
/// A combination of version description and parsed version number.
|
||||
class _VersionInfo {
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
|
||||
/// The windows-specific implementation of a [Workflow].
|
||||
|
@ -5,7 +5,7 @@
|
||||
// @dart = 2.8
|
||||
|
||||
import '../base/user_messages.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import 'cocoapods.dart';
|
||||
|
||||
/// A validator that confirms cocoapods is in a valid state.
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/user_messages.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import 'xcode.dart';
|
||||
|
||||
class XcodeValidator extends DoctorValidator {
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'base/platform.dart';
|
||||
import 'doctor.dart';
|
||||
import 'doctor_validator.dart';
|
||||
|
||||
/// A validator that displays configured HTTP_PROXY environment variables.
|
||||
///
|
||||
|
@ -124,7 +124,7 @@ class DoctorResultEvent extends UsageEvent {
|
||||
}
|
||||
final GroupedValidator group = validator as GroupedValidator;
|
||||
// The validator crashed.
|
||||
if (group.subResults == null) {
|
||||
if (group.subResults.isEmpty) {
|
||||
flutterUsage.sendEvent(category, parameter, label: label);
|
||||
return;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import '../build_system/exceptions.dart';
|
||||
import '../convert.dart';
|
||||
import '../dart/language_version.dart';
|
||||
import '../devfs.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
import '../flutter_manifest.dart';
|
||||
import '../flutter_project_metadata.dart';
|
||||
|
@ -11,7 +11,7 @@ import '../base/platform.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../base/version.dart';
|
||||
import '../convert.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
|
||||
// Include VS Code insiders (useful for debugging).
|
||||
const bool _includeInsiders = false;
|
||||
|
@ -8,7 +8,7 @@ import '../base/file_system.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../base/user_messages.dart';
|
||||
import '../base/version.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import 'vscode.dart';
|
||||
|
||||
class VsCodeValidator extends DoctorValidator {
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import 'chrome.dart';
|
||||
|
||||
/// A validator for Chromium-based browsers.
|
||||
|
@ -7,7 +7,7 @@
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
|
||||
class WebWorkflow extends Workflow {
|
||||
|
@ -8,7 +8,7 @@ import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/context.dart';
|
||||
import '../base/user_messages.dart' hide userMessages;
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import 'visual_studio.dart';
|
||||
|
||||
VisualStudioValidator get visualStudioValidator => context.get<VisualStudioValidator>();
|
||||
|
@ -8,7 +8,7 @@ import 'package:meta/meta.dart';
|
||||
|
||||
import '../base/context.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
import '../doctor_validator.dart';
|
||||
import '../features.dart';
|
||||
|
||||
/// The [WindowsWorkflow] instance.
|
||||
|
@ -10,6 +10,7 @@ import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/create.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
|
||||
|
||||
|
@ -21,6 +21,7 @@ import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/doctor.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
|
@ -5,7 +5,7 @@
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/proxy_validator.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
@ -11,7 +11,7 @@ import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
@ -13,7 +13,7 @@ import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/base/version.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
@ -13,6 +13,7 @@ import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/version.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
|
@ -10,7 +10,7 @@ import 'package:archive/archive.dart';
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/intellij/intellij.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
@ -10,7 +10,7 @@ import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/intellij/intellij_validator.dart';
|
||||
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
||||
import 'package:test/fake.dart';
|
||||
|
@ -5,7 +5,7 @@
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/linux/linux_doctor.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
|
@ -5,7 +5,7 @@
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/macos/cocoapods.dart';
|
||||
import 'package:flutter_tools/src/macos/cocoapods_validator.dart';
|
||||
import 'package:test/fake.dart';
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/base/version.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/macos/xcode.dart';
|
||||
import 'package:flutter_tools/src/macos/xcode_validator.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
@ -5,7 +5,7 @@
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
|
||||
|
@ -8,7 +8,7 @@ import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/web/chrome.dart';
|
||||
import 'package:flutter_tools/src/web/web_validator.dart';
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter_tools/src/base/user_messages.dart' hide userMessages;
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/windows/visual_studio.dart';
|
||||
import 'package:flutter_tools/src/windows/visual_studio_validator.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
@ -20,7 +20,7 @@ import 'package:flutter_tools/src/base/user_messages.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/create.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/doctor.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
|
||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||
|
@ -18,6 +18,7 @@ import 'package:flutter_tools/src/base/process.dart';
|
||||
import 'package:flutter_tools/src/base/signals.dart';
|
||||
import 'package:flutter_tools/src/base/template.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||
import 'package:flutter_tools/src/isolated/mustache_template.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/context_runner.dart';
|
||||
|
Loading…
x
Reference in New Issue
Block a user