Skip to content

Commit 313ecb0

Browse files
committed
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](#10729 (comment)) 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: #10729 (comment) 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 ```
2 parents 7b7af30 + d35cb17 commit 313ecb0

File tree

28 files changed

+134
-10
lines changed

28 files changed

+134
-10
lines changed

crates/resolver-tests/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ pub fn resolve_with_config_raw(
111111
for summary in self.list.iter() {
112112
let matched = match kind {
113113
QueryKind::Exact => dep.matches(summary),
114-
QueryKind::Fuzzy => true,
114+
QueryKind::Alternatives => true,
115+
QueryKind::Normalized => true,
115116
};
116117
if matched {
117118
self.used.insert(summary.package_id());

src/cargo/core/resolver/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub(super) fn activation_error(
305305
// Maybe the user mistyped the name? Like `dep-thing` when `Dep_Thing`
306306
// was meant. So we try asking the registry for a `fuzzy` search for suggestions.
307307
let candidates = loop {
308-
match registry.query_vec(&new_dep, QueryKind::Fuzzy) {
308+
match registry.query_vec(&new_dep, QueryKind::Alternatives) {
309309
Poll::Ready(Ok(candidates)) => break candidates,
310310
Poll::Ready(Err(e)) => return to_resolve_err(e),
311311
Poll::Pending => match registry.block_until_ready() {

src/cargo/ops/cargo_add/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ fn get_latest_dependency(
588588
}
589589
MaybeWorkspace::Other(query) => {
590590
let possibilities = loop {
591-
match registry.query_vec(&query, QueryKind::Fuzzy) {
591+
match registry.query_vec(&query, QueryKind::Normalized) {
592592
std::task::Poll::Ready(res) => {
593593
break res?;
594594
}
@@ -711,7 +711,7 @@ fn select_package(
711711
MaybeWorkspace::Other(query) => {
712712
let possibilities = loop {
713713
// Exact to avoid returning all for path/git
714-
match registry.query_vec(&query, QueryKind::Exact) {
714+
match registry.query_vec(&query, QueryKind::Normalized) {
715715
std::task::Poll::Ready(res) => {
716716
break res?;
717717
}
@@ -938,7 +938,7 @@ fn populate_available_features(
938938
}
939939

940940
let possibilities = loop {
941-
match registry.query_vec(&query, QueryKind::Exact) {
941+
match registry.query_vec(&query, QueryKind::Normalized) {
942942
std::task::Poll::Ready(res) => {
943943
break res?;
944944
}

src/cargo/sources/directory.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ impl<'cfg> Source for DirectorySource<'cfg> {
108108
let packages = self.packages.values().map(|p| &p.0);
109109
let matches = packages.filter(|pkg| match kind {
110110
QueryKind::Exact => dep.matches(pkg.summary()),
111-
QueryKind::Fuzzy => true,
111+
QueryKind::Alternatives => true,
112+
QueryKind::Normalized => dep.matches(pkg.summary()),
112113
});
113114
for summary in matches.map(|pkg| pkg.summary().clone()) {
114115
f(IndexSummary::Candidate(summary));

src/cargo/sources/path.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,8 @@ impl<'cfg> Source for PathSource<'cfg> {
554554
for s in self.packages.iter().map(|p| p.summary()) {
555555
let matched = match kind {
556556
QueryKind::Exact => dep.matches(s),
557-
QueryKind::Fuzzy => true,
557+
QueryKind::Alternatives => true,
558+
QueryKind::Normalized => dep.matches(s),
558559
};
559560
if matched {
560561
f(IndexSummary::Candidate(s.clone()))

src/cargo/sources/registry/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,8 @@ impl<'cfg> Source for RegistrySource<'cfg> {
792792
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
793793
let matched = match kind {
794794
QueryKind::Exact => dep.matches(s.as_summary()),
795-
QueryKind::Fuzzy => true,
795+
QueryKind::Alternatives => true,
796+
QueryKind::Normalized => true,
796797
};
797798
if !matched {
798799
return;
@@ -831,7 +832,7 @@ impl<'cfg> Source for RegistrySource<'cfg> {
831832
return Poll::Ready(Ok(()));
832833
}
833834
let mut any_pending = false;
834-
if kind == QueryKind::Fuzzy {
835+
if kind == QueryKind::Alternatives || kind == QueryKind::Normalized {
835836
// Attempt to handle misspellings by searching for a chain of related
836837
// names to the original name. The resolver will later
837838
// reject any candidates that have the wrong name, and with this it'll

src/cargo/sources/source.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,10 @@ pub enum QueryKind {
179179
/// Path/Git sources may return all dependencies that are at that URI,
180180
/// whereas an `Registry` source may return dependencies that have the same
181181
/// canonicalization.
182-
Fuzzy,
182+
Alternatives,
183+
/// Match a denpendency in all ways and will normalize the package name.
184+
/// Each source defines what normalizing means.
185+
Normalized,
183186
}
184187

185188
/// A download status that represents if a [`Package`] has already been
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[source.crates-io]
2+
replace-with = "vendored-sources"
3+
4+
[source.vendored-sources]
5+
directory = "./vendor"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"

tests/testsuite/cargo_add/add_no_vendored_package_with_alter_registry/in/src/lib.rs

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"files":{}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "aa"
5+
version = "0.0.0"

tests/testsuite/cargo_add/add_no_vendored_package_with_alter_registry/in/vendor/aa/src/lib.rs

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use cargo_test_support::compare::assert_ui;
2+
use cargo_test_support::prelude::*;
3+
use cargo_test_support::Project;
4+
5+
use cargo_test_support::curr_dir;
6+
7+
#[cargo_test]
8+
fn case() {
9+
cargo_test_support::registry::alt_init();
10+
cargo_test_support::registry::Package::new("linked-hash-map", "0.5.4")
11+
.feature("clippy", &[])
12+
.feature("heapsize", &[])
13+
.feature("heapsize_impl", &[])
14+
.feature("nightly", &[])
15+
.feature("serde", &[])
16+
.feature("serde_impl", &[])
17+
.feature("serde_test", &[])
18+
.alternative(true)
19+
.publish();
20+
21+
let project = Project::from_template(curr_dir!().join("in"));
22+
let project_root = project.root();
23+
let cwd = &project_root;
24+
25+
snapbox::cmd::Command::cargo_ui()
26+
.arg("add")
27+
.arg_line("linked_hash_map --registry alternative")
28+
.current_dir(cwd)
29+
.assert()
30+
.success()
31+
.stdout_matches_path(curr_dir!().join("stdout.log"))
32+
.stderr_matches_path(curr_dir!().join("stderr.log"));
33+
34+
assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"
6+
7+
[dependencies]
8+
linked-hash-map = { version = "0.5.4", registry = "alternative" }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Updating `alternative` index
2+
warning: translating `linked_hash_map` to `linked-hash-map`
3+
Adding linked-hash-map v0.5.4 to dependencies.
4+
Features:
5+
- clippy
6+
- heapsize
7+
- heapsize_impl
8+
- nightly
9+
- serde
10+
- serde_impl
11+
- serde_test

tests/testsuite/cargo_add/add_no_vendored_package_with_alter_registry/stdout.log

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[source.crates-io]
2+
replace-with = "vendored-sources"
3+
4+
[source.vendored-sources]
5+
directory = "./vendor"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"

tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/in/src/lib.rs

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"files":{}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "aa"
5+
version = "0.0.0"

tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/in/vendor/aa/src/lib.rs

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use cargo_test_support::compare::assert_ui;
2+
use cargo_test_support::prelude::*;
3+
use cargo_test_support::Project;
4+
5+
use cargo_test_support::curr_dir;
6+
7+
#[cargo_test]
8+
fn case() {
9+
let project = Project::from_template(curr_dir!().join("in"));
10+
let project_root = project.root();
11+
let cwd = &project_root;
12+
13+
snapbox::cmd::Command::cargo_ui()
14+
.arg("add")
15+
.arg_line("cbindgen")
16+
.current_dir(cwd)
17+
.assert()
18+
.failure()
19+
.stdout_matches_path(curr_dir!().join("stdout.log"))
20+
.stderr_matches_path(curr_dir!().join("stderr.log"));
21+
22+
assert_ui().subset_matches(curr_dir!().join("out"), &project_root);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
[package]
4+
name = "cargo-list-test-fixture"
5+
version = "0.0.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
error: the crate `cbindgen` could not be found in registry index.

tests/testsuite/cargo_add/add_no_vendored_package_with_vendor/stdout.log

Whitespace-only changes.

tests/testsuite/cargo_add/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
mod add_basic;
22
mod add_multiple;
3+
mod add_no_vendored_package_with_alter_registry;
4+
mod add_no_vendored_package_with_vendor;
35
mod add_normalized_name_external;
46
mod add_toolchain;
57
mod build;

0 commit comments

Comments
 (0)