summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCole Faust <colefaust@google.com>2024-06-07 19:00:11 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-06-07 19:00:11 +0000
commitfa0d805aaf457c90939cae88777690f2680cdf49 (patch)
tree48a17ce685ad311b2f67dccb6afa2514e24a09b5
parent8b94724c07052c00a66ba542c753f7898f82e466 (diff)
parenta276e3ea530a1d5c35db481c400058f888ed3709 (diff)
downloadn2-main.tar.gz
Merge "Assert output files exist" into mainmain
-rw-r--r--src/work.rs29
-rw-r--r--tests/e2e/basic.rs16
-rw-r--r--tests/e2e/missing.rs28
3 files changed, 43 insertions, 30 deletions
diff --git a/src/work.rs b/src/work.rs
index 0e98c66..118bac7 100644
--- a/src/work.rs
+++ b/src/work.rs
@@ -527,18 +527,31 @@ impl<'a> Work<'a> {
}
}
- let input_was_missing = self.graph.builds[id]
+ // Check for missing input files, which should not be possible
+ // because they would be requested to be built previously, and if their
+ // build failed, the following missing output file check would've
+ // failed.
+ let missing_input_file = self.graph.builds[id]
.dirtying_ins()
.iter()
- .any(|file| self.file_state.get(file.as_ref()).unwrap() == MTime::Missing);
+ .find(|file| self.file_state.get(file.as_ref()).unwrap() == MTime::Missing);
+ if let Some(missing) = missing_input_file {
+ anyhow::bail!(
+ "{}: input file missing: {}",
+ self.graph.builds[id].location,
+ missing.name
+ );
+ }
// Update any cached state of the output files to reflect their new state.
- let output_was_missing = self.stat_all_outputs(id)?.is_some();
-
- if input_was_missing || output_was_missing {
- // If a file is missing, don't record the build in in the db.
- // It will be considered dirty next time anyway due to the missing file.
- return Ok(());
+ // Also error out if any output files were not created by the command.
+ let missing_output_file = self.stat_all_outputs(id)?;
+ if let Some(missing) = missing_output_file {
+ anyhow::bail!(
+ "{}: output file missing after successful execution: {}",
+ self.graph.builds[id].location,
+ missing.name
+ );
}
let build = &self.graph.builds[id];
diff --git a/tests/e2e/basic.rs b/tests/e2e/basic.rs
index 3bca1b3..d656738 100644
--- a/tests/e2e/basic.rs
+++ b/tests/e2e/basic.rs
@@ -291,20 +291,20 @@ rule touch_in
Ok(())
}
+// cfg(unix) because I don't have a windows computer to test it on, but it's
+// really a windows-focused test
+#[cfg(unix)]
#[test]
fn showincludes() -> anyhow::Result<()> {
let space = TestSpace::new()?;
space.write(
"build.ninja",
- &[
- ECHO_RULE,
- "
-build out: echo
- text = Note: including file: foo
+ "
+rule myrule
+ command = touch out && echo Note: including file: foo
+build out: myrule
deps = msvc
",
- ]
- .join("\n"),
)?;
space.write("foo", "")?;
@@ -332,7 +332,7 @@ var = 123
rule custom
command = $cmd $var
build out: custom
- cmd = echo $var hello
+ cmd = touch out && echo $var hello
",
]
.join("\n"),
diff --git a/tests/e2e/missing.rs b/tests/e2e/missing.rs
index 1b78d36..9ad7f91 100644
--- a/tests/e2e/missing.rs
+++ b/tests/e2e/missing.rs
@@ -16,26 +16,26 @@ fn missing_input() -> anyhow::Result<()> {
Ok(())
}
+#[cfg(unix)]
#[test]
-fn missing_generated() -> anyhow::Result<()> {
+fn missing_output_file_gives_error() -> anyhow::Result<()> {
+ use anyhow::bail;
+
let space = TestSpace::new()?;
space.write(
"build.ninja",
- &[
- TOUCH_RULE,
- ECHO_RULE,
- "build mid: echo", // never writes output
- "build out: touch mid", // uses never-written output
- "",
- ]
- .join("\n"),
+ "
+rule myrule
+ command = touch out2
+build out: myrule
+",
)?;
- // https://github.com/evmar/n2/issues/69
-
- let out = space.run_expect(&mut n2_command(vec!["out"]))?;
- assert_output_contains(&out, "echo mid");
- assert_output_contains(&out, "touch out");
+ let out = space.run(&mut n2_command(vec!["out"]))?;
+ if out.status.success() {
+ bail!("expected error, got success");
+ }
+ assert_output_contains(&out, "output file missing after successful execution: out");
Ok(())
}