dotenv-merge 1.0.1 → 1.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2f61ab8206645b763c803606b57761a9d2f2dfd1ab9681a3d2403041750ecc0
4
- data.tar.gz: 0fe6095d564764ac602d7382d1c7257dfb9be78e908256fd3be6899b317755fd
3
+ metadata.gz: 9c982a0bec61937d370eb9b353e1da52cc960fb76e20e477922a9edbed7ec064
4
+ data.tar.gz: 4463c4e011c866bb24cfe3031ba2f1017372aede506f065c0c1a7aa88a5929df
5
5
  SHA512:
6
- metadata.gz: 30eaef68fe4f68ad4851c0493f4e138468de2c3c348c3df495ec01c509d65ad2b9050f75749eb2f7394acded92e960cc79b4a955174e261d96101099dbc43f47
7
- data.tar.gz: 9f913cc700a8c5138ea286c78e30049f70321a12171fa6cf66d528d4739781e50ed71d12cdb046fd74b820b860ec4520b87ebed71b668ffab7b7a8dd8f0411b2
6
+ metadata.gz: 2e9f2c6b34e2dbb1c9f303f48a40762ff7c4c06c33cfe223f65cde1e96938e80c894c7f4571e0da6aff84052d8911ef3c1de4b2bd08eb93dc4963fd191b8e50c
7
+ data.tar.gz: b68ac2aa403de2eb8ca7d795bbb1a51d522cb25426c9ffea0ccea6e38819c618234c1e606f8ae7d2a9fe83361f486161b486c7e92f03184117e532a3af7f2d50
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,23 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.0.2] - 2026-02-01
34
+
35
+ - TAG: [v1.0.2][1.0.2t]
36
+ - COVERAGE: 97.73% -- 345/353 lines in 8 files
37
+ - BRANCH COVERAGE: 83.06% -- 103/124 branches in 8 files
38
+ - 96.83% documented
39
+
40
+ ### Added
41
+
42
+ - Utilizes `Ast::Merge::RSpec::MergeGemRegistry` when running RSpec tests
43
+
44
+ ### Changed
45
+
46
+ - Documentation cleanup
47
+ - Upgrade to [ast-merge v4.0.5](https://github.com/kettle-rb/ast-merge/releases/tag/v4.0.5)
48
+ - Upgrade to [tree_haver v5.0.3](https://github.com/kettle-rb/tree_haver/releases/tag/v5.0.3)
49
+
33
50
  ## [1.0.1] - 2026-01-01
34
51
 
35
52
  - TAG: [v1.0.1][1.0.1t]
@@ -69,7 +86,9 @@ Please file a bug if you notice a violation of semantic versioning.
69
86
 
70
87
  - Initial release
71
88
 
72
- [Unreleased]: https://github.com/kettle-rb/dotenv-merge/compare/v1.0.1...HEAD
89
+ [Unreleased]: https://github.com/kettle-rb/dotenv-merge/compare/v1.0.2...HEAD
90
+ [1.0.2]: https://github.com/kettle-rb/dotenv-merge/compare/v1.0.1...v1.0.2
91
+ [1.0.2t]: https://github.com/kettle-rb/dotenv-merge/releases/tag/v1.0.2
73
92
  [1.0.1]: https://github.com/kettle-rb/dotenv-merge/compare/v1.0.0...v1.0.1
74
93
  [1.0.1t]: https://github.com/kettle-rb/dotenv-merge/releases/tag/v1.0.1
75
94
  [1.0.0]: https://github.com/kettle-rb/dotenv-merge/compare/a34c8f20c877a45d03b9f0b83b973614e123a92b...v1.0.0
data/README.md CHANGED
@@ -1,16 +1,16 @@
1
- | 📍 NOTE |
2
- | --- |
3
- | RubyGems (the [GitHub org](https://github.com/rubygems/), not the website) [suffered](https://joel.drapper.me/p/ruby-central-security-measures/) a [hostile takeover](https://pup-e.com/blog/goodbye-rubygems/) in September 2025. |
4
- | Ultimately [4 maintainers](https://www.reddit.com/r/ruby/s/gOk42POCaV) were [hard removed](https://bsky.app/profile/martinemde.com/post/3m3occezxxs2q) and a reason has been given for only 1 of those, while 2 others resigned in protest. |
5
- | It is a [complicated story](https://joel.drapper.me/p/ruby-central-takeover/) which is difficult to [parse quickly](https://joel.drapper.me/p/ruby-central-fact-check/). |
6
- | Simply put - there was active policy for adding or removing maintainers/owners of [rubygems](https://github.com/ruby/rubygems/blob/b1ab33a3d52310a84d16b193991af07f5a6a07c0/doc/rubygems/POLICIES.md?plain=1#L187-L196) and [bundler](https://github.com/ruby/rubygems/blob/b1ab33a3d52310a84d16b193991af07f5a6a07c0/doc/bundler/playbooks/TEAM_CHANGES.md), and those [policies were not followed](https://www.reddit.com/r/ruby/comments/1ove9vp/rubycentral_hates_this_one_fact/). |
7
- | I'm adding notes like this to gems because I [don't condone theft](https://joel.drapper.me/p/ruby-central/) of repositories or gems from their rightful owners. |
8
- | If a similar theft happened with my repos/gems, I'd hope some would stand up for me. |
9
- | Disenfranchised former-maintainers have started [gem.coop](https://gem.coop). |
10
- | Once available I will publish there exclusively; unless RubyCentral makes amends with the community. |
11
- | The ["Technology for Humans: Joel Draper"](https://youtu.be/_H4qbtC5qzU?si=BvuBU90R2wAqD2E6) podcast episode by [reinteractive](https://reinteractive.com/ruby-on-rails) is the most cogent summary I'm aware of. |
12
- | See [here](https://github.com/gem-coop/gem.coop/issues/12), [here](https://gem.coop) and [here](https://martinemde.com/2025/10/05/announcing-gem-coop.html) for more info on what comes next. |
13
- | What I'm doing: A (WIP) proposal for [bundler/gem scopes](https://github.com/galtzo-floss/bundle-namespace), and a (WIP) proposal for a federated [gem server](https://github.com/galtzo-floss/gem-server). |
1
+ | 📍 NOTE |
2
+ |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
3
+ | RubyGems (the [GitHub org][rubygems-org], not the website) [suffered][draper-security] a [hostile takeover][ellen-takeover] in September 2025. |
4
+ | Ultimately [4 maintainers][simi-removed] were [hard removed][martin-removed] and a reason has been given for only 1 of those, while 2 others resigned in protest. |
5
+ | It is a [complicated story][draper-takeover] which is difficult to [parse quickly][draper-lies]. |
6
+ | Simply put - there was active policy for adding or removing maintainers/owners of [rubygems][rubygems-maint-policy] and [bundler][bundler-maint-policy], and those [policies were not followed][policy-fail]. |
7
+ | I'm adding notes like this to gems because I [don't condone theft][draper-theft] of repositories or gems from their rightful owners. |
8
+ | If a similar theft happened with my repos/gems, I'd hope some would stand up for me. |
9
+ | Disenfranchised former-maintainers have started [gem.coop][gem-coop]. |
10
+ | Once available I will publish there exclusively; unless RubyCentral makes amends with the community. |
11
+ | The ["Technology for Humans: Joel Draper"][reinteractive-podcast] podcast episode by [reinteractive][reinteractive] is the most cogent summary I'm aware of. |
12
+ | See [here][gem-naming], [here][gem-coop] and [here][martin-ann] for more info on what comes next. |
13
+ | What I'm doing: A (WIP) proposal for [bundler/gem scopes][gem-scopes], and a (WIP) proposal for a federated [gem server][gem-server]. |
14
14
 
15
15
  [rubygems-org]: https://github.com/rubygems/
16
16
  [draper-security]: https://joel.drapper.me/p/ruby-central-security-measures/
@@ -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](https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg)](https://discord.gg/3qme4XHNKN) [![ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5](https://logos.galtzo.com/assets/images/ruby-lang/avatar-192px.svg)](https://www.ruby-lang.org/) [![kettle-rb Logo by Aboling0, CC BY-SA 4.0](https://logos.galtzo.com/assets/images/kettle-rb/avatar-192px.svg)](https://github.com/kettle-rb)
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,33 +42,34 @@
42
42
 
43
43
  # ☯️ Dotenv::Merge
44
44
 
45
- [![Version](https://img.shields.io/gem/v/dotenv-merge.svg)](https://bestgems.org/gems/dotenv-merge) [![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/kettle-rb/dotenv-merge.svg)](http://github.com/kettle-rb/dotenv-merge/releases) [![License: MIT](https://img.shields.io/badge/License-MIT-259D6C.svg)](https://opensource.org/licenses/MIT) [![Downloads Rank](https://img.shields.io/gem/rd/dotenv-merge.svg)](https://bestgems.org/gems/dotenv-merge) [![Open Source Helpers](https://www.codetriage.com/kettle-rb/dotenv-merge/badges/users.svg)](https://www.codetriage.com/kettle-rb/dotenv-merge) [![CodeCov Test Coverage](https://codecov.io/gh/kettle-rb/dotenv-merge/graph/badge.svg)](https://codecov.io/gh/kettle-rb/dotenv-merge) [![Coveralls Test Coverage](https://coveralls.io/repos/github/kettle-rb/dotenv-merge/badge.svg?branch=main)](https://coveralls.io/github/kettle-rb/dotenv-merge?branch=main) [![QLTY Test Coverage](https://qlty.sh/gh/kettle-rb/projects/dotenv-merge/coverage.svg)](https://qlty.sh/gh/kettle-rb/projects/dotenv-merge/metrics/code?sort=coverageRating) [![QLTY Maintainability](https://qlty.sh/gh/kettle-rb/projects/dotenv-merge/maintainability.svg)](https://qlty.sh/gh/kettle-rb/projects/dotenv-merge) [![CI Heads](https://github.com/kettle-rb/dotenv-merge/actions/workflows/heads.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/heads.yml) [![CI Runtime Dependencies @ HEAD](https://github.com/kettle-rb/dotenv-merge/actions/workflows/dep-heads.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/dep-heads.yml) [![CI Current](https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml) [![CI Truffle Ruby](https://github.com/kettle-rb/dotenv-merge/actions/workflows/truffle.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/truffle.yml) [![Deps Locked](https://github.com/kettle-rb/dotenv-merge/actions/workflows/locked_deps.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/locked_deps.yml) [![Deps Unlocked](https://github.com/kettle-rb/dotenv-merge/actions/workflows/unlocked_deps.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/unlocked_deps.yml) [![CI Supported](https://github.com/kettle-rb/dotenv-merge/actions/workflows/supported.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/supported.yml) [![CI Test Coverage](https://github.com/kettle-rb/dotenv-merge/actions/workflows/coverage.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/coverage.yml) [![CI Style](https://github.com/kettle-rb/dotenv-merge/actions/workflows/style.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/style.yml) [![CodeQL](https://github.com/kettle-rb/dotenv-merge/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/security/code-scanning) [![Apache SkyWalking Eyes License Compatibility Check](https://github.com/kettle-rb/dotenv-merge/actions/workflows/license-eye.yml/badge.svg)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/license-eye.yml)
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](https://discord.gg/3qme4XHNKN), as I may have missed the [discord notification](https://discord.gg/3qme4XHNKN).
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](https://opencollective.com/kettle-rb/backers/badge.svg?style=flat)](https://opencollective.com/kettle-rb#backer) [![OpenCollective Sponsors](https://opencollective.com/kettle-rb/sponsors/badge.svg?style=flat)](https://opencollective.com/kettle-rb#sponsor) [![Sponsor Me on Github](https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github)](https://github.com/sponsors/pboling) [![Liberapay Goal Progress](https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat)](https://liberapay.com/pboling/donate) [![Donate on PayPal](https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal)](https://www.paypal.com/paypalme/peterboling) [![Buy me a coffee](https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat)](https://www.buymeacoffee.com/pboling) [![Donate on Polar](https://img.shields.io/badge/polar-donate-a51611.svg?style=flat)](https://polar.sh/pboling) [![Donate at ko-fi.com](https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat)](https://ko-fi.com/O5O86SNP4)
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
- Dotenv::Merge is a standalone Ruby module that intelligently merges two versions of a dotenv (`.env`) file. It's like a smart "git merge" specifically designed for environment configuration files. Built on top of [ast-merge](https://github.com/kettle-rb/ast-merge), it shares the same architecture as [prism-merge](https://github.com/kettle-rb/prism-merge) for Ruby source files.
57
+ Dotenv::Merge is a standalone Ruby module that intelligently merges two versions of a dotenv (`.env`) file. It's like a smart "git merge" specifically designed for environment 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
59
  ### Key Features
59
60
 
60
- - **Dotenv-Aware**: Understands dotenv file format (KEY=value, comments, exports)
61
- - **Intelligent**: Matches environment variables by key name
62
- - **Comment-Preserving**: Comments and blank lines are preserved in their context
63
- - **Freeze Block Support**: Respects freeze markers (default: `dotenv-merge:freeze` / `dotenv-merge:unfreeze`) for merge control - customizable to match your project's conventions
64
- - **Full Provenance**: Tracks origin of every line
65
- - **Standalone**: Minimal dependencies - just `ast-merge`
66
- - **Customizable**:
67
- - `signature_generator` - callable custom signature generators
68
- - `preference` - setting of `:template`, `:destination`, or a Hash for per-node-type preferences
69
- - `node_splitter` - Hash mapping node types to callables for per-node-type merge customization (see [ast-merge](https://github.com/kettle-rb/ast-merge) docs)
70
- - `add_template_only_nodes` - setting to retain variables that do not exist in destination
71
- - `freeze_token` - customize freeze block markers (default: `"dotenv-merge"`)
61
+ - **Dotenv-Aware**: Understands dotenv file format (KEY=value, comments, exports)
62
+ - **Intelligent**: Matches environment variables by key name
63
+ - **Comment-Preserving**: Comments and blank lines are preserved in their context
64
+ - **Freeze Block Support**: Respects freeze markers (default: `dotenv-merge:freeze` / `dotenv-merge:unfreeze`) for merge control - customizable to match your project's conventions
65
+ - **Full Provenance**: Tracks origin of every line
66
+ - **Standalone**: Minimal dependencies - just `ast-merge`
67
+ - **Customizable**:
68
+ - `signature_generator` - callable custom signature generators
69
+ - `preference` - setting of `:template`, `:destination`, or a Hash for per-node-type preferences
70
+ - `node_splitter` - Hash mapping node types to callables for per-node-type merge customization (see [ast-merge][ast-merge] docs)
71
+ - `add_template_only_nodes` - setting to retain variables that do not exist in destination
72
+ - `freeze_token` - customize freeze block markers (default: `"dotenv-merge"`)
72
73
 
73
74
  ### Supported Line Types
74
75
 
@@ -84,7 +85,7 @@ Dotenv::Merge is a standalone Ruby module that intelligently merges two versions
84
85
 
85
86
  ### Example
86
87
 
87
- ``` ruby
88
+ ```ruby
88
89
  require "dotenv/merge"
89
90
 
90
91
  template = File.read("template.env")
@@ -96,33 +97,57 @@ result = merger.merge
96
97
  File.write("merged.env", result.to_s)
97
98
  ```
98
99
 
99
-
100
100
  ### The `*-merge` Gem Family
101
101
 
102
102
  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
103
 
104
- | Gem | Format | Parser Backend(s) | Description |
105
- |------------------------------------------|----------|-----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
106
- | [tree_haver][tree_haver] | Multi | MRI C, Rust, FFI, Java, Prism, Psych, Commonmarker, Markly, Citrus | **Foundation**: Cross-Ruby adapter for parsing libraries (like Faraday for HTTP) |
107
- | [ast-merge][ast-merge] | Text | internal | **Infrastructure**: Shared base classes and merge logic for all `*-merge` gems |
108
- | [prism-merge][prism-merge] | Ruby | [Prism][prism] | Smart merge for Ruby source files |
109
- | [psych-merge][psych-merge] | YAML | [Psych][psych] | Smart merge for YAML files |
110
- | [json-merge][json-merge] | JSON | [tree-sitter-json][ts-json] (via tree_haver) | Smart merge for JSON files |
111
- | [jsonc-merge][jsonc-merge] | JSONC | [tree-sitter-jsonc][ts-jsonc] (via tree_haver) | ⚠️ Proof of concept; Smart merge for JSON with Comments |
112
- | [bash-merge][bash-merge] | Bash | [tree-sitter-bash][ts-bash] (via tree_haver) | Smart merge for Bash scripts |
113
- | [rbs-merge][rbs-merge] | RBS | [RBS][rbs] | Smart merge for Ruby type signatures |
114
- | [dotenv-merge][dotenv-merge] | Dotenv | internal | Smart merge for `.env` files |
115
- | [toml-merge][toml-merge] | TOML | [Citrus + toml-rb][toml-rb] (default, via tree_haver), [tree-sitter-toml][ts-toml] (via tree_haver) | Smart merge for TOML files |
116
- | [markdown-merge][markdown-merge] | Markdown | [Commonmarker][commonmarker] / [Markly][markly] (via tree_haver) | **Foundation**: Shared base for Markdown mergers with inner code block merging |
117
- | [markly-merge][markly-merge] | Markdown | [Markly][markly] (via tree_haver) | Smart merge for Markdown (CommonMark via cmark-gfm C) |
118
- | [commonmarker-merge][commonmarker-merge] | Markdown | [Commonmarker][commonmarker] (via tree_haver) | Smart merge for Markdown (CommonMark via comrak Rust) |
104
+ | Gem | Version / CI | Language<br>/ Format | Parser Backend(s) | Description |
105
+ |------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------:|----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
106
+ | [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) |
107
+ | [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 |
108
+ | [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 |
109
+ | [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) |
110
+ | [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 |
111
+ | [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 |
112
+ | [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 |
113
+ | [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 |
114
+ | [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) |
115
+ | [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 |
116
+ | [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 |
117
+ | [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 |
118
+ | [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
+
120
+ #### Backend Platform Compatibility
121
+
122
+ tree_haver supports multiple parsing backends, but not all backends work on all Ruby platforms:
123
+
124
+ | Platform 👉️<br> TreeHaver Backend 👇️ | MRI | JRuby | TruffleRuby | Notes |
125
+ |-------------------------------------------------|:---:|:-----:|:-----------:|----------------------------------------------------------------------------|
126
+ | **MRI** ([ruby_tree_sitter][ruby_tree_sitter]) | ✅ | ❌ | ❌ | C extension, MRI only |
127
+ | **Rust** ([tree_stump][tree_stump]) | ✅ | ❌ | ❌ | Rust extension via magnus/rb-sys, MRI only |
128
+ | **FFI** ([ffi][ffi]) | ✅ | ✅ | ❌ | TruffleRuby's FFI doesn't support `STRUCT_BY_VALUE` |
129
+ | **Java** ([jtreesitter][jtreesitter]) | ❌ | ✅ | ❌ | JRuby only, requires grammar JARs |
130
+ | **Prism** ([prism][prism]) | ✅ | ✅ | ✅ | Ruby parsing, stdlib in Ruby 3.4+ |
131
+ | **Psych** ([psych][psych]) | ✅ | ✅ | ✅ | YAML parsing, stdlib |
132
+ | **Citrus** ([citrus][citrus]) | ✅ | ✅ | ✅ | Pure Ruby PEG parser, no native dependencies |
133
+ | **Parslet** ([parslet][parslet]) | ✅ | ✅ | ✅ | Pure Ruby PEG parser, no native dependencies |
134
+ | **Commonmarker** ([commonmarker][commonmarker]) | ✅ | ❌ | ❓ | Rust extension for Markdown (via [commonmarker-merge][commonmarker-merge]) |
135
+ | **Markly** ([markly][markly]) | ✅ | ❌ | ❓ | C extension for Markdown (via [markly-merge][markly-merge]) |
136
+
137
+ **Legend**: ✅ = Works, ❌ = Does not work, ❓ = Untested
138
+
139
+ **Why some backends don't work on certain platforms**:
140
+
141
+ - **JRuby**: Runs on the JVM; cannot load native C/Rust extensions (`.so` files)
142
+ - **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`)
143
+ - **FFI on TruffleRuby**: TruffleRuby's FFI implementation doesn't support returning structs by value, which tree-sitter's C API requires
119
144
 
120
145
  **Example implementations** for the gem templating use case:
121
146
 
122
- | Gem | Purpose | Description |
123
- | --- | --- | --- |
124
- | [kettle-dev](https://github.com/kettle-rb/kettle-dev) | Gem Development | Gem templating tool using `*-merge` gems |
125
- | [kettle-jem](https://github.com/kettle-rb/kettle-jem) | Gem Templating | Gem template library with smart merge support |
147
+ | Gem | Purpose | Description |
148
+ |--------------------------|-----------------|-----------------------------------------------|
149
+ | [kettle-dev][kettle-dev] | Gem Development | Gem templating tool using `*-merge` gems |
150
+ | [kettle-jem][kettle-jem] | Gem Templating | Gem template library with smart merge support |
126
151
 
127
152
  [tree_haver]: https://github.com/kettle-rb/tree_haver
128
153
  [ast-merge]: https://github.com/kettle-rb/ast-merge
@@ -139,58 +164,126 @@ The `*-merge` gem family provides intelligent, AST-based merging for various fil
139
164
  [commonmarker-merge]: https://github.com/kettle-rb/commonmarker-merge
140
165
  [kettle-dev]: https://github.com/kettle-rb/kettle-dev
141
166
  [kettle-jem]: https://github.com/kettle-rb/kettle-jem
167
+ [tree_haver-gem]: https://bestgems.org/gems/tree_haver
168
+ [ast-merge-gem]: https://bestgems.org/gems/ast-merge
169
+ [prism-merge-gem]: https://bestgems.org/gems/prism-merge
170
+ [psych-merge-gem]: https://bestgems.org/gems/psych-merge
171
+ [json-merge-gem]: https://bestgems.org/gems/json-merge
172
+ [jsonc-merge-gem]: https://bestgems.org/gems/jsonc-merge
173
+ [bash-merge-gem]: https://bestgems.org/gems/bash-merge
174
+ [rbs-merge-gem]: https://bestgems.org/gems/rbs-merge
175
+ [dotenv-merge-gem]: https://bestgems.org/gems/dotenv-merge
176
+ [toml-merge-gem]: https://bestgems.org/gems/toml-merge
177
+ [markdown-merge-gem]: https://bestgems.org/gems/markdown-merge
178
+ [markly-merge-gem]: https://bestgems.org/gems/markly-merge
179
+ [commonmarker-merge-gem]: https://bestgems.org/gems/commonmarker-merge
180
+ [kettle-dev-gem]: https://bestgems.org/gems/kettle-dev
181
+ [kettle-jem-gem]: https://bestgems.org/gems/kettle-jem
182
+ [tree_haver-gem-i]: https://img.shields.io/gem/v/tree_haver.svg
183
+ [ast-merge-gem-i]: https://img.shields.io/gem/v/ast-merge.svg
184
+ [prism-merge-gem-i]: https://img.shields.io/gem/v/prism-merge.svg
185
+ [psych-merge-gem-i]: https://img.shields.io/gem/v/psych-merge.svg
186
+ [json-merge-gem-i]: https://img.shields.io/gem/v/json-merge.svg
187
+ [jsonc-merge-gem-i]: https://img.shields.io/gem/v/jsonc-merge.svg
188
+ [bash-merge-gem-i]: https://img.shields.io/gem/v/bash-merge.svg
189
+ [rbs-merge-gem-i]: https://img.shields.io/gem/v/rbs-merge.svg
190
+ [dotenv-merge-gem-i]: https://img.shields.io/gem/v/dotenv-merge.svg
191
+ [toml-merge-gem-i]: https://img.shields.io/gem/v/toml-merge.svg
192
+ [markdown-merge-gem-i]: https://img.shields.io/gem/v/markdown-merge.svg
193
+ [markly-merge-gem-i]: https://img.shields.io/gem/v/markly-merge.svg
194
+ [commonmarker-merge-gem-i]: https://img.shields.io/gem/v/commonmarker-merge.svg
195
+ [kettle-dev-gem-i]: https://img.shields.io/gem/v/kettle-dev.svg
196
+ [kettle-jem-gem-i]: https://img.shields.io/gem/v/kettle-jem.svg
197
+ [tree_haver-ci-i]: https://github.com/kettle-rb/tree_haver/actions/workflows/current.yml/badge.svg
198
+ [ast-merge-ci-i]: https://github.com/kettle-rb/ast-merge/actions/workflows/current.yml/badge.svg
199
+ [prism-merge-ci-i]: https://github.com/kettle-rb/prism-merge/actions/workflows/current.yml/badge.svg
200
+ [psych-merge-ci-i]: https://github.com/kettle-rb/psych-merge/actions/workflows/current.yml/badge.svg
201
+ [json-merge-ci-i]: https://github.com/kettle-rb/json-merge/actions/workflows/current.yml/badge.svg
202
+ [jsonc-merge-ci-i]: https://github.com/kettle-rb/jsonc-merge/actions/workflows/current.yml/badge.svg
203
+ [bash-merge-ci-i]: https://github.com/kettle-rb/bash-merge/actions/workflows/current.yml/badge.svg
204
+ [rbs-merge-ci-i]: https://github.com/kettle-rb/rbs-merge/actions/workflows/current.yml/badge.svg
205
+ [dotenv-merge-ci-i]: https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml/badge.svg
206
+ [toml-merge-ci-i]: https://github.com/kettle-rb/toml-merge/actions/workflows/current.yml/badge.svg
207
+ [markdown-merge-ci-i]: https://github.com/kettle-rb/markdown-merge/actions/workflows/current.yml/badge.svg
208
+ [markly-merge-ci-i]: https://github.com/kettle-rb/markly-merge/actions/workflows/current.yml/badge.svg
209
+ [commonmarker-merge-ci-i]: https://github.com/kettle-rb/commonmarker-merge/actions/workflows/current.yml/badge.svg
210
+ [kettle-dev-ci-i]: https://github.com/kettle-rb/kettle-dev/actions/workflows/current.yml/badge.svg
211
+ [kettle-jem-ci-i]: https://github.com/kettle-rb/kettle-jem/actions/workflows/current.yml/badge.svg
212
+ [tree_haver-ci]: https://github.com/kettle-rb/tree_haver/actions/workflows/current.yml
213
+ [ast-merge-ci]: https://github.com/kettle-rb/ast-merge/actions/workflows/current.yml
214
+ [prism-merge-ci]: https://github.com/kettle-rb/prism-merge/actions/workflows/current.yml
215
+ [psych-merge-ci]: https://github.com/kettle-rb/psych-merge/actions/workflows/current.yml
216
+ [json-merge-ci]: https://github.com/kettle-rb/json-merge/actions/workflows/current.yml
217
+ [jsonc-merge-ci]: https://github.com/kettle-rb/jsonc-merge/actions/workflows/current.yml
218
+ [bash-merge-ci]: https://github.com/kettle-rb/bash-merge/actions/workflows/current.yml
219
+ [rbs-merge-ci]: https://github.com/kettle-rb/rbs-merge/actions/workflows/current.yml
220
+ [dotenv-merge-ci]: https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml
221
+ [toml-merge-ci]: https://github.com/kettle-rb/toml-merge/actions/workflows/current.yml
222
+ [markdown-merge-ci]: https://github.com/kettle-rb/markdown-merge/actions/workflows/current.yml
223
+ [markly-merge-ci]: https://github.com/kettle-rb/markly-merge/actions/workflows/current.yml
224
+ [commonmarker-merge-ci]: https://github.com/kettle-rb/commonmarker-merge/actions/workflows/current.yml
225
+ [kettle-dev-ci]: https://github.com/kettle-rb/kettle-dev/actions/workflows/current.yml
226
+ [kettle-jem-ci]: https://github.com/kettle-rb/kettle-jem/actions/workflows/current.yml
142
227
  [prism]: https://github.com/ruby/prism
143
228
  [psych]: https://github.com/ruby/psych
229
+ [ffi]: https://github.com/ffi/ffi
144
230
  [ts-json]: https://github.com/tree-sitter/tree-sitter-json
231
+ [ts-jsonc]: https://gitlab.com/WhyNotHugo/tree-sitter-jsonc
145
232
  [ts-bash]: https://github.com/tree-sitter/tree-sitter-bash
233
+ [ts-rbs]: https://github.com/joker1007/tree-sitter-rbs
146
234
  [ts-toml]: https://github.com/tree-sitter-grammars/tree-sitter-toml
235
+ [dotenv]: https://github.com/bkeepers/dotenv
147
236
  [rbs]: https://github.com/ruby/rbs
148
237
  [toml-rb]: https://github.com/emancu/toml-rb
238
+ [toml]: https://github.com/jm/toml
149
239
  [markly]: https://github.com/ioquatix/markly
150
240
  [commonmarker]: https://github.com/gjtorikian/commonmarker
151
- [ts-jsonc]: https://gitlab.com/WhyNotHugo/tree-sitter-jsonc
152
- [dotenv]: https://github.com/bkeepers/dotenv
241
+ [ruby_tree_sitter]: https://github.com/Faveod/ruby-tree-sitter
242
+ [tree_stump]: https://github.com/joker1007/tree_stump
243
+ [jtreesitter]: https://central.sonatype.com/artifact/io.github.tree-sitter/jtreesitter
244
+ [citrus]: https://github.com/mjackson/citrus
245
+ [parslet]: https://github.com/kschiess/parslet
153
246
 
154
247
  ## 💡 Info you can shake a stick at
155
248
 
156
- | Tokens to Remember | [![Gem name](https://img.shields.io/badge/name-dotenv--merge-3C2D2D.svg?style=square&logo=rubygems&logoColor=red)](https://bestgems.org/gems/dotenv-merge) [![Gem namespace](https://img.shields.io/badge/namespace-Dotenv::Merge-3C2D2D.svg?style=square&logo=ruby&logoColor=white)](https://github.com/kettle-rb/dotenv-merge) |
157
- | --- | --- |
158
- | Works with JRuby | [![JRuby 10.0 Compat](https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml) [![JRuby HEAD Compat](https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/heads.yml) |
159
- | Works with Truffle Ruby | [![Truffle Ruby 23.1 Compat](https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/truffle.yml) [![Truffle Ruby 24.1 Compat](https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml) |
160
- | Works with MRI Ruby 3 | [![Ruby 3.2 Compat](https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/supported.yml) [![Ruby 3.3 Compat](https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/supported.yml) [![Ruby 3.4 Compat](https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/current.yml) [![Ruby HEAD Compat](https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue)](https://github.com/kettle-rb/dotenv-merge/actions/workflows/heads.yml) |
161
- | Support & Community | [![Join Me on Daily.dev's RubyFriends](https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white)](https://app.daily.dev/squads/rubyfriends) [![Live Chat on Discord](https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord)](https://discord.gg/3qme4XHNKN) [![Get help from me on Upwork](https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white)](https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share) [![Get help from me on Codementor](https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white)](https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github) |
162
- | Source | [![Source on GitLab.com](https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange)](https://gitlab.com/kettle-rb/dotenv-merge/) [![Source on CodeBerg.org](https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue)](https://codeberg.org/kettle-rb/dotenv-merge) [![Source on Github.com](https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green)](https://github.com/kettle-rb/dotenv-merge) [![The best SHA: dQw4w9WgXcQ\!](https://img.shields.io/badge/KLOC-0.326-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue)](https://www.youtube.com/watch?v=dQw4w9WgXcQ) |
163
- | Documentation | [![Current release on RubyDoc.info](https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white)](http://rubydoc.info/gems/dotenv-merge) [![YARD on Galtzo.com](https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white)](https://dotenv-merge.galtzo.com) [![Maintainer Blog](https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange)](http://www.railsbling.com/tags/dotenv-merge) [![GitLab Wiki](https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white)](https://gitlab.com/kettle-rb/dotenv-merge/-/wikis/home) [![GitHub Wiki](https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/kettle-rb/dotenv-merge/wiki) |
164
- | Compliance | [![License: MIT](https://img.shields.io/badge/License-MIT-259D6C.svg)](https://opensource.org/licenses/MIT) [![Compatible with Apache Software Projects: Verified by SkyWalking Eyes](https://img.shields.io/badge/Apache_Compatible:_Category_A-%E2%9C%93-259D6C.svg?style=flat&logo=Apache)](https://dev.to/galtzo/how-to-check-license-compatibility-41h0) [![📄ilo-declaration-img](https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat)](https://www.ilo.org/declaration/lang--en/index.htm) [![Security Policy](https://img.shields.io/badge/security-policy-259D6C.svg?style=flat)](SECURITY.md) [![Contributor Covenant 2.1](https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg)](CODE_OF_CONDUCT.md) [![SemVer 2.0.0](https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat)](https://semver.org/spec/v2.0.0.html) |
165
- | Style | [![Enforced Code Style Linter](https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white)](https://github.com/rubocop-lts/rubocop-lts) [![Keep-A-Changelog 1.0.0](https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat)](https://keepachangelog.com/en/1.0.0/) [![Gitmoji Commits](https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square)](https://gitmoji.dev) [![Compatibility appraised by: appraisal2](https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white)](https://github.com/appraisal-rb/appraisal2) |
166
- | Maintainer 🎖️ | [![Follow Me on LinkedIn](https://img.shields.io/badge/PeterBoling-LinkedIn-0B66C2?style=flat&logo=newjapanprowrestling)](http://www.linkedin.com/in/peterboling) [![Follow Me on Ruby.Social](https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo)](https://ruby.social/@galtzo) [![Follow Me on Bluesky](https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white)](https://bsky.app/profile/galtzo.com) [![Contact Maintainer](https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red)](http://www.railsbling.com/contact) [![My technical writing](https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white)](https://dev.to/galtzo) |
167
- | `...` 💖 | [![Find Me on WellFound:](https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound)](https://wellfound.com/u/peter-boling) [![Find Me on CrunchBase](https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase)](https://www.crunchbase.com/person/peter-boling) [![My LinkTree](https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree)](https://linktr.ee/galtzo) [![More About Me](https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white)](https://about.me/peter.boling) [🧊](https://codeberg.org/pboling) [🐙](https://github.org/pboling) [🛖](https://sr.ht/~galtzo/) [🧪](https://gitlab.com/pboling) |
249
+ | Tokens to Remember | [![Gem name][⛳️name-img]][👽dl-rank] [![Gem namespace][⛳️namespace-img]][📜src-gh] |
250
+ |-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
251
+ | Works with JRuby | [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
252
+ | 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] |
253
+ | 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] |
254
+ | 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] |
255
+ | 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] [![The best SHA: dQw4w9WgXcQ\!](https://img.shields.io/badge/KLOC-0.326-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue)][🧮kloc] |
256
+ | 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] |
257
+ | 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] |
258
+ | 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] |
259
+ | 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] |
260
+ | `...` 💖 | [![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] |
168
261
 
169
262
  ### Compatibility
170
263
 
171
264
  Compatible with MRI Ruby 3.2.0+, and concordant releases of JRuby, and TruffleRuby.
172
265
 
173
- | 🚚 *Amazing* test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
174
- | --- | --- |
175
- | 👟 Check it out\! | ✨ [github.com/appraisal-rb/appraisal2](https://github.com/appraisal-rb/appraisal2) ✨ |
266
+ | 🚚 *Amazing* test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
267
+ |------------------------------------------------|--------------------------------------------------------|
268
+ | 👟 Check it out\! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
176
269
 
177
270
  ### Federated DVCS
178
271
 
179
272
  <details markdown="1">
180
273
  <summary>Find this repo on federated forges (Coming soon!)</summary>
181
274
 
182
- | Federated [DVCS](https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/) Repository | Status | Issues | PRs | Wiki | CI | Discussions |
183
- | --- | --- | --- | --- | --- | --- | --- |
184
- | 🧪 [kettle-rb/dotenv-merge on GitLab](https://gitlab.com/kettle-rb/dotenv-merge/) | The Truth | [💚](https://gitlab.com/kettle-rb/dotenv-merge/-/issues) | [💚](https://gitlab.com/kettle-rb/dotenv-merge/-/merge_requests) | [💚](https://gitlab.com/kettle-rb/dotenv-merge/-/wikis/home) | 🐭 Tiny Matrix | ➖ |
185
- | 🧊 [kettle-rb/dotenv-merge on CodeBerg](https://codeberg.org/kettle-rb/dotenv-merge) | An Ethical Mirror ([Donate](https://donate.codeberg.org/)) | [💚](https://codeberg.org/kettle-rb/dotenv-merge/issues) | [💚](https://codeberg.org/kettle-rb/dotenv-merge/pulls) | ➖ | ⭕️ No Matrix | ➖ |
186
- | 🐙 [kettle-rb/dotenv-merge on GitHub](https://github.com/kettle-rb/dotenv-merge) | Another Mirror | [💚](https://github.com/kettle-rb/dotenv-merge/issues) | [💚](https://github.com/kettle-rb/dotenv-merge/pulls) | [💚](https://github.com/kettle-rb/dotenv-merge/wiki) | 💯 Full Matrix | [💚](https://github.com/kettle-rb/dotenv-merge/discussions) |
187
- | 🎮️ [Discord Server](https://discord.gg/3qme4XHNKN) | [![Live Chat on Discord](https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord)](https://discord.gg/3qme4XHNKN) | [Let's](https://discord.gg/3qme4XHNKN) | [talk](https://discord.gg/3qme4XHNKN) | [about](https://discord.gg/3qme4XHNKN) | [this](https://discord.gg/3qme4XHNKN) | [library\!](https://discord.gg/3qme4XHNKN) |
275
+ | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
276
+ |---------------------------------------------------|------------------------------------------------------------------------|----------------------------|---------------------------|----------------------------|---------------------------|--------------------------------|
277
+ | 🧪 [kettle-rb/dotenv-merge on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
278
+ | 🧊 [kettle-rb/dotenv-merge on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
279
+ | 🐙 [kettle-rb/dotenv-merge on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
280
+ | 🎮️ [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] |
188
281
 
189
282
  </details>
190
283
 
191
284
  [gh-discussions]: https://github.com/kettle-rb/dotenv-merge/discussions
192
285
 
193
- ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/dotenv-merge)](https://tidelift.com/subscription/pkg/rubygems-dotenv-merge?utm_source=rubygems-dotenv-merge&utm_medium=referral&utm_campaign=readme)
286
+ ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/dotenv-merge)][🏙️entsup-tidelift]
194
287
 
195
288
  Available as part of the Tidelift Subscription.
196
289
 
@@ -199,29 +292,30 @@ Available as part of the Tidelift Subscription.
199
292
 
200
293
  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.
201
294
 
202
- [![Get help from me on Tidelift](https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white)](https://tidelift.com/subscription/pkg/rubygems-dotenv-merge?utm_source=rubygems-dotenv-merge&utm_medium=referral&utm_campaign=readme)
295
+ [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]
203
296
 
204
- - 💡Subscribe for support guarantees covering *all* your FLOSS dependencies
205
- - 💡Tidelift is part of [Sonar](https://blog.tidelift.com/tidelift-joins-sonar)
206
- - 💡Tidelift pays maintainers to maintain the software you depend on\!<br/>📊`@`Pointy Haired Boss: An [enterprise support](https://tidelift.com/subscription/pkg/rubygems-dotenv-merge?utm_source=rubygems-dotenv-merge&utm_medium=referral&utm_campaign=readme) subscription is "[never gonna let you down](https://www.youtube.com/watch?v=dQw4w9WgXcQ)", and *supports* open source maintainers
207
- Alternatively:
297
+ - 💡Subscribe for support guarantees covering *all* your FLOSS dependencies
298
+ - 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
299
+ - 💡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
300
+ Alternatively:
301
+
302
+ - [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord]
303
+ - [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork]
304
+ - [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor]
208
305
 
209
- - [![Live Chat on Discord](https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord)](https://discord.gg/3qme4XHNKN)
210
- - [![Get help from me on Upwork](https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white)](https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share)
211
- - [![Get help from me on Codementor](https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white)](https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github)
212
306
  </details>
213
307
 
214
308
  ## ✨ Installation
215
309
 
216
310
  Install the gem and add to the application's Gemfile by executing:
217
311
 
218
- ``` console
312
+ ```console
219
313
  bundle add dotenv-merge
220
314
  ```
221
315
 
222
316
  If bundler is not being used to manage dependencies, install the gem by executing:
223
317
 
224
- ``` console
318
+ ```console
225
319
  gem install dotenv-merge
226
320
  ```
227
321
 
@@ -230,19 +324,19 @@ gem install dotenv-merge
230
324
  <details markdown="1">
231
325
  <summary>For Medium or High Security Installations</summary>
232
326
 
233
- This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512](https://gitlab.com/kettle-rb/dotenv-merge/-/tree/main/checksums) checksums by
234
- [stone\_checksums](https://github.com/galtzo-floss/stone_checksums). Be sure the gem you install hasn’t been tampered with
327
+ This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
328
+ [stone\_checksums][💎stone_checksums]. Be sure the gem you install hasn’t been tampered with
235
329
  by following the instructions below.
236
330
 
237
331
  Add my public key (if you haven’t already, expires 2045-04-29) as a trusted certificate:
238
332
 
239
- ``` console
333
+ ```console
240
334
  gem cert --add <(curl -Ls https://raw.github.com/galtzo-floss/certs/main/pboling.pem)
241
335
  ```
242
336
 
243
337
  You only need to do that once. Then proceed to install with:
244
338
 
245
- ``` console
339
+ ```console
246
340
  gem install dotenv-merge -P HighSecurity
247
341
  ```
248
342
 
@@ -250,7 +344,7 @@ The `HighSecurity` trust profile will verify signed gems, and not allow the inst
250
344
 
251
345
  If you want to up your security game full-time:
252
346
 
253
- ``` console
347
+ ```console
254
348
  bundle config set --global trust-policy MediumSecurity
255
349
  ```
256
350
 
@@ -262,7 +356,7 @@ NOTE: Be prepared to track down certs for signed gems and add them the same way
262
356
 
263
357
  ## ⚙️ Configuration
264
358
 
265
- ``` ruby
359
+ ```ruby
266
360
  merger = Dotenv::Merge::SmartMerger.new(
267
361
  template,
268
362
  destination,
@@ -277,33 +371,35 @@ merger = Dotenv::Merge::SmartMerger.new(
277
371
 
278
372
  Control which source wins when both files have the same key:
279
373
 
280
- - **`:template`** - Template values replace destination values
374
+ - **`:template`** - Template values replace destination values
375
+
376
+ - Version files (`VERSION=2.0.0` should replace `VERSION=1.0.0`)
377
+ - API endpoint updates (`API_URL=https://new-api.example.com`)
281
378
 
282
- - Version files (`VERSION=2.0.0` should replace `VERSION=1.0.0`)
283
- - API endpoint updates (`API_URL=https://new-api.example.com`)
379
+ - **`:destination`** (default) - Destination values are preserved
284
380
 
285
- - **`:destination`** (default) - Destination values are preserved
381
+ - Local development settings
382
+ - Project-specific customizations
286
383
 
287
- - Local development settings
288
- - Project-specific customizations
289
384
  ### Template-Only Nodes
290
385
 
291
386
  Control whether to add entries that only exist in the template:
292
387
 
293
- - **`true`** - Add new entries from template
388
+ - **`true`** - Add new entries from template
294
389
 
295
- - New required environment variables
296
- - New configuration options
390
+ - New required environment variables
391
+ - New configuration options
297
392
 
298
- - **`false`** (default) - Skip template-only entries
393
+ - **`false`** (default) - Skip template-only entries
394
+
395
+ - Template has placeholder values
396
+ - Destination is authoritative
299
397
 
300
- - Template has placeholder values
301
- - Destination is authoritative
302
398
  ## 🔧 Basic Usage
303
399
 
304
400
  ### Simple Merge
305
401
 
306
- ``` ruby
402
+ ```ruby
307
403
  require "dotenv/merge"
308
404
 
309
405
  template = File.read("template.env")
@@ -329,7 +425,7 @@ Freeze blocks protect sections of your `.env` file from being modified during me
329
425
 
330
426
  ### Adding Template-Only Entries
331
427
 
332
- ``` ruby
428
+ ```ruby
333
429
  # Template introduces a new required variable
334
430
  template = <<~ENV
335
431
  DATABASE_URL=postgresql://localhost/template_db
@@ -356,17 +452,17 @@ Raising a monthly budget of... "dollars" would make the project more sustainable
356
452
 
357
453
  We welcome both individual and corporate sponsors\! We also offer a
358
454
  wide array of funding channels to account for your preferences
359
- (although currently [Open Collective](https://opencollective.com/kettle-rb) is our preferred funding platform).
455
+ (although currently [Open Collective][🖇osc] is our preferred funding platform).
360
456
 
361
457
  **If you're working in a company that's making significant use of kettle-rb tools we'd
362
458
  appreciate it if you suggest to your company to become a kettle-rb sponsor.**
363
459
 
364
460
  You can support the development of kettle-rb tools via
365
- [GitHub Sponsors](https://github.com/sponsors/pboling),
366
- [Liberapay](https://liberapay.com/pboling/donate),
367
- [PayPal](https://www.paypal.com/paypalme/peterboling),
368
- [Open Collective](https://opencollective.com/kettle-rb)
369
- and [Tidelift](https://tidelift.com/subscription/pkg/rubygems-dotenv-merge?utm_source=rubygems-dotenv-merge&utm_medium=referral&utm_campaign=readme).
461
+ [GitHub Sponsors][🖇sponsor],
462
+ [Liberapay][⛳liberapay],
463
+ [PayPal][🖇paypal],
464
+ [Open Collective][🖇osc]
465
+ and [Tidelift][🏙️entsup-tidelift].
370
466
 
371
467
  | 📍 NOTE |
372
468
  | --- |
@@ -374,22 +470,22 @@ and [Tidelift](https://tidelift.com/subscription/pkg/rubygems-dotenv-merge?utm_s
374
470
 
375
471
  ### Open Collective for Individuals
376
472
 
377
- Support us with a monthly donation and help us continue our activities. \[[Become a backer](https://opencollective.com/kettle-rb#backer)\]
473
+ Support us with a monthly donation and help us continue our activities. \[[Become a backer][🖇osc-backers]\]
378
474
 
379
- NOTE: [kettle-readme-backers](https://github.com/kettle-rb/dotenv-merge/blob/main/exe/kettle-readme-backers) updates this list every day, automatically.
475
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
380
476
 
381
477
  <!-- OPENCOLLECTIVE-INDIVIDUALS:START -->
382
- No backers yet. Be the first\!
478
+ No backers yet. Be the first!
383
479
  <!-- OPENCOLLECTIVE-INDIVIDUALS:END -->
384
480
 
385
481
  ### Open Collective for Organizations
386
482
 
387
- Become a sponsor and get your logo on our README on GitHub with a link to your site. \[[Become a sponsor](https://opencollective.com/kettle-rb#sponsor)\]
483
+ Become a sponsor and get your logo on our README on GitHub with a link to your site. \[[Become a sponsor][🖇osc-sponsors]\]
388
484
 
389
- NOTE: [kettle-readme-backers](https://github.com/kettle-rb/dotenv-merge/blob/main/exe/kettle-readme-backers) updates this list every day, automatically.
485
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
390
486
 
391
487
  <!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
392
- No sponsors yet. Be the first\!
488
+ No sponsors yet. Be the first!
393
489
  <!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
394
490
 
395
491
  [kettle-readme-backers]: https://github.com/kettle-rb/dotenv-merge/blob/main/exe/kettle-readme-backers
@@ -400,48 +496,48 @@ I’m driven by a passion to foster a thriving open-source community – a space
400
496
 
401
497
  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`.
402
498
 
403
- I’m developing a new library, [floss\_funding](https://github.com/galtzo-floss/floss_funding), 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.
499
+ 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.
404
500
 
405
- **[Floss-Funding.dev](https://floss-funding.dev): 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
501
+ **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
406
502
 
407
- [![OpenCollective Backers](https://opencollective.com/kettle-rb/backers/badge.svg?style=flat)](https://opencollective.com/kettle-rb#backer) [![OpenCollective Sponsors](https://opencollective.com/kettle-rb/sponsors/badge.svg?style=flat)](https://opencollective.com/kettle-rb#sponsor) [![Sponsor Me on Github](https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github)](https://github.com/sponsors/pboling) [![Liberapay Goal Progress](https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat)](https://liberapay.com/pboling/donate) [![Donate on PayPal](https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal)](https://www.paypal.com/paypalme/peterboling) [![Buy me a coffee](https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat)](https://www.buymeacoffee.com/pboling) [![Donate on Polar](https://img.shields.io/badge/polar-donate-a51611.svg?style=flat)](https://polar.sh/pboling) [![Donate to my FLOSS efforts at ko-fi.com](https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat)](https://ko-fi.com/O5O86SNP4) [![Donate to my FLOSS efforts using Patreon](https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat)](https://patreon.com/galtzo)
503
+ [![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]
408
504
 
409
505
  ## 🔐 Security
410
506
 
411
- See [SECURITY.md](SECURITY.md).
507
+ See [SECURITY.md][🔐security].
412
508
 
413
509
  ## 🤝 Contributing
414
510
 
415
511
  If you need some ideas of where to help, you could work on adding more code coverage,
416
- or if it is already 💯 (see [below](#code-coverage)) check [reek](REEK), [issues](https://github.com/kettle-rb/dotenv-merge/issues), or [PRs](https://github.com/kettle-rb/dotenv-merge/pulls),
512
+ or if it is already 💯 (see [below](#code-coverage)) check [reek](REEK), [issues][🤝gh-issues], or [PRs][🤝gh-pulls],
417
513
  or use the gem and think about how it could be better.
418
514
 
419
- We [![Keep A Changelog](https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat)](https://keepachangelog.com/en/1.0.0/) so if you make changes, remember to update it.
515
+ We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
420
516
 
421
- See [CONTRIBUTING.md](CONTRIBUTING.md) for more detailed instructions.
517
+ See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
422
518
 
423
519
  ### 🚀 Release Instructions
424
520
 
425
- See [CONTRIBUTING.md](CONTRIBUTING.md).
521
+ See [CONTRIBUTING.md][🤝contributing].
426
522
 
427
523
  ### Code Coverage
428
524
 
429
- [![Coverage Graph](https://codecov.io/gh/kettle-rb/dotenv-merge/graphs/tree.svg)](https://codecov.io/gh/kettle-rb/dotenv-merge)
525
+ [![Coverage Graph][🏀codecov-g]][🏀codecov]
430
526
 
431
- [![Coveralls Test Coverage](https://coveralls.io/repos/github/kettle-rb/dotenv-merge/badge.svg?branch=main)](https://coveralls.io/github/kettle-rb/dotenv-merge?branch=main)
527
+ [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
432
528
 
433
- [![QLTY Test Coverage](https://qlty.sh/gh/kettle-rb/projects/dotenv-merge/coverage.svg)](https://qlty.sh/gh/kettle-rb/projects/dotenv-merge/metrics/code?sort=coverageRating)
529
+ [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
434
530
 
435
531
  ### 🪇 Code of Conduct
436
532
 
437
533
  Everyone interacting with this project's codebases, issue trackers,
438
- chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1](https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg)](CODE_OF_CONDUCT.md).
534
+ chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
439
535
 
440
536
  ## 🌈 Contributors
441
537
 
442
- [![Contributors](https://contrib.rocks/image?repo=kettle-rb/dotenv-merge)](https://github.com/kettle-rb/dotenv-merge/graphs/contributors)
538
+ [![Contributors][🖐contributors-img]][🖐contributors]
443
539
 
444
- Made with [contributors-img](https://contrib.rocks).
540
+ Made with [contributors-img][🖐contrib-rocks].
445
541
 
446
542
  Also see GitLab Contributors: <https://gitlab.com/kettle-rb/dotenv-merge/-/graphs/main>
447
543
 
@@ -460,23 +556,23 @@ Also see GitLab Contributors: <https://gitlab.com/kettle-rb/dotenv-merge/-/graph
460
556
 
461
557
  ## 📌 Versioning
462
558
 
463
- This Library adheres to [![Semantic Versioning 2.0.0](https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat)](https://semver.org/spec/v2.0.0.html).
559
+ This Library adheres to [![Semantic Versioning 2.0.0][📌semver-img]][📌semver].
464
560
  Violations of this scheme should be reported as bugs.
465
561
  Specifically, if a minor or patch version is released that breaks backward compatibility,
466
562
  a new version should be immediately released that restores compatibility.
467
563
  Breaking changes to the public API will only be introduced with new major versions.
468
564
 
469
565
  > dropping support for a platform is both obviously and objectively a breaking change <br/>
470
- > —Jordan Harband ([@ljharb](https://github.com/ljharb), maintainer of SemVer) [in SemVer issue 716](https://github.com/semver/semver/issues/716#issuecomment-869336139)
566
+ > —Jordan Harband ([@ljharb](https://github.com/ljharb), maintainer of SemVer) [in SemVer issue 716][📌semver-breaking]
471
567
 
472
568
  I understand that policy doesn't work universally ("exceptions to every rule\!"),
473
569
  but it is the policy here.
474
570
  As such, in many cases it is good to specify a dependency on this library using
475
- the [Pessimistic Version Constraint](http://guides.rubygems.org/patterns/#pessimistic-version-constraint) with two digits of precision.
571
+ the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
476
572
 
477
573
  For example:
478
574
 
479
- ``` ruby
575
+ ```ruby
480
576
  spec.add_dependency("dotenv-merge", "~> 1.0")
481
577
  ```
482
578
 
@@ -489,16 +585,17 @@ is a *breaking change* to an API, and for that reason the bike shedding is endle
489
585
  To get a better understanding of how SemVer is intended to work over a project's lifetime,
490
586
  read this article from the creator of SemVer:
491
587
 
492
- - ["Major Version Numbers are Not Sacred"](https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html)
588
+ - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
589
+
493
590
  </details>
494
591
 
495
- See [CHANGELOG.md](CHANGELOG.md) for a list of releases.
592
+ See [CHANGELOG.md][📌changelog] for a list of releases.
496
593
 
497
594
  ## 📄 License
498
595
 
499
596
  The gem is available as open source under the terms of
500
- the [MIT License](LICENSE.txt) [![License: MIT](https://img.shields.io/badge/License-MIT-259D6C.svg)](https://opensource.org/licenses/MIT).
501
- See [LICENSE.txt](LICENSE.txt) for the official [Copyright Notice](https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year).
597
+ the [MIT License][📄license] [![License: MIT][📄license-img]][📄license-ref].
598
+ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright-notice-explainer].
502
599
 
503
600
  ### © Copyright
504
601
 
@@ -525,11 +622,11 @@ Please consider sponsoring me or the project.
525
622
 
526
623
  To join the community or get help 👇️ Join the Discord.
527
624
 
528
- [![Live Chat on Discord](https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord)](https://discord.gg/3qme4XHNKN)
625
+ [![Live Chat on Discord][✉️discord-invite-img-ftb]][🖼️galtzo-discord]
529
626
 
530
627
  To say "thanks\!" ☝️ Join the Discord or 👇️ send money.
531
628
 
532
- [![Sponsor kettle-rb/dotenv-merge on Open Source Collective](https://img.shields.io/opencollective/all/kettle-rb?style=for-the-badge)](https://opencollective.com/kettle-rb) 💌 [![Sponsor me on GitHub Sponsors](https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github)](https://github.com/sponsors/pboling) 💌 [![Sponsor me on Liberapay](https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611)](https://liberapay.com/pboling/donate) 💌 [![Donate on PayPal](https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A)](https://www.paypal.com/paypalme/peterboling)
629
+ [![Sponsor kettle-rb/dotenv-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]
533
630
 
534
631
  ### Please give the project a star ⭐ ♥.
535
632
 
@@ -570,7 +667,6 @@ Thanks for RTFM. ☺️
570
667
  [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
571
668
  [✉️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
572
669
  [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
573
-
574
670
  [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
575
671
  [⛳️gem-namespace]: https://github.com/kettle-rb/dotenv-merge
576
672
  [⛳️namespace-img]: https://img.shields.io/badge/namespace-Dotenv::Merge-3C2D2D.svg?style=square&logo=ruby&logoColor=white
@@ -694,7 +790,7 @@ Thanks for RTFM. ☺️
694
790
  [📌gitmoji]: https://gitmoji.dev
695
791
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
696
792
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
697
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.351-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
793
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.353-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
698
794
  [🔐security]: SECURITY.md
699
795
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
700
796
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -5,7 +5,7 @@ module Dotenv
5
5
  # Version information for Dotenv::Merge
6
6
  module Version
7
7
  # Current version of the dotenv-merge gem
8
- VERSION = "1.0.1"
8
+ VERSION = "1.0.2"
9
9
  end
10
10
  VERSION = Version::VERSION # traditional location
11
11
  end
data/lib/dotenv/merge.rb CHANGED
@@ -68,6 +68,18 @@ module Dotenv
68
68
  end
69
69
  end
70
70
 
71
+ # Register with ast-merge's MergeGemRegistry for RSpec dependency tags
72
+ # Only register if MergeGemRegistry is loaded (i.e., in test environment)
73
+ if defined?(Ast::Merge::RSpec::MergeGemRegistry)
74
+ Ast::Merge::RSpec::MergeGemRegistry.register(
75
+ :dotenv_merge,
76
+ require_path: "dotenv/merge",
77
+ merger_class: "Dotenv::Merge::SmartMerger",
78
+ test_source: "KEY=value",
79
+ category: :config,
80
+ )
81
+ end
82
+
71
83
  Dotenv::Merge::Version.class_eval do
72
84
  extend VersionGem::Basic
73
85
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotenv-merge
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -37,26 +37,46 @@ cert_chain:
37
37
  -----END CERTIFICATE-----
38
38
  date: 1980-01-02 00:00:00.000000000 Z
39
39
  dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: tree_haver
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.0'
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 5.0.3
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '5.0'
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 5.0.3
40
60
  - !ruby/object:Gem::Dependency
41
61
  name: ast-merge
42
62
  requirement: !ruby/object:Gem::Requirement
43
63
  requirements:
44
64
  - - "~>"
45
65
  - !ruby/object:Gem::Version
46
- version: '2.0'
66
+ version: '4.0'
47
67
  - - ">="
48
68
  - !ruby/object:Gem::Version
49
- version: 2.0.6
69
+ version: 4.0.5
50
70
  type: :runtime
51
71
  prerelease: false
52
72
  version_requirements: !ruby/object:Gem::Requirement
53
73
  requirements:
54
74
  - - "~>"
55
75
  - !ruby/object:Gem::Version
56
- version: '2.0'
76
+ version: '4.0'
57
77
  - - ">="
58
78
  - !ruby/object:Gem::Version
59
- version: 2.0.6
79
+ version: 4.0.5
60
80
  - !ruby/object:Gem::Dependency
61
81
  name: version_gem
62
82
  requirement: !ruby/object:Gem::Requirement
@@ -272,10 +292,10 @@ licenses:
272
292
  - MIT
273
293
  metadata:
274
294
  homepage_uri: https://dotenv-merge.galtzo.com/
275
- source_code_uri: https://github.com/kettle-rb/dotenv-merge/tree/v1.0.1
276
- changelog_uri: https://github.com/kettle-rb/dotenv-merge/blob/v1.0.1/CHANGELOG.md
295
+ source_code_uri: https://github.com/kettle-rb/dotenv-merge/tree/v1.0.2
296
+ changelog_uri: https://github.com/kettle-rb/dotenv-merge/blob/v1.0.2/CHANGELOG.md
277
297
  bug_tracker_uri: https://github.com/kettle-rb/dotenv-merge/issues
278
- documentation_uri: https://www.rubydoc.info/gems/dotenv-merge/1.0.1
298
+ documentation_uri: https://www.rubydoc.info/gems/dotenv-merge/1.0.2
279
299
  funding_uri: https://github.com/sponsors/pboling
280
300
  wiki_uri: https://github.com/kettle-rb/dotenv-merge/wiki
281
301
  news_uri: https://www.railsbling.com/tags/dotenv-merge
@@ -304,7 +324,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
304
324
  - !ruby/object:Gem::Version
305
325
  version: '0'
306
326
  requirements: []
307
- rubygems_version: 4.0.3
327
+ rubygems_version: 4.0.5
308
328
  specification_version: 4
309
329
  summary: "☯️ Intelligent .env file merging using structured parsing"
310
330
  test_files: []
metadata.gz.sig CHANGED
Binary file