Unverified Commit e1967eca authored by Andrew Kolos's avatar Andrew Kolos Committed by GitHub

handle exceptions raised while searching for configured android studio (#133180)

Fixes #133055
parent 12cf9de6
......@@ -236,16 +236,7 @@ class AndroidStudio {
/// Android Studio found at that location is always returned, even if it is
/// invalid.
static AndroidStudio? latestValid() {
final String? configuredStudioPath = globals.config.getValue('android-studio-dir') as String?;
if (configuredStudioPath != null && !globals.fs.directory(configuredStudioPath).existsSync()) {
throwToolExit('''
Could not find the Android Studio installation at the manually configured path "$configuredStudioPath".
Please verify that the path is correct and update it by running this command: flutter config --android-studio-dir '<path>'
To have flutter search for Android Studio installations automatically, remove
the configured path by running this command: flutter config --android-studio-dir ''
''');
}
final Directory? configuredStudioDir = _configuredDir();
// Find all available Studio installations.
final List<AndroidStudio> studios = allInstalled();
......@@ -255,8 +246,8 @@ the configured path by running this command: flutter config --android-studio-dir
final AndroidStudio? manuallyConfigured = studios
.where((AndroidStudio studio) => studio.configuredPath != null &&
configuredStudioPath != null &&
_pathsAreEqual(studio.configuredPath!, configuredStudioPath))
configuredStudioDir != null &&
_pathsAreEqual(studio.configuredPath!, configuredStudioDir.path))
.firstOrNull;
if (manuallyConfigured != null) {
......@@ -323,16 +314,14 @@ the configured path by running this command: flutter config --android-studio-dir
));
}
final String? configuredStudioDir = globals.config.getValue('android-studio-dir') as String?;
FileSystemEntity? configuredStudioDirAsEntity;
Directory? configuredStudioDir = _configuredDir();
if (configuredStudioDir != null) {
configuredStudioDirAsEntity = globals.fs.directory(configuredStudioDir);
if (configuredStudioDirAsEntity.basename == 'Contents') {
configuredStudioDirAsEntity = configuredStudioDirAsEntity.parent;
if (configuredStudioDir.basename == 'Contents') {
configuredStudioDir = configuredStudioDir.parent;
}
if (!candidatePaths
.any((FileSystemEntity e) => _pathsAreEqual(e.path, configuredStudioDirAsEntity!.path))) {
candidatePaths.add(configuredStudioDirAsEntity);
.any((FileSystemEntity e) => _pathsAreEqual(e.path, configuredStudioDir!.path))) {
candidatePaths.add(configuredStudioDir);
}
}
......@@ -357,13 +346,13 @@ the configured path by running this command: flutter config --android-studio-dir
return candidatePaths
.map<AndroidStudio?>((FileSystemEntity e) {
if (configuredStudioDirAsEntity == null) {
if (configuredStudioDir == null) {
return AndroidStudio.fromMacOSBundle(e.path);
}
return AndroidStudio.fromMacOSBundle(
e.path,
configuredPath: _pathsAreEqual(configuredStudioDirAsEntity.path, e.path) ? configuredStudioDir : null,
configuredPath: _pathsAreEqual(configuredStudioDir.path, e.path) ? configuredStudioDir.path : null,
);
})
.whereType<AndroidStudio>()
......@@ -493,6 +482,38 @@ the configured path by running this command: flutter config --android-studio-dir
return studios;
}
/// Gets the Android Studio install directory set by the user, if it is configured.
///
/// The returned [Directory], if not null, is guaranteed to have existed during
/// this function's execution.
static Directory? _configuredDir() {
final String? configuredPath = globals.config.getValue('android-studio-dir') as String?;
if (configuredPath == null) {
return null;
}
final Directory result = globals.fs.directory(configuredPath);
bool? configuredStudioPathExists;
String? exceptionMessage;
try {
configuredStudioPathExists = result.existsSync();
} on FileSystemException catch (e) {
exceptionMessage = e.toString();
}
if (configuredStudioPathExists == false || exceptionMessage != null) {
throwToolExit('''
Could not find the Android Studio installation at the manually configured path "$configuredPath".
${exceptionMessage == null ? '' : 'Encountered exception: $exceptionMessage\n\n'}
Please verify that the path is correct and update it by running this command: flutter config --android-studio-dir '<path>'
To have flutter search for Android Studio installations automatically, remove
the configured path by running this command: flutter config --android-studio-dir
''');
}
return result;
}
static String? extractStudioPlistValueWithMatcher(String plistValue, RegExp keyMatcher) {
return keyMatcher.stringMatch(plistValue)?.split('=').last.trim().replaceAll('"', '');
}
......
......@@ -11,6 +11,7 @@ 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';
......@@ -1287,6 +1288,20 @@ void main() {
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('handles file system exception when checking for explicitly configured Android Studio install', () {
const String androidStudioDir = '/Users/Dash/Desktop/android-studio';
config.setValue('android-studio-dir', androidStudioDir);
expect(() => AndroidStudio.latestValid(),
throwsToolExit(message: RegExp(r'[.\s\S]*Could not find[.\s\S]*FileSystemException[.\s\S]*')));
}, overrides: <Type, Generator>{
Config: () => config,
Platform: () => platform,
FileSystem: () => _FakeFileSystem(),
FileSystemUtils: () => _FakeFsUtils(),
ProcessManager: () => FakeProcessManager.any(),
});
});
}
......@@ -1298,3 +1313,33 @@ class FakePlistUtils extends Fake implements PlistParser {
return fileContents[plistFilePath]!;
}
}
class _FakeFileSystem extends Fake implements FileSystem {
@override
Directory directory(dynamic path) {
return _NonExistentDirectory();
}
@override
Context get path {
return MemoryFileSystem.test().path;
}
}
class _NonExistentDirectory extends Fake implements Directory {
@override
bool existsSync() {
throw const FileSystemException('OS Error: Filename, directory name, or volume label syntax is incorrect.');
}
@override
String get path => '';
@override
Directory get parent => _NonExistentDirectory();
}
class _FakeFsUtils extends Fake implements FileSystemUtils {
@override
String get homeDirPath => '/home/';
}
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