From e1c0f9afad20f55bb6607de17fd6b705c088f3fd Mon Sep 17 00:00:00 2001 From: tobinio Date: Sat, 28 Dec 2024 12:27:24 +0100 Subject: [PATCH] run prune in temp folder --- CHANGELOG.md | 4 ++ Cargo.lock | 147 +++++++++++++++++++++++++++++++------- Cargo.toml | 3 +- src/edit/display.rs | 4 +- src/io/parsing/package.rs | 5 +- src/main.rs | 7 +- src/project/document.rs | 11 ++- src/prune/mod.rs | 54 +++++++------- 8 files changed, 177 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30a335c..5b80be8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## unreleased + +* run prune in temp folder + ## 0.9.1 * Add http2 to known false positives for rocket/hyper/hyper-util - [RivenSkaye](https://github.com/ToBinio/cargo-features-manager/pull/41) diff --git a/Cargo.lock b/Cargo.lock index 3bbd74a..a6e785f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,11 +106,12 @@ dependencies = [ "clap_complete", "color-eyre", "console", + "copy_dir", "ctrlc", "fuzzy-matcher", "itertools", "semver", - "toml", + "tempdir", "toml_edit", ] @@ -252,6 +253,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "copy_dir" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "543d1dd138ef086e2ff05e3a48cf9da045da2033d16f8538fd76b86cd49b2ca3" +dependencies = [ + "walkdir", +] + [[package]] name = "ctrlc" version = "3.4.5" @@ -290,6 +300,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "fuzzy-matcher" version = "0.3.7" @@ -438,6 +454,52 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -450,6 +512,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "semver" version = "1.0.23" @@ -491,15 +562,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -532,6 +594,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand", + "remove_dir_all", +] + [[package]] name = "thiserror" version = "1.0.65" @@ -562,25 +634,11 @@ dependencies = [ "once_cell", ] -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", -] - [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -652,6 +710,47 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 4d37816..f859a39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,9 @@ ctrlc = "3.4.5" fuzzy-matcher = "0.3.7" itertools = { version = "0.13.0", default-features = false, features = ["use_alloc"] } semver = { version = "1.0.23", default-features = false } -toml = { version = "0.8.19", default-features = false } toml_edit = "0.22.22" +tempdir = "0.3.7" +copy_dir = "0.1.3" [[bin]] name = "cargo-features" diff --git a/src/edit/display.rs b/src/edit/display.rs index b266fba..99623ab 100644 --- a/src/edit/display.rs +++ b/src/edit/display.rs @@ -23,7 +23,9 @@ pub struct Display { } impl Display { - pub fn new(document: Document) -> Result { + pub fn new() -> Result { + let document = Document::new(".")?; + Ok(Display { term: Term::buffered_stdout(), package_selector: FilterView { diff --git a/src/io/parsing/package.rs b/src/io/parsing/package.rs index b388278..5b9bcc2 100644 --- a/src/io/parsing/package.rs +++ b/src/io/parsing/package.rs @@ -10,9 +10,11 @@ use crate::project::package::Package; use color_eyre::eyre::ContextCompat; use semver::VersionReq; use std::collections::HashMap; +use std::path::PathBuf; -pub fn get_packages() -> Result<(Vec, Option)> { +pub fn get_packages(path: impl Into) -> Result<(Vec, Option, PathBuf)> { let metadata = cargo_metadata::MetadataCommand::new() + .current_dir(path) .features(CargoOpt::AllFeatures) .exec()?; @@ -31,6 +33,7 @@ pub fn get_packages() -> Result<(Vec, Option)> { Ok(( packages, parse_workspace(metadata.workspace_root.as_str(), &metadata_packages)?, + metadata.workspace_root.into(), )) } diff --git a/src/main.rs b/src/main.rs index 5910de0..fd6338e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,6 @@ use color_eyre::Result; use console::Term; use crate::edit::display::Display; -use crate::project::document::Document; use crate::prune::prune; mod edit; @@ -80,8 +79,6 @@ fn main() -> Result<()> { } fn run(args: FeaturesArgs) -> Result<()> { - let document = Document::new()?; - if let Some(sub) = args.sub { match sub { FeaturesSubCommands::Prune { @@ -89,11 +86,11 @@ fn run(args: FeaturesArgs) -> Result<()> { skip_tests, clean, } => { - prune(document, dry_run, skip_tests, clean)?; + prune(dry_run, skip_tests, clean)?; } } } else { - let mut display = Display::new(document)?; + let mut display = Display::new()?; if let Some(name) = args.dependency { display.set_selected_dep(name)? diff --git a/src/project/document.rs b/src/project/document.rs index 7fe35f9..25d6b52 100644 --- a/src/project/document.rs +++ b/src/project/document.rs @@ -1,4 +1,5 @@ use color_eyre::eyre::{bail, eyre, ContextCompat}; +use std::path::PathBuf; use color_eyre::Result; use itertools::Itertools; @@ -10,11 +11,12 @@ use crate::project::package::Package; pub struct Document { packages: Vec, workspace_index: Option, + root_path: PathBuf, } impl Document { - pub fn new() -> Result { - let (mut packages, workspace) = get_packages()?; + pub fn new(path: impl Into) -> Result { + let (mut packages, workspace, root_path) = get_packages(path)?; if packages.len() == 1 && packages @@ -37,6 +39,7 @@ impl Document { let mut document = Document { packages, workspace_index, + root_path, }; document.update_workspace_deps()?; @@ -44,6 +47,10 @@ impl Document { Ok(document) } + pub fn root_path(&self) -> &PathBuf { + &self.root_path + } + pub fn update_workspace_deps(&mut self) -> Result<()> { let Some(workspace_index) = self.workspace_index else { return Ok(()); diff --git a/src/prune/mod.rs b/src/prune/mod.rs index 68857e5..41c49d7 100644 --- a/src/prune/mod.rs +++ b/src/prune/mod.rs @@ -1,8 +1,3 @@ -use color_eyre::Result; -use std::collections::HashMap; - -use std::ops::Not; - use crate::io::save::save_dependency; use crate::project::dependency::Dependency; use crate::project::document::Document; @@ -10,8 +5,14 @@ use crate::prune::display::Display; use crate::prune::parse::get_features_to_test; use crate::CleanLevel; use color_eyre::eyre::{eyre, ContextCompat}; +use color_eyre::Result; +use copy_dir::copy_dir; use itertools::Itertools; +use std::collections::HashMap; +use std::ops::Not; +use std::path::Path; use std::process::{Command, Stdio}; +use tempdir::TempDir; mod parse; @@ -22,16 +23,18 @@ pub type DependencyName = String; pub type FeatureName = String; pub type FeaturesMap = HashMap>>; -pub fn prune( - mut document: Document, - is_dry_run: bool, - skip_tests: bool, - clean: CleanLevel, -) -> Result<()> { - let features_to_test = get_features_to_test(&document)?; +pub fn prune(is_dry_run: bool, skip_tests: bool, clean: CleanLevel) -> Result<()> { + let mut main_document = Document::new(".")?; + let temp_dir = TempDir::new("cargo-features-manager")?; + let project_path = temp_dir.path().join("project"); + copy_dir(main_document.root_path(), &project_path)?; + + let mut tmp_document = Document::new(project_path)?; + + let features_to_test = get_features_to_test(&tmp_document)?; let to_be_disabled = prune_features( - &mut document, + &mut tmp_document, skip_tests, clean, features_to_test, @@ -45,13 +48,13 @@ pub fn prune( for (package_name, dependency) in to_be_disabled { for (dependency_name, features) in dependency { for feature in features { - document + main_document .get_package_mut(&package_name)? .get_dep_mut(&dependency_name)? .disable_feature(&feature)?; } - save_dependency(&mut document, &package_name, &dependency_name)?; + save_dependency(&mut main_document, &package_name, &dependency_name)?; } } @@ -143,7 +146,7 @@ fn prune_features( save_dependency(document, &package_name, &dependency_name)?; - if !to_be_disabled.contains(feature) && check(skip_tests)? { + if !to_be_disabled.contains(feature) && check(skip_tests, document.root_path())? { set_features_to_be_disabled( document .get_package(&package_name)? @@ -182,7 +185,7 @@ fn prune_features( display.finish_dependency(features_result)?; if let CleanLevel::Dependency = should_clean { - clean()?; + clean(document.root_path())?; } let to_be_disabled = to_be_disabled @@ -197,7 +200,7 @@ fn prune_features( } if let CleanLevel::Package = should_clean { - clean()?; + clean(document.root_path())?; } } @@ -250,8 +253,9 @@ fn set_features_to_be_kept( } } -fn clean() -> Result<()> { +fn clean>(path: P) -> Result<()> { let mut child = Command::new("cargo") + .current_dir(path) .arg("clean") .stdout(Stdio::null()) .stderr(Stdio::null()) @@ -262,20 +266,21 @@ fn clean() -> Result<()> { Ok(()) } -fn check(skip_tests: bool) -> Result { - if !build()? { +fn check>(skip_tests: bool, path: P) -> Result { + if !build(&path)? { return Ok(false); } - if !skip_tests && !test()? { + if !skip_tests && !test(&path)? { return Ok(false); } Ok(true) } -fn build() -> Result { +fn build>(path: P) -> Result { let mut child = Command::new("cargo") + .current_dir(path) .arg("build") .arg("--all-targets") .stdout(Stdio::null()) @@ -287,8 +292,9 @@ fn build() -> Result { Ok(code == 0) } -fn test() -> Result { +fn test>(path: P) -> Result { let mut child = Command::new("cargo") + .current_dir(path) .arg("test") .arg("--workspace") .stdout(Stdio::null()) -- 2.51.2