snaky_hash 2.0.1 → 2.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.
data/README.md CHANGED
@@ -1,13 +1,122 @@
1
- # SnakyHash
1
+ # 🐍 SnakyHash
2
2
 
3
- This gem is used by the `oauth` and `oauth2` gems, and others, to normalize hash keys and lookups,
3
+ [![Version][👽versioni]][👽version] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![Depfu][🔑depfui♻️]][🔑depfu] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi♻️]][🔑qlty-cov] [![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] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL]
4
+
5
+ ---
6
+
7
+ [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
8
+
9
+ This library is similar in purpose to the HashWithIndifferentAccess that is famously used in Rails, but does a lot more.
10
+
11
+ This gem is used by `oauth` and `oauth2` gems to normalize hash keys to `snake_case` and lookups,
4
12
  and provide a nice psuedo-object interface.
5
13
 
6
- It has its roots in the `Rash` (specifically the [`rash_alt`](https://github.com/shishi/rash_alt) flavor), which is a special `Mash`, made popular by the `hashie` gem.
14
+ It can be thought of as a mashup of:
15
+
16
+ * `Rash` (specifically the [`rash_alt`](https://github.com/shishi/rash_alt) flavor), which is a special `Mash`, made popular by the `hashie` gem, and
17
+ * `serialized_hashie` [gem by krystal](https://github.com/krystal/serialized-hashie)
18
+
19
+ Classes that `include SnakyHash::Snake.new` should inherit from `Hashie::Mash`.
20
+
21
+ ## New for v2.0.2: Serialization Support
22
+
23
+ The serialization support is set to `false` by default, for backwards compatibility, but may be switched to `true` in the next major release, which will be v3. Example:
24
+
25
+ ```ruby
26
+ # This class has `dump` and `load` abilities!
27
+ class MyStringKeyedHash < Hashie::Mash
28
+ include SnakyHash::Snake.new(
29
+ key_type: :string,
30
+ serializer: true,
31
+ )
32
+ end
33
+ ```
34
+
35
+ ✨ Also new dump & load plugin extensions to control the way your data is dumped and loaded.
36
+
37
+ ### Note for use with oauth2 gem
38
+
39
+ The serializer is being introduced as a disabled option for backwards compatibility.
40
+ In snaky_hash v3 it will default to `true`.
41
+ If you want to start using the serializer immediately, reopen the `SnakyHash::StringKeyed` class and add the `SnakyHash::Serializer` module like this:
42
+
43
+ ```ruby
44
+ SnakyHash::StringKeyed.class_eval do
45
+ extend SnakyHash::Serializer
46
+ end
47
+ ```
48
+
49
+ You can then add serialization extensions as needed. See [serialization](#serialization) and [extensions](#extensions) for more.
50
+
51
+ | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
52
+ |-----------------------------------------------|-------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
53
+ | 🧪 [oauth-xx/snaky_hash on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜wiki] | 🏀 Tiny Matrix | ➖ |
54
+ | 🧊 [oauth-xx/snaky_hash on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | ➖ | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
55
+ | 🐙 [oauth-xx/snaky_hash on GitHub][📜src-gh] | A Dirty Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | ➖ | 💯 Full Matrix | ➖ |
56
+ | 🤼 [OAuth Ruby Google Group][⛳gg-discussions] | "Active" | ➖ | ➖ | ➖ | ➖ | [💚][⛳gg-discussions] |
57
+ | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
58
+
59
+ ## Upgrading Runtime Gem Dependencies
60
+
61
+ Due to oauth and oauth2 gems depending on this gem,
62
+ this project sits underneath a large portion of the authorization systems on the internet.
63
+
64
+ That means it is painful for the Ruby community when this gem forces updates to its runtime dependencies.
65
+
66
+ As a result, great care, and a lot of time, have been invested to ensure this gem is working with all the
67
+ leading versions per each minor version of Ruby of all the runtime dependencies it can install with.
68
+
69
+ What does that mean specifically for the runtime dependencies?
70
+
71
+ We have 100% test coverage of lines and branches, and this test suite runs across a large matrix
72
+ covering the latest patch for each of the following minor versions:
7
73
 
8
- Classes that include `SnakyHash::Snake` should inherit from `Hashie::Mash`.
74
+ * MRI Ruby @ v2.3, v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2, v3.3, v3.4, HEAD
75
+ * NOTE: This gem will still install on ruby v2.2, but vanilla GitHub Actions no longer supports testing against it, so YMMV.
76
+ * JRuby @ v9.2, v9.3, v9.4, v10.0, HEAD
77
+ * TruffleRuby @ v23.1, v23.2, HEAD
78
+ * gem `hashie` @ v0, v1, v2, v3, v4, v5, HEAD ⏩️ [hashie/hashie](https://github.com/hashie/hashie)
79
+ * gem `version_gem` - @v1, HEAD ⏩️ [oauth-xx/version_gem](https://gitlab.com/oauth-xx/version_gem)
9
80
 
10
- ## Installation
81
+ NOTE: `version_gem`, and this library, were both extracted from the ouaht2 gem. They are part of the `oauth-xx` org,
82
+ and are developed in tight collaboration with the oauth and oauth2 gems.
83
+
84
+ ### You should upgrade this gem with confidence\*.
85
+
86
+ - This gem follows a _strict & correct_ (according to the maintainer of SemVer; [more info][sv-pub-api]) interpretation of SemVer.
87
+ - Dropping support for **any** of the runtime dependency versions above will be a major version bump.
88
+ - If you aren't on one of the minor versions above, make getting there a priority.
89
+ - You should upgrade the dependencies of this gem with confidence\*.
90
+ - Please do upgrade, and then, when it goes smooth as butter [please sponsor me][🖇sponsor]. Thanks!
91
+
92
+ [sv-pub-api]: #-is-platform-support-part-of-the-public-api
93
+
94
+ \* MIT license; I am unable to make guarantees.
95
+
96
+ | 🚚 Test matrix brought to you by | 🔎 appraisal++ |
97
+ |----------------------------------|-------------------------------------------------------------------------|
98
+ | Adds back support for old Rubies | ✨ [appraisal PR #250](https://github.com/thoughtbot/appraisal/pull/250) |
99
+ | Adds support for `eval_gemfile` | ✨ [appraisal PR #248](https://github.com/thoughtbot/appraisal/pull/248) |
100
+ | Please review | my PRs! |
101
+
102
+ ## 💡 Info you can shake a stick at
103
+
104
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
105
+ |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
106
+ | Works with JRuby | [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎10-j-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎10-j-wf] [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
107
+ | 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] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf] |
108
+ | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![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] |
109
+ | Works with MRI Ruby 2 | [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
110
+ | 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] |
111
+ | Documentation | [![Discussion][⛳gg-discussions-img]][⛳gg-discussions] [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![HEAD on RubyDoc.info][📜docs-head-rd-img]][🚎yard-head] [![BDFL Blog][🚂bdfl-blog-img]][🚂bdfl-blog] [![Wiki][📜wiki-img]][📜wiki] |
112
+ | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
113
+ | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] |
114
+ | Support | [![Live Chat on Discord][✉️discord-invite-img]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
115
+ | Enterprise Support | [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]<br/>💡Subscribe for support guarantees covering _all_ FLOSS dependencies!<br/>💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]!<br/>💡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! |
116
+ | Comrade BDFL 🎖️ | [![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 BDFL][🚂bdfl-contact-img]][🚂bdfl-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] |
117
+ | `...` 💖 | [![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] |
118
+
119
+ ## ✨ Installation
11
120
 
12
121
  Install the gem and add to the application's Gemfile by executing:
13
122
 
@@ -17,17 +126,48 @@ If bundler is not being used to manage dependencies, install the gem by executin
17
126
 
18
127
  $ gem install snaky_hash
19
128
 
20
- ## Usage
129
+ ### 🔒 Secure Installation
130
+
131
+ `snaky_hash` is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
132
+ [stone_checksums][💎stone_checksums]. Be sure the gem you install hasn’t been tampered with
133
+ by following the instructions below.
134
+
135
+ Add my public key (if you haven’t already, expires 2045-04-29) as a trusted certificate:
136
+
137
+ ```shell
138
+ gem cert --add <(curl -Ls https://raw.github.com/oauth-xx/snaky_hash/main/certs/pboling.pem)
139
+ ```
140
+
141
+ You only need to do that once. Then proceed to install with:
142
+
143
+ ```shell
144
+ gem install snaky_hash -P MediumSecurity
145
+ ```
146
+
147
+ The `MediumSecurity` trust profile will verify signed gems, but allow the installation of unsigned dependencies.
148
+
149
+ This is necessary because not all of `snaky_hash`’s dependencies are signed, so we cannot use `HighSecurity`.
150
+
151
+ If you want to up your security game full-time:
152
+
153
+ ```shell
154
+ bundle config set --global trust-policy MediumSecurity
155
+ ```
156
+
157
+ NOTE: Be prepared to track down certs for signed gems and add them the same way you added mine.
158
+
159
+ ## 🔧 Basic Usage
21
160
 
22
161
  ```ruby
23
162
  class MySnakedHash < Hashie::Mash
24
163
  include SnakyHash::Snake.new(key_type: :string) # or :symbol
25
164
  end
26
165
 
27
- snake = MySnakedHash.new(a: "a", "b" => "b", 2 => 2, "VeryFineHat" => "Feathers")
166
+ snake = MySnakedHash.new(:a => "a", "b" => "b", 2 => 2, "VeryFineHat" => "Feathers")
28
167
  snake.a # => 'a'
29
168
  snake.b # => 'b'
30
- snake[2] # 2
169
+ snake[2] # => 2
170
+ snake["2"] # => nil, note that this gem only affects string / symbol keys.
31
171
  snake.very_fine_hat # => 'Feathers'
32
172
  snake[:very_fine_hat] # => 'Feathers'
33
173
  snake["very_fine_hat"] # => 'Feathers'
@@ -38,11 +178,97 @@ The `key_type` determines how the key is actually stored, but the hash acts as "
38
178
  Note also that keys which do not respond to `to_sym`, because they don't have a natural conversion to a Symbol,
39
179
  are left as-is.
40
180
 
181
+ ### Serialization
182
+
183
+ ```ruby
184
+ class MySerializedSnakedHash < Hashie::Mash
185
+ include SnakyHash::Snake.new(
186
+ key_type: :symbol, # default :string
187
+ serializer: true, # default: false
188
+ )
189
+ end
190
+
191
+ snake = MySerializedSnakedHash.new(:a => "a", "b" => "b", 2 => 2, "VeryFineHat" => "Feathers") # => {a: "a", b: "b", 2 => 2, very_fine_hat: "Feathers"}
192
+ dump = MySerializedSnakedHash.dump(snake) # => "{\"a\":\"a\",\"b\":\"b\",\"2\":2,\"very_fine_hat\":\"Feathers\"}"
193
+ hydrated = MySerializedSnakedHash.load(dump) # => {a: "a", b: "b", "2": 2, very_fine_hat: "Feathers"}
194
+ hydrated.class # => MySerializedSnakedHash
195
+ hydrated.a # => 'a'
196
+ hydrated.b # => 'b'
197
+ hydrated[2] # => nil # NOTE: this is the opposite of snake[2] => 2
198
+ hydrated["2"] # => 2 # NOTE: this is the opposite of snake["2"] => nil
199
+ hydrated.very_fine_hat # => 'Feathers'
200
+ hydrated[:very_fine_hat] # => 'Feathers'
201
+ hydrated["very_fine_hat"] # => 'Feathers'
202
+ ```
203
+
204
+ Note that the key `VeryFineHat` changed to `very_fine_hat`.
205
+ That is indeed the point of this library, so not a bug.
206
+
207
+ Note that the key `2` changed to `"2"` (because JSON keys are strings).
208
+ When the JSON dump was reloaded it did not know to restore it as `2` instead of `"2"`.
209
+ This is also not a bug, though if you need different behavior, there is a solution in the [next section](#extensions).
210
+
211
+ ### Extensions
212
+
213
+ You can write your own arbitrary extensions:
214
+
215
+ * "Hash Load" extensions operate on the hash, and nested hashes
216
+ * use `::load_hash_extensions.add(:extension_name) { |hash| }`
217
+ * "Load" extensions operate on the values, and nested hash's values, if any
218
+ * use `::load_extensions.add(:extension_name) { |value| }`
219
+ * "Dump" extensions operate on the values, and nested hash's values, if any
220
+ * use `::dump_extensions.add(:extension_name) { |value| }`
221
+
222
+ #### Example
223
+
224
+ Let's say I want all integer-like keys, except 0, to be integer keys,
225
+ while 0 converts to, and stays, a string forever.
226
+
227
+ ```ruby
228
+ class MyExtSnakedHash < Hashie::Mash
229
+ include SnakyHash::Snake.new(
230
+ key_type: :symbol, # default :string
231
+ serializer: true, # default: false
232
+ )
233
+ end
234
+
235
+ MyExtSnakedHash.load_hash_extensions.add(:non_zero_keys_to_int) do |value|
236
+ if value.is_a?(Hash)
237
+ value.transform_keys do |key|
238
+ key_int = key.to_s.to_i
239
+ if key_int > 0
240
+ key_int
241
+ else
242
+ key
243
+ end
244
+ end
245
+ else
246
+ value
247
+ end
248
+ end
249
+
250
+ snake = MyExtSnakedHash.new(1 => "a", 0 => 4, "VeryFineHat" => {3 => "v", 5 => 7, :very_fine_hat => "feathers"}) # => {1 => "a", 0 => 4, very_fine_hat: {3 => "v", 5 => 7, very_fine_hat: "feathers"}}
251
+ dump = MyExtSnakedHash.dump(snake) # => "{\"1\":\"a\",\"0\":4,\"very_fine_hat\":{\"3\":\"v\",\"5\":7,\"very_fine_hat\":\"feathers\"}}"
252
+ hydrated = MyExtSnakedHash.load(dump) # => {1 => "a", "0": 4, very_fine_hat: {3 => "v", 5 => 7, very_fine_hat: "feathers"}}
253
+ hydrated.class # => MyExtSnakedHash
254
+ hydrated["1"] # => nil
255
+ hydrated[1] # => "a"
256
+ hydrated["0"] # => 4
257
+ hydrated[0] # => nil
258
+ hydrated.very_fine_hat # => {3 => "v", 5 => 7, very_fine_hat: "feathers"}
259
+ hydrated.very_fine_hat.very_fine_hat # => "feathers"
260
+ hydrated.very_fine_hat[:very_fine_hat] # => 'feathers'
261
+ hydrated.very_fine_hat["very_fine_hat"] # => 'feathers'
262
+ ```
263
+
264
+ See the specs for more examples.
265
+
41
266
  ### Stranger Things
42
267
 
43
268
  I don't recommend using these features... but they exist (for now).
44
269
  You can still access the original un-snaked camel keys.
45
270
  And through them you can even use un-snaked camel methods.
271
+ But don't.
46
272
 
47
273
  ```ruby
48
274
  snake.key?("VeryFineHat") # => true
@@ -59,20 +285,300 @@ snake["very_fine_hat"] = "cheese" # => 'cheese', or do this instead!!!
59
285
  snake.very_fine_hat # => 'cheese'
60
286
  ```
61
287
 
62
- ## Development
288
+ ### 🚀 Release Instructions
289
+
290
+ See [CONTRIBUTING.md][🤝contributing].
291
+
292
+ ## 🔐 Security
293
+
294
+ See [SECURITY.md][🔐security].
295
+
296
+ ## 🤝 Contributing
297
+
298
+ If you need some ideas of where to help, you could work on adding more code coverage,
299
+ or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues], or [PRs][🤝gh-pulls],
300
+ or use the gem and think about how it could be better.
301
+
302
+ We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
303
+
304
+ See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
305
+
306
+ ### Code Coverage
307
+
308
+ [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls]
309
+ [![QLTY Test Coverage][🔑qlty-covi♻️]][🔑qlty-cov]
310
+
311
+ ### 🪇 Code of Conduct
312
+
313
+ Everyone interacting in this project's codebases, issue trackers,
314
+ chat rooms and mailing lists is expected to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
315
+
316
+ ## 🌈 Contributors
317
+
318
+ [![Contributors][🖐contributors-img]][🖐contributors]
319
+
320
+ Made with [contributors-img][🖐contrib-rocks].
321
+
322
+ Also see GitLab Contributors: [https://gitlab.com/oauth-xx/snaky_hash/-/graphs/main][🚎contributors-gl]
323
+
324
+ ## ⭐️ Star History
325
+
326
+ <a href="https://star-history.com/#oauth-xx/snaky_hash&Date">
327
+ <picture>
328
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=oauth-xx/snaky_hash&type=Date&theme=dark" />
329
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=oauth-xx/snaky_hash&type=Date" />
330
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=oauth-xx/snaky_hash&type=Date" />
331
+ </picture>
332
+ </a>
333
+
334
+ ## 📌 Versioning
335
+
336
+ This Library adheres to [![Semantic Versioning 2.0.0][📌semver-img]][📌semver].
337
+ Violations of this scheme should be reported as bugs.
338
+ Specifically, if a minor or patch version is released that breaks backward compatibility,
339
+ a new version should be immediately released that restores compatibility.
340
+ Breaking changes to the public API will only be introduced with new major versions.
341
+
342
+ ### 📌 Is "Platform Support" part of the public API?
343
+
344
+ Yes. But I'm obligated to include notes...
345
+
346
+ SemVer should, but doesn't explicitly, say that dropping support for specific Platforms
347
+ is a *breaking change* to an API.
348
+ It is obvious to many, but not all, and since the spec is silent, the bike shedding is endless.
349
+
350
+ > dropping support for a platform is both obviously and objectively a breaking change
351
+
352
+ - Jordan Harband (@ljharb, maintainer of SemVer) [in SemVer issue 716][📌semver-breaking]
353
+
354
+ To get a better understanding of how SemVer is intended to work over a project's lifetime,
355
+ read this article from the creator of SemVer:
356
+
357
+ - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
358
+
359
+ As a result of this policy, and the interpretive lens used by the maintainer,
360
+ you can (and should) specify a dependency on these libraries using
361
+ the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
362
+
363
+ For example:
364
+
365
+ ```ruby
366
+ spec.add_dependency("snaky_hash", "~> 2.0")
367
+ ```
368
+
369
+ See [CHANGELOG.md][📌changelog] for list of releases.
370
+
371
+ ## 📄 License
372
+
373
+ The gem is available as open source under the terms of
374
+ the [MIT License][📄license] [![License: MIT][📄license-img]][📄license-ref].
375
+ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright-notice-explainer].
376
+
377
+ ### © Copyright
378
+
379
+ <ul>
380
+ <li>
381
+ 2022, 2025 Peter H. Boling, of
382
+ <a href="https://railsbling.com">
383
+ RailsBling.com
384
+ <picture>
385
+ <img alt="Rails Bling" height="20" src="https://railsbling.com/images/logos/RailsBling-TrainLogo.svg" />
386
+ </picture>
387
+ </a>, and snaky_hash contributors
388
+ </li>
389
+ </ul>
390
+
391
+ ## 🤑 One more thing
392
+
393
+ You made it to the bottom of the page,
394
+ so perhaps you'll indulge me for another 20 seconds.
395
+ I maintain many dozens of gems, including this one,
396
+ because I want Ruby to be a great place for people to solve problems, big and small.
397
+ Please consider supporting my efforts via the giant yellow link below,
398
+ or one of the others at the head of this README.
63
399
 
64
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
400
+ [![Buy me a latte][🖇buyme-img]][🖇buyme]
65
401
 
66
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
402
+ [⛳gg-discussions]: https://groups.google.com/g/oauth-ruby
403
+ [⛳gg-discussions-img]: https://img.shields.io/badge/google-group-0093D0.svg?style=for-the-badge&logo=google&logoColor=orange
67
404
 
68
- ## Contributing
405
+ [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
406
+ [⛳️gem-namespace]: https://github.com/oauth-xx/snaky_hash
407
+ [⛳️namespace-img]: https://img.shields.io/badge/namespace-OAuth2-brightgreen.svg?style=flat&logo=ruby&logoColor=white
408
+ [⛳️gem-name]: https://rubygems.org/gems/snaky_hash
409
+ [⛳️name-img]: https://img.shields.io/badge/name-snaky_hash-brightgreen.svg?style=flat&logo=rubygems&logoColor=red
410
+ [🚂bdfl-blog]: http://www.railsbling.com/tags/snaky_hash
411
+ [🚂bdfl-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
412
+ [🚂bdfl-contact]: http://www.railsbling.com/contact
413
+ [🚂bdfl-contact-img]: https://img.shields.io/badge/Contact-BDFL-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red
414
+ [💖🖇linkedin]: http://www.linkedin.com/in/peterboling
415
+ [💖🖇linkedin-img]: https://img.shields.io/badge/PeterBoling-LinkedIn-0B66C2?style=flat&logo=newjapanprowrestling
416
+ [💖✌️wellfound]: https://angel.co/u/peter-boling
417
+ [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound
418
+ [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
419
+ [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
420
+ [💖🐘ruby-mast]: https://ruby.social/@galtzo
421
+ [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https%3A%2F%2Fruby.social&style=flat&logo=mastodon&label=Ruby%20%40galtzo
422
+ [💖🦋bluesky]: https://bsky.app/profile/galtzo.com
423
+ [💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
424
+ [💖🌳linktree]: https://linktr.ee/galtzo
425
+ [💖🌳linktree-img]: https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree
426
+ [💖💁🏼‍♂️devto]: https://dev.to/galtzo
427
+ [💖💁🏼‍♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white
428
+ [💖💁🏼‍♂️aboutme]: https://about.me/peter.boling
429
+ [💖💁🏼‍♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white
430
+ [💖🧊berg]: https://codeberg.org/pboling
431
+ [💖🐙hub]: https://github.org/pboling
432
+ [💖🛖hut]: https://sr.ht/~galtzo/
433
+ [💖🧪lab]: https://gitlab.com/pboling
434
+ [👨🏼‍🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share
435
+ [👨🏼‍🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white
436
+ [👨🏼‍🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
437
+ [👨🏼‍🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white
438
+ [🏙️entsup-tidelift]: https://tidelift.com/subscription
439
+ [🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white
440
+ [🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar
441
+ [💁🏼‍♂️peterboling]: http://www.peterboling.com
442
+ [🚂railsbling]: http://www.railsbling.com
443
+ [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
444
+ [📜src-gl]: https://gitlab.com/oauth-xx/snaky_hash/
445
+ [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue
446
+ [📜src-cb]: https://codeberg.org/oauth-xx/snaky_hash
447
+ [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green
448
+ [📜src-gh]: https://github.com/oauth-xx/snaky_hash
449
+ [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
450
+ [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
451
+ [📜wiki]: https://gitlab.com/oauth-xx/snaky_hash/-/wikis/home
452
+ [📜wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=Wiki&logoColor=white
453
+ [👽dl-rank]: https://rubygems.org/gems/snaky_hash
454
+ [👽dl-ranki]: https://img.shields.io/gem/rd/snaky_hash.svg
455
+ [👽oss-help]: https://www.codetriage.com/oauth-xx/snaky_hash
456
+ [👽oss-helpi]: https://www.codetriage.com/oauth-xx/snaky_hash/badges/users.svg
457
+ [👽version]: https://rubygems.org/gems/snaky_hash
458
+ [👽versioni]: https://img.shields.io/gem/v/snaky_hash.svg
459
+ [🔑qlty-mnt]: https://qlty.sh/gh/oauth-xx/projects/snaky_hash
460
+ [🔑qlty-mnti♻️]: https://qlty.sh/badges/84e960b2-4ed2-4b47-9913-02c32680ec98/maintainability.svg
461
+ [🔑qlty-cov]: https://qlty.sh/gh/oauth-xx/projects/snaky_hash
462
+ [🔑qlty-covi♻️]: https://qlty.sh/badges/84e960b2-4ed2-4b47-9913-02c32680ec98/test_coverage.svg
463
+ [🔑codecov]: https://codecov.io/gh/oauth-xx/snaky_hash
464
+ [🔑codecovi♻️]: https://codecov.io/gh/oauth-xx/snaky_hash/graph/badge.svg?token=XqaZixl4ss
465
+ [🔑coveralls]: https://coveralls.io/github/oauth-xx/snaky_hash?branch=main
466
+ [🔑coveralls-img]: https://coveralls.io/repos/github/oauth-xx/snaky_hash/badge.svg?branch=main
467
+ [🔑depfu]: https://depfu.com/github/oauth-xx/snaky_hash?project_id=63073
468
+ [🔑depfui♻️]: https://badges.depfu.com/badges/7019dcf43672ba8c0e77e7fdd1063398/count.svg
469
+ [🖐codeQL]: https://github.com/oauth-xx/snaky_hash/security/code-scanning
470
+ [🖐codeQL-img]: https://github.com/oauth-xx/snaky_hash/actions/workflows/codeql-analysis.yml/badge.svg
471
+ [🚎1-an-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/ancient.yml
472
+ [🚎1-an-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/ancient.yml/badge.svg
473
+ [🚎2-cov-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/coverage.yml
474
+ [🚎2-cov-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/coverage.yml/badge.svg
475
+ [🚎3-hd-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/heads.yml
476
+ [🚎3-hd-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/heads.yml/badge.svg
477
+ [🚎4-lg-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/legacy.yml
478
+ [🚎4-lg-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/legacy.yml/badge.svg
479
+ [🚎5-st-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/style.yml
480
+ [🚎5-st-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/style.yml/badge.svg
481
+ [🚎6-s-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/supported.yml
482
+ [🚎6-s-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/supported.yml/badge.svg
483
+ [🚎7-us-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/unsupported.yml
484
+ [🚎7-us-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/unsupported.yml/badge.svg
485
+ [🚎8-ho-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/hoary.yml
486
+ [🚎8-ho-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/hoary.yml/badge.svg
487
+ [🚎9-t-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/truffle.yml
488
+ [🚎9-t-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/truffle.yml/badge.svg
489
+ [🚎10-j-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/jruby.yml
490
+ [🚎10-j-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/jruby.yml/badge.svg
491
+ [🚎11-c-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/current.yml
492
+ [🚎11-c-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/current.yml/badge.svg
493
+ [🚎12-crh-wf]: https://github.com/oauth-xx/snaky_hash/actions/workflows/current-runtime-heads.yml
494
+ [🚎12-crh-wfi]: https://github.com/oauth-xx/snaky_hash/actions/workflows/current-runtime-heads.yml/badge.svg
495
+ [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay
496
+ [⛳liberapay]: https://liberapay.com/pboling/donate
497
+ [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github
498
+ [🖇sponsor]: https://github.com/sponsors/pboling
499
+ [🖇polar-img]: https://img.shields.io/badge/polar-donate-yellow.svg
500
+ [🖇polar]: https://polar.sh/pboling
501
+ [🖇kofi-img]: https://img.shields.io/badge/a_more_different_coffee-✓-yellow.svg
502
+ [🖇kofi]: https://ko-fi.com/O5O86SNP4
503
+ [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-yellow.svg
504
+ [🖇patreon]: https://patreon.com/galtzo
505
+ [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
506
+ [🖇buyme]: https://www.buymeacoffee.com/pboling
507
+ [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-✓-yellow.svg?style=flat
508
+ [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
509
+ [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
510
+ [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
511
+ [💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
512
+ [💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
513
+ [💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
514
+ [💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white
515
+ [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
516
+ [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
517
+ [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
518
+ [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
519
+ [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
520
+ [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
521
+ [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
522
+ [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
523
+ [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
524
+ [💎jruby-9.1i]: https://img.shields.io/badge/JRuby-9.1-FBE742?style=for-the-badge&logo=ruby&logoColor=red
525
+ [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red
526
+ [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red
527
+ [💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red
528
+ [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
529
+ [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
530
+ [🤝gh-issues]: https://github.com/oauth-xx/snaky_hash/issues
531
+ [🤝gh-pulls]: https://github.com/oauth-xx/snaky_hash/pulls
532
+ [🤝gl-issues]: https://gitlab.com/oauth-xx/snaky_hash/-/issues
533
+ [🤝gl-pulls]: https://gitlab.com/oauth-xx/snaky_hash/-/merge_requests
534
+ [🤝cb-issues]: https://codeberg.org/oauth-xx/snaky_hash/issues
535
+ [🤝cb-pulls]: https://codeberg.org/oauth-xx/snaky_hash/pulls
536
+ [🤝cb-donate]: https://donate.codeberg.org/
537
+ [🤝contributing]: CONTRIBUTING.md
538
+ [🔑codecov-g♻️]: https://codecov.io/gh/oauth-xx/snaky_hash/graphs/tree.svg?token=XqaZixl4ss
539
+ [🖐contrib-rocks]: https://contrib.rocks
540
+ [🖐contributors]: https://github.com/oauth-xx/snaky_hash/graphs/contributors
541
+ [🖐contributors-img]: https://contrib.rocks/image?repo=oauth-xx/snaky_hash
542
+ [🚎contributors-gl]: https://gitlab.com/oauth-xx/snaky_hash/-/graphs/main
543
+ [🪇conduct]: CODE_OF_CONDUCT.md
544
+ [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg
545
+ [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
546
+ [📌semver]: https://semver.org/spec/v2.0.0.html
547
+ [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat
548
+ [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
549
+ [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
550
+ [📌changelog]: CHANGELOG.md
551
+ [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
552
+ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
553
+ [📌gitmoji]:https://gitmoji.dev
554
+ [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20😜%20😍-34495e.svg?style=flat-square
555
+ [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
556
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.119-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
557
+ [🔐security]: SECURITY.md
558
+ [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
559
+ [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
560
+ [📄license]: LICENSE.txt
561
+ [📄license-ref]: https://opensource.org/licenses/MIT
562
+ [📄license-img]: https://img.shields.io/badge/License-MIT-259D6C.svg
563
+ [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
564
+ [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat
565
+ [🚎yard-current]: http://rubydoc.info/gems/snaky_hash
566
+ [🚎yard-head]: https://snaky_hash.galtzo.com
567
+ [💎stone_checksums]: https://github.com/pboling/stone_checksums
568
+ [💎SHA_checksums]: https://gitlab.com/oauth-xx/snaky_hash/-/tree/main/checksums
569
+ [💎rlts]: https://github.com/rubocop-lts/rubocop-lts
570
+ [💎rlts-img]: https://img.shields.io/badge/code_style_%26_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
571
+ [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
572
+ [✉️discord-invite]: https://discord.gg/3qme4XHNKN
573
+ [✉️discord-invite-img]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge
69
574
 
70
- Bug reports and pull requests are welcome on GitHub at https://gitlab.com/oauth-xx/snaky_hash. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://gitlab.com/oauth-xx/snaky_hash/-/blob/main/CODE_OF_CONDUCT.md).
575
+ <details>
576
+ <summary>Deprecated Badges</summary>
71
577
 
72
- ## License
578
+ CodeCov currently fails to parse the coverage upload.
73
579
 
74
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
580
+ [![CodeCov Test Coverage][🔑codecovi♻️]][🔑codecov]
75
581
 
76
- ## Code of Conduct
582
+ [![Coverage Graph][🔑codecov-g♻️]][🔑codecov]
77
583
 
78
- Everyone interacting in the SnakyHash project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/oauth-xx/snaky_hash/-/blob/main/CODE_OF_CONDUCT.md).
584
+ </details>
data/SECURITY.md CHANGED
@@ -4,7 +4,8 @@
4
4
 
5
5
  | Version | Supported | EOL | Post-EOL / Enterprise |
6
6
  |---------|-----------|---------|---------------------------------------|
7
- | 1.0.x | ✅ | 04/2023 | [Tidelift Subscription][tidelift-ref] |
7
+ | 2.0.x | ✅ | 04/2023 | [Tidelift Subscription][tidelift-ref] |
8
+ | 1.0.x | | | |
8
9
 
9
10
  ### EOL Policy
10
11