Skip to content

Commit

Permalink
Auto merge of #8166 - kornelski:net-cli, r=alexcrichton
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed May 4, 2020
2 parents c7eddc1 + 4fd4835 commit 893db8c
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 3 deletions.
39 changes: 36 additions & 3 deletions src/cargo/sources/git/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
}
Expand All @@ -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)
}
Expand Down
82 changes: 82 additions & 0 deletions tests/testsuite/git_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

0 comments on commit 893db8c

Please sign in to comment.