kettle-jem 7.0.0 → 7.1.3

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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +1505 -0
  4. data/LICENSE.md +13 -0
  5. data/README.md +794 -0
  6. data/exe/kettle-jem +20 -0
  7. data/lib/kettle/jem/cli.rb +334 -0
  8. data/lib/kettle/jem/license_txt_migrator.rb +33 -0
  9. data/lib/kettle/jem/rakelib/install.rake +10 -0
  10. data/lib/kettle/jem/rakelib/prepare.rake +10 -0
  11. data/lib/kettle/jem/rakelib/selftest.rake +10 -0
  12. data/lib/kettle/jem/rakelib/template.rake +10 -0
  13. data/lib/kettle/jem/tasks/install_task.rb +2178 -0
  14. data/lib/kettle/jem/tasks/prepare_task.rb +274 -0
  15. data/lib/kettle/jem/tasks/self_test_task.rb +256 -0
  16. data/lib/kettle/jem/tasks/template_task.rb +124 -0
  17. data/lib/kettle/jem/tasks.rb +6 -0
  18. data/lib/kettle/jem/templates/.aiignore.example +19 -0
  19. data/lib/kettle/jem/templates/.config/mise/env.sh +26 -0
  20. data/lib/kettle/jem/templates/.devcontainer/apt-install/devcontainer-feature.json.example +9 -0
  21. data/lib/kettle/jem/templates/.devcontainer/apt-install/install.sh.example +19 -0
  22. data/lib/kettle/jem/templates/.devcontainer/devcontainer.json.example +27 -0
  23. data/lib/kettle/jem/templates/.devcontainer/scripts/setup-tree-sitter.sh.example +210 -0
  24. data/lib/kettle/jem/templates/.env.local.example +67 -0
  25. data/lib/kettle/jem/templates/.envrc.example +4 -0
  26. data/lib/kettle/jem/templates/.envrc.no-osc.example +4 -0
  27. data/lib/kettle/jem/templates/.gemrc.example +1 -0
  28. data/lib/kettle/jem/templates/.git-hooks/commit-msg.example +60 -0
  29. data/lib/kettle/jem/templates/.git-hooks/commit-subjects-goalie.txt.example +8 -0
  30. data/lib/kettle/jem/templates/.git-hooks/footer-template.erb.txt.example +16 -0
  31. data/lib/kettle/jem/templates/.git-hooks/prepare-commit-msg.example +9 -0
  32. data/lib/kettle/jem/templates/.github/.codecov.yml.example +14 -0
  33. data/lib/kettle/jem/templates/.github/FUNDING.yml.example +10 -0
  34. data/lib/kettle/jem/templates/.github/FUNDING.yml.no-osc.example +10 -0
  35. data/lib/kettle/jem/templates/.github/copilot_instructions.md.example +1 -0
  36. data/lib/kettle/jem/templates/.github/dependabot.yml.example +13 -0
  37. data/lib/kettle/jem/templates/.github/workflows/auto-assign.yml.example +21 -0
  38. data/lib/kettle/jem/templates/.github/workflows/coverage.yml.example +102 -0
  39. data/lib/kettle/jem/templates/.github/workflows/current.yml.example +86 -0
  40. data/lib/kettle/jem/templates/.github/workflows/dep-heads.yml.example +249 -0
  41. data/lib/kettle/jem/templates/.github/workflows/dependency-review.yml.example +22 -0
  42. data/lib/kettle/jem/templates/.github/workflows/discord-notifier.yml.example +39 -0
  43. data/lib/kettle/jem/templates/.github/workflows/framework-ci.yml.example +81 -0
  44. data/lib/kettle/jem/templates/.github/workflows/heads.yml.example +212 -0
  45. data/lib/kettle/jem/templates/.github/workflows/jruby-10.0.yml.example +91 -0
  46. data/lib/kettle/jem/templates/.github/workflows/jruby-9.1.yml.example +90 -0
  47. data/lib/kettle/jem/templates/.github/workflows/jruby-9.2.yml.example +95 -0
  48. data/lib/kettle/jem/templates/.github/workflows/jruby-9.3.yml.example +95 -0
  49. data/lib/kettle/jem/templates/.github/workflows/jruby-9.4.yml.example +95 -0
  50. data/lib/kettle/jem/templates/.github/workflows/jruby.yml.example +91 -0
  51. data/lib/kettle/jem/templates/.github/workflows/license-eye.yml.example +43 -0
  52. data/lib/kettle/jem/templates/.github/workflows/locked_deps.yml.example +89 -0
  53. data/lib/kettle/jem/templates/.github/workflows/opencollective.yml.example +44 -0
  54. data/lib/kettle/jem/templates/.github/workflows/ruby-2.3.yml.example +80 -0
  55. data/lib/kettle/jem/templates/.github/workflows/ruby-2.4.yml.example +84 -0
  56. data/lib/kettle/jem/templates/.github/workflows/ruby-2.5.yml.example +84 -0
  57. data/lib/kettle/jem/templates/.github/workflows/ruby-2.6.yml.example +84 -0
  58. data/lib/kettle/jem/templates/.github/workflows/ruby-2.7.yml.example +84 -0
  59. data/lib/kettle/jem/templates/.github/workflows/ruby-3.0.yml.example +85 -0
  60. data/lib/kettle/jem/templates/.github/workflows/ruby-3.1.yml.example +83 -0
  61. data/lib/kettle/jem/templates/.github/workflows/ruby-3.2.yml.example +80 -0
  62. data/lib/kettle/jem/templates/.github/workflows/ruby-3.3.yml.example +80 -0
  63. data/lib/kettle/jem/templates/.github/workflows/ruby-3.4.yml.example +80 -0
  64. data/lib/kettle/jem/templates/.github/workflows/style.yml.example +78 -0
  65. data/lib/kettle/jem/templates/.github/workflows/templating.yml.example +86 -0
  66. data/lib/kettle/jem/templates/.github/workflows/truffle.yml.example +91 -0
  67. data/lib/kettle/jem/templates/.github/workflows/truffleruby-22.3.yml.example +92 -0
  68. data/lib/kettle/jem/templates/.github/workflows/truffleruby-23.0.yml.example +92 -0
  69. data/lib/kettle/jem/templates/.github/workflows/truffleruby-23.1.yml.example +78 -0
  70. data/lib/kettle/jem/templates/.github/workflows/truffleruby-24.2.yml.example +91 -0
  71. data/lib/kettle/jem/templates/.github/workflows/truffleruby-25.0.yml.example +96 -0
  72. data/lib/kettle/jem/templates/.github/workflows/truffleruby-33.0.yml.example +91 -0
  73. data/lib/kettle/jem/templates/.github/workflows/unlocked_deps.yml.example +93 -0
  74. data/lib/kettle/jem/templates/.gitignore.example +53 -0
  75. data/lib/kettle/jem/templates/.gitlab-ci.yml.example +134 -0
  76. data/lib/kettle/jem/templates/.idea/.gitignore.example +44 -0
  77. data/lib/kettle/jem/templates/.licenserc.yaml.example +8 -0
  78. data/lib/kettle/jem/templates/.opencollective.yml.example +3 -0
  79. data/lib/kettle/jem/templates/.qlty/qlty.toml.example +79 -0
  80. data/lib/kettle/jem/templates/.rspec.example +10 -0
  81. data/lib/kettle/jem/templates/.rubocop.example +1 -0
  82. data/lib/kettle/jem/templates/.rubocop.yml.example +47 -0
  83. data/lib/kettle/jem/templates/.rubocop_rspec.yml.example +55 -0
  84. data/lib/kettle/jem/templates/.simplecov.example +18 -0
  85. data/lib/kettle/jem/templates/.structuredmerge/git-drivers.toml.example +86 -0
  86. data/lib/kettle/jem/templates/.structuredmerge/kettle-jem.yml.example +519 -0
  87. data/lib/kettle/jem/templates/.yard-lint.yml.example +54 -0
  88. data/lib/kettle/jem/templates/.yardignore.example +13 -0
  89. data/lib/kettle/jem/templates/.yardopts.example +14 -0
  90. data/lib/kettle/jem/templates/AGENTS.md.example +283 -0
  91. data/lib/kettle/jem/templates/AGPL-3.0-only.md.example +235 -0
  92. data/lib/kettle/jem/templates/Appraisal.root.gemfile.example +26 -0
  93. data/lib/kettle/jem/templates/Appraisals.example +150 -0
  94. data/lib/kettle/jem/templates/Big-Time-Public-License.md.example +99 -0
  95. data/lib/kettle/jem/templates/CHANGELOG.md.example +33 -0
  96. data/lib/kettle/jem/templates/CHANGELOG.transfer.md +109 -0
  97. data/lib/kettle/jem/templates/CITATION.cff.example +20 -0
  98. data/lib/kettle/jem/templates/CODE_OF_CONDUCT.md.example +134 -0
  99. data/lib/kettle/jem/templates/CONTRIBUTING.md.example +292 -0
  100. data/lib/kettle/jem/templates/FUNDING.md.example +74 -0
  101. data/lib/kettle/jem/templates/FUNDING.md.no-osc.example +63 -0
  102. data/lib/kettle/jem/templates/Gemfile.example +52 -0
  103. data/lib/kettle/jem/templates/IRP.md.example +34 -0
  104. data/lib/kettle/jem/templates/LICENSE.md.example +3 -0
  105. data/lib/kettle/jem/templates/MIT.md.example +21 -0
  106. data/lib/kettle/jem/templates/PolyForm-Noncommercial-1.0.0.md.example +131 -0
  107. data/lib/kettle/jem/templates/PolyForm-Small-Business-1.0.0.md.example +121 -0
  108. data/lib/kettle/jem/templates/README.md.example +544 -0
  109. data/lib/kettle/jem/templates/REEK +0 -0
  110. data/lib/kettle/jem/templates/RUBOCOP.md.example +78 -0
  111. data/lib/kettle/jem/templates/Rakefile.example +163 -0
  112. data/lib/kettle/jem/templates/SECURITY.md.example +21 -0
  113. data/lib/kettle/jem/templates/bin/setup.example +36 -0
  114. data/lib/kettle/jem/templates/certs/pboling.pem.example +27 -0
  115. data/lib/kettle/jem/templates/gem.gemspec.example +161 -0
  116. data/lib/kettle/jem/templates/gemfiles/modular/benchmark/r4/v0.5.gemfile.example +2 -0
  117. data/lib/kettle/jem/templates/gemfiles/modular/benchmark/vHEAD.gemfile.example +2 -0
  118. data/lib/kettle/jem/templates/gemfiles/modular/cgi/r4/v0.5.gemfile.example +1 -0
  119. data/lib/kettle/jem/templates/gemfiles/modular/cgi/vHEAD.gemfile.example +1 -0
  120. data/lib/kettle/jem/templates/gemfiles/modular/changelog.gemfile.example +6 -0
  121. data/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example +14 -0
  122. data/lib/kettle/jem/templates/gemfiles/modular/coverage_local.gemfile.example +34 -0
  123. data/lib/kettle/jem/templates/gemfiles/modular/debug.gemfile.example +22 -0
  124. data/lib/kettle/jem/templates/gemfiles/modular/documentation.gemfile.example +24 -0
  125. data/lib/kettle/jem/templates/gemfiles/modular/documentation_local.gemfile.example +20 -0
  126. data/lib/kettle/jem/templates/gemfiles/modular/erb/r2/v3.0.gemfile.example +1 -0
  127. data/lib/kettle/jem/templates/gemfiles/modular/erb/r2.3/default.gemfile.example +6 -0
  128. data/lib/kettle/jem/templates/gemfiles/modular/erb/r2.6/v2.2.gemfile.example +3 -0
  129. data/lib/kettle/jem/templates/gemfiles/modular/erb/r3/v5.0.gemfile.example +1 -0
  130. data/lib/kettle/jem/templates/gemfiles/modular/erb/r3.1/v4.0.gemfile.example +2 -0
  131. data/lib/kettle/jem/templates/gemfiles/modular/erb/r4/v5.0.gemfile.example +1 -0
  132. data/lib/kettle/jem/templates/gemfiles/modular/erb/vHEAD.gemfile.example +2 -0
  133. data/lib/kettle/jem/templates/gemfiles/modular/json/truffleruby_22_3.gemfile.example +6 -0
  134. data/lib/kettle/jem/templates/gemfiles/modular/json/truffleruby_23_0.gemfile.example +6 -0
  135. data/lib/kettle/jem/templates/gemfiles/modular/json/truffleruby_23_1.gemfile.example +6 -0
  136. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r2/v0.3.gemfile.example +2 -0
  137. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r2.4/v0.1.gemfile.example +3 -0
  138. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r3/v0.3.gemfile.example +2 -0
  139. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r4/v0.3.gemfile.example +2 -0
  140. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/vHEAD.gemfile.example +2 -0
  141. data/lib/kettle/jem/templates/gemfiles/modular/optional.gemfile.example +16 -0
  142. data/lib/kettle/jem/templates/gemfiles/modular/recording/r2.3/recording.gemfile.example +16 -0
  143. data/lib/kettle/jem/templates/gemfiles/modular/recording/r2.4/recording.gemfile.example +18 -0
  144. data/lib/kettle/jem/templates/gemfiles/modular/recording/r2.5/recording.gemfile.example +16 -0
  145. data/lib/kettle/jem/templates/gemfiles/modular/recording/r3/recording.gemfile.example +16 -0
  146. data/lib/kettle/jem/templates/gemfiles/modular/recording/r4/recording.gemfile.example +16 -0
  147. data/lib/kettle/jem/templates/gemfiles/modular/recording/vHEAD.gemfile.example +2 -0
  148. data/lib/kettle/jem/templates/gemfiles/modular/rspec.gemfile.example +4 -0
  149. data/lib/kettle/jem/templates/gemfiles/modular/runtime_heads.gemfile.example +14 -0
  150. data/lib/kettle/jem/templates/gemfiles/modular/shunted.gemfile.example +21 -0
  151. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r2/v3.0.gemfile.example +5 -0
  152. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r2.4/v0.0.2.gemfile.example +4 -0
  153. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r3/v3.0.gemfile.example +5 -0
  154. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r4/v3.0.gemfile.example +5 -0
  155. data/lib/kettle/jem/templates/gemfiles/modular/stringio/vHEAD.gemfile.example +2 -0
  156. data/lib/kettle/jem/templates/gemfiles/modular/style.gemfile.example +33 -0
  157. data/lib/kettle/jem/templates/gemfiles/modular/style_local.gemfile.example +26 -0
  158. data/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example +34 -0
  159. data/lib/kettle/jem/templates/gemfiles/modular/templating_local.gemfile.example +73 -0
  160. data/lib/kettle/jem/templates/gemfiles/modular/webrick/r4/v1.9.gemfile.example +1 -0
  161. data/lib/kettle/jem/templates/gemfiles/modular/webrick/vHEAD.gemfile.example +1 -0
  162. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2/libs.gemfile.example +3 -0
  163. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2.3/libs.gemfile.example +3 -0
  164. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2.4/libs.gemfile.example +3 -0
  165. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2.6/libs.gemfile.example +3 -0
  166. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r3/libs.gemfile.example +3 -0
  167. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r3.1/libs.gemfile.example +5 -0
  168. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r4/libs.gemfile.example +6 -0
  169. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/vHEAD.gemfile.example +6 -0
  170. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs.gemfile.example +12 -0
  171. data/lib/kettle/jem/templates/lib/gem/version.rb.example +1 -0
  172. data/lib/kettle/jem/templates/lib/gem/version_gem.rb.example +1 -0
  173. data/lib/kettle/jem/templates/mise.toml.example +25 -0
  174. data/lib/kettle/jem/templates/mise.toml.no-osc.example +25 -0
  175. data/lib/kettle/jem/templates/parsers.toml.example +19 -0
  176. data/lib/kettle/jem/templates/readme/partials/basic_usage.md.example +28 -0
  177. data/lib/kettle/jem/templates/readme/partials/configuration.md.example +112 -0
  178. data/lib/kettle/jem/templates/readme/partials/synopsis.md.example +3 -0
  179. data/lib/kettle/jem/templates/shim/.github/workflows/current.yml.example +40 -0
  180. data/lib/kettle/jem/templates/shim/.rspec.example +5 -0
  181. data/lib/kettle/jem/templates/shim/.structuredmerge/kettle-jem.yml.example +28 -0
  182. data/lib/kettle/jem/templates/shim/CHANGELOG.md.example +9 -0
  183. data/lib/kettle/jem/templates/shim/Gemfile.example +14 -0
  184. data/lib/kettle/jem/templates/shim/README.md.example +25 -0
  185. data/lib/kettle/jem/templates/shim/Rakefile.example +8 -0
  186. data/lib/kettle/jem/templates/shim/gem.gemspec.example +45 -0
  187. data/lib/kettle/jem/templates/shim/lib/compat_require.rb.example +3 -0
  188. data/lib/kettle/jem/templates/shim/lib/entrypoint.rb.example +3 -0
  189. data/lib/kettle/jem/templates/shim/lib/version.rb.example +1 -0
  190. data/lib/kettle/jem/templates/shim/spec/shim_spec.rb.example +15 -0
  191. data/lib/kettle/jem/templates/shim/spec/spec_helper.rb.example +23 -0
  192. data/lib/kettle/jem/templates/sig/gem.rbs.example +1 -0
  193. data/lib/kettle/jem/templates/spec/README.md.example +28 -0
  194. data/lib/kettle/jem/templates/spec/spec_helper.rb.example +39 -0
  195. data/lib/kettle/jem/version.rb +5 -3
  196. data/lib/kettle/jem/version_gem.rb +8 -0
  197. data/lib/kettle/jem.rb +18540 -1517
  198. data/lib/kettle-jem.rb +2 -1
  199. data/sig/kettle/jem.rbs +8 -0
  200. data.tar.gz.sig +0 -0
  201. metadata +870 -32
  202. metadata.gz.sig +0 -0
@@ -0,0 +1,26 @@
1
+ # shellcheck shell=bash
2
+
3
+ prepend_unique_path_value() {
4
+ local value="$1"
5
+ local current="$2"
6
+
7
+ if [[ -z "$current" ]]; then
8
+ printf '%s' "$value"
9
+ elif [[ ":$current:" == *":$value:"* ]]; then
10
+ printf '%s' "$current"
11
+ else
12
+ printf '%s:%s' "$value" "$current"
13
+ fi
14
+ }
15
+
16
+ # Preserve existing values while prepending the project defaults needed by TreeHaver.
17
+ _tree_sitter_runtime_lib="${TREE_SITTER_RUNTIME_LIB:-/home/linuxbrew/.linuxbrew/Cellar/tree-sitter/0.26.6/lib/libtree-sitter.so}"
18
+ _tree_sitter_runtime_dir="$(dirname "${_tree_sitter_runtime_lib}")"
19
+ _tree_sitter_java_jars_dir="${TREE_SITTER_JAVA_JARS_DIR:-}"
20
+
21
+ if [[ -n "${_tree_sitter_java_jars_dir}" ]]; then
22
+ _tree_sitter_java_jar="${_tree_sitter_java_jars_dir}/jtreesitter-0.26.0.jar"
23
+ export CLASSPATH="$(prepend_unique_path_value "${_tree_sitter_java_jar}" "${CLASSPATH:-}")"
24
+ fi
25
+
26
+ export LD_LIBRARY_PATH="$(prepend_unique_path_value "${_tree_sitter_runtime_dir}" "${LD_LIBRARY_PATH:-}")"
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "Apt Install Packages",
3
+ "id": "apt-install",
4
+ "version": "1.0.0",
5
+ "description": "More packages are needed",
6
+ "install": {
7
+ "script": "install.sh"
8
+ }
9
+ }
@@ -0,0 +1,19 @@
1
+ #!/bin/sh
2
+ set -e # Exit on error
3
+
4
+ # Install basic development dependencies for Ruby & JRuby projects
5
+ apt-get update -y
6
+ apt-get install -y direnv default-jdk git zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev
7
+
8
+ # Support for PostgreSQL (commented out by default)
9
+ # apt-get install -y postgresql libpq-dev
10
+
11
+ # NOTE: Tree-sitter setup is NOT done here because the workspace is not mounted yet
12
+ # during the devcontainer build phase. Tree-sitter setup happens in postCreateCommand
13
+ # after the workspace is mounted. See devcontainer.json for details.
14
+ # This gem needs ALL grammars for top-level merging tool (handled by setup-tree-sitter.sh).
15
+
16
+ echo "Basic apt packages installed. Tree-sitter will be set up after workspace mount."
17
+
18
+ # Adds the direnv setup script to ~/.bashrc file (at the end)
19
+ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
@@ -0,0 +1,27 @@
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
3
+ {
4
+ "name": "Ruby",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ "image": "mcr.microsoft.com/devcontainers/ruby:1-3-bookworm",
7
+ // Features to add to the dev container. More info: https://containers.dev/features.
8
+ "features": {
9
+ "./apt-install": {}
10
+ },
11
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
12
+ // "forwardPorts": [],
13
+
14
+ // Use 'postCreateCommand' to run commands after the container is created.
15
+ // First setup tree-sitter (auto-detects sudo requirement), then run bundle as the regular user
16
+ // Use ${containerWorkspaceFolder} to get the actual workspace path in the container
17
+ "postCreateCommand": "bash ${containerWorkspaceFolder}/.devcontainer/scripts/setup-tree-sitter.sh --workspace=${containerWorkspaceFolder} && bundle update --bundler",
18
+ // Configure tool-specific properties.
19
+ "customizations": {
20
+ "jetbrains": {
21
+ "backend": "RubyMine"
22
+ }
23
+ }
24
+
25
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
26
+ // "remoteUser": "root"
27
+ }
@@ -0,0 +1,210 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Setup script for tree-sitter dependencies (Ubuntu/Debian)
5
+ # Works for both GitHub Actions and devcontainer environments
6
+ #
7
+ # Dual-Environment Design:
8
+ # - GitHub Actions: Runs as non-root user, auto-detects need for sudo
9
+ # - Devcontainer: Can run as root (apt-install feature) or non-root (postCreateCommand)
10
+ # - Auto-detection: Checks if running as root (id -u = 0), uses sudo if non-root
11
+ #
12
+ # Grammar building is delegated to tsdl (https://github.com/stackmystack/tsdl).
13
+ # Configure grammars and versions in parsers.toml at the project root.
14
+ #
15
+ # Options:
16
+ # --sudo: Force use of sudo (optional, auto-detected by default)
17
+ # --cli: Install tree-sitter-cli via npm (optional)
18
+ # --build: Build and install the tree-sitter C runtime from source when distro packages are missing (optional)
19
+ # --tsdl-version VERSION: Pin tsdl release version (default: v2.0.0)
20
+ # --workspace PATH: Workspace root path for informational/debugging purposes only
21
+
22
+ SUDO=""
23
+ INSTALL_CLI=false
24
+ BUILD_FROM_SOURCE=false
25
+ TSDL_VERSION="v2.0.0"
26
+ WORKSPACE_ROOT="/workspaces/${PWD##*/}"
27
+
28
+ while [[ $# -gt 0 ]]; do
29
+ case $1 in
30
+ --sudo) SUDO="sudo"; shift ;;
31
+ --cli) INSTALL_CLI=true; shift ;;
32
+ --build) BUILD_FROM_SOURCE=true; shift ;;
33
+ --tsdl-version) TSDL_VERSION="$2"; shift 2 ;;
34
+ --tsdl-version=*) TSDL_VERSION="${1#*=}"; shift ;;
35
+ --workspace) WORKSPACE_ROOT="$2"; shift 2 ;;
36
+ --workspace=*) WORKSPACE_ROOT="${1#*=}"; shift ;;
37
+ *) echo "Unknown option: $1" >&2; shift ;;
38
+ esac
39
+ done
40
+
41
+ # Auto-detect if we need sudo (running as non-root)
42
+ if [ -z "$SUDO" ] && [ "$(id -u)" -ne 0 ]; then
43
+ SUDO="sudo"
44
+ fi
45
+
46
+ echo "Configuration:"
47
+ echo " Workspace root: $WORKSPACE_ROOT (informational only)"
48
+ echo " Using sudo: $([ -n "$SUDO" ] && echo "yes" || echo "no")"
49
+ echo " Install CLI: $INSTALL_CLI"
50
+ echo " Build from source: $BUILD_FROM_SOURCE"
51
+ echo " tsdl version: $TSDL_VERSION"
52
+ echo ""
53
+
54
+ have_cmd() { command -v "$1" >/dev/null 2>&1; }
55
+
56
+ have_tree_sitter() {
57
+ [ -f /usr/include/tree-sitter/api.h ] && return 0
58
+ [ -f /usr/local/include/tree-sitter/api.h ] && return 0
59
+ [ -f /usr/local/include/tree-sitter/lib/include/api.h ] && return 0
60
+ ldconfig -p 2>/dev/null | grep -q libtree-sitter && return 0 || return 1
61
+ }
62
+
63
+ install_tree_sitter_from_source() {
64
+ echo "[tree-sitter] Building runtime from source..."
65
+ tmpdir=$(mktemp -d /tmp/tree-sitter-src-XXXX)
66
+ trap 'rm -rf "$tmpdir"' EXIT
67
+ git clone --depth 1 https://github.com/tree-sitter/tree-sitter.git "$tmpdir" || return 1
68
+ pushd "$tmpdir" >/dev/null || return 1
69
+ if ! make; then
70
+ echo "[tree-sitter] ERROR: 'make' failed" >&2
71
+ popd >/dev/null
72
+ return 1
73
+ fi
74
+ $SUDO mkdir -p /usr/local/include/tree-sitter
75
+ $SUDO cp -r lib/include/* /usr/local/include/tree-sitter/ || true
76
+ $SUDO cp -a lib/libtree-sitter.* /usr/local/lib/ 2>/dev/null || true
77
+ have_cmd ldconfig && $SUDO ldconfig || true
78
+ popd >/dev/null
79
+ echo "[tree-sitter] Runtime installed to /usr/local."
80
+ return 0
81
+ }
82
+
83
+ install_tsdl() {
84
+ if have_cmd tsdl; then
85
+ echo "[tsdl] Already installed: $(tsdl --version)"
86
+ return 0
87
+ fi
88
+
89
+ echo "[tsdl] Installing tsdl ${TSDL_VERSION}..."
90
+ local arch
91
+ arch="$(uname -m)"
92
+ case "$arch" in
93
+ x86_64) arch="x64" ;;
94
+ aarch64) arch="arm64" ;;
95
+ armv7l) arch="arm" ;;
96
+ i686) arch="x86" ;;
97
+ *) echo "[tsdl] ERROR: Unsupported architecture: $arch" >&2; return 1 ;;
98
+ esac
99
+
100
+ local os
101
+ os="$(uname -s | tr '[:upper:]' '[:lower:]')"
102
+ case "$os" in
103
+ linux) os="linux" ;;
104
+ darwin) os="macos" ;;
105
+ *) echo "[tsdl] ERROR: Unsupported OS: $os" >&2; return 1 ;;
106
+ esac
107
+
108
+ local url="https://github.com/stackmystack/tsdl/releases/download/${TSDL_VERSION}/tsdl-${os}-${arch}.gz"
109
+ local tmpbin
110
+ tmpbin=$(mktemp /tmp/tsdl-XXXX)
111
+
112
+ if ! wget -q "$url" -O "${tmpbin}.gz"; then
113
+ echo "[tsdl] ERROR: Failed to download from $url" >&2
114
+ return 1
115
+ fi
116
+ gunzip -f "${tmpbin}.gz"
117
+ chmod +x "$tmpbin"
118
+ $SUDO mv "$tmpbin" /usr/local/bin/tsdl
119
+ echo "[tsdl] Installed: $(tsdl --version)"
120
+ }
121
+
122
+ # --- 1. System dependencies ---
123
+ echo "Installing system dependencies..."
124
+ $SUDO apt-get update -y
125
+ if ! $SUDO apt-get install -y \
126
+ build-essential \
127
+ pkg-config \
128
+ $( [ "$BUILD_FROM_SOURCE" = false ] && echo "libtree-sitter-dev" ) \
129
+ wget \
130
+ gcc \
131
+ g++ \
132
+ make \
133
+ zlib1g-dev \
134
+ libssl-dev \
135
+ libreadline-dev \
136
+ libyaml-dev \
137
+ libxml2-dev \
138
+ libxslt1-dev \
139
+ libcurl4-openssl-dev \
140
+ software-properties-common \
141
+ libffi-dev; then
142
+ echo "ERROR: apt-get failed to install required packages." >&2
143
+ exit 1
144
+ fi
145
+
146
+ # --- 2. Tree-sitter runtime ---
147
+ if [ "$BUILD_FROM_SOURCE" = true ]; then
148
+ echo "[tree-sitter] --build specified; building runtime from source."
149
+ fi
150
+
151
+ if ! have_tree_sitter; then
152
+ if [ "$BUILD_FROM_SOURCE" = true ]; then
153
+ if ! install_tree_sitter_from_source; then
154
+ echo "[tree-sitter] ERROR: Failed to build runtime. Aborting." >&2
155
+ exit 1
156
+ fi
157
+ else
158
+ echo "[tree-sitter] ERROR: Runtime (headers/libs) not found." >&2
159
+ echo "Install libtree-sitter-dev or re-run with --build." >&2
160
+ exit 1
161
+ fi
162
+ fi
163
+
164
+ # --- 3. tree-sitter-cli (optional) ---
165
+ if [ "$INSTALL_CLI" = true ]; then
166
+ echo "Installing tree-sitter-cli via npm..."
167
+ $SUDO npm install -g tree-sitter-cli
168
+ else
169
+ echo "Skipping tree-sitter-cli (use --cli to install)"
170
+ fi
171
+
172
+ # --- 4. Install tsdl and build grammars ---
173
+ install_tsdl
174
+
175
+ echo ""
176
+ echo "Building tree-sitter grammars via tsdl..."
177
+ # Use parsers.toml from the project root if it exists, otherwise build defaults.
178
+ # tsdl automatically reads parsers.toml in the current directory.
179
+ if [ -f parsers.toml ]; then
180
+ echo "[tsdl] Using parsers.toml config"
181
+ $SUDO tsdl build --out-dir /usr/local/lib --progress plain
182
+ else
183
+ echo "[tsdl] No parsers.toml found; building default grammars: toml json bash rbs"
184
+ $SUDO tsdl build toml json bash rbs --out-dir /usr/local/lib --progress plain
185
+ fi
186
+
187
+ $SUDO ldconfig || echo "WARNING: ldconfig failed" >&2
188
+
189
+ echo ""
190
+ echo "tree-sitter setup complete!"
191
+ echo ""
192
+ echo "Detected library paths:"
193
+
194
+ if [ -f /usr/lib/x86_64-linux-gnu/libtree-sitter.so.0 ]; then
195
+ echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/x86_64-linux-gnu/libtree-sitter.so.0"
196
+ elif [ -f /usr/lib/x86_64-linux-gnu/libtree-sitter.so ]; then
197
+ echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/x86_64-linux-gnu/libtree-sitter.so"
198
+ elif [ -f /usr/lib/libtree-sitter.so.0 ]; then
199
+ echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/libtree-sitter.so.0"
200
+ elif [ -f /usr/lib/libtree-sitter.so ]; then
201
+ echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/libtree-sitter.so"
202
+ else
203
+ echo " WARNING: Could not find libtree-sitter runtime library!"
204
+ fi
205
+
206
+ echo ""
207
+ echo "Grammar libraries:"
208
+ for lib in /usr/local/lib/libtree-sitter-*.so; do
209
+ [ -f "$lib" ] && echo " $lib"
210
+ done
@@ -0,0 +1,67 @@
1
+ #
2
+ # DO NOT EDIT THIS FILE
3
+ #
4
+ # COPY THIS FILE TO .env.local
5
+ #
6
+ # That file is ignored by .gitignore. This file is not.
7
+ # mise loads .env.local via dotenvy, so use KEY=value lines (not shell `export` statements).
8
+ #
9
+ DEBUG=false # do not allow byebug statements (override in .env.local)
10
+ FLOSS_FUNDING_DEBUG=false # extra logging to help diagnose issues (override in .env.local)
11
+ AUTOGEN_FIXTURE_CLEANUP=false # autogenerated gem fixture cleanup after every RSpec run
12
+ GIT_HOOK_FOOTER_APPEND=false
13
+ GIT_HOOK_FOOTER_APPEND_DEBUG=false
14
+ GIT_HOOK_FOOTER_SENTINEL="⚡️ A message from a fellow meat-based-AI"
15
+
16
+ # Tokens used by ci:act and CI helpers for reading workflow/pipeline status via APIs
17
+ # GitHub (either GITHUB_TOKEN or GH_TOKEN will be used; fine-grained recommended)
18
+ # - Scope/permissions: For fine-grained tokens, grant repository access (Read) and Actions: Read
19
+ # - For classic tokens, public repos need no scopes; private repos typically require repo
20
+ GITHUB_TOKEN="<your GH token for GHA status; NEVER COMMIT>"
21
+ # Alternatively:
22
+ # GH_TOKEN="<your GH token>"
23
+
24
+ # GitLab (either GITLAB_TOKEN or GL_TOKEN will be used)
25
+ # - Scope: read_api is sufficient to read pipelines
26
+ GITLAB_TOKEN="<your GitLab token for pipeline status; NEVER COMMIT>"
27
+ # Alternatively:
28
+ # GL_TOKEN="<your GitLab token>"
29
+
30
+ # If this gem does not have an open source collective uncomment and set these to false.
31
+ # OPENCOLLECTIVE_HANDLE=false
32
+ # FUNDING_ORG=false
33
+
34
+ # ── Kettle-Jem Token Replacements ──────────────────────────────────────────────
35
+ # Used by `apply_common_replacements` during templating.
36
+ # Set these to your own values. Blank/unset values leave the token unresolved.
37
+
38
+ # ── Forge Repository Owner ────────────────────────────────────────────────────
39
+ # Used for scaffolded repository URLs before a forge origin remote exists.
40
+ # FORGE_ORG=<your preferred forge organization or owner>
41
+ # KJ_GH_ORG=<your GitHub organization or owner>
42
+
43
+ # ── Forge Users ────────────────────────────────────────────────────────────────
44
+ # KJ_GH_USER=<your GitHub username>
45
+ # KJ_GL_USER=<your GitLab username>
46
+ # KJ_CB_USER=<your CodeBerg username>
47
+ # KJ_SH_USER=<your SourceHut username>
48
+
49
+ # ── Author Identity ───────────────────────────────────────────────────────────
50
+ # KJ_AUTHOR_NAME=<your full name>
51
+ # KJ_AUTHOR_GIVEN_NAMES=<your given/first names>
52
+ # KJ_AUTHOR_FAMILY_NAMES=<your family/last name>
53
+ # KJ_AUTHOR_EMAIL=<your email>
54
+ # KJ_AUTHOR_ORCID=<your ORCID identifier>
55
+ # KJ_AUTHOR_DOMAIN=<your domain, e.g. example.com>
56
+
57
+ # ── Funding Platforms ─────────────────────────────────────────────────────────
58
+ # KJ_FUNDING_KOFI=<your Ko-fi ID>
59
+ # KJ_FUNDING_PAYPAL=<your PayPal.me username>
60
+ # KJ_FUNDING_BUYMEACOFFEE=<your Buy Me a Coffee username>
61
+ # KJ_FUNDING_LIBERAPAY=<your Liberapay username>
62
+
63
+ # ── Social / Community ────────────────────────────────────────────────────────
64
+ # KJ_SOCIAL_MASTODON=<your Mastodon username>
65
+ # KJ_SOCIAL_BLUESKY=<your Bluesky handle>
66
+ # KJ_SOCIAL_LINKTREE=<your Linktree username>
67
+ # KJ_SOCIAL_DEVTO=<your dev.to username>
@@ -0,0 +1,4 @@
1
+ # This project uses mise.toml for environment management.
2
+ # Install/activate mise, or run commands with:
3
+ # mise exec -C /path/to/project -- <command>
4
+ true
@@ -0,0 +1,4 @@
1
+ # This project uses mise.toml for environment management.
2
+ # Install/activate mise, or run commands with:
3
+ # mise exec -C /path/to/project -- <command>
4
+ true
@@ -0,0 +1 @@
1
+ gem: --no-document
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set syntax=ruby
3
+
4
+ # kettle-jem:freeze
5
+ # To retain chunks of comments & code during kettle-jem templating:
6
+ # Wrap custom sections with freeze markers (e.g., as above and below this comment chunk).
7
+ # kettle-jem will then preserve content between those markers across template runs.
8
+ # kettle-jem:unfreeze
9
+
10
+ # Do not rely on Bundler; allow running outside a Bundler context
11
+ begin
12
+ require "rubygems"
13
+ rescue LoadError
14
+ # continue
15
+ end
16
+
17
+ begin
18
+ # External gems
19
+ require "gitmoji/regex"
20
+
21
+ full_text = File.read(ARGV[0])
22
+ # Is the first character a GitMoji?
23
+ gitmoji_index = full_text =~ Gitmoji::Regex::REGEX
24
+ if gitmoji_index == 0
25
+ exit(0)
26
+ else
27
+ denied = <<~EOM
28
+ Oh snap, think again...
29
+
30
+ ______ _______ ___ _______ _______ _______ _______ ______ __
31
+ | _ | | | | || || || || || | | |
32
+ | | || | ___| | || ___|| ||_ _|| ___|| _ || |
33
+ | |_||_ | |___ | || |___ | | | | | |___ | | | || |
34
+ | __ || ___| ___| || ___|| _| | | | ___|| |_| ||__|
35
+ | | | || |___ | || |___ | |_ | | | |___ | | __
36
+ |___| |_||_______||_______||_______||_______| |___| |_______||______| |__|
37
+
38
+
39
+ Did you forget to add a relevant gitmoji? (see https://gitmoji.dev/ for tools)
40
+ In this project, a Gitmoji must be the first grapheme of the commit message.
41
+ What's a grapheme?
42
+ A symbol rendered to be visually identifiable as a single character, but which may be composed of multiple Unicode code points)
43
+ Must match: #{Gitmoji::Regex::REGEX}
44
+ #{"Found a gitmoji at character index #{gitmoji_index}... not good enough.\n" if gitmoji_index}
45
+ Example: git commit -m "✨ My excellent new feature"
46
+
47
+ EOM
48
+ puts denied
49
+ exit(1)
50
+ end
51
+ rescue LoadError => e
52
+ failure = <<~EOM
53
+ gitmoji-regex gem not found: #{e.class}: #{e.message}.
54
+ Skipping gitmoji check and allowing commit to proceed.
55
+ Recommendation: add 'gitmoji-regex' to your development dependencies to enable this check.
56
+
57
+ EOM
58
+ warn(failure)
59
+ exit(0)
60
+ end
@@ -0,0 +1,8 @@
1
+ 🔖 Prepare release v
2
+ 🔒️ Checksums for v
3
+
4
+ # Lines beginning with # are ignored.
5
+ # This file is read by .git-hooks/prepare-commit-msg in each project.
6
+ # Each line of this file will be matched against the commit subject using `starts_with?`.
7
+ # If any `starts_with?` match the project script bin/prepare-commit-msg will run.
8
+ # 🔒️ Checksums for v is the standard commit message by stone_checksums.
@@ -0,0 +1,16 @@
1
+ ⚡️ A message from a fellow meat-based-AI ⚡️
2
+ - [❤️] Finely-crafted open-source tools like <%= @gem_name %> (& many more) require time and effort.
3
+ - [❤️] Though I adore my work, it lacks financial sustainability.
4
+ - [❤️] Please, help me continue enhancing your tools by becoming a sponsor:
5
+ - [💲] https://liberapay.com/{KJ|FUNDING:LIBERAPAY}/donate
6
+ - [💲] https://github.com/sponsors/{KJ|GH:USER}
7
+
8
+ <% if ENV["GIT_HOOK_FOOTER_APPEND_DEBUG"] == "true" %>
9
+ @pwd = <%= @pwd %>
10
+ @gemspecs = <%= @gemspecs %>
11
+ @spec = <%= @spec %>
12
+ @gemspec_path = <%= @gemspec_path %>
13
+ @gem_name <%= @gem_name %>
14
+ @spec_name <%= @spec_name %>
15
+ @content <%= @content %>
16
+ <% end %>
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ # Fail on error and unset variables
4
+ set -eu
5
+
6
+ # Run the generated wrapper directly so hook execution does not depend on shell activation.
7
+ # We are not using direnv exec here because mise and direnv can result in conflicting PATH settings:
8
+ # See: https://mise.jdx.dev/direnv.html
9
+ exec "kettle-commit-msg" "$@"
@@ -0,0 +1,14 @@
1
+ codecov:
2
+ bot: "autobolt"
3
+ max_report_age: 24
4
+ disable_default_path_fixes: no
5
+ require_ci_to_pass: yes
6
+ notify:
7
+ after_n_builds: 2
8
+ wait_for_ci: yes
9
+ coverage:
10
+ status:
11
+ project:
12
+ default:
13
+ target: 100%
14
+ threshold: 1%
@@ -0,0 +1,10 @@
1
+ # These are supported funding model platforms
2
+
3
+ buy_me_a_coffee: "{KJ|FUNDING:BUYMEACOFFEE}"
4
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
5
+ github: ["{KJ|GH:USER}"] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
6
+ ko_fi: "{KJ|FUNDING:KOFI}" # Replace with a single Ko-fi username
7
+ liberapay: "{KJ|FUNDING:LIBERAPAY}" # Replace with a single Liberapay username
8
+ open_collective: "{KJ|OPENCOLLECTIVE_ORG}"
9
+ thanks_dev: u/gh/{KJ|GH:USER}
10
+ tidelift: rubygems/{KJ|GEM_NAME}
@@ -0,0 +1,10 @@
1
+ # These are supported funding model platforms
2
+
3
+ buy_me_a_coffee: "{KJ|FUNDING:BUYMEACOFFEE}"
4
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
5
+ github: ["{KJ|GH:USER}"] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
6
+ ko_fi: "{KJ|FUNDING:KOFI}" # Replace with a single Ko-fi username
7
+ liberapay: "{KJ|FUNDING:LIBERAPAY}" # Replace with a single Liberapay username
8
+ open_collective: # Replace with a single Open Collective slug e.g., orgs/cloud-foundry
9
+ thanks_dev: u/gh/{KJ|GH:USER}
10
+ tidelift: rubygems/{KJ|GEM_NAME}
@@ -0,0 +1 @@
1
+ See AGENTS.md for important information on tool use and project context.
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 5
8
+ ignore:
9
+ - dependency-name: "rubocop-lts"
10
+ - package-ecosystem: "github-actions"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "weekly"
@@ -0,0 +1,21 @@
1
+ name: Auto Assign
2
+ on:
3
+ issues:
4
+ types: [opened]
5
+ pull_request:
6
+ types: [opened]
7
+ jobs:
8
+ run:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ issues: write
12
+ pull-requests: write
13
+ steps:
14
+ - name: 'Auto-assign issue'
15
+ uses: pozil/auto-assign-issue@af6beea6bdf1e8eb373f061c5bc168681fc6d011 # v4.0.1
16
+ with:
17
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
18
+ assignees: "{KJ|GH:USER}"
19
+ abortIfPreviousAssignees: true
20
+ allowSelfAssign: true
21
+ numOfAssignee: 1
@@ -0,0 +1,102 @@
1
+ name: Test Coverage
2
+
3
+ permissions:
4
+ contents: read
5
+ pull-requests: write
6
+ id-token: write
7
+
8
+ env:
9
+ K_SOUP_COV_MIN_BRANCH: 100
10
+ K_SOUP_COV_MIN_LINE: 100
11
+ K_SOUP_COV_MIN_HARD: true
12
+ K_SOUP_COV_FORMATTERS: "xml,rcov,lcov,tty"
13
+ K_SOUP_COV_DO: true
14
+ K_SOUP_COV_MULTI_FORMATTERS: true
15
+ K_SOUP_COV_COMMAND_NAME: "Test Coverage"
16
+
17
+ on:
18
+ push:
19
+ branches:
20
+ - 'main'
21
+ - '*-stable'
22
+ tags:
23
+ - '!*' # Do not execute on tags
24
+ pull_request:
25
+ branches:
26
+ - '*'
27
+ # Allow manually triggering the workflow.
28
+ workflow_dispatch:
29
+
30
+ # Cancels all previous workflow runs for the same branch that have not yet completed.
31
+ concurrency:
32
+ # The concurrency group contains the workflow name and the branch name.
33
+ group: "${{ github.workflow }}-${{ github.ref }}"
34
+ cancel-in-progress: true
35
+
36
+ jobs:
37
+ coverage:
38
+ if: "github.event_name != 'push' || (!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]'))"
39
+ name: Code Coverage on ${{ matrix.ruby }}@current
40
+ runs-on: ubuntu-latest
41
+ continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
42
+ env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps
43
+ BUNDLE_GEMFILE: ${{ github.workspace }}/Appraisal.root.gemfile
44
+ strategy:
45
+ fail-fast: false
46
+ matrix:
47
+ include:
48
+ # Coverage
49
+ - ruby: "ruby"
50
+ appraisal: "coverage"
51
+ exec_cmd: "{KJ|CI:EXEC_CMD}"
52
+ rubygems: latest
53
+ bundler: latest
54
+
55
+ steps:
56
+ - name: Checkout
57
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
58
+ with:
59
+ persist-credentials: false
60
+
61
+ - name: Setup Ruby & RubyGems
62
+ uses: appraisal-rb/setup-ruby-flash@925395edf973d2dc0a629919f407f3547a03d4b5 # v2.1 compatibility bundle installation
63
+ with:
64
+ ruby-version: "${{ matrix.ruby }}"
65
+ rubygems: "${{ matrix.rubygems }}"
66
+ bundler: "${{ matrix.bundler }}"
67
+ bundler-cache: true
68
+ manual-compatibility-bundle: true
69
+ gem-install-retries: 7
70
+
71
+ - name: "[Attempt 1] Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal }}"
72
+ id: bundleAppraisalAttempt1
73
+ run: bundle exec appraisal ${{ matrix.appraisal }} install
74
+ # Continue to the next step on failure
75
+ continue-on-error: true
76
+
77
+ # Effectively an automatic retry of the previous step.
78
+ - name: "[Attempt 2] Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal }}"
79
+ id: bundleAppraisalAttempt2
80
+ # If bundleAppraisalAttempt1 failed, try again here; Otherwise skip.
81
+ if: ${{ steps.bundleAppraisalAttempt1.outcome == 'failure' }}
82
+ run: bundle exec appraisal ${{ matrix.appraisal }} install
83
+
84
+ - name: Restore RSpec status log
85
+ if: "${{!env.ACT}}"
86
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
87
+ with:
88
+ path: .rspec_status
89
+ key: rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-${{github.run_id}}-${{github.run_attempt}}
90
+ restore-keys: |
91
+ rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-${{hashFiles('**/Gemfile.lock','Appraisal.root.gemfile','gemfiles/**/*.gemfile')}}-
92
+ rspec-status-coverage-${{matrix.ruby}}-${{matrix.appraisal}}-
93
+
94
+ - name: Tests for ${{ matrix.ruby }}@current via ${{ matrix.exec_cmd }}
95
+ run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
96
+
97
+ - name: Verify coverage reports
98
+ run: |
99
+ test -s coverage/lcov.info
100
+ test -s coverage/coverage.xml
101
+
102
+ {KJ|GITHUB_ACTIONS:COVERAGE_UPLOAD_STEPS}