handle exceptions raised while searching for configured android studio (#133180)
Fixes #133055
This commit is contained in:
parent
12cf9de68b
commit
e1967ecabf
@ -236,16 +236,7 @@ class AndroidStudio {
|
|||||||
/// Android Studio found at that location is always returned, even if it is
|
/// Android Studio found at that location is always returned, even if it is
|
||||||
/// invalid.
|
/// invalid.
|
||||||
static AndroidStudio? latestValid() {
|
static AndroidStudio? latestValid() {
|
||||||
final String? configuredStudioPath = globals.config.getValue('android-studio-dir') as String?;
|
final Directory? configuredStudioDir = _configuredDir();
|
||||||
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 ''
|
|
||||||
''');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find all available Studio installations.
|
// Find all available Studio installations.
|
||||||
final List<AndroidStudio> studios = allInstalled();
|
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
|
final AndroidStudio? manuallyConfigured = studios
|
||||||
.where((AndroidStudio studio) => studio.configuredPath != null &&
|
.where((AndroidStudio studio) => studio.configuredPath != null &&
|
||||||
configuredStudioPath != null &&
|
configuredStudioDir != null &&
|
||||||
_pathsAreEqual(studio.configuredPath!, configuredStudioPath))
|
_pathsAreEqual(studio.configuredPath!, configuredStudioDir.path))
|
||||||
.firstOrNull;
|
.firstOrNull;
|
||||||
|
|
||||||
if (manuallyConfigured != null) {
|
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?;
|
Directory? configuredStudioDir = _configuredDir();
|
||||||
FileSystemEntity? configuredStudioDirAsEntity;
|
|
||||||
if (configuredStudioDir != null) {
|
if (configuredStudioDir != null) {
|
||||||
configuredStudioDirAsEntity = globals.fs.directory(configuredStudioDir);
|
if (configuredStudioDir.basename == 'Contents') {
|
||||||
if (configuredStudioDirAsEntity.basename == 'Contents') {
|
configuredStudioDir = configuredStudioDir.parent;
|
||||||
configuredStudioDirAsEntity = configuredStudioDirAsEntity.parent;
|
|
||||||
}
|
}
|
||||||
if (!candidatePaths
|
if (!candidatePaths
|
||||||
.any((FileSystemEntity e) => _pathsAreEqual(e.path, configuredStudioDirAsEntity!.path))) {
|
.any((FileSystemEntity e) => _pathsAreEqual(e.path, configuredStudioDir!.path))) {
|
||||||
candidatePaths.add(configuredStudioDirAsEntity);
|
candidatePaths.add(configuredStudioDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,13 +346,13 @@ the configured path by running this command: flutter config --android-studio-dir
|
|||||||
|
|
||||||
return candidatePaths
|
return candidatePaths
|
||||||
.map<AndroidStudio?>((FileSystemEntity e) {
|
.map<AndroidStudio?>((FileSystemEntity e) {
|
||||||
if (configuredStudioDirAsEntity == null) {
|
if (configuredStudioDir == null) {
|
||||||
return AndroidStudio.fromMacOSBundle(e.path);
|
return AndroidStudio.fromMacOSBundle(e.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AndroidStudio.fromMacOSBundle(
|
return AndroidStudio.fromMacOSBundle(
|
||||||
e.path,
|
e.path,
|
||||||
configuredPath: _pathsAreEqual(configuredStudioDirAsEntity.path, e.path) ? configuredStudioDir : null,
|
configuredPath: _pathsAreEqual(configuredStudioDir.path, e.path) ? configuredStudioDir.path : null,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.whereType<AndroidStudio>()
|
.whereType<AndroidStudio>()
|
||||||
@ -493,6 +482,38 @@ the configured path by running this command: flutter config --android-studio-dir
|
|||||||
return studios;
|
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) {
|
static String? extractStudioPlistValueWithMatcher(String plistValue, RegExp keyMatcher) {
|
||||||
return keyMatcher.stringMatch(plistValue)?.split('=').last.trim().replaceAll('"', '');
|
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/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';
|
||||||
@ -1287,6 +1288,20 @@ void main() {
|
|||||||
Platform: () => platform,
|
Platform: () => platform,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
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]!;
|
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/';
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user