Skip to content

Commit 2de6c3e

Browse files
committed
Auto merge of #6871 - ehuss:offline-spurious-suggestion, r=alexcrichton
Add some help with updating the registry in offline mode. This includes the following: - Move offline tests to a dedicated file. - If an index has never been downloaded, and `-Z offline` is used, provide a suggestion to run without `-Z offline`. - ~~If an index needs to be updated, and the network appears to be down, suggest running with `-Z offline`.~~ (removed this) - The `offline_resolve_optional_fail` test is added to show that resolver errors are still possible (though hopefully rare!).
2 parents 2c335f7 + c6fad3a commit 2de6c3e

File tree

7 files changed

+567
-500
lines changed

7 files changed

+567
-500
lines changed

src/cargo/sources/registry/index.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,12 @@ impl<'cfg> RegistryIndex<'cfg> {
300300
let summaries = summaries
301301
.iter()
302302
.filter(|&(summary, yanked)| {
303+
// Note: This particular logic can cause problems with
304+
// optional dependencies when offline. If at least 1 version
305+
// of an optional dependency is downloaded, but that version
306+
// does not satisfy the requirements, then resolution will
307+
// fail. Unfortunately, whether or not something is optional
308+
// is not known here.
303309
(online || load.is_crate_downloaded(summary.package_id()))
304310
&& (!yanked || {
305311
log::debug!("{:?}", yanked_whitelist);

src/cargo/sources/registry/remote.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,18 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
176176

177177
fn update_index(&mut self) -> CargoResult<()> {
178178
if self.config.cli_unstable().offline {
179+
if self.repo()?.is_empty()? {
180+
// An empty repository is guaranteed to fail, since hitting
181+
// this path means we need at least one crate. This is an
182+
// attempt to provide a better error message other than "no
183+
// matching package named …".
184+
failure::bail!(
185+
"unable to fetch {} in offline mode\n\
186+
Try running without the offline flag, or try running \
187+
`cargo fetch` within your project directory before going offline.",
188+
self.source_id
189+
);
190+
}
179191
return Ok(());
180192
}
181193
if self.config.cli_unstable().no_index_update {

tests/testsuite/build.rs

Lines changed: 0 additions & 307 deletions
Original file line numberDiff line numberDiff line change
@@ -956,261 +956,6 @@ Did you mean `a`?",
956956
.run();
957957
}
958958

959-
#[test]
960-
fn cargo_compile_path_with_offline() {
961-
let p = project()
962-
.file(
963-
"Cargo.toml",
964-
r#"
965-
[package]
966-
name = "foo"
967-
version = "0.0.1"
968-
authors = []
969-
970-
[dependencies.bar]
971-
path = "bar"
972-
"#,
973-
)
974-
.file("src/lib.rs", "")
975-
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
976-
.file("bar/src/lib.rs", "")
977-
.build();
978-
979-
p.cargo("build -Zoffline")
980-
.masquerade_as_nightly_cargo()
981-
.run();
982-
}
983-
984-
#[test]
985-
fn cargo_compile_with_downloaded_dependency_with_offline() {
986-
Package::new("present_dep", "1.2.3")
987-
.file("Cargo.toml", &basic_manifest("present_dep", "1.2.3"))
988-
.file("src/lib.rs", "")
989-
.publish();
990-
991-
{
992-
// make package downloaded
993-
let p = project()
994-
.file(
995-
"Cargo.toml",
996-
r#"
997-
[project]
998-
name = "foo"
999-
version = "0.1.0"
1000-
1001-
[dependencies]
1002-
present_dep = "1.2.3"
1003-
"#,
1004-
)
1005-
.file("src/lib.rs", "")
1006-
.build();
1007-
p.cargo("build").run();
1008-
}
1009-
1010-
let p2 = project()
1011-
.at("bar")
1012-
.file(
1013-
"Cargo.toml",
1014-
r#"
1015-
[project]
1016-
name = "bar"
1017-
version = "0.1.0"
1018-
1019-
[dependencies]
1020-
present_dep = "1.2.3"
1021-
"#,
1022-
)
1023-
.file("src/lib.rs", "")
1024-
.build();
1025-
1026-
p2.cargo("build -Zoffline")
1027-
.masquerade_as_nightly_cargo()
1028-
.with_stderr(
1029-
"\
1030-
[COMPILING] present_dep v1.2.3
1031-
[COMPILING] bar v0.1.0 ([..])
1032-
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
1033-
)
1034-
.run();
1035-
}
1036-
1037-
#[test]
1038-
fn cargo_compile_offline_not_try_update() {
1039-
let p = project()
1040-
.at("bar")
1041-
.file(
1042-
"Cargo.toml",
1043-
r#"
1044-
[project]
1045-
name = "bar"
1046-
version = "0.1.0"
1047-
1048-
[dependencies]
1049-
not_cached_dep = "1.2.5"
1050-
"#,
1051-
)
1052-
.file("src/lib.rs", "")
1053-
.build();
1054-
1055-
p.cargo("build -Zoffline")
1056-
.masquerade_as_nightly_cargo()
1057-
.with_status(101)
1058-
.with_stderr(
1059-
"\
1060-
error: no matching package named `not_cached_dep` found
1061-
location searched: registry `[..]`
1062-
required by package `bar v0.1.0 ([..])`
1063-
As a reminder, you're using offline mode (-Z offline) \
1064-
which can sometimes cause surprising resolution failures, \
1065-
if this error is too confusing you may wish to retry \
1066-
without the offline flag.",
1067-
)
1068-
.run();
1069-
}
1070-
1071-
#[test]
1072-
fn compile_offline_without_maxvers_cached() {
1073-
Package::new("present_dep", "1.2.1").publish();
1074-
Package::new("present_dep", "1.2.2").publish();
1075-
1076-
Package::new("present_dep", "1.2.3")
1077-
.file("Cargo.toml", &basic_manifest("present_dep", "1.2.3"))
1078-
.file(
1079-
"src/lib.rs",
1080-
r#"pub fn get_version()->&'static str {"1.2.3"}"#,
1081-
)
1082-
.publish();
1083-
1084-
Package::new("present_dep", "1.2.5")
1085-
.file("Cargo.toml", &basic_manifest("present_dep", "1.2.5"))
1086-
.file("src/lib.rs", r#"pub fn get_version(){"1.2.5"}"#)
1087-
.publish();
1088-
1089-
{
1090-
// make package cached
1091-
let p = project()
1092-
.file(
1093-
"Cargo.toml",
1094-
r#"
1095-
[project]
1096-
name = "foo"
1097-
version = "0.1.0"
1098-
1099-
[dependencies]
1100-
present_dep = "=1.2.3"
1101-
"#,
1102-
)
1103-
.file("src/lib.rs", "")
1104-
.build();
1105-
p.cargo("build").run();
1106-
}
1107-
1108-
let p2 = project()
1109-
.file(
1110-
"Cargo.toml",
1111-
r#"
1112-
[project]
1113-
name = "foo"
1114-
version = "0.1.0"
1115-
1116-
[dependencies]
1117-
present_dep = "1.2"
1118-
"#,
1119-
)
1120-
.file(
1121-
"src/main.rs",
1122-
"\
1123-
extern crate present_dep;
1124-
fn main(){
1125-
println!(\"{}\", present_dep::get_version());
1126-
}",
1127-
)
1128-
.build();
1129-
1130-
p2.cargo("run -Zoffline")
1131-
.masquerade_as_nightly_cargo()
1132-
.with_stderr(
1133-
"\
1134-
[COMPILING] present_dep v1.2.3
1135-
[COMPILING] foo v0.1.0 ([CWD])
1136-
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1137-
Running `[..]`",
1138-
)
1139-
.with_stdout("1.2.3")
1140-
.run();
1141-
}
1142-
1143-
#[test]
1144-
fn offline_unused_target_dep() {
1145-
// -Z offline with a target dependency that is not used and not downloaded.
1146-
Package::new("unused_dep", "1.0.0").publish();
1147-
Package::new("used_dep", "1.0.0").publish();
1148-
let p = project()
1149-
.file(
1150-
"Cargo.toml",
1151-
r#"
1152-
[project]
1153-
name = "foo"
1154-
version = "0.1.0"
1155-
[dependencies]
1156-
used_dep = "1.0"
1157-
[target.'cfg(unused)'.dependencies]
1158-
unused_dep = "1.0"
1159-
"#,
1160-
)
1161-
.file("src/lib.rs", "")
1162-
.build();
1163-
// Do a build that downloads only what is necessary.
1164-
p.cargo("build")
1165-
.with_stderr_contains("[DOWNLOADED] used_dep [..]")
1166-
.with_stderr_does_not_contain("[DOWNLOADED] unused_dep [..]")
1167-
.run();
1168-
p.cargo("clean").run();
1169-
// Build offline, make sure it works.
1170-
p.cargo("build -Z offline")
1171-
.masquerade_as_nightly_cargo()
1172-
.run();
1173-
}
1174-
1175-
#[test]
1176-
fn offline_missing_optional() {
1177-
Package::new("opt_dep", "1.0.0").publish();
1178-
let p = project()
1179-
.file(
1180-
"Cargo.toml",
1181-
r#"
1182-
[project]
1183-
name = "foo"
1184-
version = "0.1.0"
1185-
[dependencies]
1186-
opt_dep = { version = "1.0", optional = true }
1187-
"#,
1188-
)
1189-
.file("src/lib.rs", "")
1190-
.build();
1191-
// Do a build that downloads only what is necessary.
1192-
p.cargo("build")
1193-
.with_stderr_does_not_contain("[DOWNLOADED] opt_dep [..]")
1194-
.run();
1195-
p.cargo("clean").run();
1196-
// Build offline, make sure it works.
1197-
p.cargo("build -Z offline")
1198-
.masquerade_as_nightly_cargo()
1199-
.run();
1200-
p.cargo("build -Z offline --features=opt_dep")
1201-
.masquerade_as_nightly_cargo()
1202-
.with_stderr(
1203-
"\
1204-
[ERROR] failed to download `opt_dep v1.0.0`
1205-
1206-
Caused by:
1207-
can't make HTTP request in the offline mode
1208-
",
1209-
)
1210-
.with_status(101)
1211-
.run();
1212-
}
1213-
1214959
#[test]
1215960
fn incompatible_dependencies() {
1216961
Package::new("bad", "0.1.0").publish();
@@ -1310,58 +1055,6 @@ failed to select a version for `bad` which could resolve this conflict",
13101055
.run();
13111056
}
13121057

1313-
#[test]
1314-
fn compile_offline_while_transitive_dep_not_cached() {
1315-
let baz = Package::new("baz", "1.0.0");
1316-
let baz_path = baz.archive_dst();
1317-
baz.publish();
1318-
1319-
let mut content = Vec::new();
1320-
1321-
let mut file = File::open(baz_path.clone()).ok().unwrap();
1322-
let _ok = file.read_to_end(&mut content).ok().unwrap();
1323-
drop(file);
1324-
drop(File::create(baz_path.clone()).ok().unwrap());
1325-
1326-
Package::new("bar", "0.1.0").dep("baz", "1.0.0").publish();
1327-
1328-
let p = project()
1329-
.file(
1330-
"Cargo.toml",
1331-
r#"
1332-
[project]
1333-
name = "foo"
1334-
version = "0.0.1"
1335-
1336-
[dependencies]
1337-
bar = "0.1.0"
1338-
"#,
1339-
)
1340-
.file("src/main.rs", "fn main(){}")
1341-
.build();
1342-
1343-
// simulate download bar, but fail to download baz
1344-
p.cargo("build")
1345-
.with_status(101)
1346-
.with_stderr_contains("[..]failed to verify the checksum of `baz[..]")
1347-
.run();
1348-
1349-
drop(File::create(baz_path).ok().unwrap().write_all(&content));
1350-
1351-
p.cargo("build -Zoffline")
1352-
.masquerade_as_nightly_cargo()
1353-
.with_status(101)
1354-
.with_stderr(
1355-
"\
1356-
[ERROR] failed to download `baz v1.0.0`
1357-
1358-
Caused by:
1359-
can't make HTTP request in the offline mode
1360-
",
1361-
)
1362-
.run();
1363-
}
1364-
13651058
#[test]
13661059
fn compile_path_dep_then_change_version() {
13671060
let p = project()

0 commit comments

Comments
 (0)