From 954f3c88bed82d5e7eaba04585f0fcf1a7873cb5 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Tue, 10 Jan 2023 17:22:57 +0100 Subject: [PATCH] make cargo backend use .crates2.json file --- Cargo.lock | 1 + Cargo.toml | 4 +++ src/backend/rust.rs | 77 ++++++++++++++------------------------------- src/path.rs | 2 +- 4 files changed, 30 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 972358a..9f8c80e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,6 +349,7 @@ dependencies = [ "anyhow", "clap", "criterion", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 91af9dd..64a7275 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ alpm = "*" anyhow = "*" # clap 4 until (at least) 4.0.32 have scrapped actual color support. we stay on 3.x until that's fixed. clap = "3.*" +serde_json = "1.0.91" [profile.release] lto = "fat" @@ -21,3 +22,6 @@ criterion = "*" harness = false name = "bench" +[[bin]] +name = "pacdef" +path = "src/main.rs" diff --git a/src/backend/rust.rs b/src/backend/rust.rs index 82814ef..752f4a5 100644 --- a/src/backend/rust.rs +++ b/src/backend/rust.rs @@ -1,4 +1,9 @@ -use std::{collections::HashSet, process::Command}; +use std::collections::HashSet; +use std::fs::read_to_string; +use std::path::PathBuf; + +use anyhow::Result; +use serde_json::Value; use super::{Backend, Switches, Text}; use crate::{impl_backend_constants, Group, Package}; @@ -16,9 +21,10 @@ impl Backend for Rust { impl_backend_constants!(); fn get_all_installed_packages(&self) -> HashSet { - extract_packages_names(&run_cargo_install_list()) - .filter_map(Package::try_from) - .collect() + let file = get_crates_file().unwrap(); + let content = read_to_string(file).unwrap(); + let json: Value = serde_json::from_str(&content).unwrap(); + extract_packages(json) } fn get_explicitly_installed_packages(&self) -> HashSet { @@ -26,20 +32,16 @@ impl Backend for Rust { } } -fn run_cargo_install_list() -> String { - let stdout = Command::new("cargo") - .args(["install", "--list"]) - .output() +fn extract_packages(json: Value) -> HashSet { + json.get("installs") .unwrap() - .stdout; - String::from_utf8(stdout).unwrap() -} - -fn extract_packages_names(output: &str) -> impl Iterator + '_ { - output - .lines() - .filter(|line| !line.starts_with(char::is_whitespace)) - .map(|line| line.split_whitespace().next().unwrap().to_owned()) + .as_object() + .unwrap() + .into_iter() + .map(|(name, _)| name) + .map(|name| name.split_whitespace().next().unwrap()) + .filter_map(Package::try_from) + .collect() } impl Rust { @@ -56,40 +58,9 @@ impl Default for Rust { } } -#[cfg(test)] -mod tests { - use super::extract_packages_names; - - #[test] - fn test_extract_packages() { - const OUTPUT: &str = "cargo-audit v0.17.4: - cargo-audit -cargo-cache v0.8.3: - cargo-cache -cargo-criterion v1.1.0: - cargo-criterion -cargo-update v11.1.1: - cargo-install-update - cargo-install-update-config -flamegraph v0.6.2: - cargo-flamegraph - flamegraph -topgrade v10.1.2 (/home/ratajc72/tmp/topgrade): - topgrade -wthrr v0.6.1: - wthrr"; - let extracted: Vec = extract_packages_names(OUTPUT).collect(); - assert_eq!( - &extracted, - &[ - "cargo-audit", - "cargo-cache", - "cargo-criterion", - "cargo-update", - "flamegraph", - "topgrade", - "wthrr" - ] - ); - } +fn get_crates_file() -> Result { + let mut result = crate::path::get_home_dir()?; + result.push(".cargo"); + result.push(".crates2.json"); + Ok(result) } diff --git a/src/path.rs b/src/path.rs index b01eb0b..c8bda49 100644 --- a/src/path.rs +++ b/src/path.rs @@ -24,6 +24,6 @@ fn get_xdg_config_home() -> Result { } } -fn get_home_dir() -> Result { +pub(crate) fn get_home_dir() -> Result { Ok(env::var("HOME").context("getting $HOME variable")?.into()) }