diff --git a/Cargo.lock b/Cargo.lock index 6c8cd2c..12616fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -537,6 +537,7 @@ dependencies = [ "serde", "serde-inline-default", "serde_json", + "tempfile", "toml", "toml_edit", "walkdir", @@ -688,9 +689,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags", "errno", @@ -806,9 +807,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", diff --git a/Cargo.toml b/Cargo.toml index 70ebabf..cab5be6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ hostname = "0.4.0" walkdir = "2.5.0" toml_edit = "0.22.22" which = '7.0.0' +tempfile = "3.14.0" [dev-dependencies] assert_cmd = "2.0.16" diff --git a/src/backends/winget.rs b/src/backends/winget.rs index 165a36d..6a56fdd 100644 --- a/src/backends/winget.rs +++ b/src/backends/winget.rs @@ -1,9 +1,11 @@ use std::collections::{BTreeMap, BTreeSet}; +use std::io::Read; use color_eyre::Result; use serde::{Deserialize, Serialize}; +use serde_json::Value; -use crate::cmd::{command_found, run_command, run_command_for_stdout}; +use crate::cmd::{command_found, run_command}; use crate::prelude::*; #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, derive_more::Display)] @@ -31,11 +33,29 @@ impl Backend for WinGet { return Ok(BTreeMap::new()); } - let explicit = run_command_for_stdout(["winget", "list", "--id"], Perms::Same)?; + //TODO: refactor if https://github.com/microsoft/winget-cli/issues/184 or https://github.com/microsoft/winget-cli/issues/4267 are ever fixed + let mut tempfile = tempfile::NamedTempFile::new()?; + run_command( + ["winget", "export", tempfile.path().to_str().unwrap()], + Perms::Same, + )?; - Ok(explicit - .lines() - .map(|x| (x.to_string(), WinGetQueryInfo {})) + let mut export = String::new(); + tempfile.read_to_string(&mut export)?; + + let export: Value = serde_json::from_str(&export)?; + + Ok(export["Sources"] + .as_array() + .unwrap() + .iter() + .flat_map(|x| x["Packages"].as_array().unwrap()) + .map(|x| { + ( + x["PackageIdentifier"].as_str().unwrap().to_string(), + WinGetQueryInfo {}, + ) + }) .collect()) } @@ -46,7 +66,7 @@ impl Backend for WinGet { ) -> Result<()> { if !packages.is_empty() { run_command( - ["winget", "install", "--id", "--exact"] + ["winget", "install"] .into_iter() .chain(packages.keys().map(String::as_str)), Perms::Same, @@ -59,7 +79,7 @@ impl Backend for WinGet { fn remove_packages(packages: &BTreeSet, _: bool, _: &Config) -> Result<()> { if !packages.is_empty() { run_command( - ["winget", "uninstall", "--id", "--exact"] + ["winget", "uninstall"] .into_iter() .chain(packages.iter().map(String::as_str)), Perms::Same,