Skip to content

Commit 5cb6995

Browse files
committed
Add simple tests, cleanup
Tests for existence for dep-info output in simple compilation cases. Deletes the dep-info file if it fails (for example, if it can't find one of the dep-info inputs).
1 parent d79249b commit 5cb6995

File tree

2 files changed

+107
-11
lines changed

2 files changed

+107
-11
lines changed

src/cargo/ops/cargo_rustc/output_depinfo.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashSet;
2-
use std::io::{Write, BufWriter};
3-
use std::fs::File;
2+
use std::io::{Write, BufWriter, ErrorKind};
3+
use std::fs::{self, File};
44
use std::path::{Path, PathBuf};
55

66
use ops::{Context, Unit};
@@ -22,17 +22,20 @@ fn render_filename<P: AsRef<Path>>(path: P, basedir: Option<&str>) -> CargoResul
2222
fn add_deps_for_unit<'a, 'b>(deps: &mut HashSet<PathBuf>, context: &mut Context<'a, 'b>,
2323
unit: &Unit<'a>, visited: &mut HashSet<Unit<'a>>) -> CargoResult<()>
2424
{
25-
if visited.contains(unit) {
25+
if !visited.insert(unit.clone()) {
2626
return Ok(());
2727
}
28-
visited.insert(unit.clone());
2928

3029
// Add dependencies from rustc dep-info output (stored in fingerprint directory)
3130
let dep_info_loc = fingerprint::dep_info_loc(context, unit);
3231
if let Some(paths) = fingerprint::parse_dep_info(&dep_info_loc)? {
3332
for path in paths {
3433
deps.insert(path);
3534
}
35+
} else {
36+
debug!("can't find dep_info for {:?} {:?}",
37+
unit.pkg.package_id(), unit.profile);
38+
return Err(internal("dep_info missing"));
3639
}
3740

3841
// Add rerun-if-changed dependencies
@@ -56,18 +59,32 @@ fn add_deps_for_unit<'a, 'b>(deps: &mut HashSet<PathBuf>, context: &mut Context<
5659
pub fn output_depinfo<'a, 'b>(context: &mut Context<'a, 'b>, unit: &Unit<'a>) -> CargoResult<()> {
5760
let mut deps = HashSet::new();
5861
let mut visited = HashSet::new();
59-
add_deps_for_unit(&mut deps, context, unit, &mut visited)?;
62+
let success = add_deps_for_unit(&mut deps, context, unit, &mut visited).is_ok();
6063
let basedir = None; // TODO
6164
for (_filename, link_dst, _linkable) in context.target_filenames(unit)? {
6265
if let Some(link_dst) = link_dst {
6366
let output_path = link_dst.with_extension("d");
64-
let target_fn = render_filename(link_dst, basedir)?;
65-
let mut outfile = BufWriter::new(File::create(output_path)?);
66-
write!(outfile, "{}:", target_fn)?;
67-
for dep in &deps {
68-
write!(outfile, " {}", render_filename(dep, basedir)?)?;
67+
if success {
68+
let mut outfile = BufWriter::new(File::create(output_path)?);
69+
let target_fn = render_filename(link_dst, basedir)?;
70+
write!(outfile, "{}:", target_fn)?;
71+
for dep in &deps {
72+
write!(outfile, " {}", render_filename(dep, basedir)?)?;
73+
}
74+
writeln!(outfile, "")?;
75+
} else {
76+
// dep-info generation failed, so delete output file. This will usually
77+
// cause the build system to always rerun the build rule, which is correct
78+
// if inefficient.
79+
match fs::remove_file(output_path) {
80+
Err(err) => {
81+
if err.kind() != ErrorKind::NotFound {
82+
return Err(err.into());
83+
}
84+
}
85+
_ => ()
86+
}
6987
}
70-
writeln!(outfile, "")?;
7188
}
7289
}
7390
Ok(())

tests/dep-info.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
extern crate cargotest;
2+
extern crate hamcrest;
3+
4+
use cargotest::support::{basic_bin_manifest, main_file, execs, project};
5+
use hamcrest::{assert_that, existing_file};
6+
7+
#[test]
8+
fn build_dep_info() {
9+
let p = project("foo")
10+
.file("Cargo.toml", &basic_bin_manifest("foo"))
11+
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
12+
13+
assert_that(p.cargo_process("build"), execs().with_status(0));
14+
15+
let depinfo_bin_path = &p.bin("foo").with_extension("d");
16+
17+
assert_that(depinfo_bin_path, existing_file());
18+
}
19+
20+
#[test]
21+
fn build_dep_info_lib() {
22+
let p = project("foo")
23+
.file("Cargo.toml", r#"
24+
[package]
25+
name = "foo"
26+
version = "0.0.1"
27+
authors = []
28+
29+
[[example]]
30+
name = "ex"
31+
crate-type = ["lib"]
32+
"#)
33+
.file("src/lib.rs", "")
34+
.file("examples/ex.rs", "");
35+
36+
assert_that(p.cargo_process("build").arg("--example=ex"), execs().with_status(0));
37+
assert_that(&p.example_lib("ex", "lib").with_extension("d"), existing_file());
38+
}
39+
40+
41+
#[test]
42+
fn build_dep_info_rlib() {
43+
let p = project("foo")
44+
.file("Cargo.toml", r#"
45+
[package]
46+
name = "foo"
47+
version = "0.0.1"
48+
authors = []
49+
50+
[[example]]
51+
name = "ex"
52+
crate-type = ["rlib"]
53+
"#)
54+
.file("src/lib.rs", "")
55+
.file("examples/ex.rs", "");
56+
57+
assert_that(p.cargo_process("build").arg("--example=ex"), execs().with_status(0));
58+
assert_that(&p.example_lib("ex", "rlib").with_extension("d"), existing_file());
59+
}
60+
61+
#[test]
62+
fn build_dep_info_dylib() {
63+
let p = project("foo")
64+
.file("Cargo.toml", r#"
65+
[package]
66+
name = "foo"
67+
version = "0.0.1"
68+
authors = []
69+
70+
[[example]]
71+
name = "ex"
72+
crate-type = ["dylib"]
73+
"#)
74+
.file("src/lib.rs", "")
75+
.file("examples/ex.rs", "");
76+
77+
assert_that(p.cargo_process("build").arg("--example=ex"), execs().with_status(0));
78+
assert_that(&p.example_lib("ex", "dylib").with_extension("d"), existing_file());
79+
}

0 commit comments

Comments
 (0)