Commit f5733f7a authored by Francisco Magdaleno's avatar Francisco Magdaleno Committed by stuartmorgan

Fix crash on vswhere search from flutter doctor (#40263)

Fixes a crash introduced on #40011 due to an incorrect type in the vswhere search

Fixes #40238
parent be3ff133
...@@ -35,10 +35,6 @@ class VisualStudio { ...@@ -35,10 +35,6 @@ class VisualStudio {
String get displayVersion => String get displayVersion =>
_bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey]; _bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey];
/// True if the Visual Studio installation is as pre-release version.
bool get isPrerelease =>
_bestVisualStudioDetails[_catalogKey][_isPrereleaseKey];
/// The directory where Visual Studio is installed. /// The directory where Visual Studio is installed.
String get installLocation => _bestVisualStudioDetails[_installationPathKey]; String get installLocation => _bestVisualStudioDetails[_installationPathKey];
...@@ -47,14 +43,21 @@ class VisualStudio { ...@@ -47,14 +43,21 @@ class VisualStudio {
/// For instance: "15.4.27004.2002". /// For instance: "15.4.27004.2002".
String get fullVersion => _bestVisualStudioDetails[_fullVersionKey]; String get fullVersion => _bestVisualStudioDetails[_fullVersionKey];
// Properties that determine the status of the installation. There might be
// Visual Studio versions that don't include them, so default to a "valid" value to
// avoid false negatives.
/// True there is complete installation of Visual Studio. /// True there is complete installation of Visual Studio.
bool get isComplete => _bestVisualStudioDetails[_isCompleteKey]; bool get isComplete => _bestVisualStudioDetails[_isCompleteKey] ?? false;
/// True if Visual Studio is launchable. /// True if Visual Studio is launchable.
bool get isLaunchable => _bestVisualStudioDetails[_isLaunchableKey]; bool get isLaunchable => _bestVisualStudioDetails[_isLaunchableKey] ?? false;
/// True if the Visual Studio installation is as pre-release version.
bool get isPrerelease => _bestVisualStudioDetails[_isPrereleaseKey] ?? false;
/// True if a reboot is required to complete the Visual Studio installation. /// True if a reboot is required to complete the Visual Studio installation.
bool get isRebootRequired => _bestVisualStudioDetails[_isRebootRequiredKey]; bool get isRebootRequired => _bestVisualStudioDetails[_isRebootRequiredKey] ?? false;
/// The name of the recommended Visual Studio installer workload. /// The name of the recommended Visual Studio installer workload.
String get workloadDescription => 'Desktop development with C++'; String get workloadDescription => 'Desktop development with C++';
...@@ -141,16 +144,14 @@ class VisualStudio { ...@@ -141,16 +144,14 @@ class VisualStudio {
/// The 'catalog' entry containing more details. /// The 'catalog' entry containing more details.
static const String _catalogKey = 'catalog'; static const String _catalogKey = 'catalog';
/// The key for a pre-release version.
static const String _isPrereleaseKey = 'isPrerelease';
/// The user-friendly version. /// The user-friendly version.
/// ///
/// This key is under the 'catalog' entry. /// This key is under the 'catalog' entry.
static const String _catalogDisplayVersionKey = 'productDisplayVersion'; static const String _catalogDisplayVersionKey = 'productDisplayVersion';
/// The key for a pre-release version.
///
/// This key is under the 'catalog' entry.
static const String _isPrereleaseKey = 'productMilestoneIsPreRelease';
/// vswhere argument keys /// vswhere argument keys
static const String _prereleaseKey = '-prerelease'; static const String _prereleaseKey = '-prerelease';
...@@ -189,15 +190,24 @@ class VisualStudio { ...@@ -189,15 +190,24 @@ class VisualStudio {
} }
/// Checks if the given installation has issues that the user must resolve. /// Checks if the given installation has issues that the user must resolve.
///
/// Returns false if the required information is missing since older versions
/// of Visual Studio might not include them.
bool installationHasIssues(Map<String, dynamic>installationDetails) { bool installationHasIssues(Map<String, dynamic>installationDetails) {
assert(installationDetails != null); assert(installationDetails != null);
assert(installationDetails[_isCompleteKey] != null); if (installationDetails[_isCompleteKey] != null && !installationDetails[_isCompleteKey]) {
assert(installationDetails[_isRebootRequiredKey] != null); return true;
assert(installationDetails[_isLaunchableKey] != null); }
if (installationDetails[_isLaunchableKey] != null && !installationDetails[_isLaunchableKey]) {
return true;
}
if (installationDetails[_isRebootRequiredKey] != null && installationDetails[_isRebootRequiredKey]) {
return true;
}
return installationDetails[_isCompleteKey] == false || return false;
installationDetails[_isRebootRequiredKey] == true ||
installationDetails[_isLaunchableKey] == false;
} }
/// Returns the details dictionary for the latest version of Visual Studio /// Returns the details dictionary for the latest version of Visual Studio
......
...@@ -40,9 +40,20 @@ void main() { ...@@ -40,9 +40,20 @@ void main() {
'isRebootRequired': false, 'isRebootRequired': false,
'isComplete': true, 'isComplete': true,
'isLaunchable': true, 'isLaunchable': true,
'isPrerelease': false,
'catalog': <String, dynamic>{
'productDisplayVersion': '15.9.12',
}
};
// A version of a response that doesn't include certain installation status
// information that might be missing in older Visual Studio versions.
const Map<String, dynamic> _oldResponse = <String, dynamic>{
'installationPath': visualStudioPath,
'displayName': 'Visual Studio Community 2017',
'installationVersion': '15.9.28307.665',
'catalog': <String, dynamic>{ 'catalog': <String, dynamic>{
'productDisplayVersion': '15.9.12', 'productDisplayVersion': '15.9.12',
'productMilestoneIsPreRelease': true,
} }
}; };
...@@ -173,6 +184,19 @@ void main() { ...@@ -173,6 +184,19 @@ void main() {
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
}); });
testUsingContext('isInstalled returns true even with missing status information', () {
setMockCompatibleVisualStudioInstallation(null);
setMockPrereleaseVisualStudioInstallation(null);
setMockAnyVisualStudioInstallation(_oldResponse);
visualStudio = VisualStudio();
expect(visualStudio.isInstalled, true);
}, overrides: <Type, Generator>{
FileSystem: () => memoryFilesystem,
Platform: () => windowsPlatform,
ProcessManager: () => mockProcessManager,
});
testUsingContext('isInstalled returns true when VS is present but missing components', () { testUsingContext('isInstalled returns true when VS is present but missing components', () {
setMockCompatibleVisualStudioInstallation(null); setMockCompatibleVisualStudioInstallation(null);
setMockPrereleaseVisualStudioInstallation(null); setMockPrereleaseVisualStudioInstallation(null);
...@@ -191,15 +215,9 @@ void main() { ...@@ -191,15 +215,9 @@ void main() {
setMockAnyVisualStudioInstallation(null); setMockAnyVisualStudioInstallation(null);
final Map<String, dynamic> response = Map<String, dynamic>.from(_defaultResponse) final Map<String, dynamic> response = Map<String, dynamic>.from(_defaultResponse)
..addAll(<String, dynamic>{ ..['isPrerelease'] = true;
'catalog': <String, dynamic>{
'productDisplayVersion': '15.9.12',
'productMilestoneIsPreRelease': true,
}
});
setMockPrereleaseVisualStudioInstallation(response); setMockPrereleaseVisualStudioInstallation(response);
visualStudio = VisualStudio(); visualStudio = VisualStudio();
expect(visualStudio.isInstalled, true); expect(visualStudio.isInstalled, true);
expect(visualStudio.isPrerelease, true); expect(visualStudio.isPrerelease, true);
......
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