From 4a0c8834e57f6e8fbad677f95d7563096e647ed9 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Tue, 28 Feb 2023 16:46:45 -0600 Subject: [PATCH] Improve error for missing crate in --offline mode for sparse index This changes sparse registries to instead return not found when a non-cached crate is requested in offline mode. The resolver can then suggest removing the --offline flag if resolution fails. --- src/cargo/sources/registry/http_remote.rs | 7 +++++ tests/testsuite/generate_lockfile.rs | 8 ++++- tests/testsuite/offline.rs | 38 ++++++++++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/cargo/sources/registry/http_remote.rs b/src/cargo/sources/registry/http_remote.rs index c3bcadf60bf3..79620f0ca941 100644 --- a/src/cargo/sources/registry/http_remote.rs +++ b/src/cargo/sources/registry/http_remote.rs @@ -438,6 +438,13 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> { return Poll::Ready(Ok(LoadResponse::NotFound)); } + if self.config.offline() || self.config.cli_unstable().no_index_update { + // Return NotFound in offline mode when the file doesn't exist in the cache. + // If this results in resolution failure, the resolver will suggest + // removing the --offline flag. + return Poll::Ready(Ok(LoadResponse::NotFound)); + } + if let Some(result) = self.downloads.results.remove(path) { let result = result.with_context(|| format!("download of {} failed", path.display()))?; diff --git a/tests/testsuite/generate_lockfile.rs b/tests/testsuite/generate_lockfile.rs index 74f6e78cc9a4..2b55ee210d4c 100644 --- a/tests/testsuite/generate_lockfile.rs +++ b/tests/testsuite/generate_lockfile.rs @@ -1,6 +1,6 @@ //! Tests for the `cargo generate-lockfile` command. -use cargo_test_support::registry::Package; +use cargo_test_support::registry::{Package, RegistryBuilder}; use cargo_test_support::{basic_manifest, paths, project, ProjectBuilder}; use std::fs; @@ -56,6 +56,12 @@ fn adding_and_removing_packages() { assert_eq!(lock1, lock4); } +#[cargo_test] +fn no_index_update_sparse() { + let _registry = RegistryBuilder::new().http_index().build(); + no_index_update(); +} + #[cargo_test] fn no_index_update() { Package::new("serde", "1.0.0").publish(); diff --git a/tests/testsuite/offline.rs b/tests/testsuite/offline.rs index cd4bc10d2b5e..533add9624cc 100644 --- a/tests/testsuite/offline.rs +++ b/tests/testsuite/offline.rs @@ -1,6 +1,9 @@ //! Tests for --offline flag. -use cargo_test_support::{basic_manifest, git, main_file, path2url, project, registry::Package}; +use cargo_test_support::{ + basic_manifest, git, main_file, path2url, project, + registry::{Package, RegistryBuilder}, +}; use std::fs; #[cargo_test] @@ -362,6 +365,39 @@ retry without the offline flag.", .run(); } +#[cargo_test] +fn update_offline_not_cached_sparse() { + let _registry = RegistryBuilder::new().http_index().build(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "*" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("update --offline") + .with_status(101) + .with_stderr( + "\ +[ERROR] no matching package named `bar` found +location searched: registry `[..]` +required by package `foo v0.0.1 ([..]/foo)` +As a reminder, you're using offline mode (--offline) which can sometimes cause \ +surprising resolution failures, if this error is too confusing you may wish to \ +retry without the offline flag.", + ) + .run(); +} + #[cargo_test] fn cargo_compile_offline_with_cached_git_dep() { let git_project = git::new("dep1", |project| {