mirror of
https://github.com/rust-lang/cargo
synced 2024-10-03 22:43:59 +00:00
Auto merge of #10130 - weihanglo:issue-8690, r=alexcrichton
Improve unused patch message when source URLs mismatched Resolves #8690 `Resolve.unused_patches` does not contains info about which source URLs they are going to patch. As a result, we cannot provide a precise message but only list all possible URLs of the packages with the same name in the resolved graph. There is a little flaw that if multiple patches are patching the same package, the source URL of the used one would be shown as a possible URL in the warning.
This commit is contained in:
commit
c5fddb0f56
|
@ -413,11 +413,12 @@ impl<'cfg> PackageRegistry<'cfg> {
|
|||
self.patches_locked = true;
|
||||
}
|
||||
|
||||
pub fn patches(&self) -> Vec<Summary> {
|
||||
self.patches
|
||||
.values()
|
||||
.flat_map(|v| v.iter().cloned())
|
||||
.collect()
|
||||
/// Gets all patches grouped by the source URLS they are going to patch.
|
||||
///
|
||||
/// These patches are mainly collected from [`patch`](Self::patch).
|
||||
/// They might not be the same as patches actually used during dependency resolving.
|
||||
pub fn patches(&self) -> &HashMap<CanonicalUrl, Vec<Summary>> {
|
||||
&self.patches
|
||||
}
|
||||
|
||||
fn load(&mut self, source_id: SourceId, kind: Kind) -> CargoResult<()> {
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::util::errors::CargoResult;
|
|||
use crate::util::{profile, CanonicalUrl};
|
||||
use anyhow::Context as _;
|
||||
use log::{debug, trace};
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
/// Result for `resolve_ws_with_opts`.
|
||||
pub struct WorkspaceResolve<'cfg> {
|
||||
|
@ -467,25 +467,17 @@ pub fn resolve_with_previous<'cfg>(
|
|||
.require(Feature::public_dependency())
|
||||
.is_ok(),
|
||||
)?;
|
||||
resolved.register_used_patches(®istry.patches());
|
||||
if register_patches {
|
||||
// It would be good if this warning was more targeted and helpful
|
||||
// (such as showing close candidates that failed to match). However,
|
||||
// that's not terribly easy to do, so just show a general help
|
||||
// message.
|
||||
let warnings: Vec<String> = resolved
|
||||
.unused_patches()
|
||||
.iter()
|
||||
.map(|pkgid| format!("Patch `{}` was not used in the crate graph.", pkgid))
|
||||
.collect();
|
||||
if !warnings.is_empty() {
|
||||
ws.config().shell().warn(format!(
|
||||
"{}\n{}",
|
||||
warnings.join("\n"),
|
||||
UNUSED_PATCH_WARNING
|
||||
))?;
|
||||
}
|
||||
let patches: Vec<_> = registry
|
||||
.patches()
|
||||
.values()
|
||||
.flat_map(|v| v.iter().cloned())
|
||||
.collect();
|
||||
resolved.register_used_patches(&patches[..]);
|
||||
|
||||
if register_patches && !resolved.unused_patches().is_empty() {
|
||||
emit_warnings_of_unused_patches(ws, &resolved, ®istry)?;
|
||||
}
|
||||
|
||||
if let Some(previous) = previous {
|
||||
resolved.merge_from(previous)?;
|
||||
}
|
||||
|
@ -757,3 +749,79 @@ fn master_branch_git_source(id: PackageId, resolve: &Resolve) -> Option<PackageI
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Emits warnings of unused patches case by case.
|
||||
///
|
||||
/// This function does its best to provide more targeted and helpful
|
||||
/// (such as showing close candidates that failed to match). However, that's
|
||||
/// not terribly easy to do, so just show a general help message if we cannot.
|
||||
fn emit_warnings_of_unused_patches(
|
||||
ws: &Workspace<'_>,
|
||||
resolve: &Resolve,
|
||||
registry: &PackageRegistry<'_>,
|
||||
) -> CargoResult<()> {
|
||||
const MESSAGE: &str = "was not used in the crate graph.";
|
||||
|
||||
// Patch package with the source URLs being patch
|
||||
let mut patch_pkgid_to_urls = HashMap::new();
|
||||
for (url, summaries) in registry.patches().iter() {
|
||||
for summary in summaries.iter() {
|
||||
patch_pkgid_to_urls
|
||||
.entry(summary.package_id())
|
||||
.or_insert_with(HashSet::new)
|
||||
.insert(url);
|
||||
}
|
||||
}
|
||||
|
||||
// pkg name -> all source IDs of under the same pkg name
|
||||
let mut source_ids_grouped_by_pkg_name = HashMap::new();
|
||||
for pkgid in resolve.iter() {
|
||||
source_ids_grouped_by_pkg_name
|
||||
.entry(pkgid.name())
|
||||
.or_insert_with(HashSet::new)
|
||||
.insert(pkgid.source_id());
|
||||
}
|
||||
|
||||
let mut unemitted_unused_patches = Vec::new();
|
||||
for unused in resolve.unused_patches().iter() {
|
||||
// Show alternative source URLs if the source URLs being patch
|
||||
// cannot not be found in the crate graph.
|
||||
match (
|
||||
source_ids_grouped_by_pkg_name.get(&unused.name()),
|
||||
patch_pkgid_to_urls.get(unused),
|
||||
) {
|
||||
(Some(ids), Some(patched_urls))
|
||||
if ids
|
||||
.iter()
|
||||
.all(|id| !patched_urls.contains(id.canonical_url())) =>
|
||||
{
|
||||
use std::fmt::Write;
|
||||
let mut msg = String::new();
|
||||
writeln!(&mut msg, "Patch `{}` {}", unused, MESSAGE)?;
|
||||
write!(
|
||||
&mut msg,
|
||||
"Perhaps you misspell the source URL being patched.\n\
|
||||
Possible URLs for `[patch.<URL>]`:",
|
||||
)?;
|
||||
for id in ids.iter() {
|
||||
write!(&mut msg, "\n {}", id.display_registry_name())?;
|
||||
}
|
||||
ws.config().shell().warn(msg)?;
|
||||
}
|
||||
_ => unemitted_unused_patches.push(unused),
|
||||
}
|
||||
}
|
||||
|
||||
// Show general help message.
|
||||
if !unemitted_unused_patches.is_empty() {
|
||||
let warnings: Vec<_> = unemitted_unused_patches
|
||||
.iter()
|
||||
.map(|pkgid| format!("Patch `{}` {}", pkgid, MESSAGE))
|
||||
.collect();
|
||||
ws.config()
|
||||
.shell()
|
||||
.warn(format!("{}\n{}", warnings.join("\n"), UNUSED_PATCH_WARNING))?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
|
|
@ -358,10 +358,10 @@ fn unused() {
|
|||
"\
|
||||
[UPDATING] `dummy-registry` index
|
||||
[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] bar v0.1.0 [..]
|
||||
[COMPILING] bar v0.1.0
|
||||
|
@ -374,10 +374,10 @@ fn unused() {
|
|||
.with_stderr(
|
||||
"\
|
||||
[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[FINISHED] [..]
|
||||
",
|
||||
)
|
||||
|
@ -394,6 +394,60 @@ fn unused() {
|
|||
);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn unused_with_mismatch_source_being_patched() {
|
||||
registry::alt_init();
|
||||
Package::new("bar", "0.1.0").publish();
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
bar = "0.1.0"
|
||||
|
||||
[patch.alternative]
|
||||
bar = { path = "bar" }
|
||||
|
||||
[patch.crates-io]
|
||||
bar = { path = "baz" }
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
|
||||
.file("bar/src/lib.rs", "not rust code")
|
||||
.file("baz/Cargo.toml", &basic_manifest("bar", "0.3.0"))
|
||||
.file("baz/src/lib.rs", "not rust code")
|
||||
.build();
|
||||
|
||||
p.cargo("build")
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] `dummy-registry` index
|
||||
[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
|
||||
Perhaps you misspell the source URL being patched.
|
||||
Possible URLs for `[patch.<URL>]`:
|
||||
crates-io
|
||||
[WARNING] Patch `bar v0.3.0 ([CWD]/baz)` was not used in the crate graph.
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] bar v0.1.0 [..]
|
||||
[COMPILING] bar v0.1.0
|
||||
[COMPILING] foo v0.0.1 ([CWD])
|
||||
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn prefer_patch_version() {
|
||||
Package::new("bar", "0.1.2").publish();
|
||||
|
@ -477,10 +531,10 @@ fn unused_from_config() {
|
|||
"\
|
||||
[UPDATING] `dummy-registry` index
|
||||
[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] bar v0.1.0 [..]
|
||||
[COMPILING] bar v0.1.0
|
||||
|
@ -493,10 +547,10 @@ fn unused_from_config() {
|
|||
.with_stderr(
|
||||
"\
|
||||
[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[FINISHED] [..]
|
||||
",
|
||||
)
|
||||
|
@ -550,10 +604,10 @@ fn unused_git() {
|
|||
[UPDATING] git repository `file://[..]`
|
||||
[UPDATING] `dummy-registry` index
|
||||
[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] bar v0.1.0 [..]
|
||||
[COMPILING] bar v0.1.0
|
||||
|
@ -566,10 +620,10 @@ fn unused_git() {
|
|||
.with_stderr(
|
||||
"\
|
||||
[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[FINISHED] [..]
|
||||
",
|
||||
)
|
||||
|
@ -752,10 +806,10 @@ fn add_ignored_patch() {
|
|||
.with_stderr(
|
||||
"\
|
||||
[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
|
||||
)
|
||||
.run();
|
||||
|
@ -763,10 +817,10 @@ fn add_ignored_patch() {
|
|||
.with_stderr(
|
||||
"\
|
||||
[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph.
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
[..]
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
[FINISHED] [..]",
|
||||
)
|
||||
.run();
|
||||
|
@ -1714,10 +1768,9 @@ fn two_semver_compatible() {
|
|||
.with_stderr(
|
||||
"\
|
||||
warning: Patch `bar v0.1.1 [..]` was not used in the crate graph.
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
Perhaps you misspell the source URL being patched.
|
||||
Possible URLs for `[patch.<URL>]`:
|
||||
[CWD]/bar
|
||||
[FINISHED] [..]",
|
||||
)
|
||||
.run();
|
||||
|
@ -1769,10 +1822,9 @@ fn multipatch_select_big() {
|
|||
.with_stderr(
|
||||
"\
|
||||
warning: Patch `bar v0.1.0 [..]` was not used in the crate graph.
|
||||
Check that [..]
|
||||
with the [..]
|
||||
what is [..]
|
||||
version. [..]
|
||||
Perhaps you misspell the source URL being patched.
|
||||
Possible URLs for `[patch.<URL>]`:
|
||||
[CWD]/bar
|
||||
[FINISHED] [..]",
|
||||
)
|
||||
.run();
|
||||
|
|
Loading…
Reference in a new issue