From 02723e1fd8b024b1c97019d959fcf69e534d921e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se>
Date: Tue, 19 Sep 2023 15:51:29 +0200
Subject: [PATCH] Support blocks for collect statements.

---
 muppet/puppet/ast.py           |  6 ++++++
 muppet/puppet/format/parser.py | 10 +++++++++-
 tests/test_parse_elsif.py      | 18 ++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/muppet/puppet/ast.py b/muppet/puppet/ast.py
index f30acaa..a8baa1a 100644
--- a/muppet/puppet/ast.py
+++ b/muppet/puppet/ast.py
@@ -179,6 +179,7 @@ class PuppetCollect(Puppet):
 
     type: Puppet
     query: Puppet
+    ops: list[PuppetInstanciationParameter] = field(default_factory=list)
 
 
 @dataclass
@@ -625,6 +626,11 @@ def build_ast(form: Any) -> Puppet:
         case ['concat', *parts]:
             return PuppetConcat([build_ast(p) for p in parts])
 
+        case ['collect', {'type': t, 'query': q, 'ops': ops}]:
+            return PuppetCollect(build_ast(t),
+                                 build_ast(q),
+                                 [parse_puppet_instanciation_param(x) for x in ops])
+
         case ['collect', {'type': t, 'query': q}]:
             return PuppetCollect(build_ast(t),
                                  build_ast(q))
diff --git a/muppet/puppet/format/parser.py b/muppet/puppet/format/parser.py
index b5406a9..ccb59f2 100644
--- a/muppet/puppet/format/parser.py
+++ b/muppet/puppet/format/parser.py
@@ -372,7 +372,15 @@ class ParserFormatter(Serializer[ParseDirective]):
 
     @override
     def _puppet_collect(self, it: PuppetCollect) -> ParseDirective:
-        return ws & self.s(it.type) & ws & self.s(it.query)
+        parser = ws & self.s(it.type) & ws & self.s(it.query)
+
+        sub = ws & "{"
+        for param in it.ops:
+            sub &= self.instanciation_parameter(param)
+        sub &= ws & '}'
+
+        parser &= optional(sub)
+        return parser
 
     @override
     def _puppet_concat(self, it: PuppetConcat) -> ParseDirective:
diff --git a/tests/test_parse_elsif.py b/tests/test_parse_elsif.py
index 8afa037..1bcf43d 100644
--- a/tests/test_parse_elsif.py
+++ b/tests/test_parse_elsif.py
@@ -179,3 +179,21 @@ def test_string_interpolation_deep_access():
     parse_string("""
     "${x['y']['z']}"
     """)
+
+
+def test_collect():
+    parse_string("""
+    Exec <| title=='apt_update' |> {
+      refreshonly => false,
+    }
+    """)
+
+
+def test_collect_nested():
+    parse_string("""
+    if $_update['frequency'] == 'always' {
+        Exec <| title=='apt_update' |> {
+            refreshonly => false,
+        }
+    }
+    """)
-- 
GitLab