kettle-dev 1.0.9 → 1.0.11
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 +2 -2
- data/.envrc +4 -3
- data/.github/workflows/coverage.yml +3 -3
- data/.github/workflows/coverage.yml.example +127 -0
- data/.github/workflows/discord-notifier.yml +2 -1
- data/.github/workflows/truffle.yml +0 -8
- data/.junie/guidelines.md +4 -3
- data/.simplecov +5 -1
- data/Appraisals +5 -0
- data/Appraisals.example +102 -0
- data/CHANGELOG.md +80 -25
- data/CHANGELOG.md.example +4 -4
- data/CONTRIBUTING.md +43 -1
- data/Gemfile +3 -0
- data/README.md +65 -14
- data/README.md.example +515 -0
- data/{Rakefile → Rakefile.example} +17 -35
- data/exe/kettle-changelog +401 -0
- data/exe/kettle-commit-msg +11 -143
- data/exe/kettle-readme-backers +8 -352
- data/exe/kettle-release +7 -706
- data/gemfiles/modular/optional.gemfile +5 -0
- data/lib/kettle/dev/ci_helpers.rb +1 -0
- data/lib/kettle/dev/commit_msg.rb +39 -0
- data/lib/kettle/dev/exit_adapter.rb +36 -0
- data/lib/kettle/dev/git_adapter.rb +185 -0
- data/lib/kettle/dev/git_commit_footer.rb +130 -0
- data/lib/kettle/dev/input_adapter.rb +40 -0
- data/lib/kettle/dev/rakelib/appraisal.rake +8 -9
- data/lib/kettle/dev/rakelib/bench.rake +2 -7
- data/lib/kettle/dev/rakelib/bundle_audit.rake +2 -0
- data/lib/kettle/dev/rakelib/ci.rake +4 -396
- data/lib/kettle/dev/rakelib/install.rake +1 -295
- data/lib/kettle/dev/rakelib/reek.rake +2 -0
- data/lib/kettle/dev/rakelib/rubocop_gradual.rake +2 -0
- data/lib/kettle/dev/rakelib/spec_test.rake +2 -0
- data/lib/kettle/dev/rakelib/template.rake +3 -465
- data/lib/kettle/dev/readme_backers.rb +340 -0
- data/lib/kettle/dev/release_cli.rb +674 -0
- data/lib/kettle/dev/tasks/ci_task.rb +337 -0
- data/lib/kettle/dev/tasks/install_task.rb +516 -0
- data/lib/kettle/dev/tasks/template_task.rb +593 -0
- data/lib/kettle/dev/template_helpers.rb +65 -12
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev/versioning.rb +68 -0
- data/lib/kettle/dev.rb +30 -1
- data/lib/kettle-dev.rb +2 -3
- data/sig/kettle/dev/ci_helpers.rbs +8 -17
- data/sig/kettle/dev/commit_msg.rbs +8 -0
- data/sig/kettle/dev/exit_adapter.rbs +8 -0
- data/sig/kettle/dev/git_adapter.rbs +15 -0
- data/sig/kettle/dev/git_commit_footer.rbs +16 -0
- data/sig/kettle/dev/input_adapter.rbs +8 -0
- data/sig/kettle/dev/readme_backers.rbs +20 -0
- data/sig/kettle/dev/release_cli.rbs +8 -0
- data/sig/kettle/dev/tasks/ci_task.rbs +9 -0
- data/sig/kettle/dev/tasks/install_task.rbs +10 -0
- data/sig/kettle/dev/tasks/template_task.rbs +10 -0
- data/sig/kettle/dev/tasks.rbs +0 -0
- data/sig/kettle/dev/template_helpers.rbs +3 -1
- data/sig/kettle/dev/version.rbs +0 -0
- data/sig/kettle/emoji_regex.rbs +5 -0
- data/sig/kettle-dev.rbs +0 -0
- data.tar.gz.sig +0 -0
- metadata +59 -10
- metadata.gz.sig +0 -0
- data/.gitlab-ci.yml +0 -45
@@ -0,0 +1,5 @@
|
|
1
|
+
# Optional dependencies are not dependended on directly, but will be used if present.
|
2
|
+
# git gem is not a direct dependency for two reasons:
|
3
|
+
# 1. it is incompatible with Truffleruby v23
|
4
|
+
# 2. it depends on activesupport, which is too heavy
|
5
|
+
gem "git", ">= 1.19.1" # ruby >= 2.3
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Branch rule enforcement and commit message footer support for commit-msg hook.
|
4
|
+
# Provides a lib entrypoint so the exe wrapper can be minimal.
|
5
|
+
|
6
|
+
module Kettle
|
7
|
+
module Dev
|
8
|
+
module CommitMsg
|
9
|
+
module_function
|
10
|
+
|
11
|
+
BRANCH_RULES = {
|
12
|
+
"jira" => /^(?<story_type>(hotfix)|(bug)|(feature)|(candy))\/(?<story_id>\d{8,})-.+\Z/,
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
# Enforce branch rule by appending [type][id] to the commit message when missing.
|
16
|
+
# @param path [String] path to commit message file (ARGV[0] from git)
|
17
|
+
def enforce_branch_rule!(path)
|
18
|
+
validate = ENV.fetch("GIT_HOOK_BRANCH_VALIDATE", "false")
|
19
|
+
branch_rule_type = (!validate.casecmp("false").zero? && validate) || nil
|
20
|
+
return unless branch_rule_type
|
21
|
+
branch_rule = BRANCH_RULES[branch_rule_type]
|
22
|
+
return unless branch_rule
|
23
|
+
|
24
|
+
branch = %x(git branch 2> /dev/null | grep -e ^* | awk '{print $2}')
|
25
|
+
match_data = branch.match(branch_rule)
|
26
|
+
return unless match_data
|
27
|
+
|
28
|
+
commit_msg = File.read(path)
|
29
|
+
unless commit_msg.include?(match_data[:story_id])
|
30
|
+
commit_msg = <<~EOS
|
31
|
+
#{commit_msg.strip}
|
32
|
+
[#{match_data[:story_type]}][#{match_data[:story_id]}]
|
33
|
+
EOS
|
34
|
+
File.open(path, "w") { |file| file.print(commit_msg) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kettle
|
4
|
+
module Dev
|
5
|
+
# Exit/abort indirection layer to allow controllable behavior in tests.
|
6
|
+
#
|
7
|
+
# Production/default behavior delegates to Kernel.abort / Kernel.exit,
|
8
|
+
# which raise SystemExit. Specs can stub these methods to avoid terminating
|
9
|
+
# the process or to assert on arguments without coupling to Kernel.
|
10
|
+
#
|
11
|
+
# Example (RSpec):
|
12
|
+
# allow(Kettle::Dev::ExitAdapter).to receive(:abort).and_raise(SystemExit.new(1))
|
13
|
+
#
|
14
|
+
# This adapter mirrors the "mockable adapter" approach used for GitAdapter.
|
15
|
+
module ExitAdapter
|
16
|
+
module_function
|
17
|
+
|
18
|
+
# Abort the current execution with a message. By default this calls Kernel.abort,
|
19
|
+
# which raises SystemExit after printing the message to STDERR.
|
20
|
+
#
|
21
|
+
# @param msg [String]
|
22
|
+
# @return [void]
|
23
|
+
def abort(msg)
|
24
|
+
Kernel.abort(msg)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Exit the current process with a given status code. By default this calls Kernel.exit.
|
28
|
+
#
|
29
|
+
# @param status [Integer]
|
30
|
+
# @return [void]
|
31
|
+
def exit(status = 0)
|
32
|
+
Kernel.exit(status)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "open3"
|
4
|
+
|
5
|
+
module Kettle
|
6
|
+
module Dev
|
7
|
+
# Minimal Git adapter used by kettle-dev to avoid invoking live shell commands
|
8
|
+
# directly from the higher-level library code. In tests, mock this adapter's
|
9
|
+
# methods to prevent any real network or repository mutations.
|
10
|
+
#
|
11
|
+
# Behavior:
|
12
|
+
# - Prefer the 'git' gem when available.
|
13
|
+
# - If the 'git' gem is not present (LoadError), fall back to shelling out to
|
14
|
+
# the system `git` executable for the small set of operations we need.
|
15
|
+
#
|
16
|
+
# Public API is intentionally small and only includes what we need right now.
|
17
|
+
class GitAdapter
|
18
|
+
# Create a new adapter rooted at the current working directory.
|
19
|
+
# @return [void]
|
20
|
+
def initialize
|
21
|
+
begin
|
22
|
+
# Allow users/CI to opt out of using the 'git' gem even when available.
|
23
|
+
# Set KETTLE_DEV_DISABLE_GIT_GEM to a truthy value ("1", "true", "yes") to force CLI backend.
|
24
|
+
env_val = ENV["KETTLE_DEV_DISABLE_GIT_GEM"]
|
25
|
+
# Ruby 2.3 compatibility: String#match? was added in 2.4; use Regexp#=== / =~ instead
|
26
|
+
disable_gem = env_val && !!(/\A(1|true|yes)\z/i =~ env_val)
|
27
|
+
if disable_gem
|
28
|
+
@backend = :cli
|
29
|
+
else
|
30
|
+
Kernel.require "git"
|
31
|
+
@backend = :gem
|
32
|
+
@git = ::Git.open(Dir.pwd)
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
# Optional dependency: fall back to CLI
|
36
|
+
@backend = :cli
|
37
|
+
rescue StandardError => e
|
38
|
+
raise Kettle::Dev::Error, "Failed to open git repository: #{e.message}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Push a branch to a remote.
|
43
|
+
# @param remote [String, nil] remote name (nil means default remote)
|
44
|
+
# @param branch [String] branch name (required)
|
45
|
+
# @param force [Boolean] whether to force push
|
46
|
+
# @return [Boolean] true when the push is reported successful
|
47
|
+
def push(remote, branch, force: false)
|
48
|
+
if @backend == :gem
|
49
|
+
begin
|
50
|
+
if remote
|
51
|
+
@git.push(remote, branch, force: force)
|
52
|
+
else
|
53
|
+
# Default remote according to repo config
|
54
|
+
@git.push(nil, branch, force: force)
|
55
|
+
end
|
56
|
+
true
|
57
|
+
rescue StandardError
|
58
|
+
false
|
59
|
+
end
|
60
|
+
else
|
61
|
+
args = ["git", "push"]
|
62
|
+
args << "--force" if force
|
63
|
+
if remote
|
64
|
+
args << remote.to_s << branch.to_s
|
65
|
+
end
|
66
|
+
system(*args)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [String, nil] current branch name, or nil on error
|
71
|
+
def current_branch
|
72
|
+
if @backend == :gem
|
73
|
+
@git.current_branch
|
74
|
+
else
|
75
|
+
out, status = Open3.capture2("git", "rev-parse", "--abbrev-ref", "HEAD")
|
76
|
+
status.success? ? out.strip : nil
|
77
|
+
end
|
78
|
+
rescue StandardError
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Array<String>] list of remote names
|
83
|
+
def remotes
|
84
|
+
if @backend == :gem
|
85
|
+
@git.remotes.map(&:name)
|
86
|
+
else
|
87
|
+
out, status = Open3.capture2("git", "remote")
|
88
|
+
status.success? ? out.split(/\r?\n/).map(&:strip).reject(&:empty?) : []
|
89
|
+
end
|
90
|
+
rescue StandardError
|
91
|
+
[]
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Hash{String=>String}] remote name => fetch URL
|
95
|
+
def remotes_with_urls
|
96
|
+
if @backend == :gem
|
97
|
+
@git.remotes.each_with_object({}) do |r, h|
|
98
|
+
begin
|
99
|
+
h[r.name] = r.url
|
100
|
+
rescue StandardError
|
101
|
+
# ignore
|
102
|
+
end
|
103
|
+
end
|
104
|
+
else
|
105
|
+
out, status = Open3.capture2("git", "remote", "-v")
|
106
|
+
return {} unless status.success?
|
107
|
+
urls = {}
|
108
|
+
out.each_line do |line|
|
109
|
+
# Example: origin https://github.com/me/repo.git (fetch)
|
110
|
+
if line =~ /^(\S+)\s+(\S+)\s+\(fetch\)/
|
111
|
+
urls[Regexp.last_match(1)] = Regexp.last_match(2)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
urls
|
115
|
+
end
|
116
|
+
rescue StandardError
|
117
|
+
{}
|
118
|
+
end
|
119
|
+
|
120
|
+
# @param name [String]
|
121
|
+
# @return [String, nil]
|
122
|
+
def remote_url(name)
|
123
|
+
if @backend == :gem
|
124
|
+
r = @git.remotes.find { |x| x.name == name }
|
125
|
+
r&.url
|
126
|
+
else
|
127
|
+
out, status = Open3.capture2("git", "config", "--get", "remote.#{name}.url")
|
128
|
+
status.success? ? out.strip : nil
|
129
|
+
end
|
130
|
+
rescue StandardError
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
# Checkout the given branch
|
135
|
+
# @param branch [String]
|
136
|
+
# @return [Boolean]
|
137
|
+
def checkout(branch)
|
138
|
+
if @backend == :gem
|
139
|
+
@git.checkout(branch)
|
140
|
+
true
|
141
|
+
else
|
142
|
+
system("git", "checkout", branch.to_s)
|
143
|
+
end
|
144
|
+
rescue StandardError
|
145
|
+
false
|
146
|
+
end
|
147
|
+
|
148
|
+
# Pull from a remote/branch
|
149
|
+
# @param remote [String]
|
150
|
+
# @param branch [String]
|
151
|
+
# @return [Boolean]
|
152
|
+
def pull(remote, branch)
|
153
|
+
if @backend == :gem
|
154
|
+
@git.pull(remote, branch)
|
155
|
+
true
|
156
|
+
else
|
157
|
+
system("git", "pull", remote.to_s, branch.to_s)
|
158
|
+
end
|
159
|
+
rescue StandardError
|
160
|
+
false
|
161
|
+
end
|
162
|
+
|
163
|
+
# Fetch a ref from a remote (or everything if ref is nil)
|
164
|
+
# @param remote [String]
|
165
|
+
# @param ref [String, nil]
|
166
|
+
# @return [Boolean]
|
167
|
+
def fetch(remote, ref = nil)
|
168
|
+
if @backend == :gem
|
169
|
+
if ref
|
170
|
+
@git.fetch(remote, ref)
|
171
|
+
else
|
172
|
+
@git.fetch(remote)
|
173
|
+
end
|
174
|
+
true
|
175
|
+
elsif ref
|
176
|
+
system("git", "fetch", remote.to_s, ref.to_s)
|
177
|
+
else
|
178
|
+
system("git", "fetch", remote.to_s)
|
179
|
+
end
|
180
|
+
rescue StandardError
|
181
|
+
false
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Exposed from lib/ so that exe/kettle-commit-msg can be a minimal wrapper.
|
4
|
+
|
5
|
+
module Kettle
|
6
|
+
module Dev
|
7
|
+
class GitCommitFooter
|
8
|
+
# Regex to extract `name = "value"` assignments from a gemspec.
|
9
|
+
# @return [Regexp]
|
10
|
+
NAME_ASSIGNMENT_REGEX = /\bname\s*=\s*(["'])([^"']+)\1/.freeze
|
11
|
+
|
12
|
+
# Whether footer appending is enabled (via GIT_HOOK_FOOTER_APPEND=true)
|
13
|
+
# @return [Boolean]
|
14
|
+
FOOTER_APPEND = ENV.fetch("GIT_HOOK_FOOTER_APPEND", "false").casecmp("true").zero?
|
15
|
+
# The sentinel string that must be present to avoid duplicate footers
|
16
|
+
# @return [String, nil]
|
17
|
+
SENTINEL = ENV["GIT_HOOK_FOOTER_SENTINEL"]
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# Resolve git repository top-level dir, or nil outside a repo.
|
21
|
+
# @return [String, nil]
|
22
|
+
def git_toplevel
|
23
|
+
toplevel = nil
|
24
|
+
begin
|
25
|
+
out = %x(git rev-parse --show-toplevel 2>/dev/null)
|
26
|
+
toplevel = out.strip unless out.nil? || out.empty?
|
27
|
+
rescue StandardError
|
28
|
+
end
|
29
|
+
toplevel
|
30
|
+
end
|
31
|
+
|
32
|
+
def local_hooks_dir
|
33
|
+
top = git_toplevel
|
34
|
+
return unless top && !top.empty?
|
35
|
+
File.join(top, ".git-hooks")
|
36
|
+
end
|
37
|
+
|
38
|
+
def global_hooks_dir
|
39
|
+
File.join(ENV["HOME"], ".git-hooks")
|
40
|
+
end
|
41
|
+
|
42
|
+
def hooks_path_for(filename)
|
43
|
+
local_dir = local_hooks_dir
|
44
|
+
if local_dir
|
45
|
+
local_path = File.join(local_dir, filename)
|
46
|
+
return local_path if File.file?(local_path)
|
47
|
+
end
|
48
|
+
File.join(global_hooks_dir, filename)
|
49
|
+
end
|
50
|
+
|
51
|
+
def commit_goalie_path
|
52
|
+
hooks_path_for("commit-subjects-goalie.txt")
|
53
|
+
end
|
54
|
+
|
55
|
+
def goalie_allows_footer?(subject_line)
|
56
|
+
goalie_path = commit_goalie_path
|
57
|
+
return false unless File.file?(goalie_path)
|
58
|
+
|
59
|
+
prefixes = File.read(goalie_path).lines.map { |l| l.strip }.reject { |l| l.empty? || l.start_with?("#") }
|
60
|
+
return false if prefixes.empty?
|
61
|
+
|
62
|
+
subj = subject_line.to_s.strip
|
63
|
+
prefixes.any? { |prefix| subj.start_with?(prefix) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def render(*argv)
|
67
|
+
commit_msg = File.read(argv[0])
|
68
|
+
subject_line = commit_msg.lines.first.to_s
|
69
|
+
|
70
|
+
# Evaluate configuration at runtime to respect ENV set during tests/CI
|
71
|
+
footer_append = ENV.fetch("GIT_HOOK_FOOTER_APPEND", "false").casecmp("true").zero?
|
72
|
+
sentinel = ENV["GIT_HOOK_FOOTER_SENTINEL"]
|
73
|
+
|
74
|
+
if footer_append && (sentinel.nil? || sentinel.to_s.empty?)
|
75
|
+
raise "Set GIT_HOOK_FOOTER_SENTINEL=<footer sentinel> in .env.local (e.g., '⚡️ A message from a fellow meat-based-AI ⚡️')"
|
76
|
+
end
|
77
|
+
|
78
|
+
if footer_append && goalie_allows_footer?(subject_line)
|
79
|
+
if commit_msg.include?(sentinel)
|
80
|
+
Kettle::Dev::ExitAdapter.exit(0)
|
81
|
+
else
|
82
|
+
footer_binding = GitCommitFooter.new
|
83
|
+
File.open(argv[0], "w") do |file|
|
84
|
+
file.print(commit_msg)
|
85
|
+
file.print("\n")
|
86
|
+
file.print(footer_binding.render)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
else
|
90
|
+
# Skipping footer append
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def initialize
|
96
|
+
@pwd = Dir.pwd
|
97
|
+
@gemspecs = Dir["*.gemspec"]
|
98
|
+
@spec = @gemspecs.first
|
99
|
+
@gemspec_path = File.expand_path(@spec, @pwd)
|
100
|
+
@gem_name = parse_gemspec_name || derive_gem_name
|
101
|
+
end
|
102
|
+
|
103
|
+
def render
|
104
|
+
ERB.new(template).result(binding)
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def parse_gemspec_name
|
110
|
+
begin
|
111
|
+
content = File.read(@gemspec_path)
|
112
|
+
@name_index = content =~ NAME_ASSIGNMENT_REGEX
|
113
|
+
if @name_index
|
114
|
+
return $2
|
115
|
+
end
|
116
|
+
rescue StandardError
|
117
|
+
end
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
|
121
|
+
def derive_gem_name
|
122
|
+
File.basename(@gemspec_path, ".*") if @gemspec_path
|
123
|
+
end
|
124
|
+
|
125
|
+
def template
|
126
|
+
File.read(self.class.hooks_path_for("footer-template.erb.txt"))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kettle
|
4
|
+
module Dev
|
5
|
+
# Input indirection layer to make interactive prompts safe in tests.
|
6
|
+
#
|
7
|
+
# Production/default behavior delegates to $stdin.gets (or Kernel#gets)
|
8
|
+
# so application code does not read from STDIN directly. In specs, mock
|
9
|
+
# this adapter's methods to return deterministic answers without touching
|
10
|
+
# global IO.
|
11
|
+
#
|
12
|
+
# Example (RSpec):
|
13
|
+
# allow(Kettle::Dev::InputAdapter).to receive(:gets).and_return("y\n")
|
14
|
+
#
|
15
|
+
# This mirrors the "mockable adapter" approach used for GitAdapter and ExitAdapter.
|
16
|
+
module InputAdapter
|
17
|
+
module_function
|
18
|
+
|
19
|
+
# Read one line from the standard input, including the trailing newline if
|
20
|
+
# present. Returns nil on EOF, consistent with IO#gets.
|
21
|
+
#
|
22
|
+
# @param args [Array] any args are forwarded to $stdin.gets for compatibility
|
23
|
+
# @return [String, nil]
|
24
|
+
def gets(*args)
|
25
|
+
$stdin.gets(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Read one line from standard input, raising EOFError on end-of-file.
|
29
|
+
# Provided for convenience symmetry with IO#readline when needed.
|
30
|
+
#
|
31
|
+
# @param args [Array]
|
32
|
+
# @return [String]
|
33
|
+
def readline(*args)
|
34
|
+
line = gets(*args)
|
35
|
+
raise EOFError, "end of file reached" if line.nil?
|
36
|
+
line
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,9 +1,4 @@
|
|
1
|
-
|
2
|
-
require "bundler"
|
3
|
-
rescue LoadError
|
4
|
-
warn("[kettle-dev][appraisal.rake] failed to load bundler") if Kettle::Dev::DEBUGGING
|
5
|
-
# ok, might still work
|
6
|
-
end
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
3
|
# --- Appraisals (dev-only) ---
|
9
4
|
begin
|
@@ -16,15 +11,19 @@ begin
|
|
16
11
|
run_in_unbundled = proc do
|
17
12
|
env = {"BUNDLE_GEMFILE" => "Appraisal.root.gemfile"}
|
18
13
|
|
19
|
-
# 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle
|
14
|
+
# 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler
|
15
|
+
ok = system(env, bundle, "update", "--bundler")
|
16
|
+
abort("appraisal:update failed: bundle update --bundler under Appraisal.root.gemfile") unless ok
|
17
|
+
|
18
|
+
# 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle (install)
|
20
19
|
ok = system(env, bundle)
|
21
20
|
abort("appraisal:update failed: bundler install under Appraisal.root.gemfile") unless ok
|
22
21
|
|
23
|
-
#
|
22
|
+
# 3) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal update
|
24
23
|
ok = system(env, bundle, "exec", "appraisal", "update")
|
25
24
|
abort("appraisal:update failed: bundle exec appraisal update") unless ok
|
26
25
|
|
27
|
-
#
|
26
|
+
# 4) bundle exec rake rubocop_gradual:autocorrect
|
28
27
|
ok = system(bundle, "exec", "rake", "rubocop_gradual:autocorrect")
|
29
28
|
abort("appraisal:update failed: rubocop_gradual:autocorrect") unless ok
|
30
29
|
end
|
@@ -1,11 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "bundler"
|
5
|
-
rescue LoadError
|
6
|
-
warn("[kettle-dev][bench.rake] failed to load bundler") if Kettle::Dev::DEBUGGING
|
7
|
-
# ok, might still work
|
8
|
-
end
|
3
|
+
require "rbconfig" if !Dir[File.join(__dir__, "benchmarks")].empty? # Used by `rake bench:run`
|
9
4
|
|
10
5
|
# --- Benchmarks (dev-only) ---
|
11
6
|
namespace :bench do
|