diff options
author | Cole Faust <colefaust@google.com> | 2024-06-07 19:00:11 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-06-07 19:00:11 +0000 |
commit | fa0d805aaf457c90939cae88777690f2680cdf49 (patch) | |
tree | 48a17ce685ad311b2f67dccb6afa2514e24a09b5 | |
parent | 8b94724c07052c00a66ba542c753f7898f82e466 (diff) | |
parent | a276e3ea530a1d5c35db481c400058f888ed3709 (diff) | |
download | n2-main.tar.gz |
Merge "Assert output files exist" into mainmain
-rw-r--r-- | src/work.rs | 29 | ||||
-rw-r--r-- | tests/e2e/basic.rs | 16 | ||||
-rw-r--r-- | tests/e2e/missing.rs | 28 |
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(()) } |