Unverified Commit 719268b4 authored by ekibun's avatar ekibun Committed by GitHub

add different workload & add -products * to vswhere calls to check both Visual...

add different workload & add -products * to vswhere calls to check both Visual Studio IDE and standalone Build Tools. (#64251)
parent 2d02c70a
......@@ -185,8 +185,12 @@ class VisualStudio {
/// Workload ID for use with vswhere requirements.
///
/// Workload ID is different between Visual Studio IDE and Build Tools.
/// See https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
static const String _requiredWorkload = 'Microsoft.VisualStudio.Workload.NativeDesktop';
static const List<String> _requiredWorkloads = <String>[
'Microsoft.VisualStudio.Workload.NativeDesktop',
'Microsoft.VisualStudio.Workload.VCTools'
];
/// Components for use with vswhere requirements.
///
......@@ -270,17 +274,19 @@ class VisualStudio {
Map<String, dynamic> _visualStudioDetails({
bool validateRequirements = false,
List<String> additionalArguments,
String requiredWorkload
}) {
final List<String> requirementArguments = validateRequirements
? <String>[
'-requires',
_requiredWorkload,
requiredWorkload,
..._requiredComponents(_minimumSupportedVersion).keys
]
: <String>[];
try {
final List<String> defaultArguments = <String>[
'-format', 'json',
'-products', '*',
'-utf8',
'-latest',
];
......@@ -343,13 +349,18 @@ class VisualStudio {
_vswhereMinVersionArgument,
_minimumSupportedVersion.toString(),
];
Map<String, dynamic> visualStudioDetails = _visualStudioDetails(
validateRequirements: true,
additionalArguments: minimumVersionArguments);
// If a stable version is not found, try searching for a pre-release version.
visualStudioDetails ??= _visualStudioDetails(
validateRequirements: true,
additionalArguments: <String>[...minimumVersionArguments, _vswherePrereleaseArgument]);
Map<String, dynamic> visualStudioDetails;
// Check in the order of stable VS, stable BT, pre-release VS, pre-release BT
for (final bool checkForPrerelease in <bool>[false, true]) {
for (final String requiredWorkload in _requiredWorkloads) {
visualStudioDetails ??= _visualStudioDetails(
validateRequirements: true,
additionalArguments: checkForPrerelease
? <String>[...minimumVersionArguments, _vswherePrereleaseArgument]
: minimumVersionArguments,
requiredWorkload: requiredWorkload);
}
}
if (visualStudioDetails != null) {
if (installationHasIssues(visualStudioDetails)) {
......
......@@ -41,6 +41,20 @@ const Map<String, dynamic> _defaultResponse = <String, dynamic>{
},
};
// A minimum version of a response where a Build Tools installation was found.
const Map<String, dynamic> _defaultBuildToolsResponse = <String, dynamic>{
'installationPath': visualStudioPath,
'displayName': 'Visual Studio Build Tools 2019',
'installationVersion': '16.7.30413.136',
'isRebootRequired': false,
'isComplete': true,
'isLaunchable': true,
'isPrerelease': false,
'catalog': <String, dynamic>{
'productDisplayVersion': '16.7.2',
},
};
// A response for a VS installation that's too old.
const Map<String, dynamic> _tooOldResponse = <String, dynamic>{
'installationPath': visualStudioPath,
......@@ -74,6 +88,14 @@ const List<String> _requirements = <String>[
'Microsoft.VisualStudio.Component.VC.CMake.Project',
];
// Arguments for a vswhere query to search for a Build Tools installation with the
// requirements.
const List<String> _requirementsBuildTools = <String>[
'Microsoft.VisualStudio.Workload.VCTools',
'Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
'Microsoft.VisualStudio.Component.VC.CMake.Project',
];
// Sets up the mock environment so that searching for Visual Studio with
// exactly the given required components will provide a result. By default it
// return a preset installation, but the response can be overridden.
......@@ -98,6 +120,8 @@ void setMockVswhereResponse(
vswherePath,
'-format',
'json',
'-products',
'*',
'-utf8',
'-latest',
...?additionalArguments,
......@@ -139,6 +163,38 @@ void setMockPrereleaseVisualStudioInstallation(
);
}
// Sets whether or not a vswhere query with the required components will
// return an Build Tools installation.
void setMockCompatibleVisualStudioBuildToolsInstallation(
Map<String, dynamic> response,
FileSystem fileSystem,
FakeProcessManager processManager,
) {
setMockVswhereResponse(
fileSystem,
processManager,
_requirementsBuildTools,
<String>['-version', '16'],
response,
);
}
// Sets whether or not a vswhere query with the required components will
// return a pre-release Build Tools installation.
void setMockPrereleaseVisualStudioBuildToolsInstallation(
Map<String, dynamic> response,
FileSystem fileSystem,
FakeProcessManager processManager,
) {
setMockVswhereResponse(
fileSystem,
processManager,
_requirementsBuildTools,
<String>['-version', '16', '-prerelease'],
response,
);
}
// Sets whether or not a vswhere query searching for 'all' and 'prerelease'
// versions will return an installation.
void setMockAnyVisualStudioInstallation(
......@@ -229,6 +285,32 @@ VisualStudioFixture setUpVisualStudio() {
return VisualStudioFixture(visualStudio, fileSystem, processManager);
}
// Set all vswhere query with the required components return null.
void setNoViableToolchainInstallation(
VisualStudioFixture fixture,
) {
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockCompatibleVisualStudioBuildToolsInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioBuildToolsInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
}
void main() {
group('Visual Studio', () {
testWithoutContext('isInstalled returns false when vswhere is missing', () {
......@@ -296,16 +378,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
null,
fixture.fileSystem,
......@@ -343,16 +417,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_tooOldResponse,
fixture.fileSystem,
......@@ -368,16 +434,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_missingStatusResponse,
fixture.fileSystem,
......@@ -391,16 +449,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_defaultResponse,
fixture.fileSystem,
......@@ -414,16 +464,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_tooOldResponse,
fixture.fileSystem,
......@@ -444,13 +486,13 @@ void main() {
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
response,
setMockCompatibleVisualStudioBuildToolsInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockAnyVisualStudioInstallation(
null,
setMockPrereleaseVisualStudioInstallation(
response,
fixture.fileSystem,
fixture.processManager,
);
......@@ -459,20 +501,43 @@ void main() {
expect(visualStudio.isPrerelease, true);
});
testWithoutContext('isAtLeastMinimumVersion returns false when the version found is too old', () {
testWithoutContext('isInstalled returns true when a prerelease version of Build Tools is present', () {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultBuildToolsResponse)
..['isPrerelease'] = true;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockCompatibleVisualStudioBuildToolsInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioBuildToolsInstallation(
response,
fixture.fileSystem,
fixture.processManager,
);
expect(visualStudio.isInstalled, true);
expect(visualStudio.isPrerelease, true);
});
testWithoutContext('isAtLeastMinimumVersion returns false when the version found is too old', () {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_tooOldResponse,
fixture.fileSystem,
......@@ -487,16 +552,7 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
..['isComplete'] = false;
......@@ -515,16 +571,7 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
..['isLaunchable'] = false;
......@@ -542,16 +589,7 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
final Map<String, dynamic> response = Map<String, dynamic>.of(_defaultResponse)
..['isRebootRequired'] = true;
......@@ -569,16 +607,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_defaultResponse,
fixture.fileSystem,
......@@ -592,16 +622,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_defaultResponse,
fixture.fileSystem,
......@@ -622,11 +644,6 @@ void main() {
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
expect(visualStudio.cmakePath, isNull);
});
......@@ -642,11 +659,6 @@ void main() {
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
expect(visualStudio.hasNecessaryComponents, false);
});
......@@ -655,16 +667,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockAnyVisualStudioInstallation(
_defaultResponse,
fixture.fileSystem,
......@@ -681,16 +685,8 @@ void main() {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setNoViableToolchainInstallation(fixture);
setMockEncodedAnyVisualStudioInstallation(
'{',
fixture.fileSystem,
......@@ -709,13 +705,24 @@ void main() {
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
expect(visualStudio.isInstalled, true);
expect(visualStudio.isAtLeastMinimumVersion, true);
expect(visualStudio.hasNecessaryComponents, true);
expect(visualStudio.cmakePath, equals(cmakePath));
});
testWithoutContext('Everything returns good values when Build Tools is present with all components', () {
final VisualStudioFixture fixture = setUpVisualStudio();
final VisualStudio visualStudio = fixture.visualStudio;
setMockCompatibleVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
setMockAnyVisualStudioInstallation(
null,
setMockCompatibleVisualStudioBuildToolsInstallation(
_defaultBuildToolsResponse,
fixture.fileSystem,
fixture.processManager,
);
......@@ -745,11 +752,6 @@ void main() {
fixture.fileSystem,
fixture.processManager,
);
setMockPrereleaseVisualStudioInstallation(
null,
fixture.fileSystem,
fixture.processManager,
);
// Return a different version for queries without the required packages.
final Map<String, dynamic> incompleteVersionResponse = <String, dynamic>{
'installationPath': visualStudioPath,
......
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