Skip to content

Commit

Permalink
Auto merge of #2978 - matklad:opt-level, r=alexcrichton
Browse files Browse the repository at this point in the history
Gracefully handle errors in a lockfile

Closes #2715

Question: why internal errors are hidden by default? I think if the unexpected has happened you most likely want to know some details. See also #2756.
  • Loading branch information
bors authored Aug 9, 2016
2 parents 2d85908 + afae9f3 commit c205132
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
13 changes: 8 additions & 5 deletions src/cargo/core/resolver/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct EncodableResolve {
pub type Metadata = BTreeMap<String, String>;

impl EncodableResolve {
pub fn to_resolve(self, ws: &Workspace) -> CargoResult<Resolve> {
pub fn into_resolve(self, ws: &Workspace) -> CargoResult<Resolve> {
let path_deps = build_path_deps(ws);
let default = try!(ws.current()).package_id().source_id();

Expand Down Expand Up @@ -48,14 +48,17 @@ impl EncodableResolve {
let mut register_pkg = |pkgid: &PackageId| {
let precise = pkgid.source_id().precise()
.map(|s| s.to_string());
assert!(tmp.insert(pkgid.clone(), precise).is_none(),
"a package was referenced twice in the lockfile");
if tmp.insert(pkgid.clone(), precise).is_some() {
return Err(internal(format!("package `{}` is specified twice in the lockfile",
pkgid.name())));
}
g.add(pkgid.clone(), &[]);
Ok(())
};

register_pkg(&root);
try!(register_pkg(&root));
for id in ids.iter() {
register_pkg(id);
try!(register_pkg(id));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl SourceId {
pub fn from_url(string: &str) -> CargoResult<SourceId> {
let mut parts = string.splitn(2, '+');
let kind = parts.next().unwrap();
let url = parts.next().unwrap();
let url = try!(parts.next().ok_or(human(format!("invalid source `{}`", string))));

match kind {
"git" => {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn load_pkg_lockfile(ws: &Workspace) -> CargoResult<Option<Resolve>> {
let table = toml::Value::Table(table);
let mut d = toml::Decoder::new(table);
let v: resolver::EncodableResolve = try!(Decodable::decode(&mut d));
Ok(Some(try!(v.to_resolve(ws))))
Ok(Some(try!(v.into_resolve(ws))))
}).chain_error(|| {
human(format!("failed to parse lock file at: {}", f.path().display()))
})
Expand Down
83 changes: 83 additions & 0 deletions tests/bad-config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,89 @@ Caused by:
"));
}

#[test]
fn duplicate_packages_in_cargo_lock() {
Package::new("foo", "0.1.0").publish();

let p = project("bar")
.file("Cargo.toml", r#"
[project]
name = "bar"
version = "0.0.1"
authors = []
[dependencies]
foo = "0.1.0"
"#)
.file("src/lib.rs", "")
.file("Cargo.lock", r#"
[root]
name = "bar"
version = "0.0.1"
dependencies = [
"foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "foo"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "foo"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
"#);
p.build();

assert_that(p.cargo("build").arg("--verbose"),
execs().with_status(101).with_stderr("\
[ERROR] failed to parse lock file at: [..]
Caused by:
package `foo` is specified twice in the lockfile
"));
}

#[test]
fn bad_source_in_cargo_lock() {
Package::new("foo", "0.1.0").publish();

let p = project("bar")
.file("Cargo.toml", r#"
[project]
name = "bar"
version = "0.0.1"
authors = []
[dependencies]
foo = "0.1.0"
"#)
.file("src/lib.rs", "")
.file("Cargo.lock", r#"
[root]
name = "bar"
version = "0.0.1"
dependencies = [
"foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "foo"
version = "0.1.0"
source = "You shall not parse"
"#);
p.build();

assert_that(p.cargo("build").arg("--verbose"),
execs().with_status(101).with_stderr("\
[ERROR] failed to parse lock file at: [..]
Caused by:
invalid source `You shall not parse` for the key `package.source`
"));
}

#[test]
fn bad_git_dependency() {
let foo = project("foo")
Expand Down

0 comments on commit c205132

Please sign in to comment.