nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: casey/just
Pull request #1779 (2023-12-24 17:11:33)

Display a descriptive error for `!include` directives


Patch:
diff --git a/src/compile_error.rs b/src/compile_error.rs
index 7a0d6f9c..3d3718b6 100644
--- a/src/compile_error.rs
+++ b/src/compile_error.rs
@@ -135,6 +135,10 @@ impl Display for CompileError<'_> {
         Count("argument", *found),
         expected.display(),
       ),
+      Include => write!(
+        f,
+        "The `!include` directive has been stabilized as `import`"
+      ),
       InconsistentLeadingWhitespace { expected, found } => write!(
         f,
         "Recipe line has inconsistent leading whitespace. Recipe started with `{}` but found \
diff --git a/src/compile_error_kind.rs b/src/compile_error_kind.rs
index acd8b2f7..0be55552 100644
--- a/src/compile_error_kind.rs
+++ b/src/compile_error_kind.rs
@@ -58,6 +58,7 @@ pub(crate) enum CompileErrorKind<'src> {
     found: usize,
     expected: Range<usize>,
   },
+  Include,
   InconsistentLeadingWhitespace {
     expected: &'src str,
     found: &'src str,
diff --git a/src/lexer.rs b/src/lexer.rs
index 37c8f7dd..6d380aeb 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -481,6 +481,7 @@ impl<'src> Lexer<'src> {
   fn lex_normal(&mut self, start: char) -> CompileResult<'src, ()> {
     match start {
       ' ' | '\t' => self.lex_whitespace(),
+      '!' if self.rest().starts_with("!include") => Err(self.error(Include)),
       '!' => self.lex_digraph('!', '=', BangEquals),
       '#' => self.lex_comment(),
       '$' => self.lex_single(Dollar),


Test patch:
diff --git a/tests/imports.rs b/tests/imports.rs
index 38dfe981..2c2c9139 100644
--- a/tests/imports.rs
+++ b/tests/imports.rs
@@ -110,3 +110,20 @@ fn listed_recipes_in_imports_are_in_load_order() {
     )
     .run();
 }
+
+#[test]
+fn include_error() {
+  Test::new()
+    .justfile("!include foo")
+    .status(EXIT_FAILURE)
+    .stderr(
+      "
+      error: The `!include` directive has been stabilized as `import`
+       --> justfile:1:1
+        |
+      1 | !include foo
+        | ^
+      ",
+    )
+    .run();
+}
Repository: casey/just
Pull request #910 (2021-07-20 01:17:19)

Implement `else if` chains


Patch:
diff --git a/src/parser.rs b/src/parser.rs
index 45c4c809..0453177b 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -414,48 +414,56 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
   /// Parse an expression, e.g. `1 + 2`
   fn parse_expression(&mut self) -> CompilationResult<'src, Expression<'src>> {
     if self.accepted_keyword(Keyword::If)? {
-      let lhs = self.parse_expression()?;
-
-      let inverted = self.accepted(BangEquals)?;
+      self.parse_conditional()
+    } else {
+      let value = self.parse_value()?;
 
-      if !inverted {
-        self.expect(EqualsEquals)?;
+      if self.accepted(Plus)? {
+        let lhs = Box::new(value);
+        let rhs = Box::new(self.parse_expression()?);
+        Ok(Expression::Concatination { lhs, rhs })
+      } else {
+        Ok(value)
       }
+    }
+  }
 
-      let rhs = self.parse_expression()?;
-
-      self.expect(BraceL)?;
-
-      let then = self.parse_expression()?;
+  /// Parse a conditional, e.g. `if a == b { "foo" } else { "bar" }`
+  fn parse_conditional(&mut self) -> CompilationResult<'src, Expression<'src>> {
+    let lhs = self.parse_expression()?;
 
-      self.expect(BraceR)?;
+    let inverted = self.accepted(BangEquals)?;
 
-      self.expect_keyword(Keyword::Else)?;
+    if !inverted {
+      self.expect(EqualsEquals)?;
+    }
 
-      self.expect(BraceL)?;
+    let rhs = self.parse_expression()?;
 
-      let otherwise = self.parse_expression()?;
+    self.expect(BraceL)?;
 
-      self.expect(BraceR)?;
+    let then = self.parse_expression()?;
 
-      return Ok(Expression::Conditional {
-        lhs: Box::new(lhs),
-        rhs: Box::new(rhs),
-        then: Box::new(then),
-        otherwise: Box::new(otherwise),
-        inverted,
-      });
-    }
+    self.expect(BraceR)?;
 
-    let value = self.parse_value()?;
+    self.expect_keyword(Keyword::Else)?;
 
-    if self.accepted(Plus)? {
-      let lhs = Box::new(value);
-      let rhs = Box::new(self.parse_expression()?);
-      Ok(Expression::Concatination { lhs, rhs })
+    let otherwise = if self.accepted_keyword(Keyword::If)? {
+      self.parse_conditional()?
     } else {
-      Ok(value)
-    }
+      self.expect(BraceL)?;
+      let otherwise = self.parse_expression()?;
+      self.expect(BraceR)?;
+      otherwise
+    };
+
+    Ok(Expression::Conditional {
+      lhs: Box::new(lhs),
+      rhs: Box::new(rhs),
+      then: Box::new(then),
+      otherwise: Box::new(otherwise),
+      inverted,
+    })
   }
 
   /// Parse a value, e.g. `(bar)`


Test patch:
diff --git a/tests/conditional.rs b/tests/conditional.rs
index f1b2e221..dc346e7b 100644
--- a/tests/conditional.rs
+++ b/tests/conditional.rs
@@ -156,3 +156,15 @@ test! {
         echo {{ a }}
   ",
 }
+
+test! {
+  name: if_else,
+  justfile: "
+    x := if '0' == '1' { 'a' } else if '0' == '0' { 'b' } else { 'c' }
+
+    foo:
+      echo {{ x }}
+  ",
+  stdout: "b\n",
+  stderr: "echo b\n",
+}