From 8668136f570fb11ff7b7a8c67f9f75f4a6bee177 Mon Sep 17 00:00:00 2001 From: motorailgun <28751910+motorailgun@users.noreply.github.com> Date: Mon, 10 Nov 2025 06:54:13 +0000 Subject: [PATCH 1/2] chore: add tests for github pull request's url as dependency --- tests/testsuite/bad_config.rs | 36 ++++++++++++++++++++++++ tests/testsuite/patch.rs | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index 8b8e469dc65..ab3c43eacc1 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -2259,6 +2259,42 @@ Caused by: .run(); } +#[cargo_test(public_network_test)] +fn github_pull_request_url() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.0" + edition = "2015" + authors = [] + + [dependencies.bar] + git = "https://github.com/rust-lang/does-not-exist/pull/123" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v") + .with_status(101) + .with_stderr_data(str![[r#" +[UPDATING] git repository `https://github.com/rust-lang/does-not-exist/pull/123` +... +[ERROR] failed to get `bar` as a dependency of package `foo v0.0.0 ([ROOT]/foo)` + +Caused by: + failed to load source for dependency `bar` + +Caused by: + Unable to update https://github.com/rust-lang/does-not-exist/pull/123 +... +"#]]) + .run(); +} + #[cargo_test] fn fragment_in_git_url() { let p = project() diff --git a/tests/testsuite/patch.rs b/tests/testsuite/patch.rs index 488a3ce5e24..45cc60a0e93 100644 --- a/tests/testsuite/patch.rs +++ b/tests/testsuite/patch.rs @@ -357,6 +357,58 @@ fn patch_to_git() { .run(); } +#[cargo_test(public_network_test)] +fn patch_to_git_pull_request() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + authors = [] + + [dependencies] + bar = "0.1" + + [patch.crates-io] + bar = { git = 'https://github.com/rust-lang/does-not-exist/pull/123' } + "#, + ) + .file( + "src/lib.rs", + "extern crate bar; pub fn foo() { bar::bar(); }", + ) + .build(); + + p.cargo("check -v") + .with_status(101) + .with_stderr_data(format!( + r#"[UPDATING] git repository `https://github.com/rust-lang/does-not-exist/pull/123` +... +[ERROR] failed to load source for dependency `bar` + +Caused by: + Unable to update https://github.com/rust-lang/does-not-exist/pull/123 + +Caused by: + failed to clone into: [ROOT]/home/.cargo/git/db/123-[HASH] + +Caused by: + network failure seems to have happened + if a proxy or similar is necessary `net.git-fetch-with-cli` may help here + https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli + +Caused by: +... +"# + )) + .run(); +} + #[cargo_test] fn unused() { Package::new("bar", "0.1.0").publish(); From ca2973ad6c9aea869ca7813633af387380fe98e2 Mon Sep 17 00:00:00 2001 From: motorailgun <28751910+motorailgun@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:35:18 +0000 Subject: [PATCH 2/2] feat: emit help messages for github pull request url in dependency --- src/cargo/sources/git/oxide.rs | 17 ++++++++++---- src/cargo/sources/git/utils.rs | 42 +++++++++++++++++++++++++++++----- tests/testsuite/bad_config.rs | 5 ++++ tests/testsuite/patch.rs | 5 ++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/cargo/sources/git/oxide.rs b/src/cargo/sources/git/oxide.rs index 37183ec97a3..333b83c1ca1 100644 --- a/src/cargo/sources/git/oxide.rs +++ b/src/cargo/sources/git/oxide.rs @@ -19,6 +19,7 @@ use tracing::debug; pub fn with_retry_and_progress( repo_path: &std::path::Path, gctx: &GlobalContext, + repo_remote_url: &str, cb: &( dyn Fn( &std::path::Path, @@ -54,7 +55,7 @@ pub fn with_retry_and_progress( *urls.borrow_mut() = Some(url.to_owned()); }, ); - amend_authentication_hints(res, urls.get_mut().take()) + amend_authentication_hints(res, repo_remote_url, urls.get_mut().take()) }); translate_progress_to_bar(&mut progress_bar, root, is_shallow)?; thread.join().expect("no panic in scoped thread") @@ -180,6 +181,7 @@ fn translate_progress_to_bar( fn amend_authentication_hints( res: Result<(), crate::sources::git::fetch::Error>, + remote_url: &str, last_url_for_authentication: Option, ) -> CargoResult<()> { let Err(err) = res else { return Ok(()) }; @@ -189,6 +191,7 @@ fn amend_authentication_hints( ) => Some(err), _ => None, }; + if let Some(e) = e { let auth_message = match e { gix::protocol::handshake::Error::Credentials(_) => { @@ -203,10 +206,14 @@ fn amend_authentication_hints( .into() } gix::protocol::handshake::Error::Transport(_) => { - let msg = concat!( - "network failure seems to have happened\n", - "if a proxy or similar is necessary `net.git-fetch-with-cli` may help here\n", - "https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli" + let msg = format!( + concat!( + "network failure seems to have happened\n", + "if a proxy or similar is necessary `net.git-fetch-with-cli` may help here\n", + "https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli", + "{}" + ), + super::utils::note_github_pull_request(remote_url).unwrap_or_default() ); return Err(anyhow::Error::from(err).context(msg)); } diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 0f58068b3f5..fa5438a9909 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -798,12 +798,14 @@ where | ErrorClass::FetchHead | ErrorClass::Ssh | ErrorClass::Http => { - let mut msg = "network failure seems to have happened\n".to_string(); - msg.push_str( - "if a proxy or similar is necessary `net.git-fetch-with-cli` may help here\n", - ); - msg.push_str( - "https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli", + let msg = format!( + concat!( + "network failure seems to have happened\n", + "if a proxy or similar is necessary `net.git-fetch-with-cli` may help here\n", + "https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli", + "{}" + ), + note_github_pull_request(url).unwrap_or_default() ); err = err.context(msg); } @@ -1142,6 +1144,7 @@ fn fetch_with_gitoxide( let res = oxide::with_retry_and_progress( git2_repo.path(), gctx, + remote_url, &|repo_path, should_interrupt, mut progress, @@ -1589,6 +1592,33 @@ fn is_github(url: &Url) -> bool { url.host_str() == Some("github.com") } +// Give some messages on GitHub PR URL given as is +pub(crate) fn note_github_pull_request(url: &str) -> Option { + if let Ok(url) = url.parse::() + && is_github(&url) + { + let path_segments = url + .path_segments() + .map(|p| p.into_iter().collect::>()) + .unwrap_or_default(); + if let [owner, repo, "pull", pr_number, ..] = path_segments[..] { + let repo_url = format!("https://github.com/{owner}/{repo}.git"); + let rev = format!("refs/pull/{pr_number}/head"); + return Some(format!( + concat!( + "\n\nnote: GitHub url {} is not a repository. \n", + "help: Replace the dependency with \n", + " `git = \"{}\" rev = \"{}\"` \n", + " to specify pull requests as dependencies' revision." + ), + url, repo_url, rev + )); + } + } + + None +} + /// Whether a `rev` looks like a commit hash (ASCII hex digits). fn looks_like_commit_hash(rev: &str) -> bool { rev.len() >= 7 && rev.chars().all(|ch| ch.is_ascii_hexdigit()) diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index ab3c43eacc1..ab254b5d3c8 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -2290,6 +2290,11 @@ Caused by: Caused by: Unable to update https://github.com/rust-lang/does-not-exist/pull/123 +... + [NOTE] GitHub url https://github.com/rust-lang/does-not-exist/pull/123 is not a repository. + [HELP] Replace the dependency with + `git = "https://github.com/rust-lang/does-not-exist.git" rev = "refs/pull/123/head"` + to specify pull requests as dependencies' revision. ... "#]]) .run(); diff --git a/tests/testsuite/patch.rs b/tests/testsuite/patch.rs index 45cc60a0e93..dc1b2083cca 100644 --- a/tests/testsuite/patch.rs +++ b/tests/testsuite/patch.rs @@ -402,6 +402,11 @@ Caused by: if a proxy or similar is necessary `net.git-fetch-with-cli` may help here https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli + [NOTE] GitHub url https://github.com/rust-lang/does-not-exist/pull/123 is not a repository. + [HELP] Replace the dependency with + `git = "https://github.com/rust-lang/does-not-exist.git" rev = "refs/pull/123/head"` + to specify pull requests as dependencies' revision. + Caused by: ... "#