Allow suppressing failures with - prefix (#687)

If a command in a linewise recipe is prefixed with `-`, then the exit
status is ignored and execution continues.
This commit is contained in:
Will Speak 2020-10-03 21:54:19 +01:00 committed by GitHub
parent db6a9197c6
commit 9bd0720aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 2 deletions

View File

@ -31,4 +31,11 @@ impl<'src> Line<'src> {
_ => false, _ => false,
} }
} }
pub(crate) fn is_infallable(&self) -> bool {
match self.fragments.first() {
Some(Fragment::Text { token }) => token.lexeme().starts_with('-'),
_ => false,
}
}
} }

View File

@ -211,6 +211,10 @@ impl<'src, D> Recipe<'src, D> {
let mut evaluated = String::new(); let mut evaluated = String::new();
let mut continued = false; let mut continued = false;
let quiet_command = lines.peek().map(|line| line.is_quiet()).unwrap_or(false); let quiet_command = lines.peek().map(|line| line.is_quiet()).unwrap_or(false);
let infallable_command = lines
.peek()
.map(|line| line.is_infallable())
.unwrap_or(false);
loop { loop {
if lines.peek().is_none() { if lines.peek().is_none() {
break; break;
@ -226,7 +230,7 @@ impl<'src, D> Recipe<'src, D> {
} }
} }
let mut command = evaluated.as_str(); let mut command = evaluated.as_str();
if quiet_command { if quiet_command || infallable_command {
command = &command[1..]; command = &command[1..];
} }
@ -266,7 +270,7 @@ impl<'src, D> Recipe<'src, D> {
match InterruptHandler::guard(|| cmd.status()) { match InterruptHandler::guard(|| cmd.status()) {
Ok(exit_status) => Ok(exit_status) =>
if let Some(code) = exit_status.code() { if let Some(code) = exit_status.code() {
if code != 0 { if code != 0 && !infallable_command {
return Err(RuntimeError::Code { return Err(RuntimeError::Code {
recipe: self.name(), recipe: self.name(),
line_number: Some(line_number), line_number: Some(line_number),

View File

@ -1285,6 +1285,30 @@ test! {
status: EXIT_FAILURE, status: EXIT_FAILURE,
} }
test! {
name: infallable_command,
justfile: r#"
infallable:
-exit 101
"#,
stderr: "exit 101\n",
status: EXIT_SUCCESS,
}
test! {
name: infallable_with_failing,
justfile: r#"
infallable:
-exit 101
exit 202
"#,
stderr: r#"exit 101
exit 202
error: Recipe `infallable` failed on line 4 with exit code 202
"#,
status: 202,
}
test! { test! {
name: quiet_recipe, name: quiet_recipe,
justfile: r#" justfile: r#"