Skip to content

Commit 87e86ea

Browse files
committed
fix: add gc unused patches logic and fix tests
1 parent 199c82a commit 87e86ea

File tree

3 files changed

+41
-51
lines changed

3 files changed

+41
-51
lines changed

src/bin/cargo/commands/remove.rs

+35-51
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use cargo::core::dependency::DepKind;
22
use cargo::core::PackageIdSpec;
3+
use cargo::core::Resolve;
34
use cargo::core::Workspace;
45
use cargo::ops::cargo_remove::remove;
56
use cargo::ops::cargo_remove::RemoveOptions;
@@ -109,9 +110,14 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
109110

110111
// Reload the workspace since we've changed dependencies
111112
let ws = args.workspace(config)?;
112-
resolve_ws(&ws)?;
113-
}
113+
let (_, resolve) = resolve_ws(&ws)?;
114114

115+
// Attempt to gc unused patches and re-resolve if anything is removed
116+
if gc_unused_patches(&workspace, &resolve)? {
117+
let ws = args.workspace(config)?;
118+
resolve_ws(&ws)?;
119+
}
120+
}
115121
Ok(())
116122
}
117123

@@ -229,31 +235,6 @@ fn gc_workspace(workspace: &Workspace<'_>) -> CargoResult<()> {
229235
}
230236
}
231237

232-
// Clean up the patch section
233-
if let Some(toml_edit::Item::Table(patch_section_table)) = manifest.get_mut("patch") {
234-
patch_section_table.set_implicit(true);
235-
236-
// The key in each of the subtables is a source (either a registry or a URL)
237-
for (source, item) in patch_section_table.iter_mut() {
238-
if let toml_edit::Item::Table(patch_table) = item {
239-
patch_table.set_implicit(true);
240-
241-
for (key, item) in patch_table.iter_mut() {
242-
let package_name =
243-
Dependency::from_toml(&workspace.root_manifest(), key.get(), item)?.name;
244-
if !source_has_match(
245-
&package_name,
246-
source.get(),
247-
&dependencies,
248-
workspace.config(),
249-
)? {
250-
*item = toml_edit::Item::None;
251-
}
252-
}
253-
}
254-
}
255-
}
256-
257238
// Clean up the replace section
258239
if let Some(toml_edit::Item::Table(table)) = manifest.get_mut("replace") {
259240
table.set_implicit(true);
@@ -310,35 +291,38 @@ fn spec_has_match(
310291
Ok(false)
311292
}
312293

313-
/// Check whether or not a source (URL or registry name) matches any non-workspace dependencies.
314-
fn source_has_match(
315-
name: &str,
316-
source: &str,
317-
dependencies: &[Dependency],
318-
config: &Config,
319-
) -> CargoResult<bool> {
320-
for dep in dependencies {
321-
if &dep.name != name {
322-
continue;
323-
}
294+
/// Removes unused patches from the manifest
295+
fn gc_unused_patches(workspace: &Workspace<'_>, resolve: &Resolve) -> CargoResult<bool> {
296+
let mut manifest: toml_edit::Document =
297+
cargo_util::paths::read(workspace.root_manifest())?.parse()?;
324298

325-
match dep.source_id(config)? {
326-
MaybeWorkspace::Other(source_id) => {
327-
if source_id.is_registry() {
328-
if source_id.display_registry_name() == source
329-
|| source_id.url().as_str() == source
299+
let mut modified = false;
300+
301+
// Clean up the patch section
302+
if let Some(toml_edit::Item::Table(patch_section_table)) = manifest.get_mut("patch") {
303+
patch_section_table.set_implicit(true);
304+
305+
// The key in each of the subtables is a source (either a registry or a URL)
306+
307+
for (_, item) in patch_section_table.iter_mut() {
308+
if let toml_edit::Item::Table(patch_table) = item {
309+
patch_table.set_implicit(true);
310+
311+
for (key, item) in patch_table.iter_mut() {
312+
let package_name =
313+
Dependency::from_toml(&workspace.root_manifest(), key.get(), item)?.name;
314+
if PackageIdSpec::query_str(
315+
&package_name,
316+
resolve.unused_patches().iter().cloned(),
317+
)
318+
.is_ok()
330319
{
331-
return Ok(true);
332-
}
333-
} else if source_id.is_git() {
334-
if source_id.url().as_str() == source {
335-
return Ok(true);
320+
*item = toml_edit::Item::None;
321+
modified = true;
336322
}
337323
}
338324
}
339-
MaybeWorkspace::Workspace(_) => {}
340325
}
341326
}
342-
343-
Ok(false)
327+
Ok(modified)
344328
}

tests/testsuite/cargo_remove/gc_patch/out/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@ members = [ "my-member" ]
55
name = "my-project"
66
version = "0.1.0"
77

8+
[patch."[ROOTURL]/bar1"]
9+
bar = { git = "[ROOTURL]/bar2" }
10+
811
[patch.crates-io]
912
bar = { git = "[ROOTURL]/bar2" }

tests/testsuite/cargo_remove/invalid_gc_patch/out/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
[workspace]
44
members = ["serde", "serde_derive"]
55

6+
[patch.crates-io]
7+
serde = { path = "serde" }
8+

0 commit comments

Comments
 (0)