Skip to content

Commit 115f345

Browse files
committed
Auto merge of rust-lang#11773 - weihanglo:beta-backport, r=ehuss
[beta-1.68] backport rust-lang#11756 Beta backports: - rust-lang#11756 In order to make CI pass, the following PR are also cherry-picked: - rust-lang#11771
2 parents 8d521c6 + 451b399 commit 115f345

File tree

4 files changed

+125
-14
lines changed

4 files changed

+125
-14
lines changed

src/cargo/core/source/source_id.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ impl SourceId {
8181
///
8282
/// The canonical url will be calculated, but the precise field will not
8383
fn new(kind: SourceKind, url: Url, name: Option<&str>) -> CargoResult<SourceId> {
84+
if kind == SourceKind::SparseRegistry {
85+
// Sparse URLs are different because they store the kind prefix (sparse+)
86+
// in the URL. This is because the prefix is necessary to differentiate
87+
// from regular registries (git-based). The sparse+ prefix is included
88+
// everywhere, including user-facing locations such as the `config.toml`
89+
// file that defines the registry, or whenever Cargo displays it to the user.
90+
assert!(url.as_str().starts_with("sparse+"));
91+
}
8492
let source_id = SourceId::wrap(SourceIdInner {
8593
kind,
8694
canonical_url: CanonicalUrl::new(&url)?,
@@ -152,7 +160,7 @@ impl SourceId {
152160
.with_precise(Some("locked".to_string())))
153161
}
154162
"sparse" => {
155-
let url = url.into_url()?;
163+
let url = string.into_url()?;
156164
Ok(SourceId::new(SourceKind::SparseRegistry, url, None)?
157165
.with_precise(Some("locked".to_string())))
158166
}
@@ -721,6 +729,7 @@ impl<'a> fmt::Display for SourceIdAsUrl<'a> {
721729
ref url,
722730
..
723731
} => {
732+
// Sparse registry URL already includes the `sparse+` prefix
724733
write!(f, "{url}")
725734
}
726735
SourceIdInner {
@@ -864,4 +873,14 @@ mod tests {
864873
assert_eq!(gen_hash(source_id), 17459999773908528552);
865874
assert_eq!(crate::util::hex::short_hash(&source_id), "6568fe2c2fab5bfe");
866875
}
876+
877+
#[test]
878+
fn serde_roundtrip() {
879+
let url = "sparse+https://my-crates.io/".into_url().unwrap();
880+
let source_id = SourceId::for_registry(&url).unwrap();
881+
let formatted = format!("{}", source_id.as_url());
882+
let deserialized = SourceId::from_url(&formatted).unwrap();
883+
assert_eq!(formatted, "sparse+https://my-crates.io/");
884+
assert_eq!(source_id, deserialized);
885+
}
867886
}

src/cargo/ops/cargo_install.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
307307
let compile = ops::compile_ws(&self.ws, &self.opts, &exec).with_context(|| {
308308
if let Some(td) = td_opt.take() {
309309
// preserve the temporary directory, so the user can inspect it
310-
td.into_path();
310+
drop(td.into_path());
311311
}
312312

313313
format!(

src/cargo/util/canonical_url.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::util::{errors::CargoResult, IntoUrl};
1+
use crate::util::errors::CargoResult;
22
use std::hash::{self, Hash};
33
use url::Url;
44

@@ -56,17 +56,6 @@ impl CanonicalUrl {
5656
url.path_segments_mut().unwrap().pop().push(&last);
5757
}
5858

59-
// Ignore the protocol specifier (if any).
60-
if url.scheme().starts_with("sparse+") {
61-
// NOTE: it is illegal to use set_scheme to change sparse+http(s) to http(s).
62-
url = url
63-
.to_string()
64-
.strip_prefix("sparse+")
65-
.expect("we just found that prefix")
66-
.into_url()
67-
.expect("a valid url without a protocol specifier should still be valid");
68-
}
69-
7059
Ok(CanonicalUrl(url))
7160
}
7261

tests/testsuite/install.rs

+103
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
33
use std::fs::{self, OpenOptions};
44
use std::io::prelude::*;
5+
use std::path::Path;
56

7+
use cargo_test_support::compare;
68
use cargo_test_support::cross_compile;
79
use cargo_test_support::git;
810
use cargo_test_support::registry::{self, registry_path, Package};
911
use cargo_test_support::{
1012
basic_manifest, cargo_process, no_such_file_err_msg, project, project_in, symlink_supported, t,
1113
};
14+
use cargo_util::ProcessError;
1215

1316
use cargo_test_support::install::{
1417
assert_has_installed_exe, assert_has_not_installed_exe, cargo_home,
@@ -2105,3 +2108,103 @@ fn no_auto_fix_note() {
21052108
.run();
21062109
assert_has_not_installed_exe(cargo_home(), "auto_fix");
21072110
}
2111+
2112+
#[cargo_test]
2113+
fn failed_install_retains_temp_directory() {
2114+
// Verifies that the temporary directory persists after a build failure.
2115+
Package::new("foo", "0.0.1")
2116+
.file("src/main.rs", "x")
2117+
.publish();
2118+
let err = cargo_process("install foo").exec_with_output().unwrap_err();
2119+
let err = err.downcast::<ProcessError>().unwrap();
2120+
let stderr = String::from_utf8(err.stderr.unwrap()).unwrap();
2121+
compare::match_contains(
2122+
"\
2123+
[UPDATING] `dummy-registry` index
2124+
[DOWNLOADING] crates ...
2125+
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
2126+
[INSTALLING] foo v0.0.1
2127+
[COMPILING] foo v0.0.1
2128+
",
2129+
&stderr,
2130+
None,
2131+
)
2132+
.unwrap();
2133+
compare::match_contains(
2134+
"error: failed to compile `foo v0.0.1`, intermediate artifacts can be found at `[..]`",
2135+
&stderr,
2136+
None,
2137+
)
2138+
.unwrap();
2139+
2140+
// Find the path in the output.
2141+
let start = stderr.find("found at `").unwrap() + 10;
2142+
let end = stderr[start..].find('\n').unwrap() - 1;
2143+
let path = Path::new(&stderr[start..(end + start)]);
2144+
assert!(path.exists());
2145+
assert!(path.join("release/deps").exists());
2146+
}
2147+
2148+
#[cargo_test]
2149+
fn sparse_install() {
2150+
// Checks for an issue where uninstalling something corrupted
2151+
// the SourceIds of sparse registries.
2152+
// See https://github.com/rust-lang/cargo/issues/11751
2153+
let _registry = registry::RegistryBuilder::new().http_index().build();
2154+
2155+
pkg("foo", "0.0.1");
2156+
pkg("bar", "0.0.1");
2157+
2158+
cargo_process("install foo --registry dummy-registry")
2159+
.with_stderr(
2160+
"\
2161+
[UPDATING] `dummy-registry` index
2162+
[DOWNLOADING] crates ...
2163+
[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
2164+
[INSTALLING] foo v0.0.1 (registry `dummy-registry`)
2165+
[UPDATING] `dummy-registry` index
2166+
[COMPILING] foo v0.0.1 (registry `dummy-registry`)
2167+
[FINISHED] release [optimized] target(s) in [..]
2168+
[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
2169+
[INSTALLED] package `foo v0.0.1 (registry `dummy-registry`)` (executable `foo[EXE]`)
2170+
[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
2171+
",
2172+
)
2173+
.run();
2174+
assert_has_installed_exe(cargo_home(), "foo");
2175+
let assert_v1 = |expected| {
2176+
let v1 = fs::read_to_string(paths::home().join(".cargo/.crates.toml")).unwrap();
2177+
compare::assert_match_exact(expected, &v1);
2178+
};
2179+
assert_v1(
2180+
r#"[v1]
2181+
"foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"]
2182+
"#,
2183+
);
2184+
cargo_process("install bar").run();
2185+
assert_has_installed_exe(cargo_home(), "bar");
2186+
assert_v1(
2187+
r#"[v1]
2188+
"bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = ["bar[EXE]"]
2189+
"foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"]
2190+
"#,
2191+
);
2192+
2193+
cargo_process("uninstall bar")
2194+
.with_stderr("[REMOVING] [CWD]/home/.cargo/bin/bar[EXE]")
2195+
.run();
2196+
assert_has_not_installed_exe(cargo_home(), "bar");
2197+
assert_v1(
2198+
r#"[v1]
2199+
"foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"]
2200+
"#,
2201+
);
2202+
cargo_process("uninstall foo")
2203+
.with_stderr("[REMOVING] [CWD]/home/.cargo/bin/foo[EXE]")
2204+
.run();
2205+
assert_has_not_installed_exe(cargo_home(), "foo");
2206+
assert_v1(
2207+
r#"[v1]
2208+
"#,
2209+
);
2210+
}

0 commit comments

Comments
 (0)