From 0916375f440bb7128835c9923da1f33b09d26510 Mon Sep 17 00:00:00 2001 From: hellohuanlin <41930132+hellohuanlin@users.noreply.github.com> Date: Thu, 15 Dec 2022 14:43:32 -0800 Subject: [PATCH] [tools]Build IPA validation UI Polish (#116744) * [tools]some ui polish for build ipa validation * do not print out a few success validations * rename installed type to success for more general usage * forgot nit after reverting custom validation types and re-use doctor types --- .../tasks/ios_content_validation_test.dart | 32 ++--- .../src/android/android_studio_validator.dart | 2 +- .../lib/src/android/android_workflow.dart | 4 +- .../lib/src/commands/build_ios.dart | 109 ++++++++++++++---- packages/flutter_tools/lib/src/doctor.dart | 12 +- .../lib/src/doctor_validator.dart | 14 +-- .../lib/src/http_host_validator.dart | 2 +- .../lib/src/intellij/intellij_validator.dart | 2 +- .../lib/src/linux/linux_doctor.dart | 2 +- .../lib/src/macos/cocoapods_validator.dart | 2 +- .../lib/src/macos/xcode_validator.dart | 2 +- .../lib/src/proxy_validator.dart | 4 +- .../lib/src/vscode/vscode_validator.dart | 2 +- .../lib/src/web/web_validator.dart | 2 +- .../src/windows/visual_studio_validator.dart | 2 +- .../windows/windows_version_validator.dart | 2 +- .../hermetic/build_ipa_test.dart | 86 ++++++++------ .../commands.shard/hermetic/doctor_test.dart | 16 +-- .../hermetic/http_host_validator_test.dart | 20 ++-- .../general.shard/flutter_validator_test.dart | 10 +- .../intellij/intellij_validator_test.dart | 16 +-- .../linux/linux_doctor_test.dart | 2 +- .../macos/cocoapods_validator_test.dart | 2 +- .../macos/xcode_validator_test.dart | 2 +- .../general.shard/web/web_validator_test.dart | 2 +- .../windows/visual_studio_validator_test.dart | 2 +- .../windows_version_validator_test.dart | 2 +- 27 files changed, 221 insertions(+), 134 deletions(-) diff --git a/dev/devicelab/bin/tasks/ios_content_validation_test.dart b/dev/devicelab/bin/tasks/ios_content_validation_test.dart index eeaca8fb6c47..28e0b6a2e8b2 100644 --- a/dev/devicelab/bin/tasks/ios_content_validation_test.dart +++ b/dev/devicelab/bin/tasks/ios_content_validation_test.dart @@ -42,21 +42,23 @@ Future main() async { throw TaskResult.failure('Usage archive event not sent'); } - if (!output.contains('Warning: App icon is using the wrong size (e.g. Icon-App-20x20@1x.png).')) { - throw TaskResult.failure('Must validate incorrect app icon image size.'); - } - - // The project is still using Flutter template icon and launch image. - if (!output.contains('Warning: App icon is set to the default placeholder icon. Replace with unique icons.')) { - throw TaskResult.failure('Must validate template app icon.'); - } - if (!output.contains('Warning: Launch image is set to the default placeholder. Replace with unique launch images.')) { - throw TaskResult.failure('Must validate template launch image.'); - } - - // The project is still using com.example as bundle identifier prefix. - if (!output.contains('Warning: Your application still contains the default "com.example" bundle identifier.')) { - throw TaskResult.failure('Must validate the default bundle identifier prefix'); + // The output contains extra time related prefix, so cannot use a single string. + const List expectedValidationMessages = [ + '[!] App Settings Validation\n', + ' • Version Number: 1.0.0\n', + ' • Build Number: 1\n', + ' • Display Name: Hello\n', + ' • Deployment Target: 11.0\n', + ' • Bundle Identifier: com.example.hello\n', + ' ! Your application still contains the default "com.example" bundle identifier.\n', + '[!] App Icon and Launch Image Assets Validation\n', + ' ! App icon is set to the default placeholder icon. Replace with unique icons.\n', + ' ! App icon is using the incorrect size (e.g. Icon-App-20x20@1x.png).\n', + ' ! Launch image is set to the default placeholder icon. Replace with unique launch image.\n', + 'To update the settings, please refer to https://docs.flutter.dev/deployment/ios\n', + ]; + if (expectedValidationMessages.any((String message) => !output.contains(message))) { + throw TaskResult.failure('Must have the expected validation message'); } }); diff --git a/packages/flutter_tools/lib/src/android/android_studio_validator.dart b/packages/flutter_tools/lib/src/android/android_studio_validator.dart index 8ff88acb1a0a..f7b5daae75de 100644 --- a/packages/flutter_tools/lib/src/android/android_studio_validator.dart +++ b/packages/flutter_tools/lib/src/android/android_studio_validator.dart @@ -73,7 +73,7 @@ class AndroidStudioValidator extends DoctorValidator { if (_studio.isValid) { type = _hasIssues(messages) ? ValidationType.partial - : ValidationType.installed; + : ValidationType.success; messages.addAll(_studio.validationMessages.map( (String m) => ValidationMessage(m), )); diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart index 3d9b122327e5..046f9339bc06 100644 --- a/packages/flutter_tools/lib/src/android/android_workflow.dart +++ b/packages/flutter_tools/lib/src/android/android_workflow.dart @@ -258,7 +258,7 @@ class AndroidValidator extends DoctorValidator { } // Success. - return ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText); + return ValidationResult(ValidationType.success, messages, statusInfo: sdkVersionText); } } @@ -327,7 +327,7 @@ class AndroidLicenseValidator extends DoctorValidator { messages.add(ValidationMessage.error(_userMessages.androidLicensesUnknown(_platform))); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); } - return ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText); + return ValidationResult(ValidationType.success, messages, statusInfo: sdkVersionText); } Future _checkJavaVersionNoOutput() async { diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart index f59d4991ef7a..2f86d0bf2edb 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -15,6 +15,7 @@ import '../base/process.dart'; import '../base/utils.dart'; import '../build_info.dart'; import '../convert.dart'; +import '../doctor_validator.dart'; import '../globals.dart' as globals; import '../ios/application_package.dart'; import '../ios/mac.dart'; @@ -277,7 +278,27 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { .toList(); } - Future _validateIconAssetsAfterArchive(StringBuffer messageBuffer) async { + ValidationResult? _createValidationResult(String title, List messages) { + if (messages.isEmpty) { + return null; + } + final bool anyInvalid = messages.any((ValidationMessage message) => message.type != ValidationMessageType.information); + return ValidationResult( + anyInvalid ? ValidationType.partial : ValidationType.success, + messages, + statusInfo: title, + ); + } + + ValidationMessage _createValidationMessage({ + required bool isValid, + required String message, + }) { + // Use "information" type for valid message, and "hint" type for invalid message. + return isValid ? ValidationMessage(message) : ValidationMessage.hint(message); + } + + Future> _validateIconAssetsAfterArchive() async { final BuildableIOSApp app = await buildableIOSApp; final Map<_ImageAssetFileKey, String> templateInfoMap = _parseImageAssetContentsJson( @@ -287,24 +308,35 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { app.projectAppIconDirName, requiresSize: true); + final List validationMessages = []; + final bool usesTemplate = _isAssetStillUsingTemplateFiles( templateImageInfoMap: templateInfoMap, projectImageInfoMap: projectInfoMap, templateImageDirName: await app.templateAppIconDirNameForImages, projectImageDirName: app.projectAppIconDirName); + if (usesTemplate) { - messageBuffer.writeln('\nWarning: App icon is set to the default placeholder icon. Replace with unique icons.'); + validationMessages.add(_createValidationMessage( + isValid: false, + message: 'App icon is set to the default placeholder icon. Replace with unique icons.', + )); } final List filesWithWrongSize = _imageFilesWithWrongSize( imageInfoMap: projectInfoMap, imageDirName: app.projectAppIconDirName); + if (filesWithWrongSize.isNotEmpty) { - messageBuffer.writeln('\nWarning: App icon is using the wrong size (e.g. ${filesWithWrongSize.first}).'); + validationMessages.add(_createValidationMessage( + isValid: false, + message: 'App icon is using the incorrect size (e.g. ${filesWithWrongSize.first}).', + )); } + return validationMessages; } - Future _validateLaunchImageAssetsAfterArchive(StringBuffer messageBuffer) async { + Future> _validateLaunchImageAssetsAfterArchive() async { final BuildableIOSApp app = await buildableIOSApp; final Map<_ImageAssetFileKey, String> templateInfoMap = _parseImageAssetContentsJson( @@ -314,6 +346,8 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { app.projectLaunchImageDirName, requiresSize: false); + final List validationMessages = []; + final bool usesTemplate = _isAssetStillUsingTemplateFiles( templateImageInfoMap: templateInfoMap, projectImageInfoMap: projectInfoMap, @@ -321,18 +355,23 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { projectImageDirName: app.projectLaunchImageDirName); if (usesTemplate) { - messageBuffer.writeln('\nWarning: Launch image is set to the default placeholder. Replace with unique launch images.'); + validationMessages.add(_createValidationMessage( + isValid: false, + message: 'Launch image is set to the default placeholder icon. Replace with unique launch image.', + )); } + + return validationMessages; } - Future _validateXcodeBuildSettingsAfterArchive(StringBuffer messageBuffer) async { + Future> _validateXcodeBuildSettingsAfterArchive() async { final BuildableIOSApp app = await buildableIOSApp; final String plistPath = app.builtInfoPlistPathAfterArchive; if (!globals.fs.file(plistPath).existsSync()) { globals.printError('Invalid iOS archive. Does not contain Info.plist.'); - return; + return []; } final Map xcodeProjectSettingsMap = {}; @@ -343,17 +382,32 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { xcodeProjectSettingsMap['Deployment Target'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kMinimumOSVersionKey); xcodeProjectSettingsMap['Bundle Identifier'] = globals.plistParser.getStringValueFromFile(plistPath, PlistParser.kCFBundleIdentifierKey); - xcodeProjectSettingsMap.forEach((String title, String? info) { - messageBuffer.writeln('$title: ${info ?? "Missing"}'); - }); + final List validationMessages = xcodeProjectSettingsMap.entries.map((MapEntry entry) { + final String title = entry.key; + final String? info = entry.value; + return _createValidationMessage( + isValid: info != null, + message: '$title: ${info ?? "Missing"}', + ); + }).toList(); - if (xcodeProjectSettingsMap.values.any((String? element) => element == null)) { - messageBuffer.writeln('\nYou must set up the missing settings.'); + final bool hasMissingSettings = xcodeProjectSettingsMap.values.any((String? element) => element == null); + if (hasMissingSettings) { + validationMessages.add(_createValidationMessage( + isValid: false, + message: 'You must set up the missing app settings.'), + ); } - if (xcodeProjectSettingsMap['Bundle Identifier']?.startsWith('com.example') ?? false) { - messageBuffer.writeln('\nWarning: Your application still contains the default "com.example" bundle identifier.'); + final bool usesDefaultBundleIdentifier = xcodeProjectSettingsMap['Bundle Identifier']?.startsWith('com.example') ?? false; + if (usesDefaultBundleIdentifier) { + validationMessages.add(_createValidationMessage( + isValid: false, + message: 'Your application still contains the default "com.example" bundle identifier.'), + ); } + + return validationMessages; } @override @@ -362,13 +416,26 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { displayNullSafetyMode(buildInfo); final FlutterCommandResult xcarchiveResult = await super.runCommand(); - final StringBuffer validationMessageBuffer = StringBuffer(); - await _validateXcodeBuildSettingsAfterArchive(validationMessageBuffer); - await _validateIconAssetsAfterArchive(validationMessageBuffer); - await _validateLaunchImageAssetsAfterArchive(validationMessageBuffer); - - validationMessageBuffer.write('\nTo update the settings, please refer to https://docs.flutter.dev/deployment/ios'); - globals.printBox(validationMessageBuffer.toString(), title: 'App Settings'); + final List validationResults = []; + validationResults.add(_createValidationResult( + 'App Settings Validation', + await _validateXcodeBuildSettingsAfterArchive(), + )); + validationResults.add(_createValidationResult( + 'App Icon and Launch Image Assets Validation', + await _validateIconAssetsAfterArchive() + await _validateLaunchImageAssetsAfterArchive(), + )); + + for (final ValidationResult result in validationResults.whereType()) { + globals.printStatus('\n${result.coloredLeadingBox} ${result.statusInfo}'); + for (final ValidationMessage message in result.messages) { + globals.printStatus( + '${message.coloredIndicator} ${message.message}', + indent: result.leadingBox.length + 1, + ); + } + } + globals.printStatus('\nTo update the settings, please refer to https://docs.flutter.dev/deployment/ios\n'); // xcarchive failed or not at expected location. if (xcarchiveResult.exitStatus != ExitStatus.success) { diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 85519b04be0e..2f803b3df80b 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -303,7 +303,7 @@ class Doctor { case ValidationType.notAvailable: lineBuffer.write('is not available.'); break; - case ValidationType.installed: + case ValidationType.success: lineBuffer.write('is fully installed.'); break; } @@ -320,7 +320,7 @@ class Doctor { )); buffer.writeln(); - if (result.type != ValidationType.installed) { + if (result.type != ValidationType.success) { missingComponent = true; } } @@ -400,7 +400,7 @@ class Doctor { case ValidationType.notAvailable: issues += 1; break; - case ValidationType.installed: + case ValidationType.success: break; } if (sendEvent) { @@ -558,7 +558,7 @@ class FlutterValidator extends DoctorValidator { ValidationType valid; if (messages.every((ValidationMessage message) => message.isInformation)) { - valid = ValidationType.installed; + valid = ValidationType.success; } else { // The issues for this validator stem from broken git configuration of the local install; // in that case, make it clear that it is fine to continue, but freshness check/upgrades @@ -707,13 +707,13 @@ class DeviceValidator extends DoctorValidator { } else if (diagnostics.isNotEmpty) { installedMessages.addAll(diagnosticMessages); return ValidationResult( - ValidationType.installed, + ValidationType.success, installedMessages, statusInfo: _userMessages.devicesAvailable(devices.length) ); } else { return ValidationResult( - ValidationType.installed, + ValidationType.success, installedMessages, statusInfo: _userMessages.devicesAvailable(devices.length) ); diff --git a/packages/flutter_tools/lib/src/doctor_validator.dart b/packages/flutter_tools/lib/src/doctor_validator.dart index a66cffc22ae8..d753746df690 100644 --- a/packages/flutter_tools/lib/src/doctor_validator.dart +++ b/packages/flutter_tools/lib/src/doctor_validator.dart @@ -36,7 +36,7 @@ enum ValidationType { missing, partial, notAvailable, - installed, + success, } enum ValidationMessageType { @@ -116,7 +116,7 @@ class GroupedValidator extends DoctorValidator { for (final ValidationResult result in results) { statusInfo ??= result.statusInfo; switch (result.type) { - case ValidationType.installed: + case ValidationType.success: if (mergedType == ValidationType.missing) { mergedType = ValidationType.partial; } @@ -127,7 +127,7 @@ class GroupedValidator extends DoctorValidator { break; case ValidationType.crash: case ValidationType.missing: - if (mergedType == ValidationType.installed) { + if (mergedType == ValidationType.success) { mergedType = ValidationType.partial; } break; @@ -142,7 +142,7 @@ class GroupedValidator extends DoctorValidator { @immutable class ValidationResult { - /// [ValidationResult.type] should only equal [ValidationResult.installed] + /// [ValidationResult.type] should only equal [ValidationResult.success] /// if no [messages] are hints or errors. const ValidationResult(this.type, this.messages, { this.statusInfo }); @@ -171,7 +171,7 @@ class ValidationResult { return '[☠]'; case ValidationType.missing: return '[✗]'; - case ValidationType.installed: + case ValidationType.success: return '[✓]'; case ValidationType.notAvailable: case ValidationType.partial: @@ -186,7 +186,7 @@ class ValidationResult { return globals.terminal.color(leadingBox, TerminalColor.red); case ValidationType.missing: return globals.terminal.color(leadingBox, TerminalColor.red); - case ValidationType.installed: + case ValidationType.success: return globals.terminal.color(leadingBox, TerminalColor.green); case ValidationType.notAvailable: case ValidationType.partial: @@ -202,7 +202,7 @@ class ValidationResult { return 'crash'; case ValidationType.missing: return 'missing'; - case ValidationType.installed: + case ValidationType.success: return 'installed'; case ValidationType.notAvailable: return 'notAvailable'; diff --git a/packages/flutter_tools/lib/src/http_host_validator.dart b/packages/flutter_tools/lib/src/http_host_validator.dart index 6dc832e8f445..6e6c68d110cf 100644 --- a/packages/flutter_tools/lib/src/http_host_validator.dart +++ b/packages/flutter_tools/lib/src/http_host_validator.dart @@ -110,7 +110,7 @@ class HttpHostValidator extends DoctorValidator { if (availabilityResults.every((_HostValidationResult result) => result.available)) { return ValidationResult( - ValidationType.installed, + ValidationType.success, messages..add(const ValidationMessage('All required HTTP hosts are available')), ); } diff --git a/packages/flutter_tools/lib/src/intellij/intellij_validator.dart b/packages/flutter_tools/lib/src/intellij/intellij_validator.dart index 96a1d5531c55..10df22e6c61b 100644 --- a/packages/flutter_tools/lib/src/intellij/intellij_validator.dart +++ b/packages/flutter_tools/lib/src/intellij/intellij_validator.dart @@ -114,7 +114,7 @@ abstract class IntelliJValidator extends DoctorValidator { } return ValidationResult( - _hasIssues(messages) ? ValidationType.partial : ValidationType.installed, + _hasIssues(messages) ? ValidationType.partial : ValidationType.success, messages, statusInfo: _userMessages.intellijStatusInfo(version), ); diff --git a/packages/flutter_tools/lib/src/linux/linux_doctor.dart b/packages/flutter_tools/lib/src/linux/linux_doctor.dart index 65ec6a215b5b..39b88e6cae97 100644 --- a/packages/flutter_tools/lib/src/linux/linux_doctor.dart +++ b/packages/flutter_tools/lib/src/linux/linux_doctor.dart @@ -59,7 +59,7 @@ class LinuxDoctorValidator extends DoctorValidator { @override Future validate() async { - ValidationType validationType = ValidationType.installed; + ValidationType validationType = ValidationType.success; final List messages = []; final Map installedVersions = { diff --git a/packages/flutter_tools/lib/src/macos/cocoapods_validator.dart b/packages/flutter_tools/lib/src/macos/cocoapods_validator.dart index 1d7972b68afb..56b16dbfd5b1 100644 --- a/packages/flutter_tools/lib/src/macos/cocoapods_validator.dart +++ b/packages/flutter_tools/lib/src/macos/cocoapods_validator.dart @@ -28,7 +28,7 @@ class CocoaPodsValidator extends DoctorValidator { final CocoaPodsStatus cocoaPodsStatus = await _cocoaPods .evaluateCocoaPodsInstallation; - ValidationType status = ValidationType.installed; + ValidationType status = ValidationType.success; if (cocoaPodsStatus == CocoaPodsStatus.recommended) { messages.add(ValidationMessage(_userMessages.cocoaPodsVersion((await _cocoaPods.cocoaPodsVersionText).toString()))); } else { diff --git a/packages/flutter_tools/lib/src/macos/xcode_validator.dart b/packages/flutter_tools/lib/src/macos/xcode_validator.dart index b3e1dbd2e46d..c45351c6728b 100644 --- a/packages/flutter_tools/lib/src/macos/xcode_validator.dart +++ b/packages/flutter_tools/lib/src/macos/xcode_validator.dart @@ -26,7 +26,7 @@ class XcodeValidator extends DoctorValidator { final String? xcodeSelectPath = _xcode.xcodeSelectPath; if (_xcode.isInstalled) { - xcodeStatus = ValidationType.installed; + xcodeStatus = ValidationType.success; if (xcodeSelectPath != null) { messages.add(ValidationMessage(_userMessages.xcodeLocation(xcodeSelectPath))); } diff --git a/packages/flutter_tools/lib/src/proxy_validator.dart b/packages/flutter_tools/lib/src/proxy_validator.dart index 31a9631d3dbb..b02fffaf7779 100644 --- a/packages/flutter_tools/lib/src/proxy_validator.dart +++ b/packages/flutter_tools/lib/src/proxy_validator.dart @@ -34,7 +34,7 @@ class ProxyValidator extends DoctorValidator { Future validate() async { if (_httpProxy.isEmpty) { return const ValidationResult( - ValidationType.installed, []); + ValidationType.success, []); } final List messages = [ @@ -56,7 +56,7 @@ class ProxyValidator extends DoctorValidator { (ValidationMessage msg) => msg.isHint || msg.isError); return ValidationResult( - hasIssues ? ValidationType.partial : ValidationType.installed, + hasIssues ? ValidationType.partial : ValidationType.success, messages, ); } diff --git a/packages/flutter_tools/lib/src/vscode/vscode_validator.dart b/packages/flutter_tools/lib/src/vscode/vscode_validator.dart index ba1e920eaffe..97f38dac6f48 100644 --- a/packages/flutter_tools/lib/src/vscode/vscode_validator.dart +++ b/packages/flutter_tools/lib/src/vscode/vscode_validator.dart @@ -29,7 +29,7 @@ class VsCodeValidator extends DoctorValidator { : userMessages.vsCodeVersion(_vsCode.version.toString()); return ValidationResult( - ValidationType.installed, + ValidationType.success, _vsCode.validationMessages.toList(), statusInfo: vsCodeVersionText, ); diff --git a/packages/flutter_tools/lib/src/web/web_validator.dart b/packages/flutter_tools/lib/src/web/web_validator.dart index e92fd1908710..7b0c1fc4a387 100644 --- a/packages/flutter_tools/lib/src/web/web_validator.dart +++ b/packages/flutter_tools/lib/src/web/web_validator.dart @@ -39,7 +39,7 @@ abstract class ChromiumValidator extends DoctorValidator { ); } return ValidationResult( - ValidationType.installed, + ValidationType.success, messages, ); } diff --git a/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart b/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart index ebce8e619d43..2c5b188f884c 100644 --- a/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart +++ b/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart @@ -27,7 +27,7 @@ class VisualStudioValidator extends DoctorValidator { String? versionInfo; if (_visualStudio.isInstalled) { - status = ValidationType.installed; + status = ValidationType.success; messages.add(ValidationMessage( _userMessages.visualStudioLocation(_visualStudio.installLocation ?? 'unknown') diff --git a/packages/flutter_tools/lib/src/windows/windows_version_validator.dart b/packages/flutter_tools/lib/src/windows/windows_version_validator.dart index 4e69cd37da13..9c612cbe66f3 100644 --- a/packages/flutter_tools/lib/src/windows/windows_version_validator.dart +++ b/packages/flutter_tools/lib/src/windows/windows_version_validator.dart @@ -53,7 +53,7 @@ class WindowsVersionValidator extends DoctorValidator { if (matches.length == 1 && !kUnsupportedVersions .contains(matches.elementAt(0).group(3)?.split('.').elementAt(0))) { - windowsVersionStatus = ValidationType.installed; + windowsVersionStatus = ValidationType.success; statusInfo = 'Installed version of Windows is version 10 or higher'; } else { windowsVersionStatus = ValidationType.missing; diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart index 676ba54f355a..707e1365027d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart @@ -918,18 +918,18 @@ void main() { expect( testLogger.statusText, contains( - '┌─ App Settings ──────────────────────────────────────────────────────────────────┐\n' - '│ Version Number: Missing │\n' - '│ Build Number: Missing │\n' - '│ Display Name: Missing │\n' - '│ Deployment Target: Missing │\n' - '│ Bundle Identifier: io.flutter.someProject │\n' - '│ │\n' - '│ You must set up the missing settings. │\n' - '│ │\n' - '│ To update the settings, please refer to https://docs.flutter.dev/deployment/ios │\n' - '└─────────────────────────────────────────────────────────────────────────────────┘\n' + '[!] App Settings Validation\n' + ' ! Version Number: Missing\n' + ' ! Build Number: Missing\n' + ' ! Display Name: Missing\n' + ' ! Deployment Target: Missing\n' + ' • Bundle Identifier: io.flutter.someProject\n' + ' ! You must set up the missing app settings.\n' )); + expect( + testLogger.statusText, + contains('To update the settings, please refer to https://docs.flutter.dev/deployment/ios') + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -972,17 +972,18 @@ void main() { expect( testLogger.statusText, contains( - '┌─ App Settings ──────────────────────────────────────────────────────────────────┐\n' - '│ Version Number: 12.34.56 │\n' - '│ Build Number: 666 │\n' - '│ Display Name: Awesome Gallery │\n' - '│ Deployment Target: 11.0 │\n' - '│ Bundle Identifier: io.flutter.someProject │\n' - '│ │\n' - '│ To update the settings, please refer to https://docs.flutter.dev/deployment/ios │\n' - '└─────────────────────────────────────────────────────────────────────────────────┘\n' + '[✓] App Settings Validation\n' + ' • Version Number: 12.34.56\n' + ' • Build Number: 666\n' + ' • Display Name: Awesome Gallery\n' + ' • Deployment Target: 11.0\n' + ' • Bundle Identifier: io.flutter.someProject\n' ) ); + expect( + testLogger.statusText, + contains('To update the settings, please refer to https://docs.flutter.dev/deployment/ios') + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -1019,8 +1020,8 @@ void main() { ['build', 'ipa', '--no-pub']); expect( - testLogger.statusText, - contains('Warning: Your application still contains the default "com.example" bundle identifier.') + testLogger.statusText, + contains(' ! Your application still contains the default "com.example" bundle identifier.') ); }, overrides: { FileSystem: () => fileSystem, @@ -1058,8 +1059,8 @@ void main() { ['build', 'ipa', '--no-pub']); expect( - testLogger.statusText, - isNot(contains('Warning: Your application still contains the default "com.example" bundle identifier.')) + testLogger.statusText, + isNot(contains(' ! Your application still contains the default "com.example" bundle identifier.')) ); }, overrides: { FileSystem: () => fileSystem, @@ -1140,7 +1141,7 @@ void main() { expect( testLogger.statusText, - contains('Warning: App icon is set to the default placeholder icon. Replace with unique icons.'), + contains(' ! App icon is set to the default placeholder icon. Replace with unique icons.'), ); }, overrides: { FileSystem: () => fileSystem, @@ -1217,7 +1218,10 @@ void main() { await createTestCommandRunner(command).run( ['build', 'ipa', '--no-pub']); - expect(testLogger.statusText, isNot(contains('Warning: App icon is set to the default placeholder icon. Replace with unique icons.'))); + expect( + testLogger.statusText, + isNot(contains(' ! App icon is set to the default placeholder icon. Replace with unique icons.')) + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -1273,7 +1277,10 @@ void main() { await createTestCommandRunner(command).run( ['build', 'ipa', '--no-pub']); - expect(testLogger.statusText, contains('Warning: App icon is using the wrong size (e.g. Icon-App-20x20@2x.png).')); + expect( + testLogger.statusText, + contains(' ! App icon is using the incorrect size (e.g. Icon-App-20x20@2x.png).') + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -1329,7 +1336,10 @@ void main() { await createTestCommandRunner(command).run( ['build', 'ipa', '--no-pub']); - expect(testLogger.statusText, contains('Warning: App icon is using the wrong size (e.g. Icon-App-20x20@2x.png).')); + expect( + testLogger.statusText, + contains(' ! App icon is using the incorrect size (e.g. Icon-App-20x20@2x.png).') + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -1385,7 +1395,10 @@ void main() { await createTestCommandRunner(command).run( ['build', 'ipa', '--no-pub']); - expect(testLogger.statusText, isNot(contains('Warning: App icon is using the wrong size (e.g. Icon-App-20x20@2x.png).'))); + expect( + testLogger.statusText, + isNot(contains(' ! App icon is using the incorrect size (e.g. Icon-App-20x20@2x.png).')) + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -1443,7 +1456,10 @@ void main() { ['build', 'ipa', '--no-pub']); // The validation should be skipped, even when the icon size is incorrect. - expect(testLogger.statusText, isNot(contains('Warning: App icon is using the wrong size (e.g. Icon-App-20x20@2x.png).'))); + expect( + testLogger.statusText, + isNot(contains(' ! App icon is using the incorrect size (e.g. Icon-App-20x20@2x.png).')), + ); }, overrides: { FileSystem: () => fileSystem, ProcessManager: () => fakeProcessManager, @@ -1545,8 +1561,10 @@ void main() { // The validation should be skipped, even when the image size is incorrect. for (final String imageFileName in imageFileNames) { - expect(testLogger.statusText, isNot(contains( - 'Warning: App icon is using the wrong size (e.g. $imageFileName).'))); + expect( + testLogger.statusText, + isNot(contains(' ! App icon is using the incorrect size (e.g. $imageFileName).')) + ); } }, overrides: { FileSystem: () => fileSystem, @@ -1623,7 +1641,7 @@ void main() { expect( testLogger.statusText, - contains('Warning: Launch image is set to the default placeholder. Replace with unique launch images.'), + contains(' ! Launch image is set to the default placeholder icon. Replace with unique launch image.'), ); }, overrides: { FileSystem: () => fileSystem, @@ -1701,7 +1719,7 @@ void main() { expect( testLogger.statusText, - isNot(contains('Warning: Launch image is set to the default placeholder. Replace with unique launch images.')), + isNot(contains(' ! Launch image is set to the default placeholder icon. Replace with unique launch image.')), ); }, overrides: { FileSystem: () => fileSystem, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart index a5b5ef61a3b6..7941bf05732f 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart @@ -58,7 +58,7 @@ void main() { group('doctor', () { testUsingContext('vs code validator when both installed', () async { final ValidationResult result = await VsCodeValidatorTestTargets.installedWithExtension.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); expect(result.statusInfo, 'version 1.2.3'); expect(result.messages, hasLength(2)); @@ -85,7 +85,7 @@ void main() { testUsingContext('vs code validator when 64bit installed', () async { expect(VsCodeValidatorTestTargets.installedWithExtension64bit.title, 'VS Code, 64-bit edition'); final ValidationResult result = await VsCodeValidatorTestTargets.installedWithExtension64bit.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); expect(result.statusInfo, 'version 1.2.3'); expect(result.messages, hasLength(2)); @@ -100,7 +100,7 @@ void main() { testUsingContext('vs code validator when extension missing', () async { final ValidationResult result = await VsCodeValidatorTestTargets.installedWithoutExtension.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); expect(result.statusInfo, 'version 1.2.3'); expect(result.messages, hasLength(2)); @@ -157,7 +157,7 @@ void main() { userMessages: UserMessages(), ); final ValidationResult result = await deviceValidator.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); expect(result.messages, const [ ValidationMessage('name (mobile) • device-id • android • 1.2.3'), ValidationMessage.hint('Device locked'), @@ -850,7 +850,7 @@ class PassingValidator extends DoctorValidator { ValidationMessage('A helpful message'), ValidationMessage('A second, somewhat longer helpful message'), ]; - return const ValidationResult(ValidationType.installed, messages, statusInfo: 'with statusInfo'); + return const ValidationResult(ValidationType.success, messages, statusInfo: 'with statusInfo'); } } @@ -862,7 +862,7 @@ class PiiValidator extends DoctorValidator { const List messages = [ ValidationMessage('Contains PII path/to/username', piiStrippedMessage: 'Does not contain PII'), ]; - return const ValidationResult(ValidationType.installed, messages); + return const ValidationResult(ValidationType.success, messages); } } @@ -1089,7 +1089,7 @@ class PassingGroupedValidator extends DoctorValidator { const List messages = [ ValidationMessage('A helpful message'), ]; - return const ValidationResult(ValidationType.installed, messages); + return const ValidationResult(ValidationType.success, messages); } } @@ -1125,7 +1125,7 @@ class PassingGroupedValidatorWithStatus extends DoctorValidator { const List messages = [ ValidationMessage('A different message'), ]; - return const ValidationResult(ValidationType.installed, messages, statusInfo: 'A status message'); + return const ValidationResult(ValidationType.success, messages, statusInfo: 'A status message'); } } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/http_host_validator_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/http_host_validator_test.dart index 1fe6763197fd..8fa25e423cbb 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/http_host_validator_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/http_host_validator_test.dart @@ -41,8 +41,8 @@ void main() { // Run the validation check and get the results final ValidationResult result = await httpHostValidator.validate(); - // Check for a ValidationType.installed result - expect(result.type, equals(ValidationType.installed)); + // Check for a ValidationType.success result + expect(result.type, equals(ValidationType.success)); } }); @@ -108,8 +108,8 @@ void main() { // Run the validation check and get the results final ValidationResult result = await httpHostValidator.validate(); - // Check for a ValidationType.installed result - expect(result.type, equals(ValidationType.installed)); + // Check for a ValidationType.success result + expect(result.type, equals(ValidationType.success)); } }); @@ -253,8 +253,8 @@ void main() { // Run the validation check and get the results final ValidationResult result = await httpHostValidator.validate(); - // Check for a ValidationType.installed result - expect(result.type, equals(ValidationType.installed)); + // Check for a ValidationType.success result + expect(result.type, equals(ValidationType.success)); } }); @@ -275,8 +275,8 @@ void main() { // Run the validation check and get the results final ValidationResult result = await httpHostValidator.validate(); - // Check for a ValidationType.installed result - expect(result.type, equals(ValidationType.installed)); + // Check for a ValidationType.success result + expect(result.type, equals(ValidationType.success)); } }); @@ -295,8 +295,8 @@ void main() { // Run the validation check and get the results final ValidationResult result = await httpHostValidator.validate(); - // Check for a ValidationType.installed result - expect(result.type, equals(ValidationType.installed)); + // Check for a ValidationType.success result + expect(result.type, equals(ValidationType.success)); } }); }); diff --git a/packages/flutter_tools/test/general.shard/flutter_validator_test.dart b/packages/flutter_tools/test/general.shard/flutter_validator_test.dart index 16f9006d29cb..6a20dba80a8c 100644 --- a/packages/flutter_tools/test/general.shard/flutter_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_validator_test.dart @@ -142,7 +142,7 @@ void main() { // gen_snapshot is downloaded on demand, and the doctor should not // fail if the gen_snapshot binary is not present. expect(await flutterValidator.validate(), _matchDoctorValidation( - validationType: ValidationType.installed, + validationType: ValidationType.success, statusInfo: 'Channel beta, 1.0.0, on Windows, locale en_US.UTF-8', messages: anything, )); @@ -199,7 +199,7 @@ void main() { ); expect(await flutterValidator.validate(), _matchDoctorValidation( - validationType: ValidationType.installed, + validationType: ValidationType.success, statusInfo: 'Channel beta, 1.0.0, on Windows, locale en_US.UTF-8', messages: containsAll(const [ ValidationMessage('Pub download mirror https://example.com/pub'), @@ -327,7 +327,7 @@ void main() { ); expect(await flutterValidator.validate(), _matchDoctorValidation( - validationType: ValidationType.installed, + validationType: ValidationType.success, statusInfo: 'Channel beta, 1.0.0, on Linux, locale en_US.UTF-8', messages: contains(const ValidationMessage('Upstream repository https://github.com/flutter/flutter.git')), )); @@ -418,7 +418,7 @@ void main() { ); expect(await flutterValidator.validate(), _matchDoctorValidation( - validationType: ValidationType.installed, + validationType: ValidationType.success, statusInfo: 'Channel beta, 1.0.0, on Linux, locale en_US.UTF-8', messages: isNot( contains(const ValidationMessage( @@ -598,7 +598,7 @@ void main() { ); expect(await flutterValidator.validate(), _matchDoctorValidation( - validationType: ValidationType.installed, + validationType: ValidationType.success, statusInfo: 'Channel beta, 1.0.0, on Linux, locale en_US.UTF-8', messages: isNot(contains(isA().having( (ValidationMessage message) => message.message, diff --git a/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart b/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart index c8b91054186b..eab4b0b9f892 100644 --- a/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/intellij/intellij_validator_test.dart @@ -77,7 +77,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('intellij(2020.1) plugins check on linux (installed via JetBrains ToolBox app)', () async { @@ -104,7 +104,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('intellij(>=2020.2) plugins check on linux (installed via JetBrains ToolBox app)', () async { @@ -131,7 +131,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('intellij(2020.1~) plugins check on linux (installed via tar.gz)', () async { @@ -158,7 +158,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('legacy intellij(<2020) plugins check on windows', () async { @@ -185,7 +185,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('intellij(2020.1 ~ 2020.2) plugins check on windows (installed via JetBrains ToolBox app)', () async { @@ -212,7 +212,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('intellij(>=2020.3) plugins check on windows (installed via JetBrains ToolBox app and plugins)', () async { @@ -239,7 +239,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('intellij(2020.1~) plugins check on windows (installed via installer)', () async { @@ -266,7 +266,7 @@ void main() { ); expect(1, installed.length); final ValidationResult result = await installed.toList()[0].validate(); - expect(ValidationType.installed, result.type); + expect(ValidationType.success, result.type); }); testWithoutContext('can locate installations on macOS from Spotlight', () { diff --git a/packages/flutter_tools/test/general.shard/linux/linux_doctor_test.dart b/packages/flutter_tools/test/general.shard/linux/linux_doctor_test.dart index 079039accc5e..b6bd13f4b620 100644 --- a/packages/flutter_tools/test/general.shard/linux/linux_doctor_test.dart +++ b/packages/flutter_tools/test/general.shard/linux/linux_doctor_test.dart @@ -114,7 +114,7 @@ void main() { ); final ValidationResult result = await linuxDoctorValidator.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); expect(result.messages, const [ ValidationMessage('clang version 4.0.1-6+build1'), ValidationMessage('cmake version 3.16.3'), diff --git a/packages/flutter_tools/test/general.shard/macos/cocoapods_validator_test.dart b/packages/flutter_tools/test/general.shard/macos/cocoapods_validator_test.dart index 67d8f2d0c2a7..1a5c24068366 100644 --- a/packages/flutter_tools/test/general.shard/macos/cocoapods_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/cocoapods_validator_test.dart @@ -15,7 +15,7 @@ void main() { testWithoutContext('Emits installed status when CocoaPods is installed', () async { final CocoaPodsValidator workflow = CocoaPodsValidator(FakeCocoaPods(CocoaPodsStatus.recommended, '1000.0.0'), UserMessages()); final ValidationResult result = await workflow.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); }); testWithoutContext('Emits missing status when CocoaPods is not installed', () async { diff --git a/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart b/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart index cf540c5d145a..ea66b9f88289 100644 --- a/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/xcode_validator_test.dart @@ -182,7 +182,7 @@ void main() { ); final XcodeValidator validator = XcodeValidator(xcode: xcode, userMessages: UserMessages()); final ValidationResult result = await validator.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); expect(result.messages.length, 2); final ValidationMessage firstMessage = result.messages.first; expect(firstMessage.type, ValidationMessageType.information); diff --git a/packages/flutter_tools/test/general.shard/web/web_validator_test.dart b/packages/flutter_tools/test/general.shard/web/web_validator_test.dart index 4961a46a6210..b13ec8129b9d 100644 --- a/packages/flutter_tools/test/general.shard/web/web_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/web/web_validator_test.dart @@ -50,7 +50,7 @@ void main() { testWithoutContext('WebValidator can find executable on macOS', () async { final ValidationResult result = await webValidator.validate(); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); }); testWithoutContext('WebValidator Can notice missing macOS executable ', () async { diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart index 4e3272f7e0b9..b501b5e90190 100644 --- a/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart @@ -165,7 +165,7 @@ void main() { userMessages.visualStudioVersion(fakeVisualStudio.displayName!, fakeVisualStudio.fullVersion!)); expect(result.messages.contains(expectedDisplayNameMessage), true); - expect(result.type, ValidationType.installed); + expect(result.type, ValidationType.success); }); testWithoutContext('Emits missing status when Visual Studio is not installed', () async { diff --git a/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart b/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart index c6b4e6fa4abd..ddf75a705ce2 100644 --- a/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart @@ -138,7 +138,7 @@ Hyper-V Requirements: A hypervisor has been detected. Features required for /// The expected validation result object for /// a passing windows version test const ValidationResult validWindows10ValidationResult = ValidationResult( - ValidationType.installed, + ValidationType.success, [], statusInfo: 'Installed version of Windows is version 10 or higher', );