json-merge 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +19 -1
- data/README.md +145 -128
- data/lib/json/merge/conflict_resolver.rb +33 -4
- data/lib/json/merge/smart_merger.rb +1 -0
- data/lib/json/merge/version.rb +1 -1
- data.tar.gz.sig +1 -1
- metadata +8 -8
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4b80810376606cc51dc2bb9b44a4cd40c59fc1f7c8d56f12fb2840d0860a5f0
|
|
4
|
+
data.tar.gz: dcae0b630a056f5fcc2a59d6ace275b2b649b62df5af62c287e12d80468fa78d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0002d281c55f8f0dfd5d0000d22237f5bf68495eaa724008a57efd049fe1845d32cb4318fcc00266948cc5b93855bd4315eea87bfd65bdce57386747c10d118b
|
|
7
|
+
data.tar.gz: 48360b4e51149e4c83111ec167ffb1279e84147db5d67e9701dab41f247c9862970df48681fedbfca6460791ef8f39918bb49b1d2ee59f9d9a74cb818ba16fc8
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,22 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [1.1.1] - 2026-01-26
|
|
34
|
+
|
|
35
|
+
- TAG: [v1.1.1][1.1.1t]
|
|
36
|
+
- COVERAGE: 95.72% -- 604/631 lines in 10 files
|
|
37
|
+
- BRANCH COVERAGE: 77.81% -- 235/302 branches in 10 files
|
|
38
|
+
- 96.63% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- ConflictResolver now applies per-node-type preferences via `node_typing`.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- ast-merge v4.0.4
|
|
47
|
+
- tree_haver v5.0.2
|
|
48
|
+
|
|
33
49
|
## [1.1.0] - 2026-01-12
|
|
34
50
|
|
|
35
51
|
- TAG: [v1.1.0][1.1.0t]
|
|
@@ -97,7 +113,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
97
113
|
|
|
98
114
|
### Security
|
|
99
115
|
|
|
100
|
-
[Unreleased]: https://github.com/kettle-rb/json-merge/compare/v1.1.
|
|
116
|
+
[Unreleased]: https://github.com/kettle-rb/json-merge/compare/v1.1.1...HEAD
|
|
117
|
+
[1.1.1]: https://github.com/kettle-rb/json-merge/compare/v1.1.0...v1.1.1
|
|
118
|
+
[1.1.1t]: https://github.com/kettle-rb/json-merge/releases/tag/v1.1.1
|
|
101
119
|
[1.1.0]: https://github.com/kettle-rb/json-merge/compare/v1.0.0...v1.1.0
|
|
102
120
|
[1.1.0t]: https://github.com/kettle-rb/json-merge/releases/tag/v1.1.0
|
|
103
121
|
[1.0.0]: https://github.com/kettle-rb/json-merge/compare/f1cc25b1d9b79c598270e3aa203fa56787e6c6fc...v1.0.0
|
data/README.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
[rubygems-maint-policy]: https://github.com/ruby/rubygems/blob/b1ab33a3d52310a84d16b193991af07f5a6a07c0/doc/rubygems/POLICIES.md?plain=1#L187-L196
|
|
32
32
|
[policy-fail]: https://www.reddit.com/r/ruby/comments/1ove9vp/rubycentral_hates_this_one_fact/
|
|
33
33
|
|
|
34
|
-
[![Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0]
|
|
34
|
+
[![Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0][🖼️galtzo-i]][🖼️galtzo-discord] [![ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5][🖼️ruby-lang-i]][🖼️ruby-lang] [![kettle-rb Logo by Aboling0, CC BY-SA 4.0][🖼️kettle-rb-i]][🖼️kettle-rb]
|
|
35
35
|
|
|
36
36
|
[🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
|
|
37
37
|
[🖼️galtzo-discord]: https://discord.gg/3qme4XHNKN
|
|
@@ -42,20 +42,21 @@
|
|
|
42
42
|
|
|
43
43
|
# ☯️ Json::Merge
|
|
44
44
|
|
|
45
|
-
[![Version]
|
|
45
|
+
[![Version][👽versioni]][👽dl-rank] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
|
|
46
46
|
|
|
47
|
-
`if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know]
|
|
47
|
+
`if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
|
|
48
48
|
|
|
49
49
|
-----
|
|
50
|
+
|
|
50
51
|
`if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
|
|
51
52
|
|
|
52
|
-
[![OpenCollective Backers]
|
|
53
|
+
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
|
|
53
54
|
|
|
54
55
|
## 🌻 Synopsis
|
|
55
56
|
|
|
56
|
-
Json::Merge is a standalone Ruby module that intelligently merges two versions of a JSON file using tree-sitter AST analysis. It's like a smart "git merge" specifically designed for JSON configuration files. Built on top of [ast-merge]
|
|
57
|
+
Json::Merge is a standalone Ruby module that intelligently merges two versions of a JSON file using tree-sitter AST analysis. It's like a smart "git merge" specifically designed for JSON configuration files. Built on top of [ast-merge][ast-merge], it shares the same architecture as [prism-merge][prism-merge] for Ruby source files.
|
|
57
58
|
|
|
58
|
-
For JSONC (JSON with Comments) support, see the [jsonc-merge]
|
|
59
|
+
For JSONC (JSON with Comments) support, see the [jsonc-merge][jsonc-merge] gem.
|
|
59
60
|
|
|
60
61
|
### Key Features
|
|
61
62
|
|
|
@@ -68,9 +69,10 @@ For JSONC (JSON with Comments) support, see the [jsonc-merge](https://github.com
|
|
|
68
69
|
- **Customizable**:
|
|
69
70
|
- `signature_generator` - callable custom signature generators
|
|
70
71
|
- `preference` - setting of `:template`, `:destination`, or a Hash for per-node-type preferences
|
|
71
|
-
- `node_splitter` - Hash mapping node types to callables for per-node-type merge customization (see [ast-merge]
|
|
72
|
+
- `node_splitter` - Hash mapping node types to callables for per-node-type merge customization (see [ast-merge][ast-merge] docs)
|
|
72
73
|
- `add_template_only_nodes` - setting to retain nodes that do not exist in destination
|
|
73
74
|
- `match_refiners` - array of refiners for fuzzy matching (e.g., `ObjectMatchRefiner`)
|
|
75
|
+
|
|
74
76
|
### Supported Node Types
|
|
75
77
|
|
|
76
78
|
| Node Type | Signature Format | Matching Behavior |
|
|
@@ -85,7 +87,7 @@ For JSONC (JSON with Comments) support, see the [jsonc-merge](https://github.com
|
|
|
85
87
|
|
|
86
88
|
### Example
|
|
87
89
|
|
|
88
|
-
```
|
|
90
|
+
```ruby
|
|
89
91
|
require "json/merge"
|
|
90
92
|
|
|
91
93
|
template = File.read("template.json")
|
|
@@ -101,37 +103,38 @@ File.write("merged.json", result.to_json)
|
|
|
101
103
|
|
|
102
104
|
The `*-merge` gem family provides intelligent, AST-based merging for various file formats. At the foundation is [tree_haver][tree_haver], which provides a unified cross-Ruby parsing API that works seamlessly across MRI, JRuby, and TruffleRuby.
|
|
103
105
|
|
|
104
|
-
| Gem | Language<br>/ Format | Parser Backend(s)
|
|
105
|
-
|
|
106
|
-
| [tree_haver][tree_haver] | Multi | MRI C, Rust, FFI, Java, Prism, Psych, Commonmarker, Markly, Citrus
|
|
107
|
-
| [ast-merge][ast-merge] | Text | internal
|
|
108
|
-
| [bash-merge][bash-merge] | Bash | [tree-sitter-bash][ts-bash] (via tree_haver)
|
|
109
|
-
| [commonmarker-merge][commonmarker-merge] | Markdown | [Commonmarker][commonmarker] (via tree_haver)
|
|
110
|
-
| [dotenv-merge][dotenv-merge] | Dotenv | internal
|
|
111
|
-
| [json-merge][json-merge] | JSON | [tree-sitter-json][ts-json] (via tree_haver)
|
|
112
|
-
| [jsonc-merge][jsonc-merge] | JSONC | [tree-sitter-jsonc][ts-jsonc] (via tree_haver)
|
|
113
|
-
| [markdown-merge][markdown-merge] | Markdown | [Commonmarker][commonmarker] / [Markly][markly] (via tree_haver)
|
|
114
|
-
| [markly-merge][markly-merge] | Markdown | [Markly][markly] (via tree_haver)
|
|
115
|
-
| [prism-merge][prism-merge] | Ruby | [Prism][prism] (`prism` std lib gem)
|
|
116
|
-
| [psych-merge][psych-merge] | YAML | [Psych][psych] (`psych` std lib gem)
|
|
117
|
-
| [rbs-merge][rbs-merge] | RBS | [tree-sitter-bash][ts-rbs] (via tree_haver), [RBS][rbs] (`rbs` std lib gem)
|
|
118
|
-
| [toml-merge][toml-merge] | TOML | [Citrus + toml-rb][toml-rb]
|
|
106
|
+
| Gem | Version / CI | Language<br>/ Format | Parser Backend(s) | Description |
|
|
107
|
+
|------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------:|----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
|
|
108
|
+
| [tree_haver][tree_haver] | [![Version][tree_haver-gem-i]][tree_haver-gem] <br/> [![CI][tree_haver-ci-i]][tree_haver-ci] | 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) |
|
|
109
|
+
| [ast-merge][ast-merge] | [![Version][ast-merge-gem-i]][ast-merge-gem] <br/> [![CI][ast-merge-ci-i]][ast-merge-ci] | Text | internal | **Infrastructure**: Shared base classes and merge logic for all `*-merge` gems |
|
|
110
|
+
| [bash-merge][bash-merge] | [![Version][bash-merge-gem-i]][bash-merge-gem] <br/> [![CI][bash-merge-ci-i]][bash-merge-ci] | Bash | [tree-sitter-bash][ts-bash] (via tree_haver) | Smart merge for Bash scripts |
|
|
111
|
+
| [commonmarker-merge][commonmarker-merge] | [![Version][commonmarker-merge-gem-i]][commonmarker-merge-gem] <br/> [![CI][commonmarker-merge-ci-i]][commonmarker-merge-ci] | Markdown | [Commonmarker][commonmarker] (via tree_haver) | Smart merge for Markdown (CommonMark via comrak Rust) |
|
|
112
|
+
| [dotenv-merge][dotenv-merge] | [![Version][dotenv-merge-gem-i]][dotenv-merge-gem] <br/> [![CI][dotenv-merge-ci-i]][dotenv-merge-ci] | Dotenv | internal | Smart merge for `.env` files |
|
|
113
|
+
| [json-merge][json-merge] | [![Version][json-merge-gem-i]][json-merge-gem] <br/> [![CI][json-merge-ci-i]][json-merge-ci] | JSON | [tree-sitter-json][ts-json] (via tree_haver) | Smart merge for JSON files |
|
|
114
|
+
| [jsonc-merge][jsonc-merge] | [![Version][jsonc-merge-gem-i]][jsonc-merge-gem] <br/> [![CI][jsonc-merge-ci-i]][jsonc-merge-ci] | JSONC | [tree-sitter-jsonc][ts-jsonc] (via tree_haver) | ⚠️ Proof of concept; Smart merge for JSON with Comments |
|
|
115
|
+
| [markdown-merge][markdown-merge] | [![Version][markdown-merge-gem-i]][markdown-merge-gem] <br/> [![CI][markdown-merge-ci-i]][markdown-merge-ci] | Markdown | [Commonmarker][commonmarker] / [Markly][markly] (via tree_haver), [Parslet][parslet] | **Foundation**: Shared base for Markdown mergers with inner code block merging |
|
|
116
|
+
| [markly-merge][markly-merge] | [![Version][markly-merge-gem-i]][markly-merge-gem] <br/> [![CI][markly-merge-ci-i]][markly-merge-ci] | Markdown | [Markly][markly] (via tree_haver) | Smart merge for Markdown (CommonMark via cmark-gfm C) |
|
|
117
|
+
| [prism-merge][prism-merge] | [![Version][prism-merge-gem-i]][prism-merge-gem] <br/> [![CI][prism-merge-ci-i]][prism-merge-ci] | Ruby | [Prism][prism] (`prism` std lib gem) | Smart merge for Ruby source files |
|
|
118
|
+
| [psych-merge][psych-merge] | [![Version][psych-merge-gem-i]][psych-merge-gem] <br/> [![CI][psych-merge-ci-i]][psych-merge-ci] | YAML | [Psych][psych] (`psych` std lib gem) | Smart merge for YAML files |
|
|
119
|
+
| [rbs-merge][rbs-merge] | [![Version][rbs-merge-gem-i]][rbs-merge-gem] <br/> [![CI][rbs-merge-ci-i]][rbs-merge-ci] | RBS | [tree-sitter-bash][ts-rbs] (via tree_haver), [RBS][rbs] (`rbs` std lib gem) | Smart merge for Ruby type signatures |
|
|
120
|
+
| [toml-merge][toml-merge] | [![Version][toml-merge-gem-i]][toml-merge-gem] <br/> [![CI][toml-merge-ci-i]][toml-merge-ci] | TOML | [Parslet + toml][toml], [Citrus + toml-rb][toml-rb], [tree-sitter-toml][ts-toml] (all via tree_haver) | Smart merge for TOML files |
|
|
119
121
|
|
|
120
122
|
#### Backend Platform Compatibility
|
|
121
123
|
|
|
122
124
|
tree_haver supports multiple parsing backends, but not all backends work on all Ruby platforms:
|
|
123
125
|
|
|
124
|
-
| Platform 👉️<br> TreeHaver Backend 👇️
|
|
125
|
-
|
|
126
|
-
| **MRI** ([ruby_tree_sitter][ruby_tree_sitter])
|
|
127
|
-
| **Rust** ([tree_stump][tree_stump])
|
|
128
|
-
| **FFI**
|
|
129
|
-
| **Java** ([jtreesitter][jtreesitter])
|
|
130
|
-
| **Prism**
|
|
131
|
-
| **Psych**
|
|
132
|
-
| **Citrus**
|
|
133
|
-
| **
|
|
134
|
-
| **
|
|
126
|
+
| Platform 👉️<br> TreeHaver Backend 👇️ | MRI | JRuby | TruffleRuby | Notes |
|
|
127
|
+
|-------------------------------------------------|:---:|:-----:|:-----------:|----------------------------------------------------------------------------|
|
|
128
|
+
| **MRI** ([ruby_tree_sitter][ruby_tree_sitter]) | ✅ | ❌ | ❌ | C extension, MRI only |
|
|
129
|
+
| **Rust** ([tree_stump][tree_stump]) | ✅ | ❌ | ❌ | Rust extension via magnus/rb-sys, MRI only |
|
|
130
|
+
| **FFI** ([ffi][ffi]) | ✅ | ✅ | ❌ | TruffleRuby's FFI doesn't support `STRUCT_BY_VALUE` |
|
|
131
|
+
| **Java** ([jtreesitter][jtreesitter]) | ❌ | ✅ | ❌ | JRuby only, requires grammar JARs |
|
|
132
|
+
| **Prism** ([prism][prism]) | ✅ | ✅ | ✅ | Ruby parsing, stdlib in Ruby 3.4+ |
|
|
133
|
+
| **Psych** ([psych][psych]) | ✅ | ✅ | ✅ | YAML parsing, stdlib |
|
|
134
|
+
| **Citrus** ([citrus][citrus]) | ✅ | ✅ | ✅ | Pure Ruby PEG parser, no native dependencies |
|
|
135
|
+
| **Parslet** ([parslet][parslet]) | ✅ | ✅ | ✅ | Pure Ruby PEG parser, no native dependencies |
|
|
136
|
+
| **Commonmarker** ([commonmarker][commonmarker]) | ✅ | ❌ | ❓ | Rust extension for Markdown (via [commonmarker-merge][commonmarker-merge]) |
|
|
137
|
+
| **Markly** ([markly][markly]) | ✅ | ❌ | ❓ | C extension for Markdown (via [markly-merge][markly-merge]) |
|
|
135
138
|
|
|
136
139
|
**Legend**: ✅ = Works, ❌ = Does not work, ❓ = Untested
|
|
137
140
|
|
|
@@ -225,6 +228,7 @@ tree_haver supports multiple parsing backends, but not all backends work on all
|
|
|
225
228
|
[kettle-jem-ci]: https://github.com/kettle-rb/kettle-jem/actions/workflows/current.yml
|
|
226
229
|
[prism]: https://github.com/ruby/prism
|
|
227
230
|
[psych]: https://github.com/ruby/psych
|
|
231
|
+
[ffi]: https://github.com/ffi/ffi
|
|
228
232
|
[ts-json]: https://github.com/tree-sitter/tree-sitter-json
|
|
229
233
|
[ts-jsonc]: https://gitlab.com/WhyNotHugo/tree-sitter-jsonc
|
|
230
234
|
[ts-bash]: https://github.com/tree-sitter/tree-sitter-bash
|
|
@@ -239,21 +243,23 @@ tree_haver supports multiple parsing backends, but not all backends work on all
|
|
|
239
243
|
[ruby_tree_sitter]: https://github.com/Faveod/ruby-tree-sitter
|
|
240
244
|
[tree_stump]: https://github.com/joker1007/tree_stump
|
|
241
245
|
[jtreesitter]: https://central.sonatype.com/artifact/io.github.tree-sitter/jtreesitter
|
|
246
|
+
[citrus]: https://github.com/mjackson/citrus
|
|
247
|
+
[parslet]: https://github.com/kschiess/parslet
|
|
242
248
|
|
|
243
249
|
## 💡 Info you can shake a stick at
|
|
244
250
|
|
|
245
|
-
| Tokens to Remember | [![Gem name]
|
|
251
|
+
| Tokens to Remember | [![Gem name][⛳️name-img]][👽dl-rank] [![Gem namespace][⛳️namespace-img]][📜src-gh] |
|
|
246
252
|
| --- | --- |
|
|
247
|
-
| Works with JRuby | [![JRuby 10.0 Compat]
|
|
248
|
-
| Works with Truffle Ruby | [![Truffle Ruby 23.1 Compat]
|
|
249
|
-
| Works with MRI Ruby 3 | [![Ruby 3.2 Compat]
|
|
250
|
-
| Support & Community | [![Join Me on Daily.dev's RubyFriends]
|
|
251
|
-
| Source | [![Source on GitLab.com]
|
|
252
|
-
| Documentation | [![Current release on RubyDoc.info]
|
|
253
|
-
| Compliance | [![License: MIT]
|
|
254
|
-
| Style | [![Enforced Code Style Linter]
|
|
255
|
-
| Maintainer 🎖️ | [![Follow Me on LinkedIn]
|
|
256
|
-
| `...` 💖 | [![Find Me on WellFound:]
|
|
253
|
+
| Works with JRuby | [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
|
|
254
|
+
| Works with Truffle Ruby | [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] |
|
|
255
|
+
| Works with MRI Ruby 3 | [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
|
|
256
|
+
| Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord] [![Get help from me on Upwork][👨🏼🏫expsup-upwork-img]][👨🏼🏫expsup-upwork] [![Get help from me on Codementor][👨🏼🏫expsup-codementor-img]][👨🏼🏫expsup-codementor] |
|
|
257
|
+
| Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [][🧮kloc] |
|
|
258
|
+
| Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] |
|
|
259
|
+
| Compliance | [![License: MIT][📄license-img]][📄license-ref] [![Compatible with Apache Software Projects: Verified by SkyWalking Eyes][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img][📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
|
|
260
|
+
| Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
|
|
261
|
+
| Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼♂️devto-img]][💖💁🏼♂️devto] |
|
|
262
|
+
| `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼♂️aboutme-img]][💖💁🏼♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] |
|
|
257
263
|
|
|
258
264
|
### Compatibility
|
|
259
265
|
|
|
@@ -261,25 +267,25 @@ Compatible with MRI Ruby 3.2.0+, and concordant releases of JRuby, and TruffleRu
|
|
|
261
267
|
|
|
262
268
|
| 🚚 *Amazing* test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
|
|
263
269
|
| --- | --- |
|
|
264
|
-
| 👟 Check it out\! | ✨ [github.com/appraisal-rb/appraisal2]
|
|
270
|
+
| 👟 Check it out\! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
|
|
265
271
|
|
|
266
272
|
### Federated DVCS
|
|
267
273
|
|
|
268
274
|
<details markdown="1">
|
|
269
275
|
<summary>Find this repo on federated forges (Coming soon!)</summary>
|
|
270
276
|
|
|
271
|
-
| Federated [DVCS]
|
|
277
|
+
| Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
|
|
272
278
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
273
|
-
| 🧪 [kettle-rb/json-merge on GitLab]
|
|
274
|
-
| 🧊 [kettle-rb/json-merge on CodeBerg]
|
|
275
|
-
| 🐙 [kettle-rb/json-merge on GitHub]
|
|
276
|
-
| 🎮️ [Discord Server]
|
|
279
|
+
| 🧪 [kettle-rb/json-merge on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
|
|
280
|
+
| 🧊 [kettle-rb/json-merge on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
|
|
281
|
+
| 🐙 [kettle-rb/json-merge on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
|
|
282
|
+
| 🎮️ [Discord Server][🖼️galtzo-discord] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord] | [Let's][🖼️galtzo-discord] | [talk][🖼️galtzo-discord] | [about][🖼️galtzo-discord] | [this][🖼️galtzo-discord] | [library\!][🖼️galtzo-discord] |
|
|
277
283
|
|
|
278
284
|
</details>
|
|
279
285
|
|
|
280
286
|
[gh-discussions]: https://github.com/kettle-rb/json-merge/discussions
|
|
281
287
|
|
|
282
|
-
### Enterprise Support []
|
|
288
|
+
### Enterprise Support [][🏙️entsup-tidelift]
|
|
283
289
|
|
|
284
290
|
Available as part of the Tidelift Subscription.
|
|
285
291
|
|
|
@@ -288,33 +294,34 @@ Available as part of the Tidelift Subscription.
|
|
|
288
294
|
|
|
289
295
|
The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
|
|
290
296
|
|
|
291
|
-
[![Get help from me on Tidelift]
|
|
297
|
+
[![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]
|
|
292
298
|
|
|
293
299
|
- 💡Subscribe for support guarantees covering *all* your FLOSS dependencies
|
|
294
300
|
|
|
295
|
-
- 💡Tidelift is part of [Sonar]
|
|
301
|
+
- 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
|
|
296
302
|
|
|
297
|
-
- 💡Tidelift pays maintainers to maintain the software you depend on\!<br/>📊`@`Pointy Haired Boss: An [enterprise support]
|
|
303
|
+
- 💡Tidelift pays maintainers to maintain the software you depend on\!<br/>📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers
|
|
298
304
|
Alternatively:
|
|
299
305
|
|
|
300
|
-
- [![Live Chat on Discord]
|
|
306
|
+
- [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord]
|
|
307
|
+
|
|
308
|
+
- [![Get help from me on Upwork][👨🏼🏫expsup-upwork-img]][👨🏼🏫expsup-upwork]
|
|
301
309
|
|
|
302
|
-
- [![Get help from me on
|
|
310
|
+
- [![Get help from me on Codementor][👨🏼🏫expsup-codementor-img]][👨🏼🏫expsup-codementor]
|
|
303
311
|
|
|
304
|
-
- [](https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github)
|
|
305
312
|
</details>
|
|
306
313
|
|
|
307
314
|
## ✨ Installation
|
|
308
315
|
|
|
309
316
|
Install the gem and add to the application's Gemfile by executing:
|
|
310
317
|
|
|
311
|
-
```
|
|
318
|
+
```console
|
|
312
319
|
bundle add json-merge
|
|
313
320
|
```
|
|
314
321
|
|
|
315
322
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
|
316
323
|
|
|
317
|
-
```
|
|
324
|
+
```console
|
|
318
325
|
gem install json-merge
|
|
319
326
|
```
|
|
320
327
|
|
|
@@ -323,19 +330,19 @@ gem install json-merge
|
|
|
323
330
|
<details markdown="1">
|
|
324
331
|
<summary>For Medium or High Security Installations</summary>
|
|
325
332
|
|
|
326
|
-
This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512]
|
|
327
|
-
[stone\_checksums]
|
|
333
|
+
This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
|
|
334
|
+
[stone\_checksums][💎stone_checksums]. Be sure the gem you install hasn’t been tampered with
|
|
328
335
|
by following the instructions below.
|
|
329
336
|
|
|
330
337
|
Add my public key (if you haven’t already, expires 2045-04-29) as a trusted certificate:
|
|
331
338
|
|
|
332
|
-
```
|
|
339
|
+
```console
|
|
333
340
|
gem cert --add <(curl -Ls https://raw.github.com/galtzo-floss/certs/main/pboling.pem)
|
|
334
341
|
```
|
|
335
342
|
|
|
336
343
|
You only need to do that once. Then proceed to install with:
|
|
337
344
|
|
|
338
|
-
```
|
|
345
|
+
```console
|
|
339
346
|
gem install json-merge -P HighSecurity
|
|
340
347
|
```
|
|
341
348
|
|
|
@@ -343,7 +350,7 @@ The `HighSecurity` trust profile will verify signed gems, and not allow the inst
|
|
|
343
350
|
|
|
344
351
|
If you want to up your security game full-time:
|
|
345
352
|
|
|
346
|
-
```
|
|
353
|
+
```console
|
|
347
354
|
bundle config set --global trust-policy MediumSecurity
|
|
348
355
|
```
|
|
349
356
|
|
|
@@ -358,14 +365,15 @@ NOTE: Be prepared to track down certs for signed gems and add them the same way
|
|
|
358
365
|
This gem requires the `tree-sitter-json` parser library to be installed on your system.
|
|
359
366
|
The parser is a native shared library (`.so` on Linux, `.dylib` on macOS) that provides
|
|
360
367
|
JSON syntax parsing capabilities. For JSONC (JSON with Comments) support, use the
|
|
361
|
-
[jsonc-merge]
|
|
368
|
+
[jsonc-merge][jsonc-merge] gem instead.
|
|
362
369
|
|
|
363
370
|
#### Option 1: Pre-built Binaries (Recommended)
|
|
364
371
|
|
|
365
372
|
Download pre-built parsers from [Faveod/tree-sitter-parsers](https://github.com/Faveod/tree-sitter-parsers/releases):
|
|
366
373
|
|
|
367
374
|
**Linux (x64):**
|
|
368
|
-
|
|
375
|
+
|
|
376
|
+
```console
|
|
369
377
|
# Download and extract
|
|
370
378
|
curl -Lo parsers.tar.gz https://github.com/Faveod/tree-sitter-parsers/releases/download/v4.10/tree-sitter-parsers-4.10-linux-x64.tar.gz
|
|
371
379
|
tar -xzf parsers.tar.gz
|
|
@@ -381,13 +389,15 @@ export TREE_SITTER_JSON_PATH="$HOME/.local/lib/tree-sitter/libtree-sitter-json.s
|
|
|
381
389
|
```
|
|
382
390
|
|
|
383
391
|
**Debian/Ubuntu (amd64):**
|
|
384
|
-
|
|
392
|
+
|
|
393
|
+
```console
|
|
385
394
|
curl -Lo parsers.deb https://github.com/Faveod/tree-sitter-parsers/releases/download/v4.10/tree-sitter-parsers-4.10-amd64.deb
|
|
386
395
|
sudo dpkg -i parsers.deb
|
|
387
396
|
```
|
|
388
397
|
|
|
389
398
|
**macOS (Apple Silicon):**
|
|
390
|
-
|
|
399
|
+
|
|
400
|
+
```console
|
|
391
401
|
curl -Lo parsers.tar.gz https://github.com/Faveod/tree-sitter-parsers/releases/download/v4.10/tree-sitter-parsers-4.10-macos-arm64.tar.gz
|
|
392
402
|
tar -xzf parsers.tar.gz
|
|
393
403
|
|
|
@@ -399,7 +409,7 @@ export TREE_SITTER_JSON_PATH="$HOME/.local/lib/tree-sitter/libtree-sitter-json.d
|
|
|
399
409
|
|
|
400
410
|
#### Option 2: Build from Source
|
|
401
411
|
|
|
402
|
-
```
|
|
412
|
+
```console
|
|
403
413
|
git clone https://github.com/tree-sitter/tree-sitter-json.git
|
|
404
414
|
cd tree-sitter-json
|
|
405
415
|
make
|
|
@@ -413,7 +423,8 @@ sudo cp libtree-sitter-json.dylib /usr/local/lib/ # macOS
|
|
|
413
423
|
Some package managers provide tree-sitter parsers:
|
|
414
424
|
|
|
415
425
|
**Fedora Atomic (Silverblue, Kinoite, Bazzite, Aurora, etc.):**
|
|
416
|
-
|
|
426
|
+
|
|
427
|
+
```console
|
|
417
428
|
# Install via rpm-ostree (requires reboot)
|
|
418
429
|
rpm-ostree install libtree-sitter-json
|
|
419
430
|
|
|
@@ -423,12 +434,14 @@ export TREE_SITTER_JSON_PATH="/usr/lib64/libtree-sitter-json.so"
|
|
|
423
434
|
```
|
|
424
435
|
|
|
425
436
|
**Fedora (traditional):**
|
|
426
|
-
|
|
437
|
+
|
|
438
|
+
```console
|
|
427
439
|
sudo dnf install libtree-sitter-json
|
|
428
440
|
```
|
|
429
441
|
|
|
430
442
|
**Arch Linux:**
|
|
431
|
-
|
|
443
|
+
|
|
444
|
+
```console
|
|
432
445
|
# Check AUR for tree-sitter-json
|
|
433
446
|
yay -S tree-sitter-json
|
|
434
447
|
```
|
|
@@ -438,16 +451,18 @@ yay -S tree-sitter-json
|
|
|
438
451
|
If the parser is not in a standard location (`/usr/lib/`, `/usr/lib64/`, `/usr/local/lib/`),
|
|
439
452
|
set the `TREE_SITTER_JSON_PATH` environment variable to point to the parser library:
|
|
440
453
|
|
|
441
|
-
```
|
|
454
|
+
```console
|
|
442
455
|
export TREE_SITTER_JSON_PATH="/path/to/libtree-sitter-json.so"
|
|
443
456
|
```
|
|
444
457
|
|
|
445
458
|
**Note:** Some distributions install the library with a version number suffix
|
|
446
459
|
(e.g., `libtree-sitter-json.so.14` instead of `libtree-sitter-json.so`).
|
|
447
460
|
If the gem can't find the parser, check for versioned files and either:
|
|
461
|
+
|
|
448
462
|
- Set `TREE_SITTER_JSON_PATH` to the full versioned path, or
|
|
449
463
|
- Create a symlink: `sudo ln -s /usr/lib64/libtree-sitter-json.so.14 /usr/lib64/libtree-sitter-json.so`
|
|
450
464
|
Add this to your shell profile (`.bashrc`, `.zshrc`, etc.) for persistence.
|
|
465
|
+
|
|
451
466
|
### 💎 Ruby Interface Gems
|
|
452
467
|
|
|
453
468
|
In addition to the tree-sitter parser library, you need a Ruby gem that provides
|
|
@@ -455,9 +470,9 @@ bindings to tree-sitter. Choose **one** of the following based on your Ruby impl
|
|
|
455
470
|
|
|
456
471
|
| Gem | Ruby Support | Description |
|
|
457
472
|
| --- | --- | --- |
|
|
458
|
-
| [ruby\_tree\_sitter]
|
|
459
|
-
| [tree\_stump]
|
|
460
|
-
| [ffi]
|
|
473
|
+
| [ruby\_tree\_sitter][ruby_tree_sitter] | MRI only | C extension bindings (recommended for MRI) |
|
|
474
|
+
| [tree\_stump][tree_stump] | MRI (maybe JRuby) | Rust-based bindings via Rutie |
|
|
475
|
+
| [ffi][ffi] | MRI, JRuby, TruffleRuby | Generic FFI bindings (used by tree\_haver's FFI backend) |
|
|
461
476
|
|
|
462
477
|
[ruby_tree_sitter]: https://github.com/Faveod/ruby_tree_sitter
|
|
463
478
|
[tree_stump]: https://github.com/nickstenning/tree_stump
|
|
@@ -465,25 +480,25 @@ bindings to tree-sitter. Choose **one** of the following based on your Ruby impl
|
|
|
465
480
|
|
|
466
481
|
#### For MRI Ruby (Recommended)
|
|
467
482
|
|
|
468
|
-
```
|
|
483
|
+
```console
|
|
469
484
|
gem install ruby_tree_sitter
|
|
470
485
|
```
|
|
471
486
|
|
|
472
487
|
Or add to your Gemfile:
|
|
473
488
|
|
|
474
|
-
```
|
|
489
|
+
```ruby
|
|
475
490
|
gem "ruby_tree_sitter", "~> 2.0"
|
|
476
491
|
```
|
|
477
492
|
|
|
478
493
|
#### For JRuby or TruffleRuby
|
|
479
494
|
|
|
480
|
-
```
|
|
495
|
+
```console
|
|
481
496
|
gem install ffi
|
|
482
497
|
```
|
|
483
498
|
|
|
484
499
|
Or add to your Gemfile:
|
|
485
500
|
|
|
486
|
-
```
|
|
501
|
+
```ruby
|
|
487
502
|
gem "ffi"
|
|
488
503
|
```
|
|
489
504
|
|
|
@@ -499,7 +514,7 @@ you must use the FFI backend.
|
|
|
499
514
|
|
|
500
515
|
Control which version to use when nodes have matching signatures but different content:
|
|
501
516
|
|
|
502
|
-
```
|
|
517
|
+
```ruby
|
|
503
518
|
# Use template version (for config updates)
|
|
504
519
|
merger = Json::Merge::SmartMerger.new(
|
|
505
520
|
template,
|
|
@@ -519,7 +534,7 @@ merger = Json::Merge::SmartMerger.new(
|
|
|
519
534
|
|
|
520
535
|
Control whether to add nodes that only exist in the template:
|
|
521
536
|
|
|
522
|
-
```
|
|
537
|
+
```ruby
|
|
523
538
|
# Add template-only nodes
|
|
524
539
|
merger = Json::Merge::SmartMerger.new(
|
|
525
540
|
template,
|
|
@@ -536,8 +551,10 @@ When JSON object properties (key-value pairs) don't match by exact key name, the
|
|
|
536
551
|
- Similar key names (e.g., `databaseUrl` vs `database_url`)
|
|
537
552
|
- Keys with typos or different naming conventions (camelCase vs snake\_case)
|
|
538
553
|
- Array elements with similar structure or content
|
|
554
|
+
|
|
539
555
|
<!-- end list -->
|
|
540
|
-
|
|
556
|
+
|
|
557
|
+
```ruby
|
|
541
558
|
# Enable object fuzzy matching
|
|
542
559
|
merger = Json::Merge::SmartMerger.new(
|
|
543
560
|
template,
|
|
@@ -556,7 +573,7 @@ merger = Json::Merge::SmartMerger.new(
|
|
|
556
573
|
| `key_weight` | 0.7 | Weight for key name similarity |
|
|
557
574
|
| `value_weight` | 0.3 | Weight for value similarity |
|
|
558
575
|
|
|
559
|
-
```
|
|
576
|
+
```ruby
|
|
560
577
|
# Custom weights for key-centric matching
|
|
561
578
|
refiner = Json::Merge::ObjectMatchRefiner.new(
|
|
562
579
|
threshold: 0.6,
|
|
@@ -569,7 +586,7 @@ refiner = Json::Merge::ObjectMatchRefiner.new(
|
|
|
569
586
|
|
|
570
587
|
Enable debug logging to see merge decisions:
|
|
571
588
|
|
|
572
|
-
```
|
|
589
|
+
```bash
|
|
573
590
|
export JSON_MERGE_DEBUG=1
|
|
574
591
|
```
|
|
575
592
|
|
|
@@ -577,7 +594,7 @@ export JSON_MERGE_DEBUG=1
|
|
|
577
594
|
|
|
578
595
|
### Merging Two JSON Files
|
|
579
596
|
|
|
580
|
-
```
|
|
597
|
+
```ruby
|
|
581
598
|
require "json/merge"
|
|
582
599
|
|
|
583
600
|
template_content = File.read("template.json")
|
|
@@ -591,7 +608,7 @@ File.write("merged.json", result.to_json)
|
|
|
591
608
|
|
|
592
609
|
### Analyzing a JSON File
|
|
593
610
|
|
|
594
|
-
```
|
|
611
|
+
```ruby
|
|
595
612
|
require "json/merge"
|
|
596
613
|
|
|
597
614
|
source = File.read("config.json")
|
|
@@ -609,7 +626,7 @@ end
|
|
|
609
626
|
When property names differ between template and destination (e.g., naming convention changes),
|
|
610
627
|
use the `ObjectMatchRefiner`:
|
|
611
628
|
|
|
612
|
-
```
|
|
629
|
+
```ruby
|
|
613
630
|
require "json/merge"
|
|
614
631
|
|
|
615
632
|
template = <<~JSON
|
|
@@ -649,7 +666,7 @@ result = merger.merge
|
|
|
649
666
|
|
|
650
667
|
The `ObjectMatchRefiner` also handles array elements with similar structure:
|
|
651
668
|
|
|
652
|
-
```
|
|
669
|
+
```ruby
|
|
653
670
|
template = <<~JSON
|
|
654
671
|
{
|
|
655
672
|
"users": [
|
|
@@ -685,17 +702,17 @@ Raising a monthly budget of... "dollars" would make the project more sustainable
|
|
|
685
702
|
|
|
686
703
|
We welcome both individual and corporate sponsors\! We also offer a
|
|
687
704
|
wide array of funding channels to account for your preferences
|
|
688
|
-
(although currently [Open Collective]
|
|
705
|
+
(although currently [Open Collective][🖇osc] is our preferred funding platform).
|
|
689
706
|
|
|
690
707
|
**If you're working in a company that's making significant use of kettle-rb tools we'd
|
|
691
708
|
appreciate it if you suggest to your company to become a kettle-rb sponsor.**
|
|
692
709
|
|
|
693
710
|
You can support the development of kettle-rb tools via
|
|
694
|
-
[GitHub Sponsors]
|
|
695
|
-
[Liberapay]
|
|
696
|
-
[PayPal]
|
|
697
|
-
[Open Collective]
|
|
698
|
-
and [Tidelift]
|
|
711
|
+
[GitHub Sponsors][🖇sponsor],
|
|
712
|
+
[Liberapay][⛳liberapay],
|
|
713
|
+
[PayPal][🖇paypal],
|
|
714
|
+
[Open Collective][🖇osc]
|
|
715
|
+
and [Tidelift][🏙️entsup-tidelift].
|
|
699
716
|
|
|
700
717
|
| 📍 NOTE |
|
|
701
718
|
| --- |
|
|
@@ -703,22 +720,22 @@ and [Tidelift](https://tidelift.com/subscription/pkg/rubygems-json-merge?utm_sou
|
|
|
703
720
|
|
|
704
721
|
### Open Collective for Individuals
|
|
705
722
|
|
|
706
|
-
Support us with a monthly donation and help us continue our activities. \[[Become a backer]
|
|
723
|
+
Support us with a monthly donation and help us continue our activities. \[[Become a backer][🖇osc-backers]\]
|
|
707
724
|
|
|
708
|
-
NOTE: [kettle-readme-backers]
|
|
725
|
+
NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
|
|
709
726
|
|
|
710
727
|
<!-- OPENCOLLECTIVE-INDIVIDUALS:START -->
|
|
711
|
-
No backers yet. Be the first
|
|
728
|
+
No backers yet. Be the first!
|
|
712
729
|
<!-- OPENCOLLECTIVE-INDIVIDUALS:END -->
|
|
713
730
|
|
|
714
731
|
### Open Collective for Organizations
|
|
715
732
|
|
|
716
|
-
Become a sponsor and get your logo on our README on GitHub with a link to your site. \[[Become a sponsor]
|
|
733
|
+
Become a sponsor and get your logo on our README on GitHub with a link to your site. \[[Become a sponsor][🖇osc-sponsors]\]
|
|
717
734
|
|
|
718
|
-
NOTE: [kettle-readme-backers]
|
|
735
|
+
NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
|
|
719
736
|
|
|
720
737
|
<!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
|
|
721
|
-
No sponsors yet. Be the first
|
|
738
|
+
No sponsors yet. Be the first!
|
|
722
739
|
<!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
|
|
723
740
|
|
|
724
741
|
[kettle-readme-backers]: https://github.com/kettle-rb/json-merge/blob/main/exe/kettle-readme-backers
|
|
@@ -729,48 +746,48 @@ I’m driven by a passion to foster a thriving open-source community – a space
|
|
|
729
746
|
|
|
730
747
|
If you work at a company that uses my work, please encourage them to support me as a corporate sponsor. My work on gems you use might show up in `bundle fund`.
|
|
731
748
|
|
|
732
|
-
I’m developing a new library, [floss\_funding]
|
|
749
|
+
I’m developing a new library, [floss\_funding][🖇floss-funding-gem], designed to empower open-source developers like myself to get paid for the work we do, in a sustainable way. Please give it a look.
|
|
733
750
|
|
|
734
|
-
**[Floss-Funding.dev]
|
|
751
|
+
**[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
|
|
735
752
|
|
|
736
|
-
[![OpenCollective Backers]
|
|
753
|
+
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
737
754
|
|
|
738
755
|
## 🔐 Security
|
|
739
756
|
|
|
740
|
-
See [SECURITY.md]
|
|
757
|
+
See [SECURITY.md][🔐security].
|
|
741
758
|
|
|
742
759
|
## 🤝 Contributing
|
|
743
760
|
|
|
744
761
|
If you need some ideas of where to help, you could work on adding more code coverage,
|
|
745
|
-
or if it is already 💯 (see [below](#code-coverage)) check [reek](REEK), [issues]
|
|
762
|
+
or if it is already 💯 (see [below](#code-coverage)) check [reek](REEK), [issues][🤝gh-issues], or [PRs][🤝gh-pulls],
|
|
746
763
|
or use the gem and think about how it could be better.
|
|
747
764
|
|
|
748
|
-
We [![Keep A Changelog]
|
|
765
|
+
We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
|
|
749
766
|
|
|
750
|
-
See [CONTRIBUTING.md]
|
|
767
|
+
See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
|
|
751
768
|
|
|
752
769
|
### 🚀 Release Instructions
|
|
753
770
|
|
|
754
|
-
See [CONTRIBUTING.md]
|
|
771
|
+
See [CONTRIBUTING.md][🤝contributing].
|
|
755
772
|
|
|
756
773
|
### Code Coverage
|
|
757
774
|
|
|
758
|
-
[![Coverage Graph]
|
|
775
|
+
[![Coverage Graph][🏀codecov-g]][🏀codecov]
|
|
759
776
|
|
|
760
|
-
[![Coveralls Test Coverage]
|
|
777
|
+
[![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
|
|
761
778
|
|
|
762
|
-
[![QLTY Test Coverage]
|
|
779
|
+
[![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
|
|
763
780
|
|
|
764
781
|
### 🪇 Code of Conduct
|
|
765
782
|
|
|
766
783
|
Everyone interacting with this project's codebases, issue trackers,
|
|
767
|
-
chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1]
|
|
784
|
+
chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
|
|
768
785
|
|
|
769
786
|
## 🌈 Contributors
|
|
770
787
|
|
|
771
|
-
[![Contributors]
|
|
788
|
+
[![Contributors][🖐contributors-img]][🖐contributors]
|
|
772
789
|
|
|
773
|
-
Made with [contributors-img]
|
|
790
|
+
Made with [contributors-img][🖐contrib-rocks].
|
|
774
791
|
|
|
775
792
|
Also see GitLab Contributors: <https://gitlab.com/kettle-rb/json-merge/-/graphs/main>
|
|
776
793
|
|
|
@@ -789,23 +806,23 @@ Also see GitLab Contributors: <https://gitlab.com/kettle-rb/json-merge/-/graphs/
|
|
|
789
806
|
|
|
790
807
|
## 📌 Versioning
|
|
791
808
|
|
|
792
|
-
This Library adheres to [![Semantic Versioning 2.0.0]
|
|
809
|
+
This Library adheres to [![Semantic Versioning 2.0.0][📌semver-img]][📌semver].
|
|
793
810
|
Violations of this scheme should be reported as bugs.
|
|
794
811
|
Specifically, if a minor or patch version is released that breaks backward compatibility,
|
|
795
812
|
a new version should be immediately released that restores compatibility.
|
|
796
813
|
Breaking changes to the public API will only be introduced with new major versions.
|
|
797
814
|
|
|
798
815
|
> dropping support for a platform is both obviously and objectively a breaking change <br/>
|
|
799
|
-
> —Jordan Harband ([@ljharb](https://github.com/ljharb), maintainer of SemVer) [in SemVer issue 716]
|
|
816
|
+
> —Jordan Harband ([@ljharb](https://github.com/ljharb), maintainer of SemVer) [in SemVer issue 716][📌semver-breaking]
|
|
800
817
|
|
|
801
818
|
I understand that policy doesn't work universally ("exceptions to every rule\!"),
|
|
802
819
|
but it is the policy here.
|
|
803
820
|
As such, in many cases it is good to specify a dependency on this library using
|
|
804
|
-
the [Pessimistic Version Constraint]
|
|
821
|
+
the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
|
|
805
822
|
|
|
806
823
|
For example:
|
|
807
824
|
|
|
808
|
-
```
|
|
825
|
+
```ruby
|
|
809
826
|
spec.add_dependency("json-merge", "~> 1.0")
|
|
810
827
|
```
|
|
811
828
|
|
|
@@ -818,16 +835,17 @@ is a *breaking change* to an API, and for that reason the bike shedding is endle
|
|
|
818
835
|
To get a better understanding of how SemVer is intended to work over a project's lifetime,
|
|
819
836
|
read this article from the creator of SemVer:
|
|
820
837
|
|
|
821
|
-
- ["Major Version Numbers are Not Sacred"]
|
|
838
|
+
- ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
|
|
839
|
+
|
|
822
840
|
</details>
|
|
823
841
|
|
|
824
|
-
See [CHANGELOG.md]
|
|
842
|
+
See [CHANGELOG.md][📌changelog] for a list of releases.
|
|
825
843
|
|
|
826
844
|
## 📄 License
|
|
827
845
|
|
|
828
846
|
The gem is available as open source under the terms of
|
|
829
|
-
the [MIT License]
|
|
830
|
-
See [LICENSE.txt]
|
|
847
|
+
the [MIT License][📄license] [![License: MIT][📄license-img]][📄license-ref].
|
|
848
|
+
See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright-notice-explainer].
|
|
831
849
|
|
|
832
850
|
### © Copyright
|
|
833
851
|
|
|
@@ -854,11 +872,11 @@ Please consider sponsoring me or the project.
|
|
|
854
872
|
|
|
855
873
|
To join the community or get help 👇️ Join the Discord.
|
|
856
874
|
|
|
857
|
-
[![Live Chat on Discord]
|
|
875
|
+
[![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord]
|
|
858
876
|
|
|
859
877
|
To say "thanks\!" ☝️ Join the Discord or 👇️ send money.
|
|
860
878
|
|
|
861
|
-
[![Sponsor kettle-rb/json-merge on Open Source Collective]
|
|
879
|
+
[![Sponsor kettle-rb/json-merge on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
862
880
|
|
|
863
881
|
### Please give the project a star ⭐ ♥.
|
|
864
882
|
|
|
@@ -899,7 +917,6 @@ Thanks for RTFM. ☺️
|
|
|
899
917
|
[✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
|
|
900
918
|
[✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white
|
|
901
919
|
[✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
|
|
902
|
-
|
|
903
920
|
[✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
|
|
904
921
|
[⛳️gem-namespace]: https://github.com/kettle-rb/json-merge
|
|
905
922
|
[⛳️namespace-img]: https://img.shields.io/badge/namespace-Json::Merge-3C2D2D.svg?style=square&logo=ruby&logoColor=white
|
|
@@ -1023,7 +1040,7 @@ Thanks for RTFM. ☺️
|
|
|
1023
1040
|
[📌gitmoji]: https://gitmoji.dev
|
|
1024
1041
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
1025
1042
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
1026
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.
|
|
1043
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.631-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
1027
1044
|
[🔐security]: SECURITY.md
|
|
1028
1045
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
1029
1046
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -13,14 +13,16 @@ module Json
|
|
|
13
13
|
#
|
|
14
14
|
# @param template_analysis [FileAnalysis] Analyzed template file
|
|
15
15
|
# @param dest_analysis [FileAnalysis] Analyzed destination file
|
|
16
|
-
# @param preference [Symbol] Which version to prefer when
|
|
16
|
+
# @param preference [Symbol, Hash] Which version to prefer when
|
|
17
17
|
# nodes have matching signatures:
|
|
18
18
|
# - :destination (default) - Keep destination version (customizations)
|
|
19
19
|
# - :template - Use template version (updates)
|
|
20
20
|
# @param add_template_only_nodes [Boolean] Whether to add nodes only in template
|
|
21
21
|
# @param match_refiner [#call, nil] Optional match refiner for fuzzy matching
|
|
22
22
|
# @param options [Hash] Additional options for forward compatibility
|
|
23
|
-
|
|
23
|
+
# @param node_typing [Hash{Symbol,String => #call}, nil] Node typing configuration
|
|
24
|
+
# for per-node-type preferences
|
|
25
|
+
def initialize(template_analysis, dest_analysis, preference: :destination, add_template_only_nodes: false, match_refiner: nil, node_typing: nil, **options)
|
|
24
26
|
super(
|
|
25
27
|
strategy: :batch,
|
|
26
28
|
preference: preference,
|
|
@@ -30,6 +32,7 @@ module Json
|
|
|
30
32
|
match_refiner: match_refiner,
|
|
31
33
|
**options
|
|
32
34
|
)
|
|
35
|
+
@node_typing = node_typing
|
|
33
36
|
@emitter = Emitter.new
|
|
34
37
|
end
|
|
35
38
|
|
|
@@ -168,14 +171,14 @@ module Json
|
|
|
168
171
|
|
|
169
172
|
# Emit closing brace
|
|
170
173
|
@emitter.emit_nested_object_end
|
|
171
|
-
elsif
|
|
174
|
+
elsif preference_for_pair(template_node, dest_node) == :destination
|
|
172
175
|
# Values are not both objects, or one/both are arrays - use preference and emit
|
|
173
176
|
# Arrays are always replaced, not merged
|
|
174
177
|
emit_node(dest_node, dest_analysis)
|
|
175
178
|
else
|
|
176
179
|
emit_node(template_node, template_analysis)
|
|
177
180
|
end
|
|
178
|
-
elsif
|
|
181
|
+
elsif preference_for_pair(template_node, dest_node) == :destination
|
|
179
182
|
# Leaf nodes or mismatched types - use preference
|
|
180
183
|
emit_node(dest_node, dest_analysis)
|
|
181
184
|
else
|
|
@@ -215,6 +218,32 @@ module Json
|
|
|
215
218
|
end
|
|
216
219
|
end
|
|
217
220
|
|
|
221
|
+
def preference_for_pair(template_node, dest_node)
|
|
222
|
+
return @preference unless @preference.is_a?(Hash)
|
|
223
|
+
|
|
224
|
+
typed_template = apply_node_typing(template_node)
|
|
225
|
+
typed_dest = apply_node_typing(dest_node)
|
|
226
|
+
|
|
227
|
+
if Ast::Merge::NodeTyping.typed_node?(typed_template)
|
|
228
|
+
merge_type = Ast::Merge::NodeTyping.merge_type_for(typed_template)
|
|
229
|
+
return @preference.fetch(merge_type) { default_preference } if merge_type
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
if Ast::Merge::NodeTyping.typed_node?(typed_dest)
|
|
233
|
+
merge_type = Ast::Merge::NodeTyping.merge_type_for(typed_dest)
|
|
234
|
+
return @preference.fetch(merge_type) { default_preference } if merge_type
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
default_preference
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def apply_node_typing(node)
|
|
241
|
+
return node unless @node_typing
|
|
242
|
+
return node unless node
|
|
243
|
+
|
|
244
|
+
Ast::Merge::NodeTyping.process(node, @node_typing)
|
|
245
|
+
end
|
|
246
|
+
|
|
218
247
|
# Emit a single node to the emitter
|
|
219
248
|
# @param node [NodeWrapper] Node to emit
|
|
220
249
|
# @param analysis [FileAnalysis] Analysis for accessing source
|
data/lib/json/merge/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
i��Kݟv�d�k��c-�\'��șh\V
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json-merge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -46,7 +46,7 @@ dependencies:
|
|
|
46
46
|
version: '5.0'
|
|
47
47
|
- - ">="
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: 5.0.
|
|
49
|
+
version: 5.0.2
|
|
50
50
|
type: :runtime
|
|
51
51
|
prerelease: false
|
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -56,7 +56,7 @@ dependencies:
|
|
|
56
56
|
version: '5.0'
|
|
57
57
|
- - ">="
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: 5.0.
|
|
59
|
+
version: 5.0.2
|
|
60
60
|
- !ruby/object:Gem::Dependency
|
|
61
61
|
name: ast-merge
|
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
version: '4.0'
|
|
67
67
|
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 4.0.
|
|
69
|
+
version: 4.0.4
|
|
70
70
|
type: :runtime
|
|
71
71
|
prerelease: false
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -76,7 +76,7 @@ dependencies:
|
|
|
76
76
|
version: '4.0'
|
|
77
77
|
- - ">="
|
|
78
78
|
- !ruby/object:Gem::Version
|
|
79
|
-
version: 4.0.
|
|
79
|
+
version: 4.0.4
|
|
80
80
|
- !ruby/object:Gem::Dependency
|
|
81
81
|
name: version_gem
|
|
82
82
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -294,10 +294,10 @@ licenses:
|
|
|
294
294
|
- MIT
|
|
295
295
|
metadata:
|
|
296
296
|
homepage_uri: https://json-merge.galtzo.com/
|
|
297
|
-
source_code_uri: https://github.com/kettle-rb/json-merge/tree/v1.1.
|
|
298
|
-
changelog_uri: https://github.com/kettle-rb/json-merge/blob/v1.1.
|
|
297
|
+
source_code_uri: https://github.com/kettle-rb/json-merge/tree/v1.1.1
|
|
298
|
+
changelog_uri: https://github.com/kettle-rb/json-merge/blob/v1.1.1/CHANGELOG.md
|
|
299
299
|
bug_tracker_uri: https://github.com/kettle-rb/json-merge/issues
|
|
300
|
-
documentation_uri: https://www.rubydoc.info/gems/json-merge/1.1.
|
|
300
|
+
documentation_uri: https://www.rubydoc.info/gems/json-merge/1.1.1
|
|
301
301
|
funding_uri: https://github.com/sponsors/pboling
|
|
302
302
|
wiki_uri: https://github.com/kettle-rb/json-merge/wiki
|
|
303
303
|
news_uri: https://www.railsbling.com/tags/json-merge
|
metadata.gz.sig
CHANGED
|
Binary file
|