Repository: casey/just
Pull request #1063 (2022-01-03 00:44:46)

Allow using `-` and `@` in any combination


Patch:
diff --git a/src/line.rs b/src/line.rs
index 718e4afd..878cb8cd 100644
--- a/src/line.rs
+++ b/src/line.rs
@@ -28,14 +28,18 @@ impl<'src> Line<'src> {
 
   pub(crate) fn is_quiet(&self) -> bool {
     match self.fragments.first() {
-      Some(Fragment::Text { token }) => token.lexeme().starts_with('@'),
+      Some(Fragment::Text { token }) => {
+        token.lexeme().starts_with('@') || token.lexeme().starts_with("-@")
+      }
       _ => false,
     }
   }
 
-  pub(crate) fn is_infallable(&self) -> bool {
+  pub(crate) fn is_infallible(&self) -> bool {
     match self.fragments.first() {
-      Some(Fragment::Text { token }) => token.lexeme().starts_with('-'),
+      Some(Fragment::Text { token }) => {
+        token.lexeme().starts_with('-') || token.lexeme().starts_with("@-")
+      }
       _ => false,
     }
   }
diff --git a/src/recipe.rs b/src/recipe.rs
index 97977513..6a206e1f 100644
--- a/src/recipe.rs
+++ b/src/recipe.rs
@@ -213,7 +213,7 @@ impl<'src, D> Recipe<'src, D> {
         let mut evaluated = String::new();
         let mut continued = false;
         let quiet_command = lines.peek().map_or(false, |line| line.is_quiet());
-        let infallable_command = lines.peek().map_or(false, |line| line.is_infallable());
+        let infallible_command = lines.peek().map_or(false, |line| line.is_infallible());
         loop {
           if lines.peek().is_none() {
             break;
@@ -229,7 +229,12 @@ impl<'src, D> Recipe<'src, D> {
           }
         }
         let mut command = evaluated.as_str();
-        if quiet_command || infallable_command {
+
+        if quiet_command {
+          command = &command[1..];
+        }
+
+        if infallible_command {
           command = &command[1..];
         }
 
@@ -274,7 +279,7 @@ impl<'src, D> Recipe<'src, D> {
         match InterruptHandler::guard(|| cmd.status()) {
           Ok(exit_status) => {
             if let Some(code) = exit_status.code() {
-              if code != 0 && !infallable_command {
+              if code != 0 && !infallible_command {
                 return Err(Error::Code {
                   recipe: self.name(),
                   line_number: Some(line_number),


Test patch:
diff --git a/tests/lib.rs b/tests/lib.rs
index 87b75955..72e1e49f 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
@@ -24,6 +24,7 @@ mod init;
 mod interrupts;
 mod invocation_directory;
 mod json;
+mod line_prefixes;
 mod misc;
 mod positional_arguments;
 mod quiet;
diff --git a/tests/line_prefixes.rs b/tests/line_prefixes.rs
new file mode 100644
index 00000000..c1fd510b
--- /dev/null
+++ b/tests/line_prefixes.rs
@@ -0,0 +1,25 @@
+use crate::common::*;
+
+#[test]
+fn infallible_after_quiet() {
+  Test::new()
+    .justfile(
+      "
+        foo:
+          @-exit 1
+      ",
+    )
+    .run();
+}
+
+#[test]
+fn quiet_after_infallible() {
+  Test::new()
+    .justfile(
+      "
+        foo:
+          -@exit 1
+      ",
+    )
+    .run();
+}
diff --git a/tests/misc.rs b/tests/misc.rs
index a8c6fe2a..5aede12d 100644
--- a/tests/misc.rs
+++ b/tests/misc.rs
@@ -1035,9 +1035,9 @@ foo:
 }
 
 test! {
-  name: infallable_command,
+  name: infallible_command,
   justfile: r#"
-infallable:
+infallible:
   -exit 101
 "#,
   stderr: "exit 101\n",
@@ -1045,15 +1045,15 @@ infallable:
 }
 
 test! {
-  name: infallable_with_failing,
+  name: infallible_with_failing,
   justfile: r#"
-infallable:
+infallible:
   -exit 101
   exit 202
 "#,
   stderr: r#"exit 101
 exit 202
-error: Recipe `infallable` failed on line 3 with exit code 202
+error: Recipe `infallible` failed on line 3 with exit code 202
 "#,
   status: 202,
 }