kettle-dev 1.0.9 → 1.0.10

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 (54) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.envrc +4 -3
  4. data/.github/workflows/coverage.yml +3 -3
  5. data/.junie/guidelines.md +4 -3
  6. data/.simplecov +5 -1
  7. data/Appraisals +3 -0
  8. data/CHANGELOG.md +22 -1
  9. data/CONTRIBUTING.md +6 -0
  10. data/README.md +18 -5
  11. data/Rakefile +7 -11
  12. data/exe/kettle-commit-msg +9 -143
  13. data/exe/kettle-readme-backers +7 -353
  14. data/exe/kettle-release +8 -702
  15. data/lib/kettle/dev/ci_helpers.rb +1 -0
  16. data/lib/kettle/dev/commit_msg.rb +39 -0
  17. data/lib/kettle/dev/exit_adapter.rb +36 -0
  18. data/lib/kettle/dev/git_adapter.rb +120 -0
  19. data/lib/kettle/dev/git_commit_footer.rb +130 -0
  20. data/lib/kettle/dev/rakelib/appraisal.rake +8 -9
  21. data/lib/kettle/dev/rakelib/bench.rake +2 -7
  22. data/lib/kettle/dev/rakelib/bundle_audit.rake +2 -0
  23. data/lib/kettle/dev/rakelib/ci.rake +4 -396
  24. data/lib/kettle/dev/rakelib/install.rake +1 -295
  25. data/lib/kettle/dev/rakelib/reek.rake +2 -0
  26. data/lib/kettle/dev/rakelib/rubocop_gradual.rake +2 -0
  27. data/lib/kettle/dev/rakelib/spec_test.rake +2 -0
  28. data/lib/kettle/dev/rakelib/template.rake +3 -465
  29. data/lib/kettle/dev/readme_backers.rb +340 -0
  30. data/lib/kettle/dev/release_cli.rb +672 -0
  31. data/lib/kettle/dev/tasks/ci_task.rb +334 -0
  32. data/lib/kettle/dev/tasks/install_task.rb +298 -0
  33. data/lib/kettle/dev/tasks/template_task.rb +491 -0
  34. data/lib/kettle/dev/template_helpers.rb +4 -4
  35. data/lib/kettle/dev/version.rb +1 -1
  36. data/lib/kettle/dev.rb +30 -1
  37. data/lib/kettle-dev.rb +2 -3
  38. data/sig/kettle/dev/ci_helpers.rbs +8 -17
  39. data/sig/kettle/dev/commit_msg.rbs +8 -0
  40. data/sig/kettle/dev/exit_adapter.rbs +8 -0
  41. data/sig/kettle/dev/git_adapter.rbs +15 -0
  42. data/sig/kettle/dev/git_commit_footer.rbs +16 -0
  43. data/sig/kettle/dev/readme_backers.rbs +20 -0
  44. data/sig/kettle/dev/release_cli.rbs +8 -0
  45. data/sig/kettle/dev/tasks/ci_task.rbs +9 -0
  46. data/sig/kettle/dev/tasks/install_task.rbs +10 -0
  47. data/sig/kettle/dev/tasks/template_task.rbs +10 -0
  48. data/sig/kettle/dev/tasks.rbs +0 -0
  49. data/sig/kettle/dev/version.rbs +0 -0
  50. data/sig/kettle/emoji_regex.rbs +5 -0
  51. data/sig/kettle-dev.rbs +0 -0
  52. data.tar.gz.sig +0 -0
  53. metadata +55 -5
  54. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32a4bff14544feed4dc60644fe0bb8d0ed1a76cb1f49c0144c8f9748e23ea993
4
- data.tar.gz: d574fb5dc72da3caf7ee83f64fb064606930d33df23ff6f9a6a907692a21fbe8
3
+ metadata.gz: 6e64251f36de1db3a3f0c71d1436758db8a13223b3a5740062a04fa169ae9875
4
+ data.tar.gz: afb492c0d27d008b779e426f081c0be491dff7616120115668468f9ff2c1872c
5
5
  SHA512:
6
- metadata.gz: f68fef35d7bd888e0132e68e27cfcf31f18ba6098ecbccebeadab0cb4154f1fd12ce32fdce828a5699a18362893059ea4302224084a7446fb90b7a12aaee00b5
7
- data.tar.gz: ac0dea1fca1ea03add3375fa9f8b884f5b57394d45db39c1b00caebe8bcb33f79a66b9d88ef020a4edc3b19d4630086625fda371522953a48f1f38c5994307af
6
+ metadata.gz: 0cc6afa5e3543bab0de8682f0d9a2d45df99a442e2253fe8f028ef190c59cb44710969b9f22e63c4ef4a0e604f96243b616589683ec6ff5d68273cfd2fe0ac40
7
+ data.tar.gz: 9d5253d1aac3f87db2e76ae013c16a5a71ebfd649f8bbaf882b74f90af2e5bdfe2c99cb6fbb9f83cc4efa094117d26dfd7e898d902fc0eb60a74559dca6f9af7
checksums.yaml.gz.sig CHANGED
Binary file
data/.envrc CHANGED
@@ -1,6 +1,7 @@
1
1
  # Run any command in this library's bin/ without the bin/ prefix!
2
- PATH_add bin
2
+ # Prefer exe version over binstub
3
3
  PATH_add exe
4
+ PATH_add bin
4
5
 
5
6
  # Only add things to this file that should be shared with the team.
6
7
 
@@ -20,8 +21,8 @@ export K_SOUP_COV_DO=true # Means you want code coverage
20
21
  export K_SOUP_COV_COMMAND_NAME="Test Coverage"
21
22
  # Available formats are html, xml, rcov, lcov, json, tty
22
23
  export K_SOUP_COV_FORMATTERS="html,xml,rcov,lcov,json,tty"
23
- export K_SOUP_COV_MIN_BRANCH=96 # Means you want to enforce X% branch coverage
24
- export K_SOUP_COV_MIN_LINE=100 # Means you want to enforce X% line coverage
24
+ export K_SOUP_COV_MIN_BRANCH=77 # Means you want to enforce X% branch coverage
25
+ export K_SOUP_COV_MIN_LINE=97 # Means you want to enforce X% line coverage
25
26
  export K_SOUP_COV_MIN_HARD=true # Means you want the build to fail if the coverage thresholds are not met
26
27
  export K_SOUP_COV_MULTI_FORMATTERS=true
27
28
  export K_SOUP_COV_OPEN_BIN= # Means don't try to open coverage results in browser
@@ -7,8 +7,8 @@ permissions:
7
7
 
8
8
  env:
9
9
  # Lower than local, which is at 100/100, because rubocop-lts isn't installed in the coverage workflow
10
- K_SOUP_COV_MIN_BRANCH: 90
11
- K_SOUP_COV_MIN_LINE: 95
10
+ K_SOUP_COV_MIN_BRANCH: 72
11
+ K_SOUP_COV_MIN_LINE: 94
12
12
  K_SOUP_COV_MIN_HARD: true
13
13
  K_SOUP_COV_FORMATTERS: "xml,rcov,lcov,tty"
14
14
  K_SOUP_COV_DO: true
@@ -116,7 +116,7 @@ jobs:
116
116
  hide_complexity: true
117
117
  indicators: true
118
118
  output: both
119
- thresholds: '95 90'
119
+ thresholds: '94 72'
120
120
  continue-on-error: ${{ matrix.experimental != 'false' }}
121
121
 
122
122
  - name: Add Coverage PR Comment
data/.junie/guidelines.md CHANGED
@@ -120,13 +120,14 @@ This document captures project-specific knowledge to streamline setup, testing,
120
120
 
121
121
  Quick start
122
122
  1) bundle install
123
- 2) K_SOUP_COV_FORMATTERS="xml,rcov,lcov,json" bin/rspec (generates coverage reports in coverage/ in the specified formats, only choose the formats you need)
124
- 3) Optional local HTML coverage report: K_SOUP_COV_FORMATTERS="html" bin/rspec (generates HTML coverage report in coverage/ - but this is too verbose for AI, so Junie should use one of the more terse formats, like rcov, lcov, or json)
125
- 4) Static analysis: bundle exec rake rubocop_gradual:check && bundle exec rake reek
123
+ 2) K_SOUP_COV_FORMATTERS="json" bin/rspec (generates a JSON coverage report with both line and branch data in coverage/. Use this single format.)
124
+ 3) Static analysis: bundle exec rake rubocop_gradual:check && bundle exec rake reek
126
125
 
127
126
  Notes
128
127
  - ALWAYS Run bundle exec rake rubocop_gradual:autocorrect as the final step before completing a task, to lint and autocorrect any remaining issues. Then if there are new lint failures, attempt to correct them manually.
129
128
  - NEVER run vanilla rubocop, as it won't handle the linting config properly. Always run rubocop_gradual:autocorrect or rubocop_gradual.
130
129
  - Running only a subset of specs is supported but in order to bypass the hard failure due to coverage thresholds, you need to run with K_SOUP_COV_MIN_HARD=false.
131
130
  - When adding code that writes to STDOUT, remember most specs silence output unless tagged with :check_output or DEBUG=true.
131
+ - Coverage reports: NEVER review the HTML report. Use JSON (preferred), XML, LCOV, or RCOV. For this project, always run tests with K_SOUP_COV_FORMATTERS set to "json".
132
+ - Do NOT modify .envrc in tasks; when running tests locally or in scripts, manually prefix each run, e.g.: K_SOUP_COV_FORMATTERS="json" bin/rspec
132
133
  - For all the kettle-soup-cover options, see .envrc and find the K_SOUP_COV_* env vars.
data/.simplecov CHANGED
@@ -4,4 +4,8 @@ require "kettle/soup/cover/config"
4
4
  # It is controlled by ENV variables, which are set in .envrc and loaded via `direnv allow`
5
5
  # If the values for minimum coverage need to change, they should be changed both there,
6
6
  # and in 2 places in .github/workflows/coverage.yml.
7
- SimpleCov.start
7
+ SimpleCov.start do
8
+ track_files "lib/**/*.rb"
9
+ track_files "lib/**/*.rake"
10
+ track_files "exe/*.rb"
11
+ end
data/Appraisals CHANGED
@@ -79,12 +79,15 @@ appraise "ruby-3-0" do
79
79
  end
80
80
 
81
81
  appraise "ruby-3-1" do
82
+ # all versions of git gem are incompatible with truffleruby v23.0, syntactically.
82
83
  gem "erb"
83
84
  gem "mutex_m", "~> 0.2"
84
85
  gem "stringio", "~> 3.0"
85
86
  end
86
87
 
87
88
  appraise "ruby-3-2" do
89
+ # all versions of git gem are incompatible with truffleruby v23.1, syntactically.
90
+ gem "git", "< 3"
88
91
  gem "erb"
89
92
  gem "mutex_m", "~> 0.2"
90
93
  gem "stringio", "~> 3.0"
data/CHANGELOG.md CHANGED
@@ -24,6 +24,25 @@ Please file a bug if you notice a violation of semantic versioning.
24
24
  ### Fixed
25
25
  ### Security
26
26
 
27
+ ## [1.0.10] - 2025-08-24
28
+ - TAG: [v1.0.10][1.0.10t]
29
+ - COVERAGE: 97.68% -- 1685/1725 lines in 17 files
30
+ - BRANCH COVERAGE: 77.54% -- 618/797 branches in 17 files- 95.35% documented
31
+ - 77.00% documented
32
+ ### Added
33
+ - runs git add --all before git commit, to ensure all files are committed.
34
+ ### Changed
35
+ - This gem is now loaded via Ruby's standard `autoload` feature.
36
+ - Bundler is always expected, and most things probably won't work without it.
37
+ - exe/ scripts and rake tasks logic is all now moved into classes for testability, and is nearly fully covered by tests.
38
+ - New Kettle::Dev::GitAdapter class is an adapter pattern wrapper for git commands
39
+ - New Kettle::Dev::ExitAdapter class is an adapter pattern wrapper for Kernel.exit and Kernel.abort within this codebase.
40
+ ### Removed
41
+ - attempts to make exe/* scripts work without bundler. Bundler is required.
42
+ ### Fixed
43
+ - `Kettle::Dev::ReleaseCLI#detect_version` handles gems with multiple VERSION constants
44
+ - `kettle:dev:template` task was fixed to copy `.example` files with the destination filename lacking the `.example` extension, except for `.env.local.example`
45
+
27
46
  ## [1.0.9] - 2025-08-24
28
47
  - TAG: [v1.0.9][1.0.9t]
29
48
  - COVERAGE: 100.00% -- 130/130 lines in 7 files
@@ -140,7 +159,9 @@ Please file a bug if you notice a violation of semantic versioning.
140
159
  - Selecting will run the selected workflow via `act`
141
160
  - This may move to its own gem in the future.
142
161
 
143
- [Unreleased]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.9...HEAD
162
+ [Unreleased]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.10...HEAD
163
+ [1.0.10]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.9...v1.0.10
164
+ [1.0.10t]: https://gitlab.com/kettle-rb/kettle-dev/-/tags/v1.0.10
144
165
  [1.0.9]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.8...v1.0.9
145
166
  [1.0.9t]: https://gitlab.com/kettle-rb/kettle-dev/-/tags/v1.0.9
146
167
  [1.0.8]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.7...v1.0.8
data/CONTRIBUTING.md CHANGED
@@ -51,6 +51,12 @@ To run all tests
51
51
  bundle exec rake test
52
52
  ```
53
53
 
54
+ ### Spec organization (required)
55
+
56
+ - For each class or module under `lib/`, keep all of its unit tests in a single spec file under `spec/` that mirrors the path and file name (e.g., specs for `lib/kettle/dev/release_cli.rb` live in `spec/kettle/dev/release_cli_spec.rb`).
57
+ - Do not create ad-hoc "_more" or split spec files for the same class/module. Consolidate all unit tests into the main spec file for that class/module.
58
+ - Only integration scenarios that intentionally span multiple classes belong in `spec/integration/`.
59
+
54
60
  ## Lint It
55
61
 
56
62
  Run all the default tasks, which includes running the gradually autocorrecting linter, `rubocop-gradual`.
data/README.md CHANGED
@@ -21,11 +21,16 @@ OTOH, if `ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I
21
21
 
22
22
  ## 🌻 Synopsis
23
23
 
24
- Add to your `Rakefile`:
24
+ This gem integrates tightly with [kettle-test](https://github.com/kettle-rb/kettle-test).
25
+
26
+ ```ruby
27
+ require "kettle/test/rspec"
28
+ ```
29
+
30
+ Then, add to your `Rakefile`:
25
31
 
26
32
  ```ruby
27
33
  require "kettle/dev"
28
- Kettle::Dev.install_tasks
29
34
  ```
30
35
 
31
36
  Now you have many powerful development and testing tools at your disposal, all fully [documented](#-configuration) and tested.
@@ -136,11 +141,20 @@ NOTE: Be prepared to track down certs for signed gems and add them the same way
136
141
 
137
142
  ## ⚙️ Configuration
138
143
 
144
+ ### RSpec
145
+
146
+ This gem integrates tightly with [kettle-test](https://github.com/kettle-rb/kettle-test).
147
+
148
+ ```ruby
149
+ require "kettle/test/rspec"
150
+ ```
151
+
152
+ ### Rakefile
153
+
139
154
  Add to your `Rakefile`:
140
155
 
141
156
  ```ruby
142
157
  require "kettle/dev"
143
- Kettle::Dev.install_tasks
144
158
  ```
145
159
 
146
160
  That’s it. When installed, kettle-dev:
@@ -288,7 +302,6 @@ Tip: The commit message helper `exe/kettle-commit-msg` prefers project-local `.g
288
302
  - Note: When used with the provided `.git-hooks`, the subject should start with a gitmoji character (see [gitmoji][📌gitmoji]).
289
303
  - Tip: Run this locally before committing to keep your README current, or schedule it in CI to refresh periodically.
290
304
 
291
-
292
305
  ## 🦷 FLOSS Funding
293
306
 
294
307
  While kettle-rb tools are free software and will always be, the project would benefit immensely from some funding.
@@ -646,7 +659,7 @@ Thanks for RTFM. ☺️
646
659
  [📌gitmoji]:https://gitmoji.dev
647
660
  [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20😜%20😍-34495e.svg?style=flat-square
648
661
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
649
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.130-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
662
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-1.725-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
650
663
  [🔐security]: SECURITY.md
651
664
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
652
665
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
data/Rakefile CHANGED
@@ -50,6 +50,12 @@
50
50
  # External gems
51
51
  require "bundler/gem_tasks" if !Dir[File.join(__dir__, "*.gemspec")].empty?
52
52
 
53
+ # Define a base default task early so other files can enhance it.
54
+ desc "Default tasks aggregator"
55
+ task :default do
56
+ puts "Default task complete."
57
+ end
58
+
53
59
  # Detect if the invoked task is spec/test to avoid eagerly requiring the library,
54
60
  # which would load code before SimpleCov can start (when running `rake spec`).
55
61
  invoked_tasks = Rake.application.top_level_tasks
@@ -67,22 +73,12 @@ if running_specs
67
73
  # If rspec isn't available, let it fail when the task is invoked
68
74
  end
69
75
  else
70
- require "kettle/dev"
71
-
72
- # Define a base default task early so other files can enhance it.
73
- desc "Default tasks aggregator"
74
- task :default do
75
- puts "Default task complete."
76
- end
77
-
78
- Kettle::Dev.install_tasks
76
+ require "kettle-dev"
79
77
 
80
78
  ### RELEASE TASKS
81
79
  # Setup stone_checksums
82
80
  begin
83
81
  require "stone_checksums"
84
-
85
- GemChecksums.install_tasks
86
82
  rescue LoadError
87
83
  desc("(stub) build:generate_checksums is unavailable")
88
84
  task("build:generate_checksums") do
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  # vim: set syntax=ruby
3
5
 
4
- require "rubygems"
5
- begin
6
- require "bundler/setup"
7
- rescue LoadError
8
- # Allow running outside of Bundler; runtime deps should still be available via rubygems
9
- end
6
+ # Immediate, unbuffered output
7
+ $stdout.sync = true
8
+ # Depending library or project must be using bundler
9
+ require "bundler/setup"
10
10
 
11
11
  # Standard library
12
12
  require "erb"
13
13
 
14
+ require "kettle/dev"
15
+
14
16
  # ENV variable control (set in .envrc, or .env.local)
15
17
  # BRANCH_RULE_TYPE = jira, or another type of branch rule validation, or false to disable
16
18
  # FOOTER_APPEND = true/false append commit message footer
@@ -48,140 +50,4 @@ else
48
50
  # puts "No branch rule configured (set GIT_HOOK_BRANCH_VALIDATE=jira to enforce rules for jira style branch names)"
49
51
  end
50
52
 
51
- class GitCommitFooter
52
- # Prefer project-local .git-hooks (repo root), then fallback to global ~/.git-hooks
53
- NAME_ASSIGNMENT_REGEX = /\bname\s*=\s*(["'])([^"']+)\1/.freeze
54
- FOOTER_APPEND = ENV.fetch("GIT_HOOK_FOOTER_APPEND", "false").casecmp("true").zero?
55
- SENTINEL = ENV["GIT_HOOK_FOOTER_SENTINEL"] # No default to avoid accidental duplicate commit of a footer via ammended commits
56
- raise "Set GIT_HOOK_FOOTER_SENTINEL=<footer sentinel> in .env.local (e.g., '⚡️ A message from a fellow meat-based-AI ⚡️')" if FOOTER_APPEND && (SENTINEL.nil? || SENTINEL.to_s.empty?)
57
-
58
- class << self
59
- def git_toplevel
60
- toplevel = nil
61
- begin
62
- # 'git rev-parse --show-toplevel' returns the repo root when run anywhere inside the repo
63
- out = %x(git rev-parse --show-toplevel 2>/dev/null)
64
- toplevel = out.strip unless out.nil? || out.empty?
65
- rescue StandardError
66
- # ignore
67
- end
68
- toplevel
69
- end
70
-
71
- def local_hooks_dir
72
- top = git_toplevel
73
- return unless top && !top.empty?
74
- File.join(top, ".git-hooks")
75
- end
76
-
77
- def global_hooks_dir
78
- File.join(ENV["HOME"], ".git-hooks")
79
- end
80
-
81
- def hooks_path_for(filename)
82
- local_dir = local_hooks_dir
83
- if local_dir
84
- local_path = File.join(local_dir, filename)
85
- return local_path if File.file?(local_path)
86
- end
87
- File.join(global_hooks_dir, filename)
88
- end
89
-
90
- def commit_goalie_path
91
- hooks_path_for("commit-subjects-goalie.txt")
92
- end
93
-
94
- # Determine whether the commit subject allows footer append, based on optional goalie file
95
- # ~/.git-hooks/commit-subjects-goalie.txt
96
- # - If present, only allow appending when the first line of the commit message starts with one of the non-commented prefixes
97
- # - If absent, disallow footer
98
- def goalie_allows_footer?(subject_line)
99
- goalie_path = commit_goalie_path
100
- return false unless File.file?(goalie_path)
101
-
102
- prefixes = File.read(goalie_path).lines.map { |l| l.strip }.reject { |l| l.empty? || l.start_with?("#") }
103
- # If the file exists but has no usable lines, treat as deny-all per goalie intent
104
- return false if prefixes.empty?
105
-
106
- subj = subject_line.to_s.strip
107
- prefixes.any? { |prefix| subj.start_with?(prefix) }
108
- end
109
-
110
- def render(*argv)
111
- commit_msg = File.read(argv[0])
112
- subject_line = commit_msg.lines.first.to_s
113
- if GitCommitFooter::FOOTER_APPEND && goalie_allows_footer?(subject_line)
114
- if commit_msg.include?(GitCommitFooter::SENTINEL)
115
- # This is a commit message that has already been appended
116
- # This will happen if the commit message is edited and re-committed
117
- # puts "FOOTER_APPEND is true, skipping footer append"
118
- exit(0)
119
- else
120
- footer_binding = GitCommitFooter.new
121
- # Append footer to the commit message
122
- File.open(argv[0], "w") do |file|
123
- file.print(commit_msg)
124
- file.print("\n")
125
- file.print(footer_binding.render)
126
- end
127
- end
128
- else
129
- # Skipping footer append (either FOOTER_APPEND is false, or goalie did not allow it)
130
- end
131
- end
132
- end
133
-
134
- def initialize
135
- @pwd = Dir.pwd
136
- @gemspecs = Dir["*.gemspec"]
137
- @spec = @gemspecs.first
138
- @gemspec_path = File.expand_path(@spec, @pwd)
139
- @gem_name = parse_gemspec_name || derive_gem_name
140
- end
141
-
142
- # Render ERB with binding variables
143
- def render
144
- ERB.new(template).result(binding)
145
- end
146
-
147
- private
148
-
149
- # Lightweight parse for gem name to avoid full Gem::Specification load
150
- def parse_gemspec_name
151
- begin
152
- content = File.read(@gemspec_path)
153
- # Look for name assignment patterns like:
154
- # spec.name = "my_gem" OR Gem::Specification.new do |spec|; spec.name = 'my_gem'
155
- @name_index = content =~ NAME_ASSIGNMENT_REGEX
156
- if @name_index
157
- return $2
158
- end
159
- rescue StandardError
160
- # fall through
161
- end
162
- nil
163
- end
164
-
165
- # No-parse derivation of gem name, when parsing gemspec fails
166
- def derive_gem_name
167
- File.basename(@gemspec_path, ".*") if @gemspec_path
168
- end
169
-
170
- # Example
171
- #
172
- # ⚡️ A message from a fellow meat-based-AI ⚡️
173
- # I ❤️ working on <%= @gem_name %>.
174
- #
175
- # The first line is the footer sentinel (which does appear in the commit).
176
- # The second line, and any additional, is the main body of the footer.
177
- #
178
- # The sentinel must be set in an ENV variable (e.g., in your .env.local file):
179
- #
180
- # export GIT_HOOK_FOOTER_SENTINEL="⚡️ A message from a fellow meat-based-AI ⚡️"
181
- #
182
- def template
183
- File.read(self.class.hooks_path_for("footer-template.erb.txt"))
184
- end
185
- end
186
-
187
- GitCommitFooter.render(*ARGV)
53
+ Kettle::Dev::GitCommitFooter.render(*ARGV)