You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+6Lines changed: 6 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,10 @@ Please file a bug if you notice a violation of semantic versioning.
20
20
21
21
### Added
22
22
23
+
-`body_has_mergeable_statements?` private method to check if a block body contains statements that can be signature-matched
24
+
-`mergeable_statement?` private method to determine if a node type can generate signatures for merging
25
+
-`max_recursion_depth` option (defaults to `Float::INFINITY`) as a safety valve for edge cases
26
+
23
27
### Changed
24
28
25
29
### Deprecated
@@ -28,6 +32,8 @@ Please file a bug if you notice a violation of semantic versioning.
28
32
29
33
### Fixed
30
34
35
+
-**Fixed infinite recursion** when merging `CallNode` blocks (like `git_source`) that have matching signatures but non-mergeable body content (e.g., just string literals). The fix detects when a block body contains only literals/expressions with no signature-matchable statements and treats the node atomically instead of recursing.
# Result: Existing configs keep destination values, new configs added from template
299
299
```
300
300
301
+
### Recursion Depth Limit
302
+
303
+
Prism::Merge automatically detects when block bodies contain only literals or simple expressions (no mergeable statements) and treats them atomically. However, as a safety valve for edge cases, you can limit recursion depth:
304
+
305
+
```ruby
306
+
# Limit recursive merging to 3 levels deep
307
+
merger =Prism::Merge::SmartMerger.new(
308
+
template,
309
+
destination,
310
+
max_recursion_depth:3,
311
+
)
312
+
313
+
# Disable recursive merging entirely (treat all nodes atomically)
314
+
merger =Prism::Merge::SmartMerger.new(
315
+
template,
316
+
destination,
317
+
max_recursion_depth:0,
318
+
)
319
+
```
320
+
321
+
**When to use:**
322
+
323
+
-**`Float::INFINITY`** (default) - Normal operation, recursion terminates naturally based on content analysis.
324
+
- NOTE: If you get `stack level too deep (SystemStackError)`, please file a [bug](https://github.com/kettle-rb/prism-merge/issues)!
325
+
-**Finite value** - Safety valve if you encounter edge cases with unexpected deep recursion
326
+
-**`0`** - Disable recursive merging entirely; all matching nodes are treated atomically
327
+
301
328
### Custom Signature Generator
302
329
303
330
By default, Prism::Merge uses intelligent structural signatures to match nodes. The signature determines how nodes are matched between template and destination files.
@@ -332,7 +359,7 @@ The following node types support **recursive body merging**, where nested conten
332
359
-`ClassNode` - class bodies are recursively merged
333
360
-`ModuleNode` - module bodies are recursively merged
334
361
-`SingletonClassNode` - singleton class bodies are recursively merged
335
-
-`CallNode` with block - block bodies are recursively merged (e.g., `configure do ... end`)
362
+
-`CallNode` with block - block bodies are recursively merged **only when the body contains mergeable statements**(e.g., `describe do ... end` with nested `it` blocks). Blocks containing only literals or simple expressions (like `git_source(:github) { |repo| "https://..." }`) are treated atomically.
336
363
-`BeginNode` - begin/rescue/ensure blocks are recursively merged
0 commit comments