A collection of freeze-dried and vacuum-sealed Yak shavings for Ruby development & testing.
The *-merge gem family provides intelligent, AST-based merging for various file formats. At the foundation is tree_haver, which provides a unified cross-Ruby parsing API that works seamlessly across MRI, JRuby, and TruffleRuby.
| Gem | Version / CI | Language / Format |
Parser Backend(s) | Description |
|---|---|---|---|---|
| tree_haver | Multi | Supported Backends: MRI C, Rust, FFI, Java, Prism, Psych, Commonmarker, Markly, Citrus, Parslet | Foundation: Cross-Ruby adapter for parsing libraries (like Faraday for HTTP) | |
| ast-merge | Text | internal | Infrastructure: Shared base classes and merge logic for all *-merge gems |
|
| bash-merge | Bash | tree-sitter-bash (via tree_haver) | Smart merge for Bash scripts | |
| commonmarker-merge | Markdown | Commonmarker (via tree_haver) | Smart merge for Markdown (CommonMark via comrak Rust) | |
| dotenv-merge | Dotenv | internal | Smart merge for .env files |
|
| json-merge | JSON | tree-sitter-json (via tree_haver) | Smart merge for JSON files | |
| jsonc-merge | JSONC | tree-sitter-jsonc (via tree_haver) | ||
| markdown-merge | Markdown | Commonmarker / Markly (via tree_haver), Parslet | Foundation: Shared base for Markdown mergers with inner code block merging | |
| markly-merge | Markdown | Markly (via tree_haver) | Smart merge for Markdown (CommonMark via cmark-gfm C) | |
| prism-merge | Ruby | Prism (prism std lib gem) |
Smart merge for Ruby source files | |
| psych-merge | YAML | Psych (psych std lib gem) |
Smart merge for YAML files | |
| rbs-merge | RBS | tree-sitter-bash (via tree_haver), RBS (rbs std lib gem) |
Smart merge for Ruby type signatures | |
| toml-merge | TOML | Parslet + toml, Citrus + toml-rb, tree-sitter-toml (all via tree_haver) | Smart merge for TOML files |
tree_haver supports multiple parsing backends, but not all backends work on all Ruby platforms:
| Platform 👉️ TreeHaver Backend 👇️ |
MRI | JRuby | TruffleRuby | Notes |
|---|---|---|---|---|
| MRI (ruby_tree_sitter) | ✅ | ❌ | ❌ | C extension, MRI only |
| Rust (tree_stump) | ✅ | ❌ | ❌ | Rust extension via magnus/rb-sys, MRI only |
| FFI (ffi) | ✅ | ✅ | ❌ | TruffleRuby's FFI doesn't support STRUCT_BY_VALUE |
| Java (jtreesitter) | ❌ | ✅ | ❌ | JRuby only, requires grammar JARs |
| Prism (prism) | ✅ | ✅ | ✅ | Ruby parsing, stdlib in Ruby 3.4+ |
| Psych (psych) | ✅ | ✅ | ✅ | YAML parsing, stdlib |
| Citrus (citrus) | ✅ | ✅ | ✅ | Pure Ruby PEG parser, no native dependencies |
| Parslet (parslet) | ✅ | ✅ | ✅ | Pure Ruby PEG parser, no native dependencies |
| Commonmarker (commonmarker) | ✅ | ❌ | ❓ | Rust extension for Markdown (via commonmarker-merge) |
| Markly (markly) | ✅ | ❌ | ❓ | C extension for Markdown (via markly-merge) |
Legend: ✅ = Works, ❌ = Does not work, ❓ = Untested
Why some backends don't work on certain platforms:
- JRuby: Runs on the JVM; cannot load native C/Rust extensions (
.sofiles) - TruffleRuby: Has C API emulation via Sulong/LLVM, but it doesn't expose all MRI internals that native extensions require (e.g.,
RBasic.flags,rb_gc_writebarrier) - FFI on TruffleRuby: TruffleRuby's FFI implementation doesn't support returning structs by value, which tree-sitter's C API requires
Example implementations for the gem templating use case:
| Gem | Purpose | Description |
|---|---|---|
| kettle-jem | Gem Templating | Gem template library with smart merge support |
| Gem | Purpose | Description |
|---|---|---|
| kettle-dev | Gem Development | Complete rake & dev harness for Ruby development; tasks for coverage, GHA console, linting, debugging, etc. |
| Gem | Purpose | Description |
|---|---|---|
| kettle-test | Spec Development | Complete RSpec test harness, temporal manipulation, silent output testing, block expectations, etc. |
| kettle-soup-cover | Test Coverage Harness | A Covered Kettle of SOUP. Configure SimpleCov in 4 LOC for every CI platform, w/ 12-factor ENV-based controls |
| Gem | Purpose | Description |
|---|---|---|
| kettle-wash | Spec Development | Coming soon! Runner up name: "constant_change". Provides a pattern for resetting constants for consistent deterministic results. |