mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Auto merge of #8166 - kornelski:net-cli, r=alexcrichton
Hint git-fetch-with-cli on git errors Our team has struggled with making Cargo git dependencies work in CI, until learning about this setting. Cargo doesn't have a dedicated system for error hints like `rustc`, so I've stuffed the hint into the error message.
This commit is contained in:
commit
893db8c637
@ -4,7 +4,7 @@ use crate::util::paths;
|
||||
use crate::util::process_builder::process;
|
||||
use crate::util::{network, Config, IntoUrl, Progress};
|
||||
use curl::easy::{Easy, List};
|
||||
use git2::{self, ObjectType};
|
||||
use git2::{self, ErrorClass, ObjectType};
|
||||
use log::{debug, info};
|
||||
use serde::ser;
|
||||
use serde::Serialize;
|
||||
@ -97,10 +97,43 @@ impl GitRemote {
|
||||
reference: &GitReference,
|
||||
cargo_config: &Config,
|
||||
) -> CargoResult<(GitDatabase, GitRevision)> {
|
||||
let format_error = |e: anyhow::Error, operation| {
|
||||
let may_be_libgit_fault = e
|
||||
.chain()
|
||||
.filter_map(|e| e.downcast_ref::<git2::Error>())
|
||||
.any(|e| match e.class() {
|
||||
ErrorClass::Net
|
||||
| ErrorClass::Ssl
|
||||
| ErrorClass::Submodule
|
||||
| ErrorClass::FetchHead
|
||||
| ErrorClass::Ssh
|
||||
| ErrorClass::Callback
|
||||
| ErrorClass::Http => true,
|
||||
_ => false,
|
||||
});
|
||||
let uses_cli = cargo_config
|
||||
.net_config()
|
||||
.ok()
|
||||
.and_then(|config| config.git_fetch_with_cli)
|
||||
.unwrap_or(false);
|
||||
let msg = if !uses_cli && may_be_libgit_fault {
|
||||
format!(
|
||||
r"failed to {} into: {}
|
||||
If your environment requires git authentication or proxying, try enabling `git-fetch-with-cli`
|
||||
https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli",
|
||||
operation,
|
||||
into.display()
|
||||
)
|
||||
} else {
|
||||
format!("failed to {} into: {}", operation, into.display())
|
||||
};
|
||||
e.context(msg)
|
||||
};
|
||||
|
||||
let mut repo_and_rev = None;
|
||||
if let Ok(mut repo) = git2::Repository::open(into) {
|
||||
self.fetch_into(&mut repo, cargo_config)
|
||||
.chain_err(|| format!("failed to fetch into {}", into.display()))?;
|
||||
.map_err(|e| format_error(e, "fetch"))?;
|
||||
if let Ok(rev) = reference.resolve(&repo) {
|
||||
repo_and_rev = Some((repo, rev));
|
||||
}
|
||||
@ -110,7 +143,7 @@ impl GitRemote {
|
||||
None => {
|
||||
let repo = self
|
||||
.clone_into(into, cargo_config)
|
||||
.chain_err(|| format!("failed to clone into: {}", into.display()))?;
|
||||
.map_err(|e| format_error(e, "clone"))?;
|
||||
let rev = reference.resolve(&repo)?;
|
||||
(repo, rev)
|
||||
}
|
||||
|
@ -265,3 +265,85 @@ Caused by:
|
||||
.run();
|
||||
t.join().ok().unwrap();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn net_err_suggests_fetch_with_cli() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.0"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
foo = { git = "ssh://needs-proxy.invalid/git" }
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("build -v")
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] git repository `ssh://needs-proxy.invalid/git`
|
||||
warning: spurious network error[..]
|
||||
warning: spurious network error[..]
|
||||
[ERROR] failed to get `foo` as a dependency of package `foo v0.0.0 [..]`
|
||||
|
||||
Caused by:
|
||||
failed to load source for dependency `foo`
|
||||
|
||||
Caused by:
|
||||
Unable to update ssh://needs-proxy.invalid/git
|
||||
|
||||
Caused by:
|
||||
failed to clone into: [..]
|
||||
If your environment requires git authentication or proxying, try enabling `git-fetch-with-cli`
|
||||
https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli
|
||||
|
||||
Caused by:
|
||||
failed to resolve address for needs-proxy.invalid[..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
p.change_file(
|
||||
".cargo/config",
|
||||
"
|
||||
[net]
|
||||
git-fetch-with-cli = true
|
||||
",
|
||||
);
|
||||
|
||||
p.cargo("build -v")
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] git repository `ssh://needs-proxy.invalid/git`
|
||||
[RUNNING] `git fetch[..]
|
||||
[ERROR] failed to get `foo` as a dependency of package `foo v0.0.0 [..]`
|
||||
|
||||
Caused by:
|
||||
failed to load source for dependency `foo`
|
||||
|
||||
Caused by:
|
||||
Unable to update ssh://needs-proxy.invalid/git
|
||||
|
||||
Caused by:
|
||||
failed to fetch into: [..]
|
||||
|
||||
Caused by:
|
||||
[..]process didn't exit successfully[..]
|
||||
--- stderr
|
||||
ssh: Could not resolve hostname[..]
|
||||
fatal: [..]
|
||||
|
||||
Please make sure you have the correct access rights
|
||||
and the repository exists.
|
||||
[..]",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user