for mut child in repo.submodules()? {
update_submodule(repo, &mut child, cargo_config)
- .map_err(Internal::new)
.chain_err(|| {
format!("failed to update submodule `{}`",
child.name().unwrap_or(""))
- })?;
+ })?;
}
Ok(())
}
// If the submodule hasn't been checked out yet, we need to
// clone it. If it has been checked out and the head is the same
- // as the submodule's head, then we can bail out and go to the
- // next submodule.
+ // as the submodule's head, then we can skip an update and keep
+ // recursing.
let head_and_repo = child.open().and_then(|repo| {
let target = repo.head()?.target();
Ok((target, repo))
let mut repo = match head_and_repo {
Ok((head, repo)) => {
if child.head_id() == head {
- return Ok(())
+ return update_submodules(&repo, cargo_config)
}
repo
}
use std::fs::{self, File};
use std::io::prelude::*;
+use std::net::TcpListener;
use std::path::Path;
+use std::thread;
use cargo::util::process;
use cargotest::sleep_ms;
Caused by:
failed to update submodule `src`
-To learn more, run the command again with --verbose.\n", path2url(git_project.root()));
+Caused by:
+ object not found - no match for id [..]
+", path2url(git_project.root()));
assert_that(p.cargo("build"),
execs().with_stderr(expected).with_status(101));
path2url(git_root),
)));
}
+
+#[test]
+fn failed_submodule_checkout() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [package]
+ name = "dep1"
+ version = "0.5.0"
+ authors = [""]
+ "#)
+ }).unwrap();
+
+ let git_project2 = git::new("dep2", |project| {
+ project.file("lib.rs", "")
+ }).unwrap();
+
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+ let addr = listener.local_addr().unwrap();
+
+ let t = thread::spawn(move || {
+ let a = listener.accept().unwrap();
+ drop(a);
+ let a = listener.accept().unwrap();
+ drop(a);
+ });
+
+ let repo = git2::Repository::open(&git_project2.root()).unwrap();
+ let url = format!("http://{}:{}/", addr.ip(), addr.port());
+ {
+ let mut s = repo.submodule(&url, Path::new("bar"), false).unwrap();
+ let subrepo = s.open().unwrap();
+ let mut cfg = subrepo.config().unwrap();
+ cfg.set_str("user.email", "foo@bar.com").unwrap();
+ cfg.set_str("user.name", "Foo Bar").unwrap();
+ git::commit(&subrepo);
+ s.add_finalize().unwrap();
+ }
+ git::commit(&repo);
+ drop((repo, url));
+
+ let repo = git2::Repository::open(&git_project.root()).unwrap();
+ let url = path2url(git_project2.root()).to_string();
+ git::add_submodule(&repo, &url, Path::new("src"));
+ git::commit(&repo);
+ drop(repo);
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+
+ [dependencies]
+ dep1 = {{ git = '{}' }}
+ "#, git_project.url()))
+ .file("src/lib.rs", "")
+ .build();
+
+ assert_that(project.cargo("build"),
+ execs().with_status(101)
+ .with_stderr_contains(" failed to update submodule `src`")
+ .with_stderr_contains(" failed to update submodule `bar`"));
+ assert_that(project.cargo("build"),
+ execs().with_status(101)
+ .with_stderr_contains(" failed to update submodule `src`")
+ .with_stderr_contains(" failed to update submodule `bar`"));
+
+ t.join().unwrap();
+}