token-resolver 1.0.2 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b23a9edef4ee26b3306a11c3829662efdfd3d813f325125fea41a12ab52a4d8
4
- data.tar.gz: 69f56a454fb92a428d07c19357f7f30f6c343c9538ad7931797bb0c40263d61c
3
+ metadata.gz: 2d0b29a16291b6af534e6da9b907ab056533cab2bd44504f3da0b9498f306b63
4
+ data.tar.gz: a8a2f4b21db6c3549f15a5cb451e956bf3340b21137832edd18b92d9b6755784
5
5
  SHA512:
6
- metadata.gz: 2eb601757412886989daabc322e8128c24c0afc8cbad62195a6d987fe11e6ff6c9b0946831d2b570b589991f0070ecbca60a47787343b9b1c973b07c23f4baec
7
- data.tar.gz: 62b7ec4552e63c67d80ca72e67931b87091a71311adb4e6c3fcc560fc6efff888606970fe24bacbcf201ab5b58c73f58fba497cfa25963060348df8b01271770
6
+ metadata.gz: cc016ee7c380eefc3bb573eb8c83519e1ffe354f736e092f54dcd7b8e22caf9a4418137b5358700548658020a1142360c72dc4ba56ba2e7d41b0c0609993a9e4
7
+ data.tar.gz: 8726023b36d797327b5fd8a4c04ab75e4212625e915e545da2c66dd88442e3858f9542880f524c01937e95d8af22cc1ce9619e793b1e0ba4b8eadc30804ea048
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,83 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [2.0.1] - 2026-05-31
34
+
35
+ - TAG: [v2.0.1][2.0.1t]
36
+ - COVERAGE: 100.00% -- 265/265 lines in 10 files
37
+ - BRANCH COVERAGE: 100.00% -- 64/64 branches in 10 files
38
+ - 93.55% documented
39
+
40
+ ### Added
41
+
42
+ - Added StructuredMerge git diff driver config and local `.gitattributes`
43
+ entries generated by the current kettle-jem template.
44
+
45
+ ### Changed
46
+
47
+ - Refreshed kettle-jem-managed project files, migrated template config to
48
+ `.structuredmerge/kettle-jem.yml`, and updated local development tooling
49
+ dependencies including `kettle-dev` 2.0.6 and `nomono` 1.0.2.
50
+
51
+ ### Fixed
52
+
53
+ - Fixed generated documentation URLs that incorrectly pointed at a monorepo
54
+ `gems/token-resolver` path.
55
+
56
+ ## [2.0.0] - 2026-05-27
57
+
58
+ - TAG: [v2.0.0][2.0.0t]
59
+ - COVERAGE: 100.00% -- 265/265 lines in 10 files
60
+ - BRANCH COVERAGE: 100.00% -- 64/64 branches in 10 files
61
+ - 93.55% documented
62
+
63
+ ### Added
64
+
65
+ - **New CI workflows** — Expanded Ruby/engine matrix coverage:
66
+ - `jruby.yml` — JRuby CI workflow
67
+ - `ruby-3.4.yml` — Ruby 3.4 CI workflow
68
+ - `templating.yml` — Templating CI workflow
69
+ - `truffleruby-23.1.yml`, `truffleruby-23.2.yml`, `truffleruby-24.2.yml`, `truffleruby-25.0.yml` — TruffleRuby version-pinned CI workflows
70
+ - Renamed `legacy.yml` → `ruby-3.2.yml` and `supported.yml` → `ruby-3.3.yml` for consistency
71
+ - **Dev binaries** — New developer/tooling scripts in `bin/`: `ast-merge-recipe`, `kettle-gh-release`, `kettle-jem`, `print_matches`, `rbts`, `unparser`
72
+ - **Modular gemfiles** — Added `coverage_local.gemfile`, `style_local.gemfile`, `templating.gemfile`, `templating_local.gemfile`, and recording gemfiles for local-path sibling gem development
73
+ - **Dev container setup** — Added `devcontainer/scripts/setup-tree-sitter.sh` for Tree-sitter native library installation
74
+ - **mise environment management** — Added `mise.toml` for ENV-driven local development configuration; migrated from `.envrc`-only approach to mise + dotenvy
75
+ - **Template freeze markers** — Added `kettle-jem:freeze` / `kettle-jem:unfreeze` markers in `token-resolver.gemspec` to preserve custom sections across template runs
76
+ - **`.gemrc`** — Added project-level gem configuration file
77
+ - **`.rubocop_rspec.yml`** — Added RSpec-specific RuboCop configuration
78
+ - **GitHub Copilot instructions** — Added `.github/COPILOT_INSTRUCTIONS.md`
79
+ - **License texts** — Added `AGPL-3.0-only.md` and `PolyForm-Small-Business-1.0.0.md`
80
+
81
+ ### Changed
82
+
83
+ - **BREAKING: License changed from MIT to AGPL-3.0-only OR PolyForm-Small-Business-1.0.0** — `spec.licenses` updated in gemspec; license files, README badges, and compatibility metadata updated accordingly
84
+ - **`kettle-dev`** development dependency bumped from `~> 1.2` to `~> 2.0`
85
+ - **`bundler-audit`** development dependency bumped from `~> 0.9.2` to `~> 0.9.3`
86
+ - **`appraisal2`** version constraint loosened from `~> 3.0, ~> 3.0.6` to `~> 3.0, >= 3.0.6`
87
+ - **Local dev wiring** — Switched from ad hoc monorepo paths to `nomono` Gemfile macros for sibling gem resolution in `style.gemfile` and related local gemfiles
88
+ - **Template dependency** — Updated from `jsonc-merge` to `json-merge` in `templating_local.gemfile`
89
+ - **Gemspec `homepage_uri`** — Hardcoded to `https://token-resolver.galtzo.com/` (was dynamically constructed with `tr`)
90
+ - **Skip unresolved-token scan for gemspec** — Added `.kettle-jem.yml` config to exclude `token-resolver.gemspec` from the token scan
91
+ - **CI: `codecov/codecov-action`** bumped from v5 to v6
92
+ - **CI: `marocchino/sticky-pull-request-comment`** bumped from v2 to v3
93
+ - **CI: `addressable`** (transitive dependency) bumped from 2.8.8 to 2.8.9
94
+ - **CI: `json`** (bundler group) bumped from 2.18.1 to 2.19.2
95
+ - **Dev container** — Updated `devcontainer.json` and `apt-install` scripts with improved tooling setup
96
+
97
+ ### Removed
98
+
99
+ - **`LICENSE.txt`** — Replaced by `LICENSE.md`, `AGPL-3.0-only.md`, and `PolyForm-Small-Business-1.0.0.md`
100
+ - **Previous license options not included in the new dual-license set** — Removed retired license files such as `Big-Time-Public-License.md`
101
+
102
+ ### Fixed
103
+
104
+ - **Typos** — Minor documentation/comment typo corrections in `BENCHMARK.md` and IDE configuration
105
+
106
+ ### Security
107
+
108
+ - **`bundler-audit` ~> 0.9.3`** — Picked up latest security-advisory database and patch-level fixes
109
+
33
110
  ## [1.0.2] - 2026-02-22
34
111
 
35
112
  - TAG: [v1.0.2][1.0.2t]
@@ -91,7 +168,11 @@ Please file a bug if you notice a violation of semantic versioning.
91
168
 
92
169
  ### Security
93
170
 
94
- [Unreleased]: https://github.com/kettle-rb/token-resolver/compare/v1.0.2...HEAD
171
+ [Unreleased]: https://github.com/kettle-rb/token-resolver/compare/v2.0.1...HEAD
172
+ [2.0.1]: https://github.com/kettle-rb/token-resolver/compare/v2.0.0...v2.0.1
173
+ [2.0.1t]: https://github.com/kettle-rb/token-resolver/releases/tag/v2.0.1
174
+ [2.0.0]: https://github.com/kettle-rb/token-resolver/compare/v1.0.2...v2.0.0
175
+ [2.0.0t]: https://github.com/kettle-rb/token-resolver/releases/tag/v2.0.0
95
176
  [1.0.2]: https://github.com/kettle-rb/token-resolver/compare/v1.0.1...v1.0.2
96
177
  [1.0.2t]: https://github.com/kettle-rb/token-resolver/releases/tag/v1.0.2
97
178
  [1.0.1]: https://github.com/kettle-rb/token-resolver/compare/v1.0.0...v1.0.1
data/CITATION.cff CHANGED
@@ -1,19 +1,19 @@
1
1
  cff-version: 1.2.0
2
- title: token-resolver
2
+ title: "token-resolver"
3
3
  message: >-
4
4
  If you use this work and you want to cite it,
5
5
  then you can use the metadata from this file.
6
6
  type: software
7
7
  authors:
8
- - given-names: Peter Hurn
9
- family-names: Boling
10
- email: floss@galtzo.com
11
- affiliation: galtzo.com
8
+ - given-names: "Peter H."
9
+ family-names: "Boling"
10
+ email: "floss@galtzo.com"
11
+ affiliation: "galtzo.com"
12
12
  orcid: 'https://orcid.org/0009-0008-8519-441X'
13
13
  identifiers:
14
14
  - type: url
15
15
  value: 'https://github.com/kettle-rb/token-resolver'
16
- description: token-resolver
16
+ description: "token-resolver"
17
17
  repository-code: 'https://github.com/kettle-rb/token-resolver'
18
18
  abstract: >-
19
19
  token-resolver
data/CONTRIBUTING.md CHANGED
@@ -8,19 +8,27 @@ To submit a patch, please fork the project, create a patch with tests, and send
8
8
 
9
9
  Remember to [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] if you make changes.
10
10
 
11
+ ## Developer Certificate of Origin
12
+
13
+ In order to protect users of this project, we require all contributors to comply with the
14
+ [Developer Certificate of Origin](https://developercertificate.org/).
15
+ This ensures that all contributions are properly licensed and attributed.
16
+
11
17
  ## Help out!
12
18
 
13
- Take a look at the `reek` list which is the file called `REEK` and find something to improve.
19
+ Take a look at the open issues and pull requests, or use the gem and find something to improve.
14
20
 
15
21
  Follow these instructions:
16
22
 
17
- 1. Fork the repository
18
- 2. Create a feature branch (`git checkout -b my-new-feature`)
19
- 3. Make some fixes.
20
- 4. Commit changes (`git commit -am 'Added some feature'`)
21
- 5. Push to the branch (`git push origin my-new-feature`)
22
- 6. Make sure to add tests for it. This is important, so it doesn't break in a future release.
23
- 7. Create new Pull Request.
23
+ 1. Join the Discord: [![Live Chat on Discord][✉️discord-invite-img]][✉️discord-invite]
24
+ 2. Fork the repository
25
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
26
+ 4. Make some fixes.
27
+ 5. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 6. Push to the branch (`git push origin my-new-feature`)
29
+ 7. Make sure to add tests for it. This is important, so it doesn't break in a future release.
30
+ 8. Create new Pull Request.
31
+ 9. Announce it in the channel for this org in the [Discord][✉️discord-invite]!
24
32
 
25
33
  ## Executables vs Rake tasks
26
34
 
@@ -42,6 +50,22 @@ There are many Rake tasks available as well. You can see them by running:
42
50
  bin/rake -T
43
51
  ```
44
52
 
53
+ ## Code quality checks
54
+
55
+ Run the Reek task when you want a smell check that fails on current findings:
56
+
57
+ ```shell
58
+ bin/rake reek
59
+ ```
60
+
61
+ Refresh the checked-in `REEK` backlog through the rake task, not by redirecting
62
+ the raw `reek` executable output. The rake task uses the project bundle and
63
+ avoids stale generated binstubs shadowing the Reek gem executable:
64
+
65
+ ```shell
66
+ bin/rake reek:update
67
+ ```
68
+
45
69
  ## Environment Variables for Local Development
46
70
 
47
71
  Below are the primary environment variables recognized by stone_checksums (and its integrated tools). Unless otherwise noted, set boolean values to the string "true" to enable.
@@ -52,7 +76,7 @@ General/runtime
52
76
  - CI: When set to true, adjusts default rake tasks toward CI behavior
53
77
 
54
78
  Coverage (kettle-soup-cover / SimpleCov)
55
- - K_SOUP_COV_DO: Enable coverage collection (default: true in .envrc)
79
+ - K_SOUP_COV_DO: Enable coverage collection (default: true in `mise.toml`)
56
80
  - K_SOUP_COV_FORMATTERS: Comma-separated list of formatters (html, xml, rcov, lcov, json, tty)
57
81
  - K_SOUP_COV_MIN_LINE: Minimum line coverage threshold (integer, e.g., 100)
58
82
  - K_SOUP_COV_MIN_BRANCH: Minimum branch coverage threshold (integer, e.g., 100)
@@ -78,11 +102,32 @@ Git hooks and commit message helpers (exe/kettle-commit-msg)
78
102
  - GIT_HOOK_FOOTER_SENTINEL: Required when footer append is enabled — a unique first-line sentinel to prevent duplicates
79
103
  - GIT_HOOK_FOOTER_APPEND_DEBUG: Extra debug output in the footer template (true/false)
80
104
 
81
- For a quick starting point, this repository’s `.envrc` shows sane defaults, and `.env.local` can override them locally.
105
+ Git diff driver setup
106
+ - Local setup writes repository `.gitattributes` entries so this checkout uses StructuredMerge semantic diffs.
107
+ - Global setup registers `diff.smorg-*` commands once in the user Git config; use it when you work across several StructuredMerge-enabled repositories.
108
+ - Include-file setup writes `.git/smorg/config` and includes it from local Git config, keeping command registrations out of the repository files.
109
+ - Git hosting forges generally ignore external diff drivers, so pull request views may still show raw textual diffs even when local `git diff` uses semantic drivers.
110
+
111
+ ```console
112
+ K_JEM_TEMPLATING=true bundle exec kettle-jem install
113
+ ```
114
+
115
+ Troubleshooting Git diffs
116
+ - Use `git diff --no-ext-diff` to compare against Git's built-in diff output.
117
+ - Use `git diff --no-textconv` when a textconv projection obscures the raw file bytes you need to inspect.
118
+ - If Git reports a missing `smorg-*` executable, rerun `bundle install` and the setup command above, then check `git config --get-regexp '^diff\.smorg-'`.
119
+ - To remove managed local entries, run `K_JEM_TEMPLATING=true bundle exec kettle-jem install --undo`; remove global command registrations with `git config --global --unset-all diff.smorg-ruby.command`.
120
+
121
+ For a quick starting point, this repository’s `mise.toml` defines the shared defaults, and `.env.local` can override them locally. Copy `.env.local.example` to `.env.local`, use `KEY=value` lines, and either activate `mise` in your shell or run commands through `mise exec -C /path/to/project -- ...`.
82
122
 
83
123
  ## Appraisals
84
124
 
85
125
  From time to time the [appraisal2][🚎appraisal2] gemfiles in `gemfiles/` will need to be updated.
126
+ Generated appraisal and CI workflow floors are controlled by `ruby.test_minimum`
127
+ in `.structuredmerge/kettle-jem.yml`; this project was templated with `ruby.test_minimum: 3.2.0`.
128
+ That value describes the lowest Ruby version expected to run the test/development
129
+ toolchain, and it may be higher than the gemspec runtime floor.
130
+
86
131
  They are created and updated with the commands:
87
132
 
88
133
  ```console
@@ -97,22 +142,20 @@ bin/rake appraisal:reset
97
142
 
98
143
  When adding an appraisal to CI, check the [runner tool cache][🏃‍♂️runner-tool-cache] to see which runner to use.
99
144
 
100
- ## The Reek List
101
-
102
- Take a look at the `reek` list which is the file called `REEK` and find something to improve.
145
+ ## Run Tests
103
146
 
104
- To refresh the `reek` list:
147
+ Run tests via `kettle-test` (provided by `kettle-test`). It runs RSpec, writes the full log to
148
+ `tmp/kettle-test/rspec-TIMESTAMP.log`, and prints a compact highlight block with timing, seed,
149
+ pass/fail count, failing example list, and SimpleCov coverage percentages.
105
150
 
106
151
  ```console
107
- bundle exec reek > REEK
152
+ bundle exec kettle-test
108
153
  ```
109
154
 
110
- ## Run Tests
111
-
112
- To run all tests
155
+ For targeted runs, disable the hard coverage threshold to avoid false failures:
113
156
 
114
157
  ```console
115
- bundle exec rake test
158
+ K_SOUP_COV_MIN_HARD=false bundle exec kettle-test spec/path/to/spec.rb
116
159
  ```
117
160
 
118
161
  ### Spec organization (required)
@@ -183,33 +226,34 @@ NOTE: To build without signing the gem set `SKIP_GEM_SIGNING` to any value in th
183
226
  1. Run `bin/setup && bin/rake` as a "test, coverage, & linting" sanity check
184
227
  2. Update the version number in `version.rb`, and ensure `CHANGELOG.md` reflects changes
185
228
  3. Run `bin/setup && bin/rake` again as a secondary check, and to update `Gemfile.lock`
186
- 4. Run `git commit -am "🔖 Prepare release v<VERSION>"` to commit the changes
187
- 5. Run `git push` to trigger the final CI pipeline before release, and merge PRs
229
+ 4. Run `bin/rake yard` to regenerate the docs site using the canonical docs task
230
+ 5. Run `git commit -am "🔖 Prepare release v<VERSION>"` to commit the changes
231
+ 6. Run `git push` to trigger the final CI pipeline before release, and merge PRs
188
232
  - NOTE: Remember to [check the build][🧪build].
189
- 6. Run `export GIT_TRUNK_BRANCH_NAME="$(git remote show origin | grep 'HEAD branch' | cut -d ' ' -f5)" && echo $GIT_TRUNK_BRANCH_NAME`
190
- 7. Run `git checkout $GIT_TRUNK_BRANCH_NAME`
191
- 8. Run `git pull origin $GIT_TRUNK_BRANCH_NAME` to ensure latest trunk code
192
- 9. Optional for older Bundler (< 2.7.0): Set `SOURCE_DATE_EPOCH` so `rake build` and `rake release` use the same timestamp and generate the same checksums
233
+ 7. Run `export GIT_TRUNK_BRANCH_NAME="$(git remote show origin | grep 'HEAD branch' | cut -d ' ' -f5)" && echo $GIT_TRUNK_BRANCH_NAME`
234
+ 8. Run `git checkout $GIT_TRUNK_BRANCH_NAME`
235
+ 9. Run `git pull origin $GIT_TRUNK_BRANCH_NAME` to ensure latest trunk code
236
+ 10. Optional for older Bundler (< 2.7.0): Set `SOURCE_DATE_EPOCH` so `rake build` and `rake release` use the same timestamp and generate the same checksums
193
237
  - If your Bundler is >= 2.7.0, you can skip this; builds are reproducible by default.
194
238
  - Run `export SOURCE_DATE_EPOCH=$EPOCHSECONDS && echo $SOURCE_DATE_EPOCH`
195
239
  - If the echo above has no output, then it didn't work.
196
240
  - Note: `zsh/datetime` module is needed, if running `zsh`.
197
241
  - In older versions of `bash` you can use `date +%s` instead, i.e. `export SOURCE_DATE_EPOCH=$(date +%s) && echo $SOURCE_DATE_EPOCH`
198
- 10. Run `bundle exec rake build`
199
- 11. Run `bin/gem_checksums` (more context [1][🔒️rubygems-checksums-pr], [2][🔒️rubygems-guides-pr])
242
+ 11. Run `bundle exec rake build`
243
+ 12. Run `bin/gem_checksums` (more context [1][🔒️rubygems-checksums-pr], [2][🔒️rubygems-guides-pr])
200
244
  to create SHA-256 and SHA-512 checksums. This functionality is provided by the `stone_checksums`
201
245
  [gem][💎stone_checksums].
202
246
  - The script automatically commits but does not push the checksums
203
- 12. Sanity check the SHA256, comparing with the output from the `bin/gem_checksums` command:
247
+ 13. Sanity check the SHA256, comparing with the output from the `bin/gem_checksums` command:
204
248
  - `sha256sum pkg/<gem name>-<version>.gem`
205
- 13. Run `bundle exec rake release` which will create a git tag for the version,
249
+ 14. Run `bundle exec rake release` which will create a git tag for the version,
206
250
  push git commits and tags, and push the `.gem` file to the gem host configured in the gemspec.
207
251
 
208
- [📜src-gl]: https://gitlab.com/kettle-rb/token-resolver/
252
+ [📜src-gl]: https://gitlab.com/kettle-rb/token-resolver
209
253
  [📜src-cb]: https://codeberg.org/kettle-rb/token-resolver
210
254
  [📜src-gh]: https://github.com/kettle-rb/token-resolver
211
255
  [🧪build]: https://github.com/kettle-rb/token-resolver/actions
212
- [🤝conduct]: https://gitlab.com/kettle-rb/token-resolver/-/blob/main/CODE_OF_CONDUCT.md
256
+ [🤝conduct]: https://github.com/kettle-rb/token-resolver/blob/main/CODE_OF_CONDUCT.md
213
257
  [🖐contrib-rocks]: https://contrib.rocks
214
258
  [🖐contributors]: https://github.com/kettle-rb/token-resolver/graphs/contributors
215
259
  [🚎contributors-gl]: https://gitlab.com/kettle-rb/token-resolver/-/graphs/main
@@ -225,3 +269,4 @@ NOTE: To build without signing the gem set `SKIP_GEM_SIGNING` to any value in th
225
269
  [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
226
270
  [🚎appraisal2]: https://github.com/appraisal-rb/appraisal2
227
271
  [🏃‍♂️runner-tool-cache]: https://github.com/ruby/ruby-builder/releases/tag/toolcache
272
+ [✉️discord-invite]: https://discord.gg/3qme4XHNKN
data/FUNDING.md CHANGED
@@ -19,7 +19,7 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
19
19
  [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
20
20
  [🖇polar]: https://polar.sh/pboling
21
21
  [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
22
- [🖇kofi]: https://ko-fi.com/O5O86SNP4
22
+ [🖇kofi]: https://ko-fi.com/pboling
23
23
  [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
24
24
  [🖇patreon]: https://patreon.com/galtzo
25
25
  [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
data/LICENSE.md ADDED
@@ -0,0 +1,13 @@
1
+ # License
2
+
3
+ This project is made available under the following licenses.
4
+ Choose the option that best fits your use case:
5
+
6
+ - [AGPL-3.0-only](AGPL-3.0-only.md)
7
+ - [PolyForm-Small-Business-1.0.0](PolyForm-Small-Business-1.0.0.md)
8
+
9
+ If none of the above licenses fit your use case, please [contact us](mailto:floss@galtzo.com) to discuss a custom commercial license.
10
+
11
+ ## Copyright Notice
12
+
13
+ Required Notice: Copyright (c) 2026 Peter H. Boling
data/README.md CHANGED
@@ -1,17 +1,10 @@
1
- [![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]
2
-
3
- [🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
4
- [🖼️galtzo-discord]: https://discord.gg/3qme4XHNKN
5
- [🖼️ruby-lang-i]: https://logos.galtzo.com/assets/images/ruby-lang/avatar-192px.svg
6
- [🖼️ruby-lang]: https://www.ruby-lang.org/
7
- [🖼️kettle-rb-i]: https://logos.galtzo.com/assets/images/kettle-rb/avatar-192px.svg
8
- [🖼️kettle-rb]: https://github.com/kettle-rb
1
+ <a href="https://github.com/kettle-rb"><img alt="kettle-rb Logo by Aboling0, CC BY-SA 4.0" src="https://logos.galtzo.com/assets/images/kettle-rb/avatar-128px.svg" width="14%" align="right"/></a>
9
2
 
10
3
  # 🪙 Token::Resolver
11
4
 
12
- [![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]
5
+ [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: AGPL-3.0-only OR PolyForm-Small-Business-1.0.0][📄license-img]][📄license] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![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] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
13
6
 
14
- `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
7
+ `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][✉️discord-invite], as I may have missed the [discord notification][✉️discord-invite].
15
8
 
16
9
  ---
17
10
 
@@ -20,13 +13,13 @@
20
13
  [![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]
21
14
 
22
15
  <details>
23
- <summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
16
+ <summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
24
17
 
25
18
  I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
26
19
 
27
20
  </details>
28
21
 
29
- ## 🌻 Synopsis
22
+ ## 🌻 Synopsis <a href="https://discord.gg/3qme4XHNKN"><img alt="Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0" src="https://logos.galtzo.com/assets/images/galtzo-floss/avatar-128px.svg" width="8%" align="right"/></a> <a href="https://ruby-toolbox.com"><img alt="ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5" src="https://logos.galtzo.com/assets/images/ruby-lang/avatar-128px.svg" width="8%" align="right"/></a>
30
23
 
31
24
  Token::Resolver is a configurable PEG-based token parser and resolver for structured token detection and replacement in arbitrary text.
32
25
 
@@ -36,46 +29,50 @@ Detects structured tokens like `{KJ|GEM_NAME}` in any file format and resolves t
36
29
  # One-liner: parse and resolve
37
30
  result = Token::Resolver.resolve(
38
31
  "Hello {KJ|NAME}, welcome to {KJ|PROJECT}!",
39
- {"KJ|NAME" => "World", "KJ|PROJECT" => "my-app"},
32
+ {"KJ|NAME" => "World", "KJ|PROJECT" => "my-app"}
40
33
  )
41
34
  # => "Hello World, welcome to my-app!"
42
35
  ```
43
36
 
44
37
  ## 💡 Info you can shake a stick at
45
38
 
46
- | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
39
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
47
40
  |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
48
- | Works with JRuby | [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
49
- | Works with Truffle Ruby | ![Truffle Ruby 23.1 Compat][💎truby-23.1i] ![Truffle Ruby 24.2 Compat][💎truby-24.2i] <br/> [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎9-t-wf] [![Truffle Ruby 33.0 Compat][💎truby-c-i]][🚎11-c-wf] |
50
- | Works with MRI Ruby 4 | [![Ruby 4.0 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
51
- | 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-3.4i]][🚎6-s-wf] |
52
- | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
53
- | 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!][🧮kloc-img]][🧮kloc] |
54
- | 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] |
55
- | 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] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
56
- | 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] |
57
- | 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] |
58
- | `...` 💖 | [![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] |
41
+ | Works with JRuby | [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf]|
42
+ | Works with Truffle Ruby | [![Truffle Ruby 24.2 Compat][💎truby-24.2i]][🚎truby-24.2-wf] [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎truby-25.0-wf] [![Truffle Ruby current Compat][💎truby-c-i]][🚎9-t-wf]|
43
+ | Works with MRI Ruby 4 | [![Ruby 4.0 Compat][💎ruby-4.0i]][🚎11-c-wf] [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]|
44
+ | Works with MRI Ruby 3 | [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎ruby-3.2-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎ruby-3.3-wf] [![Ruby 3.4 Compat][💎ruby-3.4i]][🚎ruby-3.4-wf]|
45
+ | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
46
+ | 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!][🧮kloc-img]][🧮kloc] |
47
+ | 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] |
48
+ | Compliance | [![License: AGPL-3.0-only OR PolyForm-Small-Business-1.0.0][📄license-img]][📄license] [![Apache license compatibility: Category X][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
49
+ | 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] |
50
+ | 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] |
51
+ | `...` 💖 | [![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] |
59
52
 
60
53
  ### Compatibility
61
54
 
62
55
  Compatible with MRI Ruby 3.2.0+, and concordant releases of JRuby, and TruffleRuby.
56
+ CI workflows and Appraisals are generated for MRI Ruby 3.2.0+.
57
+ This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
58
+ may be higher than the gem's runtime compatibility floor when legacy Rubies are
59
+ not practical for the current toolchain.
63
60
 
64
- | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
61
+ | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
65
62
  |------------------------------------------------|--------------------------------------------------------|
66
- | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
63
+ | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
67
64
 
68
65
  ### Federated DVCS
69
66
 
70
67
  <details markdown="1">
71
- <summary>Find this repo on federated forges (Coming soon!)</summary>
68
+ <summary>Find this repo on federated forges (Coming soon!)</summary>
72
69
 
73
- | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
70
+ | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
74
71
  |-------------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
75
- | 🧪 [kettle-rb/token-resolver on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
76
- | 🧊 [kettle-rb/token-resolver on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
77
- | 🐙 [kettle-rb/token-resolver on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
78
- | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
72
+ | 🧪 [kettle-rb/token-resolver on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
73
+ | 🧊 [kettle-rb/token-resolver on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
74
+ | 🐙 [kettle-rb/token-resolver on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
75
+ | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
79
76
 
80
77
  </details>
81
78
 
@@ -86,7 +83,7 @@ Compatible with MRI Ruby 3.2.0+, and concordant releases of JRuby, and TruffleRu
86
83
  Available as part of the Tidelift Subscription.
87
84
 
88
85
  <details markdown="1">
89
- <summary>Need enterprise-level guarantees?</summary>
86
+ <summary>Need enterprise-level guarantees?</summary>
90
87
 
91
88
  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.
92
89
 
@@ -118,41 +115,6 @@ If bundler is not being used to manage dependencies, install the gem by executin
118
115
  gem install token-resolver
119
116
  ```
120
117
 
121
- ### 🔒 Secure Installation
122
-
123
- <details markdown="1">
124
- <summary>For Medium or High Security Installations</summary>
125
-
126
- This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
127
- [stone_checksums][💎stone_checksums]. Be sure the gem you install hasn’t been tampered with
128
- by following the instructions below.
129
-
130
- Add my public key (if you haven’t already, expires 2045-04-29) as a trusted certificate:
131
-
132
- ```console
133
- gem cert --add <(curl -Ls https://raw.github.com/galtzo-floss/certs/main/pboling.pem)
134
- ```
135
-
136
- You only need to do that once. Then proceed to install with:
137
-
138
- ```console
139
- gem install token-resolver -P HighSecurity
140
- ```
141
-
142
- The `HighSecurity` trust profile will verify signed gems, and not allow the installation of unsigned dependencies.
143
-
144
- If you want to up your security game full-time:
145
-
146
- ```console
147
- bundle config set --global trust-policy MediumSecurity
148
- ```
149
-
150
- `MediumSecurity` instead of `HighSecurity` is necessary if not all the gems you use are signed.
151
-
152
- NOTE: Be prepared to track down certs for signed gems and add them the same way you added mine.
153
-
154
- </details>
155
-
156
118
  ## ⚙️ Configuration
157
119
 
158
120
  ### Token Config Options
@@ -203,7 +165,7 @@ doc.text_only? # => false
203
165
  # Resolve tokens
204
166
  result = Token::Resolver.resolve(
205
167
  "Deploy {KJ|GEM_NAME} to {KJ|GH_ORG}",
206
- {"KJ|GEM_NAME" => "my-gem", "KJ|GH_ORG" => "my-org"},
168
+ {"KJ|GEM_NAME" => "my-gem", "KJ|GH_ORG" => "my-org"}
207
169
  )
208
170
  # => "Deploy my-gem to my-org"
209
171
  ```
@@ -231,7 +193,7 @@ Token::Resolver.resolve("{KJ|MISSING}", {}, on_missing: :remove)
231
193
  config = Token::Resolver::Config.new(
232
194
  pre: "<<",
233
195
  post: ">>",
234
- separators: [":"],
196
+ separators: [":"]
235
197
  )
236
198
  Token::Resolver.resolve("Hello <<NS:NAME>>!", {"NS:NAME" => "World"}, config: config)
237
199
  # => "Hello World!"
@@ -242,7 +204,7 @@ Token::Resolver.resolve("Hello <<NS:NAME>>!", {"NS:NAME" => "World"}, config: co
242
204
  ```ruby
243
205
  # Tokens like {KJ|SECTION:SUBSECTION}
244
206
  config = Token::Resolver::Config.new(
245
- separators: ["|", ":"], # First boundary uses |, second uses :, rest repeat :
207
+ separators: ["|", ":"] # First boundary uses |, second uses :, rest repeat :
246
208
  )
247
209
  doc = Token::Resolver.parse("{KJ|META:AUTHOR}", config: config)
248
210
  doc.tokens.first.key # => "KJ|META:AUTHOR"
@@ -268,117 +230,6 @@ result = resolver.resolve(doc, {"KJ|NAME" => "World"})
268
230
  # => "Hello World!"
269
231
  ```
270
232
 
271
- ## Design
272
-
273
- ### Grammar Never Fails
274
-
275
- The parslet grammar is designed so that **any input is valid**. When the parser encounters
276
- `{` but it doesn't start a valid token, the `{` is consumed as plain text. No input can
277
- cause a parse failure.
278
-
279
- ### Single-Pass Resolution
280
-
281
- Replacement values are emitted as-is and are **not** re-scanned for tokens. This prevents
282
- infinite loops and ensures predictable behavior when replacement values contain token-like strings.
283
-
284
- ### Performance
285
-
286
- If the input doesn't contain the `pre` delimiter at all, the parser fast-paths and returns
287
- a single Text node without invoking parslet.
288
-
289
- #### 📊 Benchmarks
290
-
291
- Token-resolver prioritizes **flexibility, configurability, and maintainability** over raw speed.
292
-
293
- **⚠️ Important**: Token-resolver is **100-3000x slower** than simple alternatives like `String#gsub` and `Kernel#sprintf`.
294
- because it does significantly more work:
295
- - Full PEG parsing of the input string
296
- - Token validation and structure enforcement
297
- - Building an AST for introspection
298
- - Flexible error handling for missing tokens
299
-
300
- This performance difference is **expected and acceptable** because these are fundamentally different
301
- approaches solving different problems.
302
-
303
- See [BENCHMARK.md](BENCHMARK.md) for detailed performance comparisons and guidance on:
304
-
305
- - **When to use token-resolver**: Configurable token structures, validation, introspection, flexible error handling
306
- - **When to use String#gsub**: Fixed token patterns, maximum performance, simple one-shot replacements
307
- - **When to use Kernel#sprintf**: Positional formatting, fixed templates, printf-style output
308
-
309
- The choice should be based on your actual requirements, not just raw performance metrics.
310
-
311
- To run benchmarks on your system:
312
-
313
- ```bash
314
- bundle exec rake bench:comparison
315
- ```
316
-
317
- ### False Positive Prevention
318
-
319
- The grammar constrains segment content to the configured `segment_pattern` (default: word
320
- characters). This ensures that syntax using the same delimiter characters — such as Ruby
321
- block parameters (`{ |x| expr }`) or shell variable expansion (`${VAR:+val}`) — is never
322
- mistakenly parsed as a token. Replacement keys that contain characters outside the
323
- `segment_pattern` are rejected with an `ArgumentError` at resolve time.
324
-
325
- ## 🦷 FLOSS Funding
326
-
327
- While kettle-rb tools are free software and will always be, the project would benefit immensely from some funding.
328
- Raising a monthly budget of... "dollars" would make the project more sustainable.
329
-
330
- We welcome both individual and corporate sponsors! We also offer a
331
- wide array of funding channels to account for your preferences
332
- (although currently [Open Collective][🖇osc] is our preferred funding platform).
333
-
334
- **If you're working in a company that's making significant use of kettle-rb tools we'd
335
- appreciate it if you suggest to your company to become a kettle-rb sponsor.**
336
-
337
- You can support the development of kettle-rb tools via
338
- [GitHub Sponsors][🖇sponsor],
339
- [Liberapay][⛳liberapay],
340
- [PayPal][🖇paypal],
341
- [Open Collective][🖇osc]
342
- and [Tidelift][🏙️entsup-tidelift].
343
-
344
- | 📍 NOTE |
345
- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
346
- | If doing a sponsorship in the form of donation is problematic for your company <br/> from an accounting standpoint, we'd recommend the use of Tidelift, <br/> where you can get a support-like subscription instead. |
347
-
348
- ### Open Collective for Individuals
349
-
350
- Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/kettle-rb#backer)]
351
-
352
- NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
353
-
354
- <!-- OPENCOLLECTIVE-INDIVIDUALS:START -->
355
- No backers yet. Be the first!
356
- <!-- OPENCOLLECTIVE-INDIVIDUALS:END -->
357
-
358
- ### Open Collective for Organizations
359
-
360
- 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)]
361
-
362
- NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
363
-
364
- <!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
365
- No sponsors yet. Be the first!
366
- <!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
367
-
368
- [kettle-readme-backers]: https://github.com/kettle-rb/token-resolver/blob/main/exe/kettle-readme-backers
369
-
370
- ### Another way to support open-source
371
-
372
- I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈‍ cats).
373
-
374
- 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`.
375
-
376
- 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.
377
-
378
- **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
379
-
380
- [![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]
381
-
382
233
  ## 🔐 Security
383
234
 
384
235
  See [SECURITY.md][🔐security].
@@ -386,7 +237,7 @@ See [SECURITY.md][🔐security].
386
237
  ## 🤝 Contributing
387
238
 
388
239
  If you need some ideas of where to help, you could work on adding more code coverage,
389
- or if it is already 💯 (see [below](#code-coverage)) check [reek](REEK), [issues][🤝gh-issues], or [PRs][🤝gh-pulls],
240
+ or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
390
241
  or use the gem and think about how it could be better.
391
242
 
392
243
  We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
@@ -399,12 +250,17 @@ See [CONTRIBUTING.md][🤝contributing].
399
250
 
400
251
  ### Code Coverage
401
252
 
253
+ <details markdown="1">
254
+ <summary>Coverage service badges</summary>
255
+
402
256
  [![Coverage Graph][🏀codecov-g]][🏀codecov]
403
257
 
404
258
  [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
405
259
 
406
260
  [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
407
261
 
262
+ </details>
263
+
408
264
  ### 🪇 Code of Conduct
409
265
 
410
266
  Everyone interacting with this project's codebases, issue trackers,
@@ -419,13 +275,13 @@ Made with [contributors-img][🖐contrib-rocks].
419
275
  Also see GitLab Contributors: [https://gitlab.com/kettle-rb/token-resolver/-/graphs/main][🚎contributors-gl]
420
276
 
421
277
  <details>
422
- <summary>⭐️ Star History</summary>
278
+ <summary>⭐️ Star History</summary>
423
279
 
424
- <a href="https://star-history.com/#kettle-rb/token-resolver&Date">
280
+ <a href="https://star-history.com/kettle-rb/token-resolver&Date">
425
281
  <picture>
426
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=kettle-rb/token-resolver&type=Date&theme=dark" />
427
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=kettle-rb/token-resolver&type=Date" />
428
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=kettle-rb/token-resolver&type=Date" />
282
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=kettle-rb/token-resolver&type=Date&theme=dark" />
283
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=kettle-rb/token-resolver&type=Date" />
284
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=kettle-rb/token-resolver&type=Date" />
429
285
  </picture>
430
286
  </a>
431
287
 
@@ -433,31 +289,20 @@ Also see GitLab Contributors: [https://gitlab.com/kettle-rb/token-resolver/-/gra
433
289
 
434
290
  ## 📌 Versioning
435
291
 
436
- This Library adheres to [![Semantic Versioning 2.0.0][📌semver-img]][📌semver].
437
- Violations of this scheme should be reported as bugs.
438
- Specifically, if a minor or patch version is released that breaks backward compatibility,
439
- a new version should be immediately released that restores compatibility.
440
- Breaking changes to the public API will only be introduced with new major versions.
441
-
442
- > dropping support for a platform is both obviously and objectively a breaking change <br/>
443
- >—Jordan Harband ([@ljharb](https://github.com/ljharb), maintainer of SemVer) [in SemVer issue 716][📌semver-breaking]
444
-
445
- I understand that policy doesn't work universally ("exceptions to every rule!"),
446
- but it is the policy here.
447
- As such, in many cases it is good to specify a dependency on this library using
448
- the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
292
+ This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
293
+ For most applications, prefer the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
449
294
 
450
295
  For example:
451
296
 
452
297
  ```ruby
453
- spec.add_dependency("token-resolver", "~> 1.0")
298
+ spec.add_dependency("token-resolver", "~> 2.0")
454
299
  ```
455
300
 
456
301
  <details markdown="1">
457
302
  <summary>📌 Is "Platform Support" part of the public API? More details inside.</summary>
458
303
 
459
- SemVer should, IMO, but doesn't explicitly, say that dropping support for specific Platforms
460
- is a *breaking change* to an API, and for that reason the bike shedding is endless.
304
+ Dropping support for a platform can be a breaking change for affected users.
305
+ If a release changes supported platforms, it should be called out clearly in the changelog and versioned with that impact in mind.
461
306
 
462
307
  To get a better understanding of how SemVer is intended to work over a project's lifetime,
463
308
  read this article from the creator of SemVer:
@@ -470,23 +315,21 @@ See [CHANGELOG.md][📌changelog] for a list of releases.
470
315
 
471
316
  ## 📄 License
472
317
 
473
- The gem is available as open source under the terms of
474
- the [MIT License][📄license] [![License: MIT][📄license-img]][📄license-ref].
475
- See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright-notice-explainer].
318
+ The gem is available under the following licenses: [AGPL-3.0-only](AGPL-3.0-only.md), [PolyForm-Small-Business-1.0.0](PolyForm-Small-Business-1.0.0.md).
319
+ See [LICENSE.md][📄license] for details.
320
+
321
+ If none of the available licenses suit your use case, please [contact us](mailto:floss@galtzo.com) to discuss a custom commercial license.
476
322
 
477
323
  ### © Copyright
478
324
 
479
- <ul>
480
- <li>
481
- Copyright (c) 2026 Peter H. Boling, of
482
- <a href="https://discord.gg/3qme4XHNKN">
483
- Galtzo.com
484
- <picture>
485
- <img src="https://logos.galtzo.com/assets/images/galtzo-floss/avatar-128px-blank.svg" alt="Galtzo.com Logo (Wordless) by Aboling0, CC BY-SA 4.0" width="24">
486
- </picture>
487
- </a>, and token-resolver contributors.
488
- </li>
489
- </ul>
325
+ See [LICENSE.md][📄license] for the official copyright notice.
326
+
327
+ <details markdown="1">
328
+ <summary>Copyright holders</summary>
329
+
330
+ - Required Notice: Copyright (c) 2026 Peter H. Boling
331
+
332
+ </details>
490
333
 
491
334
  ## 🤑 A request for help
492
335
 
@@ -507,6 +350,8 @@ To say "thanks!" ☝️ Join the Discord or 👇️ send money.
507
350
 
508
351
  ### Please give the project a star ⭐ ♥.
509
352
 
353
+ Many parts of this project are actively managed by a [kettle-jem](https://github.com/structuredmerge/structuredmerge-ruby/tree/main/gems/kettle-jem) smart template utilizing [StructuredMerge.org](https://structuredmerge.org) merge contracts.
354
+
510
355
  Thanks for RTFM. ☺️
511
356
 
512
357
  [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
@@ -529,7 +374,7 @@ Thanks for RTFM. ☺️
529
374
  [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
530
375
  [🖇polar]: https://polar.sh/pboling
531
376
  [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
532
- [🖇kofi]: https://ko-fi.com/O5O86SNP4
377
+ [🖇kofi]: https://ko-fi.com/pboling
533
378
  [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
534
379
  [🖇patreon]: https://patreon.com/galtzo
535
380
  [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
@@ -551,13 +396,13 @@ Thanks for RTFM. ☺️
551
396
  [⛳️gem-name]: https://bestgems.org/gems/token-resolver
552
397
  [⛳️name-img]: https://img.shields.io/badge/name-token--resolver-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
553
398
  [⛳️tag-img]: https://img.shields.io/github/tag/kettle-rb/token-resolver.svg
554
- [⛳️tag]: http://github.com/kettle-rb/token-resolver/releases
399
+ [⛳️tag]: https://github.com/kettle-rb/token-resolver/releases
555
400
  [🚂maint-blog]: http://www.railsbling.com/tags/token-resolver
556
401
  [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
557
402
  [🚂maint-contact]: http://www.railsbling.com/contact
558
403
  [🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red
559
404
  [💖🖇linkedin]: http://www.linkedin.com/in/peterboling
560
- [💖🖇linkedin-img]: https://img.shields.io/badge/PeterBoling-LinkedIn-0B66C2?style=flat&logo=newjapanprowrestling
405
+ [💖🖇linkedin-img]: https://img.shields.io/badge/LinkedIn-Profile-0B66C2?style=flat&logo=newjapanprowrestling
561
406
  [💖✌️wellfound]: https://wellfound.com/u/peter-boling
562
407
  [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound
563
408
  [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
@@ -586,7 +431,7 @@ Thanks for RTFM. ☺️
586
431
  [💁🏼‍♂️peterboling]: http://www.peterboling.com
587
432
  [🚂railsbling]: http://www.railsbling.com
588
433
  [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
589
- [📜src-gl]: https://gitlab.com/kettle-rb/token-resolver/
434
+ [📜src-gl]: https://gitlab.com/kettle-rb/token-resolver
590
435
  [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue
591
436
  [📜src-cb]: https://codeberg.org/kettle-rb/token-resolver
592
437
  [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green
@@ -595,12 +440,10 @@ Thanks for RTFM. ☺️
595
440
  [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
596
441
  [📜gl-wiki]: https://gitlab.com/kettle-rb/token-resolver/-/wikis/home
597
442
  [📜gh-wiki]: https://github.com/kettle-rb/token-resolver/wiki
598
- [📜gl-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white
599
- [📜gh-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
443
+ [📜gl-wiki-img]: https://img.shields.io/badge/wiki-gitlab-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white
444
+ [📜gh-wiki-img]: https://img.shields.io/badge/wiki-github-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
600
445
  [👽dl-rank]: https://bestgems.org/gems/token-resolver
601
446
  [👽dl-ranki]: https://img.shields.io/gem/rd/token-resolver.svg
602
- [👽oss-help]: https://www.codetriage.com/kettle-rb/token-resolver
603
- [👽oss-helpi]: https://www.codetriage.com/kettle-rb/token-resolver/badges/users.svg
604
447
  [👽version]: https://bestgems.org/gems/token-resolver
605
448
  [👽versioni]: https://img.shields.io/gem/v/token-resolver.svg
606
449
  [🏀qlty-mnt]: https://qlty.sh/gh/kettle-rb/projects/token-resolver
@@ -611,24 +454,17 @@ Thanks for RTFM. ☺️
611
454
  [🏀codecovi]: https://codecov.io/gh/kettle-rb/token-resolver/graph/badge.svg
612
455
  [🏀coveralls]: https://coveralls.io/github/kettle-rb/token-resolver?branch=main
613
456
  [🏀coveralls-img]: https://coveralls.io/repos/github/kettle-rb/token-resolver/badge.svg?branch=main
614
- [🖐codeQL]: https://github.com/kettle-rb/token-resolver/security/code-scanning
615
- [🖐codeQL-img]: https://github.com/kettle-rb/token-resolver/actions/workflows/codeql-analysis.yml/badge.svg
616
- [🚎1-an-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/ancient.yml
617
- [🚎1-an-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/ancient.yml/badge.svg
457
+ [🚎ruby-3.2-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/ruby-3.2.yml
458
+ [🚎ruby-3.3-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/ruby-3.3.yml
459
+ [🚎ruby-3.4-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/ruby-3.4.yml
460
+ [🚎truby-24.2-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/truffleruby-24.2.yml
461
+ [🚎truby-25.0-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/truffleruby-25.0.yml
618
462
  [🚎2-cov-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/coverage.yml
619
463
  [🚎2-cov-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/coverage.yml/badge.svg
620
464
  [🚎3-hd-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/heads.yml
621
465
  [🚎3-hd-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/heads.yml/badge.svg
622
- [🚎4-lg-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/legacy.yml
623
- [🚎4-lg-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/legacy.yml/badge.svg
624
466
  [🚎5-st-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/style.yml
625
467
  [🚎5-st-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/style.yml/badge.svg
626
- [🚎6-s-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/supported.yml
627
- [🚎6-s-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/supported.yml/badge.svg
628
- [🚎7-us-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/unsupported.yml
629
- [🚎7-us-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/unsupported.yml/badge.svg
630
- [🚎8-ho-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/hoary.yml
631
- [🚎8-ho-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/hoary.yml/badge.svg
632
468
  [🚎9-t-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/truffle.yml
633
469
  [🚎9-t-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/truffle.yml/badge.svg
634
470
  [🚎10-j-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/jruby.yml
@@ -641,18 +477,15 @@ Thanks for RTFM. ☺️
641
477
  [🚎13-🔒️-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/locked_deps.yml/badge.svg
642
478
  [🚎14-🔓️-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/unlocked_deps.yml
643
479
  [🚎14-🔓️-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/unlocked_deps.yml/badge.svg
644
- [🚎15-🪪-wf]: https://github.com/kettle-rb/token-resolver/actions/workflows/license-eye.yml
645
- [🚎15-🪪-wfi]: https://github.com/kettle-rb/token-resolver/actions/workflows/license-eye.yml/badge.svg
646
480
  [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
647
481
  [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
648
482
  [💎ruby-3.4i]: https://img.shields.io/badge/Ruby-3.4-CC342D?style=for-the-badge&logo=ruby&logoColor=white
483
+ [💎ruby-4.0i]: https://img.shields.io/badge/Ruby-4.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
649
484
  [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
650
485
  [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
651
- [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
652
- [💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
486
+ [💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
653
487
  [💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
654
488
  [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
655
- [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
656
489
  [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
657
490
  [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
658
491
  [🤝gh-issues]: https://github.com/kettle-rb/token-resolver/issues
@@ -662,34 +495,35 @@ Thanks for RTFM. ☺️
662
495
  [🤝cb-issues]: https://codeberg.org/kettle-rb/token-resolver/issues
663
496
  [🤝cb-pulls]: https://codeberg.org/kettle-rb/token-resolver/pulls
664
497
  [🤝cb-donate]: https://donate.codeberg.org/
665
- [🤝contributing]: CONTRIBUTING.md
666
- [🏀codecov-g]: https://codecov.io/gh/kettle-rb/token-resolver/graphs/tree.svg
498
+ [🤝contributing]: https://github.com/kettle-rb/token-resolver/blob/main/CONTRIBUTING.md
499
+ [🏀codecov-g]: https://codecov.io/gh/kettle-rb/token-resolver/graph/badge.svg
667
500
  [🖐contrib-rocks]: https://contrib.rocks
668
501
  [🖐contributors]: https://github.com/kettle-rb/token-resolver/graphs/contributors
669
502
  [🖐contributors-img]: https://contrib.rocks/image?repo=kettle-rb/token-resolver
670
503
  [🚎contributors-gl]: https://gitlab.com/kettle-rb/token-resolver/-/graphs/main
671
- [🪇conduct]: CODE_OF_CONDUCT.md
504
+ [🪇conduct]: https://github.com/kettle-rb/token-resolver/blob/main/CODE_OF_CONDUCT.md
672
505
  [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg
673
506
  [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
674
507
  [📌semver]: https://semver.org/spec/v2.0.0.html
675
508
  [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat
676
509
  [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
677
510
  [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
678
- [📌changelog]: CHANGELOG.md
511
+ [📌changelog]: https://github.com/kettle-rb/token-resolver/blob/main/CHANGELOG.md
679
512
  [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
680
513
  [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
681
514
  [📌gitmoji]: https://gitmoji.dev
682
515
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
683
516
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
684
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.268-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
685
- [🔐security]: SECURITY.md
517
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.265-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
518
+ [🔐security]: https://github.com/kettle-rb/token-resolver/blob/main/SECURITY.md
686
519
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
687
520
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
688
- [📄license]: LICENSE.txt
689
- [📄license-ref]: https://opensource.org/licenses/MIT
690
- [📄license-img]: https://img.shields.io/badge/License-MIT-259D6C.svg
691
- [📄license-compat]: https://dev.to/galtzo/how-to-check-license-compatibility-41h0
692
- [📄license-compat-img]: https://img.shields.io/badge/Apache_Compatible:_Category_A-%E2%9C%93-259D6C.svg?style=flat&logo=Apache
521
+ [📄license]: LICENSE.md
522
+ [📄license-ref]: LICENSE.md
523
+ [📄license-img]: https://img.shields.io/badge/License-AGPL--3.0--only_OR_PolyForm--Small--Business--1.0.0-259D6C.svg
524
+ [📄license-compat]: https://www.apache.org/legal/resolved.html#category-x
525
+ [📄license-compat-img]: https://img.shields.io/badge/Apache_Incompatible:_Category_X-✗-C0392B.svg?style=flat&logo=Apache
526
+
693
527
  [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
694
528
  [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat
695
529
  [🚎yard-current]: http://rubydoc.info/gems/token-resolver
@@ -701,3 +535,14 @@ Thanks for RTFM. ☺️
701
535
  [💎appraisal2]: https://github.com/appraisal-rb/appraisal2
702
536
  [💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
703
537
  [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
538
+
539
+ <!-- kettle-jem:metadata:start -->
540
+ | Field | Value |
541
+ |---|---|
542
+ | Package | token-resolver |
543
+ | Description | 🪙 Token::Resolver provides configurable PEG-based (parslet) parsing and resolution of structured tokens (e.g., {KJ\|GEM_NAME}) in arbitrary text. Useful for template ETL pipelines where tokens in template files must be resolved before format-specific merging. |
544
+ | Homepage | https://github.com/kettle-rb/token-resolver |
545
+ | Source | https://github.com/kettle-rb/token-resolver/tree/v2.0.0 |
546
+ | License | `AGPL-3.0-only` OR `PolyForm-Small-Business-1.0.0` |
547
+ | Funding | https://github.com/sponsors/pboling, https://issuehunt.io/u/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/kettle-rb, https://patreon.com/galtzo, https://polar.sh/pboling, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/token-resolver, https://www.buymeacoffee.com/pboling |
548
+ <!-- kettle-jem:metadata:end -->
data/certs/pboling.pem ADDED
@@ -0,0 +1,27 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl
3
+ ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
4
+ A2NvbTAeFw0yNTA1MDQxNTMzMDlaFw00NTA0MjkxNTMzMDlaMEMxFTATBgNVBAMM
5
+ DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
6
+ LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAruUoo0WA
7
+ uoNuq6puKWYeRYiZekz/nsDeK5x/0IEirzcCEvaHr3Bmz7rjo1I6On3gGKmiZs61
8
+ LRmQ3oxy77ydmkGTXBjruJB+pQEn7UfLSgQ0xa1/X3kdBZt6RmabFlBxnHkoaGY5
9
+ mZuZ5+Z7walmv6sFD9ajhzj+oIgwWfnEHkXYTR8I6VLN7MRRKGMPoZ/yvOmxb2DN
10
+ coEEHWKO9CvgYpW7asIihl/9GMpKiRkcYPm9dGQzZc6uTwom1COfW0+ZOFrDVBuV
11
+ FMQRPswZcY4Wlq0uEBLPU7hxnCL9nKK6Y9IhdDcz1mY6HZ91WImNslOSI0S8hRpj
12
+ yGOWxQIhBT3fqCBlRIqFQBudrnD9jSNpSGsFvbEijd5ns7Z9ZMehXkXDycpGAUj1
13
+ to/5cuTWWw1JqUWrKJYoifnVhtE1o1DZ+LkPtWxHtz5kjDG/zR3MG0Ula0UOavlD
14
+ qbnbcXPBnwXtTFeZ3C+yrWpE4pGnl3yGkZj9SMTlo9qnTMiPmuWKQDatAgMBAAGj
15
+ fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQE8uWvNbPVNRXZ
16
+ HlgPbc2PCzC4bjAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG
17
+ A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD
18
+ ggGBAJbnUwfJQFPkBgH9cL7hoBfRtmWiCvdqdjeTmi04u8zVNCUox0A4gT982DE9
19
+ wmuN12LpdajxZONqbXuzZvc+nb0StFwmFYZG6iDwaf4BPywm2e/Vmq0YG45vZXGR
20
+ L8yMDSK1cQXjmA+ZBKOHKWavxP6Vp7lWvjAhz8RFwqF9GuNIdhv9NpnCAWcMZtpm
21
+ GUPyIWw/Cw/2wZp74QzZj6Npx+LdXoLTF1HMSJXZ7/pkxLCsB8m4EFVdb/IrW/0k
22
+ kNSfjtAfBHO8nLGuqQZVH9IBD1i9K6aSs7pT6TW8itXUIlkIUI2tg5YzW6OFfPzq
23
+ QekSkX3lZfY+HTSp/o+YvKkqWLUV7PQ7xh1ZYDtocpaHwgxe/j3bBqHE+CUPH2vA
24
+ 0V/FwdTRWcwsjVoOJTrYcff8pBZ8r2MvtAc54xfnnhGFzeRHfcltobgFxkAXdE6p
25
+ DVjBtqT23eugOqQ73umLcYDZkc36vnqGxUBSsXrzY9pzV5gGr2I8YUxMqf6ATrZt
26
+ L9nRqA==
27
+ -----END CERTIFICATE-----
@@ -82,6 +82,7 @@ module Token
82
82
  private
83
83
 
84
84
  def handle_missing(token_node, result)
85
+ # :nocov:
85
86
  case @on_missing
86
87
  when :raise
87
88
  raise UnresolvedTokenError.new(token_node.key)
@@ -90,6 +91,7 @@ module Token
90
91
  when :remove
91
92
  # emit nothing
92
93
  end
94
+ # :nocov:
93
95
  end
94
96
 
95
97
  # Validate that all replacement keys only contain characters allowed by the config.
@@ -2,11 +2,9 @@
2
2
 
3
3
  module Token
4
4
  module Resolver
5
- # Version information for Token::Resolver
6
5
  module Version
7
- # Current version of the token-resolver gem
8
- VERSION = "1.0.2"
6
+ VERSION = "2.0.1"
9
7
  end
10
- VERSION = Version::VERSION # traditional location
8
+ VERSION = Version::VERSION # Traditional Constant Location
11
9
  end
12
10
  end
@@ -0,0 +1,8 @@
1
+ module Token
2
+ module Resolver
3
+ module Version
4
+ VERSION: String
5
+ end
6
+ VERSION: String
7
+ end
8
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: token-resolver
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -77,28 +77,34 @@ dependencies:
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: '1.2'
80
+ version: '2.0'
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 2.0.6
81
84
  type: :development
82
85
  prerelease: false
83
86
  version_requirements: !ruby/object:Gem::Requirement
84
87
  requirements:
85
88
  - - "~>"
86
89
  - !ruby/object:Gem::Version
87
- version: '1.2'
90
+ version: '2.0'
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: 2.0.6
88
94
  - !ruby/object:Gem::Dependency
89
95
  name: bundler-audit
90
96
  requirement: !ruby/object:Gem::Requirement
91
97
  requirements:
92
98
  - - "~>"
93
99
  - !ruby/object:Gem::Version
94
- version: 0.9.2
100
+ version: 0.9.3
95
101
  type: :development
96
102
  prerelease: false
97
103
  version_requirements: !ruby/object:Gem::Requirement
98
104
  requirements:
99
105
  - - "~>"
100
106
  - !ruby/object:Gem::Version
101
- version: 0.9.2
107
+ version: 0.9.3
102
108
  - !ruby/object:Gem::Dependency
103
109
  name: rake
104
110
  requirement: !ruby/object:Gem::Requirement
@@ -140,7 +146,7 @@ dependencies:
140
146
  - - "~>"
141
147
  - !ruby/object:Gem::Version
142
148
  version: '3.0'
143
- - - "~>"
149
+ - - ">="
144
150
  - !ruby/object:Gem::Version
145
151
  version: 3.0.6
146
152
  type: :development
@@ -150,7 +156,7 @@ dependencies:
150
156
  - - "~>"
151
157
  - !ruby/object:Gem::Version
152
158
  version: '3.0'
153
- - - "~>"
159
+ - - ">="
154
160
  - !ruby/object:Gem::Version
155
161
  version: 3.0.6
156
162
  - !ruby/object:Gem::Dependency
@@ -159,20 +165,20 @@ dependencies:
159
165
  requirements:
160
166
  - - "~>"
161
167
  - !ruby/object:Gem::Version
162
- version: '1.0'
168
+ version: '2.0'
163
169
  - - ">="
164
170
  - !ruby/object:Gem::Version
165
- version: 1.0.10
171
+ version: 2.0.1
166
172
  type: :development
167
173
  prerelease: false
168
174
  version_requirements: !ruby/object:Gem::Requirement
169
175
  requirements:
170
176
  - - "~>"
171
177
  - !ruby/object:Gem::Version
172
- version: '1.0'
178
+ version: '2.0'
173
179
  - - ">="
174
180
  - !ruby/object:Gem::Version
175
- version: 1.0.10
181
+ version: 2.0.1
176
182
  - !ruby/object:Gem::Dependency
177
183
  name: ruby-progressbar
178
184
  requirement: !ruby/object:Gem::Requirement
@@ -213,20 +219,20 @@ dependencies:
213
219
  requirements:
214
220
  - - "~>"
215
221
  - !ruby/object:Gem::Version
216
- version: '1.0'
222
+ version: '2.0'
217
223
  - - ">="
218
224
  - !ruby/object:Gem::Version
219
- version: 1.0.3
225
+ version: 2.0.0
220
226
  type: :development
221
227
  prerelease: false
222
228
  version_requirements: !ruby/object:Gem::Requirement
223
229
  requirements:
224
230
  - - "~>"
225
231
  - !ruby/object:Gem::Version
226
- version: '1.0'
232
+ version: '2.0'
227
233
  - - ">="
228
234
  - !ruby/object:Gem::Version
229
- version: 1.0.3
235
+ version: 2.0.0
230
236
  description: "\U0001FA99 Token::Resolver provides configurable PEG-based (parslet)
231
237
  parsing and resolution of structured tokens (e.g., {KJ|GEM_NAME}) in arbitrary text.
232
238
  Useful for template ETL pipelines where tokens in template files must be resolved
@@ -241,9 +247,8 @@ extra_rdoc_files:
241
247
  - CODE_OF_CONDUCT.md
242
248
  - CONTRIBUTING.md
243
249
  - FUNDING.md
244
- - LICENSE.txt
250
+ - LICENSE.md
245
251
  - README.md
246
- - REEK
247
252
  - RUBOCOP.md
248
253
  - SECURITY.md
249
254
  files:
@@ -252,11 +257,11 @@ files:
252
257
  - CODE_OF_CONDUCT.md
253
258
  - CONTRIBUTING.md
254
259
  - FUNDING.md
255
- - LICENSE.txt
260
+ - LICENSE.md
256
261
  - README.md
257
- - REEK
258
262
  - RUBOCOP.md
259
263
  - SECURITY.md
264
+ - certs/pboling.pem
260
265
  - lib/token-resolver.rb
261
266
  - lib/token/resolver.rb
262
267
  - lib/token/resolver/config.rb
@@ -269,15 +274,17 @@ files:
269
274
  - lib/token/resolver/transform.rb
270
275
  - lib/token/resolver/version.rb
271
276
  - sig/token/resolver.rbs
277
+ - sig/token/resolver/version.rbs
272
278
  homepage: https://github.com/kettle-rb/token-resolver
273
279
  licenses:
274
- - MIT
280
+ - AGPL-3.0-only
281
+ - PolyForm-Small-Business-1.0.0
275
282
  metadata:
276
283
  homepage_uri: https://token-resolver.galtzo.com/
277
- source_code_uri: https://github.com/kettle-rb/token-resolver/tree/v1.0.2
278
- changelog_uri: https://github.com/kettle-rb/token-resolver/blob/v1.0.2/CHANGELOG.md
284
+ source_code_uri: https://github.com/kettle-rb/token-resolver/tree/v2.0.1
285
+ changelog_uri: https://github.com/kettle-rb/token-resolver/blob/v2.0.1/CHANGELOG.md
279
286
  bug_tracker_uri: https://github.com/kettle-rb/token-resolver/issues
280
- documentation_uri: https://www.rubydoc.info/gems/token-resolver/1.0.2
287
+ documentation_uri: https://www.rubydoc.info/gems/token-resolver/2.0.1
281
288
  funding_uri: https://github.com/sponsors/pboling
282
289
  wiki_uri: https://github.com/kettle-rb/token-resolver/wiki
283
290
  news_uri: https://www.railsbling.com/tags/token-resolver
@@ -307,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
307
314
  - !ruby/object:Gem::Version
308
315
  version: '0'
309
316
  requirements: []
310
- rubygems_version: 4.0.5
317
+ rubygems_version: 4.0.10
311
318
  specification_version: 4
312
319
  summary: "\U0001FA99 Configurable PEG-based token parser and resolver for structured
313
320
  token detection and replacement in arbitrary text"
metadata.gz.sig CHANGED
Binary file
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2026 Peter H. Boling
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/REEK DELETED
File without changes