kettle-dev 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.devcontainer/devcontainer.json +26 -0
- data/.envrc +42 -0
- data/.git-hooks/commit-msg +41 -0
- data/.git-hooks/commit-subjects-goalie.txt +8 -0
- data/.git-hooks/footer-template.erb.txt +16 -0
- data/.git-hooks/prepare-commit-msg +20 -0
- data/.github/FUNDING.yml +13 -0
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/ancient.yml +80 -0
- data/.github/workflows/auto-assign.yml +21 -0
- data/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/coverage.yml +130 -0
- data/.github/workflows/current.yml +88 -0
- data/.github/workflows/dependency-review.yml +20 -0
- data/.github/workflows/discord-notifier.yml +38 -0
- data/.github/workflows/heads.yml +87 -0
- data/.github/workflows/jruby.yml +79 -0
- data/.github/workflows/legacy.yml +70 -0
- data/.github/workflows/locked_deps.yml +88 -0
- data/.github/workflows/opencollective.yml +40 -0
- data/.github/workflows/style.yml +67 -0
- data/.github/workflows/supported.yml +85 -0
- data/.github/workflows/truffle.yml +78 -0
- data/.github/workflows/unlocked_deps.yml +87 -0
- data/.github/workflows/unsupported.yml +78 -0
- data/.gitignore +48 -0
- data/.gitlab-ci.yml +45 -0
- data/.junie/guidelines-rbs.md +49 -0
- data/.junie/guidelines.md +132 -0
- data/.opencollective.yml +3 -0
- data/.qlty/qlty.toml +79 -0
- data/.rspec +8 -0
- data/.rubocop.yml +13 -0
- data/.simplecov +7 -0
- data/.tool-versions +1 -0
- data/.yard_gfm_support.rb +22 -0
- data/.yardopts +11 -0
- data/Appraisal.root.gemfile +12 -0
- data/Appraisals +120 -0
- data/CHANGELOG.md +26 -5
- data/Gemfile +32 -0
- data/Rakefile +99 -0
- data/checksums/kettle-dev-1.0.1.gem.sha256 +1 -0
- data/checksums/kettle-dev-1.0.1.gem.sha512 +1 -0
- data/checksums/kettle-dev-1.0.2.gem.sha256 +1 -0
- data/checksums/kettle-dev-1.0.2.gem.sha512 +1 -0
- data/exe/kettle-commit-msg +185 -0
- data/exe/kettle-readme-backers +355 -0
- data/exe/kettle-release +327 -0
- data/gemfiles/modular/coverage.gemfile +6 -0
- data/gemfiles/modular/documentation.gemfile +11 -0
- data/gemfiles/modular/style.gemfile +16 -0
- data/lib/kettle/dev/rakelib/appraisal.rake +40 -0
- data/lib/kettle/dev/rakelib/bench.rake +58 -0
- data/lib/kettle/dev/rakelib/bundle_audit.rake +18 -0
- data/lib/kettle/dev/rakelib/ci.rake +348 -0
- data/lib/kettle/dev/rakelib/install.rake +304 -0
- data/lib/kettle/dev/rakelib/reek.rake +34 -0
- data/lib/kettle/dev/rakelib/require_bench.rake +7 -0
- data/lib/kettle/dev/rakelib/rubocop_gradual.rake +9 -0
- data/lib/kettle/dev/rakelib/spec_test.rake +42 -0
- data/lib/kettle/dev/rakelib/template.rake +413 -0
- data/lib/kettle/dev/rakelib/yard.rake +33 -0
- data/lib/kettle/dev/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +74 -5
- metadata.gz.sig +0 -0
data/CHANGELOG.md
CHANGED
@@ -12,6 +12,27 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.
|
|
12
12
|
### Fixed
|
13
13
|
### Security
|
14
14
|
|
15
|
+
## [1.0.2] - 2025-08-24
|
16
|
+
- TAG: [v1.0.2][1.0.2t]
|
17
|
+
- COVERAGE: 100.00% -- 98/98 lines in 7 files
|
18
|
+
- BRANCH COVERAGE: 100.00% -- 30/30 branches in 7 files
|
19
|
+
- 94.59% documented
|
20
|
+
### Fixed
|
21
|
+
- Added files necessary for kettle:dev:template task to work
|
22
|
+
- .github/workflows/opencollective.yml working!
|
23
|
+
|
24
|
+
## [1.0.1] - 2025-08-24
|
25
|
+
- TAG: [v1.0.1][1.0.1t]
|
26
|
+
- COVERAGE: 100.00% -- 98/98 lines in 7 files
|
27
|
+
- BRANCH COVERAGE: 100.00% -- 30/30 branches in 7 files
|
28
|
+
- 94.59% documented
|
29
|
+
### Added
|
30
|
+
- These were documented but not yet released:
|
31
|
+
- `kettle-release` ruby script for safely, securely, releasing a gem.
|
32
|
+
- This may move to its own gem in the future.
|
33
|
+
- `kettle-readme-backers` ruby script for integrating Open Source Collective backers into a README.md file.
|
34
|
+
- This may move to its own gem in the future.
|
35
|
+
|
15
36
|
## [1.0.0] - 2025-08-24
|
16
37
|
- TAG: [v1.0.0][1.0.0t]
|
17
38
|
- COVERAGE: 100.00% -- 98/98 lines in 7 files
|
@@ -37,11 +58,11 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.
|
|
37
58
|
- `ci:act` rake task CLI menu / scoreboard for a project's GHA workflows
|
38
59
|
- Selecting will run the selected workflow via `act`
|
39
60
|
- This may move to its own gem in the future.
|
40
|
-
- `kettle-release` ruby script for safely, securely, releasing a gem.
|
41
|
-
- This may move to its own gem in the future.
|
42
|
-
- `kettle-readme-backers` ruby script for integrating Open Source Collective backers into a README.md file.
|
43
|
-
- This may move to its own gem in the future.
|
44
61
|
|
45
|
-
[Unreleased]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.
|
62
|
+
[Unreleased]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.2...HEAD
|
63
|
+
[1.0.2]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.1...v1.0.2
|
64
|
+
[1.0.2t]: https://gitlab.com/kettle-rb/kettle-dev/-/tags/v1.0.2
|
65
|
+
[1.0.1]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.0...v1.0.1
|
66
|
+
[1.0.1t]: https://gitlab.com/kettle-rb/kettle-dev/-/tags/v1.0.1
|
46
67
|
[1.0.0]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/a427c302df09cfe4253a7c8d400333f9a4c1a208...v1.0.0
|
47
68
|
[1.0.0t]: https://gitlab.com/kettle-rb/kettle-dev/-/tags/v1.0.0
|
data/Gemfile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
6
|
+
git_source(:gitlab) { |repo_name| "https://gitlab.com/#{repo_name}" }
|
7
|
+
|
8
|
+
#### IMPORTANT #######################################################
|
9
|
+
# Gemfile is for local development ONLY; Gemfile is NOT loaded in CI #
|
10
|
+
####################################################### IMPORTANT ####
|
11
|
+
|
12
|
+
# Include dependencies from <gem name>.gemspec
|
13
|
+
gemspec
|
14
|
+
|
15
|
+
platform :mri do
|
16
|
+
# Debugging - Ensure ENV["DEBUG"] == "true" to use debuggers within spec suite
|
17
|
+
# Use binding.break, binding.b, or debugger in code
|
18
|
+
gem "debug", ">= 1.0.0" # ruby >= 2.7
|
19
|
+
gem "gem_bench", "~> 2.0", ">= 2.0.5"
|
20
|
+
|
21
|
+
# Dev Console - Binding.pry - Irb replacement
|
22
|
+
gem "pry", "~> 0.14" # ruby >= 2.0
|
23
|
+
end
|
24
|
+
|
25
|
+
# Code Coverage
|
26
|
+
eval_gemfile "gemfiles/modular/coverage.gemfile"
|
27
|
+
|
28
|
+
# Linting
|
29
|
+
eval_gemfile "gemfiles/modular/style.gemfile"
|
30
|
+
|
31
|
+
# Documentation
|
32
|
+
eval_gemfile "gemfiles/modular/documentation.gemfile"
|
data/Rakefile
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Galtzo FLOSS Rakefile v1.0.11 - 2025-08-19
|
4
|
+
# Ruby 2.3 (Safe Navigation) or higher required
|
5
|
+
#
|
6
|
+
# CHANGELOG
|
7
|
+
# v1.0.0 - initial release w/ support for rspec, minitest, rubocop, reek, yard, and stone_checksums
|
8
|
+
# v1.0.1 - fix test / spec tasks running 2x
|
9
|
+
# v1.0.2 - fix duplicate task warning from RuboCop
|
10
|
+
# v1.0.3 - add bench tasks to run mini benchmarks (add scripts to /benchmarks)
|
11
|
+
# v1.0.4 - add support for floss_funding:install
|
12
|
+
# v1.0.5 - add support for halting in Rake tasks with binding.b (from debug gem)
|
13
|
+
# v1.0.6 - add RBS files and checksums to YARD-generated docs site
|
14
|
+
# v1.0.7 - works with vanilla ruby, non-gem, bundler-managed, projects
|
15
|
+
# v1.0.8 - improved Dir globs, add back and document rbconfig dependency
|
16
|
+
# v1.0.9 - add appraisal:update task to update Appraisal gemfiles and autocorrect with RuboCop Gradual
|
17
|
+
# v1.0.10 - add ci:act to run GHA workflows locally, and get status of remote workflows
|
18
|
+
# v1.0.11 - ci:act workflows are populated entirely dynamically, based on existing files
|
19
|
+
#
|
20
|
+
# MIT License (see License.txt)
|
21
|
+
#
|
22
|
+
# Copyright (c) 2025 Peter H. Boling (galtzo.com)
|
23
|
+
#
|
24
|
+
# Expected to work in any project that uses Bundler.
|
25
|
+
#
|
26
|
+
# Sets up tasks for appraisal, floss_funding, rspec, minitest, rubocop, reek, yard, and stone_checksums.
|
27
|
+
#
|
28
|
+
# rake appraisal:update # Update Appraisal gemfiles and run RuboCop Gradual autocorrect
|
29
|
+
# rake bench # Run all benchmarks (alias for bench:run)
|
30
|
+
# rake bench:list # List available benchmark scripts
|
31
|
+
# rake bench:run # Run all benchmark scripts (skips on CI)
|
32
|
+
# rake build # Build gitmoji-regex-1.0.2.gem into the pkg directory
|
33
|
+
# rake build:checksum # Generate SHA512 checksum of gitmoji-regex-1.0.2.gem into the checksums directory
|
34
|
+
# rake build:generate_checksums # Generate both SHA256 & SHA512 checksums into the checksums directory, and git...
|
35
|
+
# rake bundle:audit:check # Checks the Gemfile.lock for insecure dependencies
|
36
|
+
# rake bundle:audit:update # Updates the bundler-audit vulnerability database
|
37
|
+
# rake ci:act[opt] # Run 'act' with a selected workflow
|
38
|
+
# rake clean # Remove any temporary products
|
39
|
+
# rake clobber # Remove any generated files
|
40
|
+
# rake coverage # Run specs w/ coverage and open results in browser
|
41
|
+
# rake floss_funding:install # (stub) floss_funding is unavailable
|
42
|
+
# rake install # Build and install gitmoji-regex-1.0.2.gem into system gems
|
43
|
+
# rake install:local # Build and install gitmoji-regex-1.0.2.gem into system gems without network ac...
|
44
|
+
# rake reek # Check for code smells
|
45
|
+
# rake reek:update # Run reek and store the output into the REEK file
|
46
|
+
# rake release[remote] # Create tag v1.0.2 and build and push gitmoji-regex-1.0.2.gem to rubygems.org
|
47
|
+
# rake rubocop # alias rubocop task to rubocop_gradual
|
48
|
+
# rake rubocop_gradual # Run RuboCop Gradual
|
49
|
+
# rake rubocop_gradual:autocorrect # Run RuboCop Gradual with autocorrect (only when it's safe)
|
50
|
+
# rake rubocop_gradual:autocorrect_all # Run RuboCop Gradual with autocorrect (safe and unsafe)
|
51
|
+
# rake rubocop_gradual:check # Run RuboCop Gradual to check the lock file
|
52
|
+
# rake rubocop_gradual:force_update # Run RuboCop Gradual to force update the lock file
|
53
|
+
# rake spec # Run RSpec code examples
|
54
|
+
# rake test # Run tests
|
55
|
+
# rake yard # Generate YARD Documentation
|
56
|
+
|
57
|
+
# External gems
|
58
|
+
require "bundler/gem_tasks" if !Dir[File.join(__dir__, "*.gemspec")].empty?
|
59
|
+
|
60
|
+
# Detect if the invoked task is spec/test to avoid eagerly requiring the library,
|
61
|
+
# which would load code before SimpleCov can start (when running `rake spec`).
|
62
|
+
invoked_tasks = Rake.application.top_level_tasks
|
63
|
+
running_specs = invoked_tasks.any? { |t| t == "spec" || t == "test" || t == "coverage" }
|
64
|
+
|
65
|
+
if running_specs
|
66
|
+
# Define minimal rspec tasks locally to keep coverage accurate
|
67
|
+
begin
|
68
|
+
require "rspec/core/rake_task"
|
69
|
+
desc("Run RSpec code examples")
|
70
|
+
RSpec::Core::RakeTask.new(:spec)
|
71
|
+
desc("Run tests")
|
72
|
+
task(test: :spec)
|
73
|
+
rescue LoadError
|
74
|
+
# If rspec isn't available, let it fail when the task is invoked
|
75
|
+
end
|
76
|
+
else
|
77
|
+
require "kettle/dev"
|
78
|
+
|
79
|
+
# Define a base default task early so other files can enhance it.
|
80
|
+
desc "Default tasks aggregator"
|
81
|
+
task :default do
|
82
|
+
puts "Default task complete."
|
83
|
+
end
|
84
|
+
|
85
|
+
Kettle::Dev.install_tasks
|
86
|
+
|
87
|
+
### RELEASE TASKS
|
88
|
+
# Setup stone_checksums
|
89
|
+
begin
|
90
|
+
require "stone_checksums"
|
91
|
+
|
92
|
+
GemChecksums.install_tasks
|
93
|
+
rescue LoadError
|
94
|
+
desc("(stub) build:generate_checksums is unavailable")
|
95
|
+
task("build:generate_checksums") do
|
96
|
+
warn("NOTE: stone_checksums isn't installed, or is disabled for #{RUBY_VERSION} in the current environment")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
5b92c8a76f54954791e4154bb22594dbc9dd4f0e06d9d4c5db15a32aa2718ede
|
@@ -0,0 +1 @@
|
|
1
|
+
5cac18505a8f780d3897f1d900a662c896537056441b1a8178531355a4b10198bee0bdc62216ab2036b640adada34911bc30b813f715a14a464d797718d7a065
|
@@ -0,0 +1 @@
|
|
1
|
+
2338f9fc4e14a03c39c6509d11fdcfad85faaa7615d855703cb511bc9f95351c
|
@@ -0,0 +1 @@
|
|
1
|
+
ccc6a5c3cd36a8c40d78458166adfbd7ad452b62055579ee4333089a56313170bf97d0aca1f8c3d4f15287bb3d396cfbfcce2174665feb7a77f0b6b03ac8096c
|
@@ -0,0 +1,185 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set syntax=ruby
|
3
|
+
|
4
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
5
|
+
|
6
|
+
require "rubygems"
|
7
|
+
require "bundler/setup"
|
8
|
+
|
9
|
+
# Standard library
|
10
|
+
require "erb"
|
11
|
+
|
12
|
+
# ENV variable control (set in .envrc, or .env.local)
|
13
|
+
# BRANCH_RULE_TYPE = jira, or another type of branch rule validation, or false to disable
|
14
|
+
# FOOTER_APPEND = true/false append commit message footer
|
15
|
+
BRANCH_RULES = {
|
16
|
+
"jira" => /^(?<story_type>(hotfix)|(bug)|(feature)|(candy))\/(?<story_id>\d{8,})-.+\Z/,
|
17
|
+
}
|
18
|
+
BRANCH_RULE_TYPE = (validate = ENV.fetch("GIT_HOOK_BRANCH_VALIDATE", "false")) && !validate.casecmp?("false") && validate
|
19
|
+
|
20
|
+
# Called the "JIRA pattern", because of traditional use with JIRA.
|
21
|
+
if (branch_rule = BRANCH_RULES[BRANCH_RULE_TYPE])
|
22
|
+
# branches should be named like:
|
23
|
+
# <story_type>/<story_id>-explosion-in-the-fudge-factory-spec-suite-fix
|
24
|
+
# where story type is one of "hotfix", "bug", "feature", "candy"
|
25
|
+
#
|
26
|
+
branch = %x(git branch 2> /dev/null | grep -e ^* | awk '{print $2}')
|
27
|
+
match_data = branch.match(branch_rule)
|
28
|
+
# NOTE: `match` will return nil if match fails, otherwise an instance of MatchData.
|
29
|
+
# If not nil then we are assured matches for both regex capture groups
|
30
|
+
# match_data_or_nil[:story_type] will be one of "hotfix", "bug", "feature", "candy"
|
31
|
+
# match_data_or_nil[:story_id] will be a numeric string
|
32
|
+
|
33
|
+
if !match_data.nil?
|
34
|
+
commit_msg = File.read(ARGV[0])
|
35
|
+
unless commit_msg.include?(match_data[:story_id])
|
36
|
+
commit_msg = <<~EOS
|
37
|
+
#{commit_msg.strip}
|
38
|
+
[#{match_data[:story_type]}][#{match_data[:story_id]}]
|
39
|
+
EOS
|
40
|
+
File.open(ARGV[0], "w") do |file|
|
41
|
+
file.print(commit_msg)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
# puts "No branch rule configured (set GIT_HOOK_BRANCH_VALIDATE=jira to enforce rules for jira style branch names)"
|
47
|
+
end
|
48
|
+
|
49
|
+
class GitCommitFooter
|
50
|
+
# Prefer project-local .git-hooks (repo root), then fallback to global ~/.git-hooks
|
51
|
+
NAME_ASSIGNMENT_REGEX = /\bname\s*=\s*(["'])([^"']+)\1/.freeze
|
52
|
+
FOOTER_APPEND = ENV.fetch("GIT_HOOK_FOOTER_APPEND", "false").casecmp("true").zero?
|
53
|
+
SENTINEL = ENV["GIT_HOOK_FOOTER_SENTINEL"] # No default to avoid accidental duplicate commit of a footer via ammended commits
|
54
|
+
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.empty?
|
55
|
+
|
56
|
+
class << self
|
57
|
+
def git_toplevel
|
58
|
+
toplevel = nil
|
59
|
+
begin
|
60
|
+
# 'git rev-parse --show-toplevel' returns the repo root when run anywhere inside the repo
|
61
|
+
out = %x(git rev-parse --show-toplevel 2>/dev/null)
|
62
|
+
toplevel = out.strip unless out.nil? || out.empty?
|
63
|
+
rescue StandardError
|
64
|
+
# ignore
|
65
|
+
end
|
66
|
+
toplevel
|
67
|
+
end
|
68
|
+
|
69
|
+
def local_hooks_dir
|
70
|
+
top = git_toplevel
|
71
|
+
return unless top && !top.empty?
|
72
|
+
File.join(top, ".git-hooks")
|
73
|
+
end
|
74
|
+
|
75
|
+
def global_hooks_dir
|
76
|
+
File.join(ENV["HOME"], ".git-hooks")
|
77
|
+
end
|
78
|
+
|
79
|
+
def hooks_path_for(filename)
|
80
|
+
local_dir = local_hooks_dir
|
81
|
+
if local_dir
|
82
|
+
local_path = File.join(local_dir, filename)
|
83
|
+
return local_path if File.file?(local_path)
|
84
|
+
end
|
85
|
+
File.join(global_hooks_dir, filename)
|
86
|
+
end
|
87
|
+
|
88
|
+
def commit_goalie_path
|
89
|
+
hooks_path_for("commit-subjects-goalie.txt")
|
90
|
+
end
|
91
|
+
|
92
|
+
# Determine whether the commit subject allows footer append, based on optional goalie file
|
93
|
+
# ~/.git-hooks/commit-subjects-goalie.txt
|
94
|
+
# - If present, only allow appending when the first line of the commit message starts with one of the non-commented prefixes
|
95
|
+
# - If absent, disallow footer
|
96
|
+
def goalie_allows_footer?(subject_line)
|
97
|
+
goalie_path = commit_goalie_path
|
98
|
+
return false unless File.file?(goalie_path)
|
99
|
+
|
100
|
+
prefixes = File.read(goalie_path).lines.map { |l| l.strip }.reject { |l| l.empty? || l.start_with?("#") }
|
101
|
+
# If the file exists but has no usable lines, treat as deny-all per goalie intent
|
102
|
+
return false if prefixes.empty?
|
103
|
+
|
104
|
+
subj = subject_line.to_s.strip
|
105
|
+
prefixes.any? { |prefix| subj.start_with?(prefix) }
|
106
|
+
end
|
107
|
+
|
108
|
+
def render(*argv)
|
109
|
+
commit_msg = File.read(argv[0])
|
110
|
+
subject_line = commit_msg.lines.first.to_s
|
111
|
+
if GitCommitFooter::FOOTER_APPEND && goalie_allows_footer?(subject_line)
|
112
|
+
if commit_msg.include?(GitCommitFooter::SENTINEL)
|
113
|
+
# This is a commit message that has already been appended
|
114
|
+
# This will happen if the commit message is edited and re-committed
|
115
|
+
# puts "FOOTER_APPEND is true, skipping footer append"
|
116
|
+
exit(0)
|
117
|
+
else
|
118
|
+
footer_binding = GitCommitFooter.new
|
119
|
+
# Append footer to the commit message
|
120
|
+
File.open(argv[0], "w") do |file|
|
121
|
+
file.print(commit_msg)
|
122
|
+
file.print("\n")
|
123
|
+
file.print(footer_binding.render)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
else
|
127
|
+
# Skipping footer append (either FOOTER_APPEND is false, or goalie did not allow it)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def initialize
|
133
|
+
@pwd = Dir.pwd
|
134
|
+
@gemspecs = Dir["*.gemspec"]
|
135
|
+
@spec = @gemspecs.first
|
136
|
+
@gemspec_path = File.expand_path(@spec, @pwd)
|
137
|
+
@gem_name = parse_gemspec_name || derive_gem_name
|
138
|
+
end
|
139
|
+
|
140
|
+
# Render ERB with binding variables
|
141
|
+
def render
|
142
|
+
ERB.new(template).result(binding)
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
# Lightweight parse for gem name to avoid full Gem::Specification load
|
148
|
+
def parse_gemspec_name
|
149
|
+
begin
|
150
|
+
content = File.read(@gemspec_path)
|
151
|
+
# Look for name assignment patterns like:
|
152
|
+
# spec.name = "my_gem" OR Gem::Specification.new do |spec|; spec.name = 'my_gem'
|
153
|
+
@name_index = content =~ NAME_ASSIGNMENT_REGEX
|
154
|
+
if @name_index
|
155
|
+
return $2
|
156
|
+
end
|
157
|
+
rescue StandardError
|
158
|
+
# fall through
|
159
|
+
end
|
160
|
+
nil
|
161
|
+
end
|
162
|
+
|
163
|
+
# No-parse derivation of gem name, when parsing gemspec fails
|
164
|
+
def derive_gem_name
|
165
|
+
File.basename(@gemspec_path, ".*") if @gemspec_path
|
166
|
+
end
|
167
|
+
|
168
|
+
# Example
|
169
|
+
#
|
170
|
+
# ⚡️ A message from a fellow meat-based-AI ⚡️
|
171
|
+
# I ❤️ working on <%= @gem_name %>.
|
172
|
+
#
|
173
|
+
# The first line is the footer sentinel (which does appear in the commit).
|
174
|
+
# The second line, and any additional, is the main body of the footer.
|
175
|
+
#
|
176
|
+
# The sentinel must be set in an ENV variable (e.g., in your .env.local file):
|
177
|
+
#
|
178
|
+
# export GIT_HOOK_FOOTER_SENTINEL="⚡️ A message from a fellow meat-based-AI ⚡️"
|
179
|
+
#
|
180
|
+
def template
|
181
|
+
File.read(self.class.hooks_path_for("footer-template.erb.txt"))
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
GitCommitFooter.render(*ARGV)
|