diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index bc80097b705..1f0b7816379 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -2144,6 +2144,8 @@ fn to_dependency_source_id( .unwrap_or(GitReference::DefaultBranch); let loc = git.into_url()?; + bail_if_github_pull_request(&name_in_toml, &loc)?; + if let Some(fragment) = loc.fragment() { let msg = format!( "URL fragment `#{fragment}` in git URL is ignored for dependency ({name_in_toml}). \ @@ -2182,6 +2184,26 @@ fn to_dependency_source_id( } } +/// Checks if the URL is a GitHub pull request URL. +/// +/// If the URL is a GitHub pull request URL, an error is returned with a message that explains +/// how to specify a specific git revision. +fn bail_if_github_pull_request(name_in_toml: &str, url: &Url) -> CargoResult<()> { + if url.host_str() != Some("github.com") { + return Ok(()); + } + let path_components = url.path().split('/').collect::>(); + if let ["", owner, repo, "pull", pr_number, ..] = path_components[..] { + bail!( + "dependency ({name_in_toml}) specifies a GitHub pull request link. \ + If you were trying to specify a specific github PR, replace the URL with the git \ + URL (e.g. `git = \"https://github.com/{owner}/{repo}.git\"`) \ + and add `rev = \"refs/pull/{pr_number}/head\"` in the dependency declaration.", + ); + } + Ok(()) +} + pub(crate) fn lookup_path_base<'a>( base: &PathBaseName, gctx: &GlobalContext, diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index 0fb00f8e8fa..5759e826ada 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -2151,6 +2151,37 @@ Caused by: .run(); } +#[cargo_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/foo/bar/pull/123" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` + +Caused by: + dependency (bar) specifies a GitHub pull request link. If you were trying to specify a specific github PR, replace the URL with the git URL (e.g. `git = "https://github.com/foo/bar.git"`) and add `rev = "refs/pull/123/head"` in the dependency declaration. + +"#]]) + .run(); +} + #[cargo_test] fn fragment_in_git_url() { let p = project()