Unverified Commit 85bece26 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

[flutter_tools] Fix TypeError when a FileSystemException happens during flutter doctor (#133373)

Fixes https://github.com/flutter/flutter/issues/133086
parent 6eca007a
...@@ -487,8 +487,11 @@ class IntelliJValidatorOnMac extends IntelliJValidator { ...@@ -487,8 +487,11 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
// Remove JetBrains Toolbox link apps. These tiny apps just // Remove JetBrains Toolbox link apps. These tiny apps just
// link to the full app, will get detected elsewhere in our search. // link to the full app, will get detected elsewhere in our search.
validators.removeWhere((DoctorValidator validator) { validators.removeWhere((DoctorValidator validator) {
if (validator is! IntelliJValidatorOnMac) {
return false;
}
final String identifierKey = plistParser.getValueFromFile( final String identifierKey = plistParser.getValueFromFile(
(validator as IntelliJValidatorOnMac).plistFile, validator.plistFile,
PlistParser.kCFBundleIdentifierKey, PlistParser.kCFBundleIdentifierKey,
) as String; ) as String;
return identifierKey.contains('com.jetbrains.toolbox.linkapp'); return identifierKey.contains('com.jetbrains.toolbox.linkapp');
......
...@@ -11,7 +11,6 @@ import 'package:flutter_tools/src/base/platform.dart'; ...@@ -11,7 +11,6 @@ import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/version.dart'; import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/plist_parser.dart'; import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:path/path.dart' show Context; // flutter_ignore: package_path_import -- We only use Context as an interface.
import 'package:test/fake.dart'; import 'package:test/fake.dart';
import '../../src/common.dart'; import '../../src/common.dart';
......
...@@ -12,7 +12,6 @@ import 'package:flutter_tools/src/base/error_handling_io.dart'; ...@@ -12,7 +12,6 @@ import 'package:flutter_tools/src/base/error_handling_io.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:path/path.dart' as p; // flutter_ignore: package_path_import
import 'package:process/process.dart'; import 'package:process/process.dart';
import 'package:test/fake.dart'; import 'package:test/fake.dart';
...@@ -1293,7 +1292,7 @@ class FakeExistsFile extends Fake implements File { ...@@ -1293,7 +1292,7 @@ class FakeExistsFile extends Fake implements File {
class FakeFileSystem extends Fake implements FileSystem { class FakeFileSystem extends Fake implements FileSystem {
@override @override
p.Context get path => p.Context(); Context get path => Context();
@override @override
Directory get currentDirectory { Directory get currentDirectory {
......
...@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/convert.dart'; ...@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/doctor_validator.dart'; import 'package:flutter_tools/src/doctor_validator.dart';
import 'package:flutter_tools/src/intellij/intellij_validator.dart'; import 'package:flutter_tools/src/intellij/intellij_validator.dart';
import 'package:flutter_tools/src/ios/plist_parser.dart'; import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:test/fake.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/fake_process_manager.dart'; import '../../src/fake_process_manager.dart';
...@@ -373,6 +374,29 @@ void main() { ...@@ -373,6 +374,29 @@ void main() {
expect(validator.pluginsPath, '/path/to/JetBrainsToolboxApp.plugins'); expect(validator.pluginsPath, '/path/to/JetBrainsToolboxApp.plugins');
}); });
testWithoutContext('IntelliJValidatorOnMac.installed() handles FileSystemExceptions)', () async {
const FileSystemException exception = FileSystemException('cannot list');
final FileSystem fileSystem = _ThrowingFileSystem(exception);
final FakeProcessManager processManager = FakeProcessManager.empty();
final Iterable<DoctorValidator> validators = IntelliJValidatorOnMac.installed(
fileSystem: fileSystem,
fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: macPlatform),
userMessages: UserMessages(),
plistParser: FakePlistParser(<String, String>{
'JetBrainsToolboxApp': '/path/to/JetBrainsToolboxApp',
'CFBundleIdentifier': 'com.jetbrains.toolbox.linkapp',
}),
processManager: processManager,
);
expect(validators.length, 1);
final DoctorValidator validator = validators.first;
expect(validator, isA<ValidatorWithResult>());
expect(validator.title, 'Cannot determine if IntelliJ is installed');
});
testWithoutContext('Remove JetBrains Toolbox', () async { testWithoutContext('Remove JetBrains Toolbox', () async {
final FileSystem fileSystem = MemoryFileSystem.test(); final FileSystem fileSystem = MemoryFileSystem.test();
final List<String> installPaths = <String>[ final List<String> installPaths = <String>[
...@@ -398,11 +422,9 @@ void main() { ...@@ -398,11 +422,9 @@ void main() {
], stdout: 'skip') ], stdout: 'skip')
]); ]);
final Iterable<DoctorValidator> installed = final Iterable<DoctorValidator> installed = IntelliJValidatorOnMac.installed(
IntelliJValidatorOnMac.installed(
fileSystem: fileSystem, fileSystem: fileSystem,
fileSystemUtils: fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: macPlatform),
FileSystemUtils(fileSystem: fileSystem, platform: macPlatform),
userMessages: UserMessages(), userMessages: UserMessages(),
plistParser: FakePlistParser(<String, String>{ plistParser: FakePlistParser(<String, String>{
'JetBrainsToolboxApp': '/path/to/JetBrainsToolboxApp', 'JetBrainsToolboxApp': '/path/to/JetBrainsToolboxApp',
...@@ -412,6 +434,7 @@ void main() { ...@@ -412,6 +434,7 @@ void main() {
); );
expect(installed.length, 0); expect(installed.length, 0);
expect(processManager, hasNoRemainingExpectations);
}); });
} }
...@@ -458,7 +481,6 @@ void createIntellijFlutterPluginJar(String pluginJarPath, FileSystem fileSystem, ...@@ -458,7 +481,6 @@ void createIntellijFlutterPluginJar(String pluginJarPath, FileSystem fileSystem,
fileSystem.file(pluginJarPath) fileSystem.file(pluginJarPath)
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsBytesSync(ZipEncoder().encode(flutterPlugins)!); ..writeAsBytesSync(ZipEncoder().encode(flutterPlugins)!);
} }
/// A helper to create a Intellij Dart plugin jar. /// A helper to create a Intellij Dart plugin jar.
...@@ -496,3 +518,30 @@ void createIntellijDartPluginJar(String pluginJarPath, FileSystem fileSystem) { ...@@ -496,3 +518,30 @@ void createIntellijDartPluginJar(String pluginJarPath, FileSystem fileSystem) {
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsBytesSync(ZipEncoder().encode(dartPlugins)!); ..writeAsBytesSync(ZipEncoder().encode(dartPlugins)!);
} }
// TODO(fujino): this should use the MemoryFileSystem and a
// FileExceptionHandler, blocked by https://github.com/google/file.dart/issues/227.
class _ThrowingFileSystem extends Fake implements FileSystem {
_ThrowingFileSystem(this._exception);
final Exception _exception;
final MemoryFileSystem memfs = MemoryFileSystem.test();
@override
Context get path => memfs.path;
@override
Directory directory(dynamic _) => _ThrowingDirectory(_exception);
}
class _ThrowingDirectory extends Fake implements Directory {
_ThrowingDirectory(this._exception);
final Exception _exception;
@override
bool existsSync() => true;
@override
List<FileSystemEntity> listSync({bool recursive = false, bool followLinks = true}) => throw _exception;
}
...@@ -7,7 +7,7 @@ import 'package:file/memory.dart'; ...@@ -7,7 +7,7 @@ import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import '../../bin/xcode_backend.dart'; import '../../bin/xcode_backend.dart';
import '../src/common.dart'; import '../src/common.dart' hide Context;
import '../src/fake_process_manager.dart'; import '../src/fake_process_manager.dart';
void main() { void main() {
......
...@@ -17,6 +17,7 @@ import 'package:path/path.dart' as path; // flutter_ignore: package_path_import ...@@ -17,6 +17,7 @@ import 'package:path/path.dart' as path; // flutter_ignore: package_path_import
import 'package:test/test.dart' as test_package show test; import 'package:test/test.dart' as test_package show test;
import 'package:test/test.dart' hide test; import 'package:test/test.dart' hide test;
export 'package:path/path.dart' show Context; // flutter_ignore: package_path_import
export 'package:test/test.dart' hide isInstanceOf, test; export 'package:test/test.dart' hide isInstanceOf, test;
void tryToDelete(FileSystemEntity fileEntity) { void tryToDelete(FileSystemEntity fileEntity) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment