Repository: casey/just (rust)

Issue:
Ignore interpolation for comments
Hi.

I've just been shuffling around some build instructions encapsulated in my justfiles. And commented out one such build instruction (since the build system of jax has been in flux).

```just
#cd jax-{{TAG}} && bazelisk run --verbose-failure=true //jaxlib/tools:build_wheel -- --output_path=dist --cpu=x86_64
```

just then told me the following:

```console
error: Variable `TAG` not defined
```

So, basically, it tried to interpolate the TAG value in the comment. I believe this is a situation where you should opt out of interpolation.

Of course, this depends whether or not the comment is a comment for the shell, or a comment for just. It seems to be a comment for the shell, in which case, well, I would understand just not being aware of what is a comment for the shell.

Nonetheless, the ergonomics of it seems suboptimal: I'd like to wildly refactor my build instructions without having just complaining about failing to interpolate my comments...

EDIT: It can be fixed by putting the # as the first element of the line and not putting it after the tab. But, still, it feels wrong.

Pull request description:
Don't analyze comments when `ignore-comments` is set
Fixes #2179.

Patch:
diff --git a/src/analyzer.rs b/src/analyzer.rs
index f2e0b654..96982844 100644
--- a/src/analyzer.rs
+++ b/src/analyzer.rs
@@ -149,7 +149,7 @@ impl<'src> Analyzer<'src> {
       }
     }
 
-    let recipes = RecipeResolver::resolve_recipes(recipe_table, &self.assignments)?;
+    let recipes = RecipeResolver::resolve_recipes(&self.assignments, &settings, recipe_table)?;
 
     let mut aliases = Table::new();
     while let Some(alias) = self.aliases.pop() {
diff --git a/src/recipe_resolver.rs b/src/recipe_resolver.rs
index 5a962d88..c56afeaf 100644
--- a/src/recipe_resolver.rs
+++ b/src/recipe_resolver.rs
@@ -8,8 +8,9 @@ pub(crate) struct RecipeResolver<'src: 'run, 'run> {
 
 impl<'src: 'run, 'run> RecipeResolver<'src, 'run> {
   pub(crate) fn resolve_recipes(
-    unresolved_recipes: Table<'src, UnresolvedRecipe<'src>>,
     assignments: &'run Table<'src, Assignment<'src>>,
+    settings: &Settings,
+    unresolved_recipes: Table<'src, UnresolvedRecipe<'src>>,
   ) -> CompileResult<'src, Table<'src, Rc<Recipe<'src>>>> {
     let mut resolver = Self {
       resolved_recipes: Table::new(),
@@ -39,6 +40,10 @@ impl<'src: 'run, 'run> RecipeResolver<'src, 'run> {
       }
 
       for line in &recipe.body {
+        if line.is_comment() && settings.ignore_comments {
+          continue;
+        }
+
         for fragment in &line.fragments {
           if let Fragment::Interpolation { expression, .. } = fragment {
             for variable in expression.variables() {


Test patch:
diff --git a/tests/ignore_comments.rs b/tests/ignore_comments.rs
index 7cc996e2..c3028a57 100644
--- a/tests/ignore_comments.rs
+++ b/tests/ignore_comments.rs
@@ -97,3 +97,41 @@ fn dont_evaluate_comments() {
     )
     .run();
 }
+
+#[test]
+fn dont_analyze_comments() {
+  Test::new()
+    .justfile(
+      "
+      set ignore-comments
+
+      some_recipe:
+        # {{ bar }}
+    ",
+    )
+    .run();
+}
+
+#[test]
+fn comments_still_must_be_parsable_when_ignored() {
+  Test::new()
+    .justfile(
+      "
+        set ignore-comments
+
+        some_recipe:
+          # {{ foo bar }}
+      ",
+    )
+    .stderr(
+      "
+        error: Expected '}}', '(', '+', or '/', but found identifier
+         ——▶ justfile:4:12
+          │
+        4 │   # {{ foo bar }}
+          │            ^^^
+      ",
+    )
+    .status(EXIT_FAILURE)
+    .run();
+}