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 {
// Remove JetBrains Toolbox link apps. These tiny apps just
// link to the full app, will get detected elsewhere in our search.
validators.removeWhere((DoctorValidator validator) {
if (validator is! IntelliJValidatorOnMac) {
return false;
}
final String identifierKey = plistParser.getValueFromFile(
(validator as IntelliJValidatorOnMac).plistFile,
validator.plistFile,
PlistParser.kCFBundleIdentifierKey,
) as String;
return identifierKey.contains('com.jetbrains.toolbox.linkapp');
......
......@@ -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/globals.dart' as globals;
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 '../../src/common.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/io.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:test/fake.dart';
......@@ -1293,7 +1292,7 @@ class FakeExistsFile extends Fake implements File {
class FakeFileSystem extends Fake implements FileSystem {
@override
p.Context get path => p.Context();
Context get path => Context();
@override
Directory get currentDirectory {
......
......@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/convert.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';
import '../../src/common.dart';
import '../../src/fake_process_manager.dart';
......@@ -373,6 +374,29 @@ void main() {
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 {
final FileSystem fileSystem = MemoryFileSystem.test();
final List<String> installPaths = <String>[
......@@ -398,11 +422,9 @@ void main() {
], stdout: 'skip')
]);
final Iterable<DoctorValidator> installed =
IntelliJValidatorOnMac.installed(
final Iterable<DoctorValidator> installed = IntelliJValidatorOnMac.installed(
fileSystem: fileSystem,
fileSystemUtils:
FileSystemUtils(fileSystem: fileSystem, platform: macPlatform),
fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: macPlatform),
userMessages: UserMessages(),
plistParser: FakePlistParser(<String, String>{
'JetBrainsToolboxApp': '/path/to/JetBrainsToolboxApp',
......@@ -412,6 +434,7 @@ void main() {
);
expect(installed.length, 0);
expect(processManager, hasNoRemainingExpectations);
});
}
......@@ -458,7 +481,6 @@ void createIntellijFlutterPluginJar(String pluginJarPath, FileSystem fileSystem,
fileSystem.file(pluginJarPath)
..createSync(recursive: true)
..writeAsBytesSync(ZipEncoder().encode(flutterPlugins)!);
}
/// A helper to create a Intellij Dart plugin jar.
......@@ -496,3 +518,30 @@ void createIntellijDartPluginJar(String pluginJarPath, FileSystem fileSystem) {
..createSync(recursive: true)
..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';
import 'package:flutter_tools/src/base/io.dart';
import '../../bin/xcode_backend.dart';
import '../src/common.dart';
import '../src/common.dart' hide Context;
import '../src/fake_process_manager.dart';
void main() {
......
......@@ -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' hide test;
export 'package:path/path.dart' show Context; // flutter_ignore: package_path_import
export 'package:test/test.dart' hide isInstanceOf, test;
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