summaryrefslogtreecommitdiffstats
path: root/third_party/rust/cc/src/windows/vs_instances.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/cc/src/windows/vs_instances.rs')
-rw-r--r--third_party/rust/cc/src/windows/vs_instances.rs199
1 files changed, 199 insertions, 0 deletions
diff --git a/third_party/rust/cc/src/windows/vs_instances.rs b/third_party/rust/cc/src/windows/vs_instances.rs
new file mode 100644
index 0000000000..e863dadabb
--- /dev/null
+++ b/third_party/rust/cc/src/windows/vs_instances.rs
@@ -0,0 +1,199 @@
+use std::borrow::Cow;
+use std::collections::HashMap;
+use std::convert::TryFrom;
+use std::io::BufRead;
+use std::path::PathBuf;
+
+use crate::windows::setup_config::{EnumSetupInstances, SetupInstance};
+
+pub enum VsInstance {
+ Com(SetupInstance),
+ Vswhere(VswhereInstance),
+}
+
+impl VsInstance {
+ pub fn installation_name(&self) -> Option<Cow<str>> {
+ match self {
+ VsInstance::Com(s) => s
+ .installation_name()
+ .ok()
+ .and_then(|s| s.into_string().ok())
+ .map(Cow::from),
+ VsInstance::Vswhere(v) => v.map.get("installationName").map(Cow::from),
+ }
+ }
+
+ pub fn installation_path(&self) -> Option<PathBuf> {
+ match self {
+ VsInstance::Com(s) => s.installation_path().ok().map(PathBuf::from),
+ VsInstance::Vswhere(v) => v.map.get("installationPath").map(PathBuf::from),
+ }
+ }
+
+ pub fn installation_version(&self) -> Option<Cow<str>> {
+ match self {
+ VsInstance::Com(s) => s
+ .installation_version()
+ .ok()
+ .and_then(|s| s.into_string().ok())
+ .map(Cow::from),
+ VsInstance::Vswhere(v) => v.map.get("installationVersion").map(Cow::from),
+ }
+ }
+}
+
+pub enum VsInstances {
+ ComBased(EnumSetupInstances),
+ VswhereBased(VswhereInstance),
+}
+
+impl IntoIterator for VsInstances {
+ type Item = VsInstance;
+ #[allow(bare_trait_objects)]
+ type IntoIter = Box<Iterator<Item = Self::Item>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ match self {
+ VsInstances::ComBased(e) => {
+ Box::new(e.into_iter().filter_map(Result::ok).map(VsInstance::Com))
+ }
+ VsInstances::VswhereBased(v) => Box::new(std::iter::once(VsInstance::Vswhere(v))),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct VswhereInstance {
+ map: HashMap<String, String>,
+}
+
+impl TryFrom<&Vec<u8>> for VswhereInstance {
+ type Error = &'static str;
+
+ fn try_from(output: &Vec<u8>) -> Result<Self, Self::Error> {
+ let map: HashMap<_, _> = output
+ .lines()
+ .filter_map(Result::ok)
+ .filter_map(|s| {
+ let mut splitn = s.splitn(2, ": ");
+ Some((splitn.next()?.to_owned(), splitn.next()?.to_owned()))
+ })
+ .collect();
+
+ if !map.contains_key("installationName")
+ || !map.contains_key("installationPath")
+ || !map.contains_key("installationVersion")
+ {
+ return Err("required properties not found");
+ }
+
+ Ok(Self { map })
+ }
+}
+
+#[cfg(test)]
+mod tests_ {
+ use std::borrow::Cow;
+ use std::convert::TryFrom;
+ use std::path::PathBuf;
+
+ #[test]
+ fn it_parses_vswhere_output_correctly() {
+ let output = br"instanceId: 58104422
+installDate: 21/02/2021 21:50:33
+installationName: VisualStudio/16.9.2+31112.23
+installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools
+installationVersion: 16.9.31112.23
+productId: Microsoft.VisualStudio.Product.BuildTools
+productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
+state: 4294967295
+isComplete: 1
+isLaunchable: 1
+isPrerelease: 0
+isRebootRequired: 0
+displayName: Visual Studio Build Tools 2019
+description: The Visual Studio Build Tools allows you to build native and managed MSBuild-based applications without requiring the Visual Studio IDE. There are options to install the Visual C++ compilers and libraries, MFC, ATL, and C++/CLI support.
+channelId: VisualStudio.16.Release
+channelUri: https://aka.ms/vs/16/release/channel
+enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
+releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9#16.9.2
+thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=660909
+updateDate: 2021-03-17T21:16:46.5963702Z
+catalog_buildBranch: d16.9
+catalog_buildVersion: 16.9.31112.23
+catalog_id: VisualStudio/16.9.2+31112.23
+catalog_localBuild: build-lab
+catalog_manifestName: VisualStudio
+catalog_manifestType: installer
+catalog_productDisplayVersion: 16.9.2
+catalog_productLine: Dev16
+catalog_productLineVersion: 2019
+catalog_productMilestone: RTW
+catalog_productMilestoneIsPreRelease: False
+catalog_productName: Visual Studio
+catalog_productPatchVersion: 2
+catalog_productPreReleaseMilestoneSuffix: 1.0
+catalog_productSemanticVersion: 16.9.2+31112.23
+catalog_requiredEngineVersion: 2.9.3365.38425
+properties_campaignId: 156063665.1613940062
+properties_channelManifestId: VisualStudio.16.Release/16.9.2+31112.23
+properties_nickname:
+properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installershell.exe
+"
+ .to_vec();
+
+ let vswhere_instance = super::VswhereInstance::try_from(&output);
+ assert!(vswhere_instance.is_ok());
+
+ let vs_instance = super::VsInstance::Vswhere(vswhere_instance.unwrap());
+ assert_eq!(
+ vs_instance.installation_name(),
+ Some(Cow::from("VisualStudio/16.9.2+31112.23"))
+ );
+ assert_eq!(
+ vs_instance.installation_path(),
+ Some(PathBuf::from(
+ r"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
+ ))
+ );
+ assert_eq!(
+ vs_instance.installation_version(),
+ Some(Cow::from("16.9.31112.23"))
+ );
+ }
+
+ #[test]
+ fn it_returns_an_error_for_empty_output() {
+ let output = b"".to_vec();
+
+ let vswhere_instance = super::VswhereInstance::try_from(&output);
+
+ assert!(vswhere_instance.is_err());
+ }
+
+ #[test]
+ fn it_returns_an_error_for_output_consisting_of_empty_lines() {
+ let output = br"
+
+"
+ .to_vec();
+
+ let vswhere_instance = super::VswhereInstance::try_from(&output);
+
+ assert!(vswhere_instance.is_err());
+ }
+
+ #[test]
+ fn it_returns_an_error_for_output_without_required_properties() {
+ let output = br"instanceId: 58104422
+installDate: 21/02/2021 21:50:33
+productId: Microsoft.VisualStudio.Product.BuildTools
+productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\LaunchDevCmd.bat
+"
+ .to_vec();
+
+ let vswhere_instance = super::VswhereInstance::try_from(&output);
+
+ assert!(vswhere_instance.is_err());
+ }
+}