Skip to content

Commit c205132

Browse files
authored
Auto merge of #2978 - matklad:opt-level, r=alexcrichton
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.
2 parents 2d85908 + afae9f3 commit c205132

File tree

4 files changed

+93
-7
lines changed

4 files changed

+93
-7
lines changed

src/cargo/core/resolver/encode.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub struct EncodableResolve {
2020
pub type Metadata = BTreeMap<String, String>;
2121

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

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

56-
register_pkg(&root);
59+
try!(register_pkg(&root));
5760
for id in ids.iter() {
58-
register_pkg(id);
61+
try!(register_pkg(id));
5962
}
6063
}
6164

src/cargo/core/source.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl SourceId {
131131
pub fn from_url(string: &str) -> CargoResult<SourceId> {
132132
let mut parts = string.splitn(2, '+');
133133
let kind = parts.next().unwrap();
134-
let url = parts.next().unwrap();
134+
let url = try!(parts.next().ok_or(human(format!("invalid source `{}`", string))));
135135

136136
match kind {
137137
"git" => {

src/cargo/ops/lockfile.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn load_pkg_lockfile(ws: &Workspace) -> CargoResult<Option<Resolve>> {
2626
let table = toml::Value::Table(table);
2727
let mut d = toml::Decoder::new(table);
2828
let v: resolver::EncodableResolve = try!(Decodable::decode(&mut d));
29-
Ok(Some(try!(v.to_resolve(ws))))
29+
Ok(Some(try!(v.into_resolve(ws))))
3030
}).chain_error(|| {
3131
human(format!("failed to parse lock file at: {}", f.path().display()))
3232
})

tests/bad-config.rs

+83
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,89 @@ Caused by:
236236
"));
237237
}
238238

239+
#[test]
240+
fn duplicate_packages_in_cargo_lock() {
241+
Package::new("foo", "0.1.0").publish();
242+
243+
let p = project("bar")
244+
.file("Cargo.toml", r#"
245+
[project]
246+
name = "bar"
247+
version = "0.0.1"
248+
authors = []
249+
250+
[dependencies]
251+
foo = "0.1.0"
252+
"#)
253+
.file("src/lib.rs", "")
254+
.file("Cargo.lock", r#"
255+
[root]
256+
name = "bar"
257+
version = "0.0.1"
258+
dependencies = [
259+
"foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
260+
]
261+
262+
[[package]]
263+
name = "foo"
264+
version = "0.1.0"
265+
source = "registry+https://github.com/rust-lang/crates.io-index"
266+
267+
[[package]]
268+
name = "foo"
269+
version = "0.1.0"
270+
source = "registry+https://github.com/rust-lang/crates.io-index"
271+
"#);
272+
p.build();
273+
274+
assert_that(p.cargo("build").arg("--verbose"),
275+
execs().with_status(101).with_stderr("\
276+
[ERROR] failed to parse lock file at: [..]
277+
278+
Caused by:
279+
package `foo` is specified twice in the lockfile
280+
"));
281+
}
282+
283+
#[test]
284+
fn bad_source_in_cargo_lock() {
285+
Package::new("foo", "0.1.0").publish();
286+
287+
let p = project("bar")
288+
.file("Cargo.toml", r#"
289+
[project]
290+
name = "bar"
291+
version = "0.0.1"
292+
authors = []
293+
294+
[dependencies]
295+
foo = "0.1.0"
296+
"#)
297+
.file("src/lib.rs", "")
298+
.file("Cargo.lock", r#"
299+
[root]
300+
name = "bar"
301+
version = "0.0.1"
302+
dependencies = [
303+
"foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
304+
]
305+
306+
[[package]]
307+
name = "foo"
308+
version = "0.1.0"
309+
source = "You shall not parse"
310+
"#);
311+
p.build();
312+
313+
assert_that(p.cargo("build").arg("--verbose"),
314+
execs().with_status(101).with_stderr("\
315+
[ERROR] failed to parse lock file at: [..]
316+
317+
Caused by:
318+
invalid source `You shall not parse` for the key `package.source`
319+
"));
320+
}
321+
239322
#[test]
240323
fn bad_git_dependency() {
241324
let foo = project("foo")

0 commit comments

Comments
 (0)