mirror of https://github.com/rust-lang/cargo
Auto merge of #13281 - LuuuXXX:issue-10729, r=epage
fix(add): Improve error when adding registry packages while vendored ### **What does this PR try to resolve?** When a vendored directory is established, cargo add no longer adds new packages. Instead, it tries to translate a package name into a package that already exists in the vendored directory. [More details](https://github.com/rust-lang/cargo/issues/10729#issue-1260548746) Since `@epage` has done most of the work, here I do the rest of the finishing work. Improves the error from #10729 ### **How should we test and review this PR?** The implementation procedure is as follows: https://github.com/rust-lang/cargo/issues/10729#issuecomment-1191633351 Test steps: 1. Try to get an arbitrary crate and execute `cargo vendor` command. 2. Configure the vendor directory in .cargo/config.toml. 3. Add `alter-registry` to the config.toml file. ``` [registries] alter-registry= { index = "XXX" } ``` 4. run the same `cargo add` command. ``` cargo add another-crate --registry alter-registry ```
This commit is contained in:
commit
e08a81333c
|
@ -112,7 +112,8 @@ pub fn resolve_with_global_context_raw(
|
||||||
for summary in self.list.iter() {
|
for summary in self.list.iter() {
|
||||||
let matched = match kind {
|
let matched = match kind {
|
||||||
QueryKind::Exact => dep.matches(summary),
|
QueryKind::Exact => dep.matches(summary),
|
||||||
QueryKind::Fuzzy => true,
|
QueryKind::Alternatives => true,
|
||||||
|
QueryKind::Normalized => true,
|
||||||
};
|
};
|
||||||
if matched {
|
if matched {
|
||||||
self.used.insert(summary.package_id());
|
self.used.insert(summary.package_id());
|
||||||
|
|
|
@ -312,7 +312,7 @@ pub(super) fn activation_error(
|
||||||
// Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
|
// Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
|
||||||
// was meant. So we try asking the registry for a `fuzzy` search for suggestions.
|
// was meant. So we try asking the registry for a `fuzzy` search for suggestions.
|
||||||
let candidates = loop {
|
let candidates = loop {
|
||||||
match registry.query_vec(&new_dep, QueryKind::Fuzzy) {
|
match registry.query_vec(&new_dep, QueryKind::Alternatives) {
|
||||||
Poll::Ready(Ok(candidates)) => break candidates,
|
Poll::Ready(Ok(candidates)) => break candidates,
|
||||||
Poll::Ready(Err(e)) => return to_resolve_err(e),
|
Poll::Ready(Err(e)) => return to_resolve_err(e),
|
||||||
Poll::Pending => match registry.block_until_ready() {
|
Poll::Pending => match registry.block_until_ready() {
|
||||||
|
|
|
@ -588,7 +588,7 @@ fn get_latest_dependency(
|
||||||
}
|
}
|
||||||
MaybeWorkspace::Other(query) => {
|
MaybeWorkspace::Other(query) => {
|
||||||
let possibilities = loop {
|
let possibilities = loop {
|
||||||
match registry.query_vec(&query, QueryKind::Fuzzy) {
|
match registry.query_vec(&query, QueryKind::Normalized) {
|
||||||
std::task::Poll::Ready(res) => {
|
std::task::Poll::Ready(res) => {
|
||||||
break res?;
|
break res?;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +711,7 @@ fn select_package(
|
||||||
MaybeWorkspace::Other(query) => {
|
MaybeWorkspace::Other(query) => {
|
||||||
let possibilities = loop {
|
let possibilities = loop {
|
||||||
// Exact to avoid returning all for path/git
|
// Exact to avoid returning all for path/git
|
||||||
match registry.query_vec(&query, QueryKind::Exact) {
|
match registry.query_vec(&query, QueryKind::Normalized) {
|
||||||
std::task::Poll::Ready(res) => {
|
std::task::Poll::Ready(res) => {
|
||||||
break res?;
|
break res?;
|
||||||
}
|
}
|
||||||
|
@ -938,7 +938,7 @@ fn populate_available_features(
|
||||||
}
|
}
|
||||||
|
|
||||||
let possibilities = loop {
|
let possibilities = loop {
|
||||||
match registry.query_vec(&query, QueryKind::Exact) {
|
match registry.query_vec(&query, QueryKind::Normalized) {
|
||||||
std::task::Poll::Ready(res) => {
|
std::task::Poll::Ready(res) => {
|
||||||
break res?;
|
break res?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,8 @@ impl<'gctx> Source for DirectorySource<'gctx> {
|
||||||
let packages = self.packages.values().map(|p| &p.0);
|
let packages = self.packages.values().map(|p| &p.0);
|
||||||
let matches = packages.filter(|pkg| match kind {
|
let matches = packages.filter(|pkg| match kind {
|
||||||
QueryKind::Exact => dep.matches(pkg.summary()),
|
QueryKind::Exact => dep.matches(pkg.summary()),
|
||||||
QueryKind::Fuzzy => true,
|
QueryKind::Alternatives => true,
|
||||||
|
QueryKind::Normalized => dep.matches(pkg.summary()),
|
||||||
});
|
});
|
||||||
for summary in matches.map(|pkg| pkg.summary().clone()) {
|
for summary in matches.map(|pkg| pkg.summary().clone()) {
|
||||||
f(IndexSummary::Candidate(summary));
|
f(IndexSummary::Candidate(summary));
|
||||||
|
|
|
@ -558,7 +558,8 @@ impl<'gctx> Source for PathSource<'gctx> {
|
||||||
for s in self.packages.iter().map(|p| p.summary()) {
|
for s in self.packages.iter().map(|p| p.summary()) {
|
||||||
let matched = match kind {
|
let matched = match kind {
|
||||||
QueryKind::Exact => dep.matches(s),
|
QueryKind::Exact => dep.matches(s),
|
||||||
QueryKind::Fuzzy => true,
|
QueryKind::Alternatives => true,
|
||||||
|
QueryKind::Normalized => dep.matches(s),
|
||||||
};
|
};
|
||||||
if matched {
|
if matched {
|
||||||
f(IndexSummary::Candidate(s.clone()))
|
f(IndexSummary::Candidate(s.clone()))
|
||||||
|
|
|
@ -791,7 +791,8 @@ impl<'gctx> Source for RegistrySource<'gctx> {
|
||||||
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
|
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
|
||||||
let matched = match kind {
|
let matched = match kind {
|
||||||
QueryKind::Exact => dep.matches(s.as_summary()),
|
QueryKind::Exact => dep.matches(s.as_summary()),
|
||||||
QueryKind::Fuzzy => true,
|
QueryKind::Alternatives => true,
|
||||||
|
QueryKind::Normalized => true,
|
||||||
};
|
};
|
||||||
if !matched {
|
if !matched {
|
||||||
return;
|
return;
|
||||||
|
@ -830,7 +831,7 @@ impl<'gctx> Source for RegistrySource<'gctx> {
|
||||||
return Poll::Ready(Ok(()));
|
return Poll::Ready(Ok(()));
|
||||||
}
|
}
|
||||||
let mut any_pending = false;
|
let mut any_pending = false;
|
||||||
if kind == QueryKind::Fuzzy {
|
if kind == QueryKind::Alternatives || kind == QueryKind::Normalized {
|
||||||
// Attempt to handle misspellings by searching for a chain of related
|
// Attempt to handle misspellings by searching for a chain of related
|
||||||
// names to the original name. The resolver will later
|
// names to the original name. The resolver will later
|
||||||
// reject any candidates that have the wrong name, and with this it'll
|
// reject any candidates that have the wrong name, and with this it'll
|
||||||
|
|
|
@ -183,7 +183,10 @@ pub enum QueryKind {
|
||||||
/// Path/Git sources may return all dependencies that are at that URI,
|
/// Path/Git sources may return all dependencies that are at that URI,
|
||||||
/// whereas an `Registry` source may return dependencies that have the same
|
/// whereas an `Registry` source may return dependencies that have the same
|
||||||
/// canonicalization.
|
/// canonicalization.
|
||||||
Fuzzy,
|
Alternatives,
|
||||||
|
/// Match a denpendency in all ways and will normalize the package name.
|
||||||
|
/// Each source defines what normalizing means.
|
||||||
|
Normalized,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A download status that represents if a [`Package`] has already been
|
/// A download status that represents if a [`Package`] has already been
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
[source.crates-io]
|
||||||
|
replace-with = "vendored-sources"
|
||||||
|
|
||||||
|
[source.vendored-sources]
|
||||||
|
directory = "./vendor"
|
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "cargo-list-test-fixture"
|
||||||
|
version = "0.0.0"
|
|
@ -0,0 +1 @@
|
||||||
|
{"files":{}}
|
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "aa"
|
||||||
|
version = "0.0.0"
|
|
@ -0,0 +1,35 @@
|
||||||
|
use cargo_test_support::compare::assert_ui;
|
||||||
|
use cargo_test_support::current_dir;
|
||||||
|
use cargo_test_support::file;
|
||||||
|
use cargo_test_support::prelude::*;
|
||||||
|
use cargo_test_support::Project;
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn case() {
|
||||||
|
cargo_test_support::registry::alt_init();
|
||||||
|
cargo_test_support::registry::Package::new("linked-hash-map", "0.5.4")
|
||||||
|
.feature("clippy", &[])
|
||||||
|
.feature("heapsize", &[])
|
||||||
|
.feature("heapsize_impl", &[])
|
||||||
|
.feature("nightly", &[])
|
||||||
|
.feature("serde", &[])
|
||||||
|
.feature("serde_impl", &[])
|
||||||
|
.feature("serde_test", &[])
|
||||||
|
.alternative(true)
|
||||||
|
.publish();
|
||||||
|
|
||||||
|
let project = Project::from_template(current_dir!().join("in"));
|
||||||
|
let project_root = project.root();
|
||||||
|
let cwd = &project_root;
|
||||||
|
|
||||||
|
snapbox::cmd::Command::cargo_ui()
|
||||||
|
.arg("add")
|
||||||
|
.arg_line("linked_hash_map --registry alternative")
|
||||||
|
.current_dir(cwd)
|
||||||
|
.assert()
|
||||||
|
.success()
|
||||||
|
.stdout_matches(file!["stdout.log"])
|
||||||
|
.stderr_matches(file!["stderr.log"]);
|
||||||
|
|
||||||
|
assert_ui().subset_matches(current_dir!().join("out"), &project_root);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "cargo-list-test-fixture"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
linked-hash-map = { version = "0.5.4", registry = "alternative" }
|
|
@ -0,0 +1,11 @@
|
||||||
|
Updating `alternative` index
|
||||||
|
warning: translating `linked_hash_map` to `linked-hash-map`
|
||||||
|
Adding linked-hash-map v0.5.4 to dependencies
|
||||||
|
Features:
|
||||||
|
- clippy
|
||||||
|
- heapsize
|
||||||
|
- heapsize_impl
|
||||||
|
- nightly
|
||||||
|
- serde
|
||||||
|
- serde_impl
|
||||||
|
- serde_test
|
|
@ -0,0 +1,5 @@
|
||||||
|
[source.crates-io]
|
||||||
|
replace-with = "vendored-sources"
|
||||||
|
|
||||||
|
[source.vendored-sources]
|
||||||
|
directory = "./vendor"
|
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "cargo-list-test-fixture"
|
||||||
|
version = "0.0.0"
|
|
@ -0,0 +1 @@
|
||||||
|
{"files":{}}
|
5
tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/in/vendor/aa/Cargo.toml
vendored
Normal file
5
tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/in/vendor/aa/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "aa"
|
||||||
|
version = "0.0.0"
|
0
tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/in/vendor/aa/src/lib.rs
vendored
Normal file
0
tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/in/vendor/aa/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use cargo_test_support::compare::assert_ui;
|
||||||
|
use cargo_test_support::current_dir;
|
||||||
|
use cargo_test_support::file;
|
||||||
|
use cargo_test_support::prelude::*;
|
||||||
|
use cargo_test_support::Project;
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn case() {
|
||||||
|
let project = Project::from_template(current_dir!().join("in"));
|
||||||
|
let project_root = project.root();
|
||||||
|
let cwd = &project_root;
|
||||||
|
|
||||||
|
snapbox::cmd::Command::cargo_ui()
|
||||||
|
.arg("add")
|
||||||
|
.arg_line("cbindgen")
|
||||||
|
.current_dir(cwd)
|
||||||
|
.assert()
|
||||||
|
.failure()
|
||||||
|
.stdout_matches(file!["stdout.log"])
|
||||||
|
.stderr_matches(file!["stderr.log"]);
|
||||||
|
|
||||||
|
assert_ui().subset_matches(current_dir!().join("out"), &project_root);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "cargo-list-test-fixture"
|
||||||
|
version = "0.0.0"
|
|
@ -0,0 +1 @@
|
||||||
|
error: the crate `cbindgen` could not be found in registry index.
|
|
@ -1,5 +1,7 @@
|
||||||
mod add_basic;
|
mod add_basic;
|
||||||
mod add_multiple;
|
mod add_multiple;
|
||||||
|
mod add_no_vendored_package_with_alter_registry;
|
||||||
|
mod add_no_vendored_package_with_vendor;
|
||||||
mod add_normalized_name_external;
|
mod add_normalized_name_external;
|
||||||
mod add_toolchain;
|
mod add_toolchain;
|
||||||
mod build;
|
mod build;
|
||||||
|
|
Loading…
Reference in New Issue