kettle-dev 2.0.6 → 2.0.8
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/CHANGELOG.md +58 -23
- data/CONTRIBUTING.md +2 -2
- data/README.md +2 -2
- data/SECURITY.md +1 -1
- data/exe/kettle-changelog +1 -1
- data/exe/kettle-commit-msg +3 -3
- data/exe/kettle-dvcs +1 -1
- data/exe/kettle-gh-release +1 -1
- data/exe/kettle-pre-release +2 -2
- data/exe/kettle-readme-backers +1 -1
- data/exe/kettle-release +1 -1
- data/lib/kettle/dev/changelog_cli.rb +14 -18
- data/lib/kettle/dev/ci_helpers.rb +5 -5
- data/lib/kettle/dev/ci_monitor.rb +8 -8
- data/lib/kettle/dev/commit_msg.rb +2 -2
- data/lib/kettle/dev/dvcs_cli.rb +8 -8
- data/lib/kettle/dev/gem_spec_reader.rb +8 -8
- data/lib/kettle/dev/git_adapter.rb +17 -17
- data/lib/kettle/dev/git_commit_footer.rb +3 -3
- data/lib/kettle/dev/open_collective_config.rb +1 -1
- data/lib/kettle/dev/pre_release_cli.rb +7 -7
- data/lib/kettle/dev/rakelib/appraisal.rake +9 -5
- data/lib/kettle/dev/readme_backers.rb +15 -16
- data/lib/kettle/dev/release_cli.rb +15 -15
- data/lib/kettle/dev/tasks/ci_task.rb +15 -14
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev.rb +3 -3
- data/lib/kettle-dev.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +28 -8
- metadata.gz.sig +0 -0
|
@@ -53,7 +53,7 @@ module Kettle
|
|
|
53
53
|
if gemspec_path && File.file?(gemspec_path)
|
|
54
54
|
begin
|
|
55
55
|
spec = Gem::Specification.load(gemspec_path)
|
|
56
|
-
rescue
|
|
56
|
+
rescue => e
|
|
57
57
|
Kettle::Dev.debug_error(e, __method__)
|
|
58
58
|
spec = nil
|
|
59
59
|
end
|
|
@@ -62,7 +62,7 @@ module Kettle
|
|
|
62
62
|
gemspec_source = if gemspec_path && File.file?(gemspec_path)
|
|
63
63
|
begin
|
|
64
64
|
File.read(gemspec_path)
|
|
65
|
-
rescue
|
|
65
|
+
rescue => e
|
|
66
66
|
Kettle::Dev.debug_error(e, __method__)
|
|
67
67
|
""
|
|
68
68
|
end
|
|
@@ -91,7 +91,7 @@ module Kettle
|
|
|
91
91
|
puts "WARNING: Minimum Ruby not detected"
|
|
92
92
|
DEFAULT_MINIMUM_RUBY
|
|
93
93
|
end
|
|
94
|
-
rescue
|
|
94
|
+
rescue => e
|
|
95
95
|
puts "WARNING: Minimum Ruby detection failed:"
|
|
96
96
|
Kettle::Dev.debug_error(e, __method__)
|
|
97
97
|
# Default to a minimum of Ruby 1.8
|
|
@@ -117,7 +117,7 @@ module Kettle
|
|
|
117
117
|
entrypoint_require = derive_entrypoint_require(
|
|
118
118
|
root: root,
|
|
119
119
|
gem_name: gem_name,
|
|
120
|
-
gemspec_source: gemspec_source
|
|
120
|
+
gemspec_source: gemspec_source
|
|
121
121
|
)
|
|
122
122
|
namespace_source = entrypoint_require.to_s.empty? ? gem_name.to_s.tr("-", "/") : entrypoint_require.to_s
|
|
123
123
|
namespace = namespace_source.split("/").reject(&:empty?).map { |seg| camel.call(seg) }.join("::")
|
|
@@ -153,7 +153,7 @@ module Kettle
|
|
|
153
153
|
end
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
|
-
rescue
|
|
156
|
+
rescue => error
|
|
157
157
|
Kettle::Dev.debug_error(error, __method__)
|
|
158
158
|
# In an unexpected exception path, escalate to a domain error to aid callers/specs
|
|
159
159
|
raise Kettle::Dev::Error, "Unable to determine funding org: #{error.message}"
|
|
@@ -182,7 +182,7 @@ module Kettle
|
|
|
182
182
|
required_ruby_version: spec&.required_ruby_version, # Gem::Requirement instance
|
|
183
183
|
require_paths: Array(spec&.require_paths),
|
|
184
184
|
bindir: (spec&.bindir || "").to_s,
|
|
185
|
-
executables: Array(spec&.executables)
|
|
185
|
+
executables: Array(spec&.executables)
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
CACHE.mutex.synchronize do
|
|
@@ -223,7 +223,7 @@ module Kettle
|
|
|
223
223
|
forge_info[:forge_org] = m[1]
|
|
224
224
|
forge_info[:origin_repo] = m[2].to_s.sub(/\.git\z/, "")
|
|
225
225
|
end
|
|
226
|
-
rescue
|
|
226
|
+
rescue => error
|
|
227
227
|
Kettle::Dev.debug_error(error, __method__)
|
|
228
228
|
# be lenient here; actual error raising will occur in caller if required
|
|
229
229
|
end
|
|
@@ -255,7 +255,7 @@ module Kettle
|
|
|
255
255
|
content = source.to_s
|
|
256
256
|
patterns = [
|
|
257
257
|
%r{require_relative\s+["']lib/([^"']+)/version["']},
|
|
258
|
-
%r{Kernel\.load\(\s*["'][
|
|
258
|
+
%r{Kernel\.load\(\s*["']\#[{]__dir__[}]/lib/([^"']+)/version\.rb["']}
|
|
259
259
|
]
|
|
260
260
|
|
|
261
261
|
patterns.each do |pattern|
|
|
@@ -23,7 +23,7 @@ module Kettle
|
|
|
23
23
|
status = @git.status
|
|
24
24
|
# git gem's Status responds to changed, added, deleted, untracked, etc.
|
|
25
25
|
status.changed.empty? && status.added.empty? && status.deleted.empty? && status.untracked.empty?
|
|
26
|
-
rescue
|
|
26
|
+
rescue => e
|
|
27
27
|
Kettle::Dev.debug_error(e, __method__)
|
|
28
28
|
false
|
|
29
29
|
end
|
|
@@ -31,7 +31,7 @@ module Kettle
|
|
|
31
31
|
out, st = Open3.capture2("git", "status", "--porcelain")
|
|
32
32
|
st.success? && out.strip.empty?
|
|
33
33
|
end
|
|
34
|
-
rescue
|
|
34
|
+
rescue => e
|
|
35
35
|
Kettle::Dev.debug_error(e, __method__)
|
|
36
36
|
false
|
|
37
37
|
end
|
|
@@ -45,7 +45,7 @@ module Kettle
|
|
|
45
45
|
def capture(args)
|
|
46
46
|
out, status = Open3.capture2("git", *args)
|
|
47
47
|
[out.strip, status.success?]
|
|
48
|
-
rescue
|
|
48
|
+
rescue => e
|
|
49
49
|
Kettle::Dev.debug_error(e, __method__)
|
|
50
50
|
["", false]
|
|
51
51
|
end
|
|
@@ -70,7 +70,7 @@ module Kettle
|
|
|
70
70
|
Kettle::Dev.debug_error(e, __method__, backtrace: false)
|
|
71
71
|
# Optional dependency: fall back to CLI
|
|
72
72
|
@backend = :cli
|
|
73
|
-
rescue
|
|
73
|
+
rescue => e
|
|
74
74
|
raise Kettle::Dev::Error, "Failed to open git repository: #{e.message}"
|
|
75
75
|
end
|
|
76
76
|
end
|
|
@@ -90,7 +90,7 @@ module Kettle
|
|
|
90
90
|
@git.push(nil, branch, force: force)
|
|
91
91
|
end
|
|
92
92
|
true
|
|
93
|
-
rescue
|
|
93
|
+
rescue => e
|
|
94
94
|
Kettle::Dev.debug_error(e, __method__)
|
|
95
95
|
false
|
|
96
96
|
end
|
|
@@ -129,7 +129,7 @@ module Kettle
|
|
|
129
129
|
else
|
|
130
130
|
system("git", "push", "--tags")
|
|
131
131
|
end
|
|
132
|
-
rescue
|
|
132
|
+
rescue => e
|
|
133
133
|
Kettle::Dev.debug_error(e, __method__)
|
|
134
134
|
false
|
|
135
135
|
end
|
|
@@ -142,7 +142,7 @@ module Kettle
|
|
|
142
142
|
out, status = Open3.capture2("git", "rev-parse", "--abbrev-ref", "HEAD")
|
|
143
143
|
status.success? ? out.strip : nil
|
|
144
144
|
end
|
|
145
|
-
rescue
|
|
145
|
+
rescue => e
|
|
146
146
|
Kettle::Dev.debug_error(e, __method__)
|
|
147
147
|
nil
|
|
148
148
|
end
|
|
@@ -154,7 +154,7 @@ module Kettle
|
|
|
154
154
|
if @backend == :gem
|
|
155
155
|
begin
|
|
156
156
|
@git.ls_files.keys
|
|
157
|
-
rescue
|
|
157
|
+
rescue => e
|
|
158
158
|
Kettle::Dev.debug_error(e, __method__)
|
|
159
159
|
[]
|
|
160
160
|
end
|
|
@@ -162,7 +162,7 @@ module Kettle
|
|
|
162
162
|
out, status = Open3.capture2("git", "ls-files")
|
|
163
163
|
status.success? ? out.split(/\r?\n/).reject(&:empty?) : []
|
|
164
164
|
end
|
|
165
|
-
rescue
|
|
165
|
+
rescue => e
|
|
166
166
|
Kettle::Dev.debug_error(e, __method__)
|
|
167
167
|
[]
|
|
168
168
|
end
|
|
@@ -178,7 +178,7 @@ module Kettle
|
|
|
178
178
|
def blame_porcelain(path)
|
|
179
179
|
out, status = Open3.capture2("git", "blame", "--porcelain", path.to_s)
|
|
180
180
|
status.success? ? out : ""
|
|
181
|
-
rescue
|
|
181
|
+
rescue => e
|
|
182
182
|
Kettle::Dev.debug_error(e, __method__)
|
|
183
183
|
""
|
|
184
184
|
end
|
|
@@ -191,7 +191,7 @@ module Kettle
|
|
|
191
191
|
out, status = Open3.capture2("git", "remote")
|
|
192
192
|
status.success? ? out.split(/\r?\n/).map(&:strip).reject(&:empty?) : []
|
|
193
193
|
end
|
|
194
|
-
rescue
|
|
194
|
+
rescue => e
|
|
195
195
|
Kettle::Dev.debug_error(e, __method__)
|
|
196
196
|
[]
|
|
197
197
|
end
|
|
@@ -202,7 +202,7 @@ module Kettle
|
|
|
202
202
|
@git.remotes.each_with_object({}) do |r, h|
|
|
203
203
|
begin
|
|
204
204
|
h[r.name] = r.url
|
|
205
|
-
rescue
|
|
205
|
+
rescue => e
|
|
206
206
|
Kettle::Dev.debug_error(e, __method__)
|
|
207
207
|
# ignore
|
|
208
208
|
end
|
|
@@ -220,7 +220,7 @@ module Kettle
|
|
|
220
220
|
end
|
|
221
221
|
urls
|
|
222
222
|
end
|
|
223
|
-
rescue
|
|
223
|
+
rescue => e
|
|
224
224
|
Kettle::Dev.debug_error(e, __method__)
|
|
225
225
|
{}
|
|
226
226
|
end
|
|
@@ -235,7 +235,7 @@ module Kettle
|
|
|
235
235
|
out, status = Open3.capture2("git", "config", "--get", "remote.#{name}.url")
|
|
236
236
|
status.success? ? out.strip : nil
|
|
237
237
|
end
|
|
238
|
-
rescue
|
|
238
|
+
rescue => e
|
|
239
239
|
Kettle::Dev.debug_error(e, __method__)
|
|
240
240
|
nil
|
|
241
241
|
end
|
|
@@ -250,7 +250,7 @@ module Kettle
|
|
|
250
250
|
else
|
|
251
251
|
system("git", "checkout", branch.to_s)
|
|
252
252
|
end
|
|
253
|
-
rescue
|
|
253
|
+
rescue => e
|
|
254
254
|
Kettle::Dev.debug_error(e, __method__)
|
|
255
255
|
false
|
|
256
256
|
end
|
|
@@ -266,7 +266,7 @@ module Kettle
|
|
|
266
266
|
else
|
|
267
267
|
system("git", "pull", remote.to_s, branch.to_s)
|
|
268
268
|
end
|
|
269
|
-
rescue
|
|
269
|
+
rescue => e
|
|
270
270
|
Kettle::Dev.debug_error(e, __method__)
|
|
271
271
|
false
|
|
272
272
|
end
|
|
@@ -288,7 +288,7 @@ module Kettle
|
|
|
288
288
|
else
|
|
289
289
|
system("git", "fetch", remote.to_s)
|
|
290
290
|
end
|
|
291
|
-
rescue
|
|
291
|
+
rescue => e
|
|
292
292
|
Kettle::Dev.debug_error(e, __method__)
|
|
293
293
|
false
|
|
294
294
|
end
|
|
@@ -20,9 +20,9 @@ module Kettle
|
|
|
20
20
|
def git_toplevel
|
|
21
21
|
toplevel = nil
|
|
22
22
|
begin
|
|
23
|
-
out =
|
|
23
|
+
out = `git rev-parse --show-toplevel 2>/dev/null`
|
|
24
24
|
toplevel = out.strip unless out.nil? || out.empty?
|
|
25
|
-
rescue
|
|
25
|
+
rescue => e
|
|
26
26
|
Kettle::Dev.debug_error(e, __method__)
|
|
27
27
|
nil
|
|
28
28
|
end
|
|
@@ -114,7 +114,7 @@ module Kettle
|
|
|
114
114
|
if @name_index
|
|
115
115
|
return $2
|
|
116
116
|
end
|
|
117
|
-
rescue
|
|
117
|
+
rescue => e
|
|
118
118
|
Kettle::Dev.debug_error(e, __method__)
|
|
119
119
|
end
|
|
120
120
|
nil
|
|
@@ -56,7 +56,7 @@ module Kettle
|
|
|
56
56
|
handle = yml["collective"] || yml[:collective] || yml["org"] || yml[:org]
|
|
57
57
|
return handle.to_s unless handle.nil? || handle.to_s.strip.empty? || handle.to_s.match?(/\{KJ\|[^}]+}/)
|
|
58
58
|
end
|
|
59
|
-
rescue
|
|
59
|
+
rescue => e
|
|
60
60
|
Kettle::Dev.debug_error(e, __method__) if Kettle::Dev.respond_to?(:debug_error)
|
|
61
61
|
# fall through to required check
|
|
62
62
|
end
|
|
@@ -102,7 +102,7 @@ module Kettle
|
|
|
102
102
|
urls = []
|
|
103
103
|
|
|
104
104
|
# Inline image syntax
|
|
105
|
-
text.scan(/!\[[^\]]*\]\(([^\s)]+)(?:\s
|
|
105
|
+
text.scan(/!\[[^\]]*\]\(([^\s)]+)(?:\s+"[^"]*")?\)/) { |m| urls << m[0] }
|
|
106
106
|
|
|
107
107
|
# Reference definitions
|
|
108
108
|
ref_defs = {}
|
|
@@ -116,8 +116,8 @@ module Kettle
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
# HTML <img src="...">
|
|
119
|
-
text.scan(/<img\b[^>]*\bsrc\s*=\s
|
|
120
|
-
text.scan(/<img\b[^>]*\bsrc\s*=\s
|
|
119
|
+
text.scan(/<img\b[^>]*\bsrc\s*=\s*"([^"]+)"[^>]*>/i) { |m| urls << m[0] }
|
|
120
|
+
text.scan(/<img\b[^>]*\bsrc\s*=\s*'([^']+)'[^>]*>/i) { |m| urls << m[0] }
|
|
121
121
|
|
|
122
122
|
urls.reject! { |u| u.nil? || u.strip.empty? }
|
|
123
123
|
urls.select! { |u| u =~ %r{^https?://}i }
|
|
@@ -132,7 +132,7 @@ module Kettle
|
|
|
132
132
|
urls = files.flat_map do |f|
|
|
133
133
|
begin
|
|
134
134
|
extract_image_urls_from_text(File.read(f))
|
|
135
|
-
rescue
|
|
135
|
+
rescue => e
|
|
136
136
|
warn("[kettle-pre-release] Could not read #{Kettle::Dev.display_path(f)}: #{e.class}: #{e.message}")
|
|
137
137
|
[]
|
|
138
138
|
end
|
|
@@ -178,7 +178,7 @@ module Kettle
|
|
|
178
178
|
files.each do |file|
|
|
179
179
|
begin
|
|
180
180
|
original = File.read(file)
|
|
181
|
-
rescue
|
|
181
|
+
rescue => e
|
|
182
182
|
warn("[kettle-pre-release] Could not read #{Kettle::Dev.display_path(file)}: #{e.class}: #{e.message}")
|
|
183
183
|
next
|
|
184
184
|
end
|
|
@@ -206,7 +206,7 @@ module Kettle
|
|
|
206
206
|
begin
|
|
207
207
|
File.write(file, updated)
|
|
208
208
|
changed << file
|
|
209
|
-
rescue
|
|
209
|
+
rescue => e
|
|
210
210
|
warn("[kettle-pre-release] Could not write #{Kettle::Dev.display_path(file)}: #{e.class}: #{e.message}")
|
|
211
211
|
end
|
|
212
212
|
end
|
|
@@ -222,7 +222,7 @@ module Kettle
|
|
|
222
222
|
puts "[kettle-pre-release] Check 2: Validate Markdown image links (HTTP HEAD)"
|
|
223
223
|
urls = [
|
|
224
224
|
Markdown.extract_image_urls_from_files("**/*.md"),
|
|
225
|
-
Markdown.extract_image_urls_from_files("**/*.md.example")
|
|
225
|
+
Markdown.extract_image_urls_from_files("**/*.md.example")
|
|
226
226
|
].flatten.uniq
|
|
227
227
|
puts "[kettle-pre-release] Found #{urls.size} unique image URL(s)."
|
|
228
228
|
failures = []
|
|
@@ -61,19 +61,23 @@ begin
|
|
|
61
61
|
run_in_unbundled = proc do
|
|
62
62
|
env = {"BUNDLE_GEMFILE" => "Appraisal.root.gemfile"}
|
|
63
63
|
|
|
64
|
-
# 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle
|
|
64
|
+
# 1) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
|
|
65
|
+
ok = system(env, bundle, "install")
|
|
66
|
+
abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install") unless ok
|
|
67
|
+
|
|
68
|
+
# 2) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler
|
|
65
69
|
ok = system(env, bundle, "update", "--bundler")
|
|
66
70
|
abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle update --bundler") unless ok
|
|
67
71
|
|
|
68
|
-
#
|
|
72
|
+
# 3) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install
|
|
69
73
|
ok = system(env, bundle, "install")
|
|
70
74
|
abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle install") unless ok
|
|
71
75
|
|
|
72
|
-
#
|
|
76
|
+
# 4) BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal update
|
|
73
77
|
ok = system(env, bundle, "exec", "appraisal", "update")
|
|
74
78
|
abort("appraisal:update failed: BUNDLE_GEMFILE=Appraisal.root.gemfile bundle exec appraisal update") unless ok
|
|
75
79
|
|
|
76
|
-
#
|
|
80
|
+
# 5) bundle exec rake rubocop_gradual:autocorrect
|
|
77
81
|
ok = system(bundle, "exec", "rake", "rubocop_gradual:autocorrect")
|
|
78
82
|
abort("appraisal:update failed: rubocop_gradual:autocorrect") unless ok
|
|
79
83
|
end
|
|
@@ -101,7 +105,7 @@ begin
|
|
|
101
105
|
File.delete(f)
|
|
102
106
|
rescue Errno::ENOENT
|
|
103
107
|
# Ignore if already gone
|
|
104
|
-
rescue
|
|
108
|
+
rescue => e
|
|
105
109
|
failures << [f, e]
|
|
106
110
|
end
|
|
107
111
|
end
|
|
@@ -76,10 +76,10 @@ module Kettle
|
|
|
76
76
|
else
|
|
77
77
|
"https://github.com/organizations/YOUR_ORG/settings/secrets/actions"
|
|
78
78
|
end
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
warn "ERROR: README_UPDATER_TOKEN is not set."
|
|
80
|
+
warn "Please create an organization-level Actions secret named README_UPDATER_TOKEN at:"
|
|
81
|
+
warn " #{org_url}"
|
|
82
|
+
warn "Then update the workflow to reference it, or provide README_UPDATER_TOKEN in the environment."
|
|
83
83
|
raise 'Missing ENV["README_UPDATER_TOKEN"]'
|
|
84
84
|
end
|
|
85
85
|
nil
|
|
@@ -250,7 +250,7 @@ module Kettle
|
|
|
250
250
|
from_yml = from_yml.to_s if from_yml
|
|
251
251
|
return from_yml unless from_yml.nil? || from_yml.strip.empty?
|
|
252
252
|
end
|
|
253
|
-
rescue
|
|
253
|
+
rescue => e
|
|
254
254
|
Kettle::Dev.debug_error(e, __method__)
|
|
255
255
|
end
|
|
256
256
|
end
|
|
@@ -265,7 +265,7 @@ module Kettle
|
|
|
265
265
|
individuals_start: "<!-- #{base}-INDIVIDUALS:START -->",
|
|
266
266
|
individuals_end: "<!-- #{base}-INDIVIDUALS:END -->",
|
|
267
267
|
orgs_start: "<!-- #{base}-ORGANIZATIONS:START -->",
|
|
268
|
-
orgs_end: "<!-- #{base}-ORGANIZATIONS:END -->"
|
|
268
|
+
orgs_end: "<!-- #{base}-ORGANIZATIONS:END -->"
|
|
269
269
|
}
|
|
270
270
|
end
|
|
271
271
|
|
|
@@ -301,7 +301,7 @@ module Kettle
|
|
|
301
301
|
warn("Error parsing #{api_path} JSON: #{e.message}")
|
|
302
302
|
debug_log("Body that failed to parse (truncated 500): #{response&.body.to_s[0, 500]}")
|
|
303
303
|
[]
|
|
304
|
-
rescue
|
|
304
|
+
rescue => e
|
|
305
305
|
warn("Error fetching #{api_path}: #{e.class}: #{e.message}")
|
|
306
306
|
debug_log(e.backtrace.join("\n"))
|
|
307
307
|
[]
|
|
@@ -378,7 +378,7 @@ module Kettle
|
|
|
378
378
|
website: (h["website"].to_s.strip.empty? ? nil : h["website"]),
|
|
379
379
|
profile: (h["profile"].to_s.strip.empty? ? nil : h["profile"]),
|
|
380
380
|
oc_type: oc_type,
|
|
381
|
-
oc_index: oc_index
|
|
381
|
+
oc_index: oc_index
|
|
382
382
|
)
|
|
383
383
|
end
|
|
384
384
|
end
|
|
@@ -427,7 +427,7 @@ module Kettle
|
|
|
427
427
|
name: m.name,
|
|
428
428
|
image: m.image,
|
|
429
429
|
website: m.website,
|
|
430
|
-
profile: m.profile
|
|
430
|
+
profile: m.profile
|
|
431
431
|
)
|
|
432
432
|
end
|
|
433
433
|
# Build a single, well-formed block per tier with deterministic spacing:
|
|
@@ -437,7 +437,7 @@ module Kettle
|
|
|
437
437
|
block = [
|
|
438
438
|
"### Open Collective for #{tier}",
|
|
439
439
|
"",
|
|
440
|
-
generate_markdown(members_plain, empty_message: "", default_name: tier)
|
|
440
|
+
generate_markdown(members_plain, empty_message: "", default_name: tier)
|
|
441
441
|
].join("\n")
|
|
442
442
|
blocks << block
|
|
443
443
|
end
|
|
@@ -497,17 +497,17 @@ module Kettle
|
|
|
497
497
|
block = content[(start_index + start_tag.length)...end_index]
|
|
498
498
|
identities = Set.new
|
|
499
499
|
# 1) Image-style link wrappers: [](HREF)
|
|
500
|
-
block.to_s.scan(/\[!\[[^\]]*\]\([
|
|
500
|
+
block.to_s.scan(/\[!\[[^\]]*\]\([^)]*\)\]\(([^)]+)\)/) do |m|
|
|
501
501
|
href = (m[0] || "").strip
|
|
502
502
|
identities << href.downcase unless href.empty?
|
|
503
503
|
end
|
|
504
504
|
# 2) Capture ALT text from image-style wrappers for name identity
|
|
505
|
-
block.to_s.scan(/\[!\[([^\]]*)\]\([
|
|
505
|
+
block.to_s.scan(/\[!\[([^\]]*)\]\([^)]*\)\]\([^)]*\)/) do |m|
|
|
506
506
|
alt = (m[0] || "").strip
|
|
507
507
|
identities << alt.downcase unless alt.empty?
|
|
508
508
|
end
|
|
509
509
|
# 3) Plain markdown links: [TEXT](HREF)
|
|
510
|
-
block.to_s.scan(/\[([^!][^\]]*)\]\(([
|
|
510
|
+
block.to_s.scan(/\[([^!][^\]]*)\]\(([^)]+)\)/) do |m|
|
|
511
511
|
text = (m[0] || "").strip
|
|
512
512
|
href = (m[1] || "").strip
|
|
513
513
|
identities << href.downcase unless href.empty?
|
|
@@ -610,8 +610,7 @@ module Kettle
|
|
|
610
610
|
handle = github_handle_from_urls(m.profile, m.website)
|
|
611
611
|
return "@#{handle}" if handle
|
|
612
612
|
|
|
613
|
-
|
|
614
|
-
name
|
|
613
|
+
(m.name && !m.name.strip.empty?) ? m.name.strip : default_name
|
|
615
614
|
end
|
|
616
615
|
|
|
617
616
|
def github_handle_from_urls(*urls)
|
|
@@ -667,7 +666,7 @@ module Kettle
|
|
|
667
666
|
from_yml = from_yml.to_s if from_yml
|
|
668
667
|
return from_yml unless from_yml.nil? || from_yml.strip.empty?
|
|
669
668
|
end
|
|
670
|
-
rescue
|
|
669
|
+
rescue => e
|
|
671
670
|
Kettle::Dev.debug_error(e, __method__)
|
|
672
671
|
end
|
|
673
672
|
end
|
|
@@ -96,7 +96,7 @@ module Kettle
|
|
|
96
96
|
begin
|
|
97
97
|
gem_name = detect_gem_name
|
|
98
98
|
latest_overall, latest_for_series = latest_released_versions(gem_name, version)
|
|
99
|
-
rescue
|
|
99
|
+
rescue => e
|
|
100
100
|
warn("[kettle-release] gem.coop release check failed: #{e.class}: #{e.message}")
|
|
101
101
|
warn(e.backtrace.first(3).map { |l| " " + l }.join("\n")) if ENV["KETTLE_DEV_DEBUG"]
|
|
102
102
|
warn("Proceeding without gem.coop latest version info.")
|
|
@@ -167,14 +167,14 @@ module Kettle
|
|
|
167
167
|
# Ensure README KLOC badge reflects current CHANGELOG coverage denominator
|
|
168
168
|
begin
|
|
169
169
|
update_readme_kloc_badge!
|
|
170
|
-
rescue
|
|
170
|
+
rescue => e
|
|
171
171
|
warn("Failed to update KLOC badge in README: #{e.class}: #{e.message}")
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
# Update Rakefile.example header banner with current version and date
|
|
175
175
|
begin
|
|
176
176
|
update_rakefile_example_header!(version)
|
|
177
|
-
rescue
|
|
177
|
+
rescue => e
|
|
178
178
|
warn("Failed to update Rakefile.example header: #{e.class}: #{e.message}")
|
|
179
179
|
end
|
|
180
180
|
end
|
|
@@ -297,7 +297,7 @@ module Kettle
|
|
|
297
297
|
version ||= detect_version
|
|
298
298
|
gem_name = detect_gem_name
|
|
299
299
|
puts "\n🚀 Release #{gem_name} v#{version} Complete 🚀"
|
|
300
|
-
rescue
|
|
300
|
+
rescue => e
|
|
301
301
|
Kettle::Dev.debug_error(e, __method__)
|
|
302
302
|
# Fallback if detection fails for any reason
|
|
303
303
|
puts "\n🚀 Release v#{version || "unknown"} Complete 🚀"
|
|
@@ -414,7 +414,7 @@ module Kettle
|
|
|
414
414
|
next unless /copyright/i.match?(line)
|
|
415
415
|
|
|
416
416
|
# Expand ranges first (supports hyphen-minus and en dash)
|
|
417
|
-
line.scan(/\b(19\d{2}|20\d{2})\s*[
|
|
417
|
+
line.scan(/\b(19\d{2}|20\d{2})\s*[-–]\s*(19\d{2}|20\d{2})\b/).each do |a, b|
|
|
418
418
|
s = a.to_i
|
|
419
419
|
e = b.to_i
|
|
420
420
|
if e < s
|
|
@@ -466,7 +466,7 @@ module Kettle
|
|
|
466
466
|
next line
|
|
467
467
|
end
|
|
468
468
|
|
|
469
|
-
m = line.match(/\A(?<pre>.*?copyright[^0-9]*)(?<years>(?:\b(?:19|20)\d{2}\b(?:\s*[
|
|
469
|
+
m = line.match(/\A(?<pre>.*?copyright[^0-9]*)(?<years>(?:\b(?:19|20)\d{2}\b(?:\s*[-–]\s*\b(?:19|20)\d{2}\b)?)(?:\s*,\s*\b(?:19|20)\d{2}\b(?:\s*[-–]\s*\b(?:19|20)\d{2}\b)?)*)(?<post>.*)\z/i)
|
|
470
470
|
unless m
|
|
471
471
|
next line
|
|
472
472
|
end
|
|
@@ -491,7 +491,7 @@ module Kettle
|
|
|
491
491
|
end
|
|
492
492
|
|
|
493
493
|
# Capture three parts: prefix up to first year, the year blob, and the rest
|
|
494
|
-
m = line.match(/\A(?<pre>.*?copyright[^0-9]*)(?<years>(?:\b(?:19|20)\d{2}\b(?:\s*[
|
|
494
|
+
m = line.match(/\A(?<pre>.*?copyright[^0-9]*)(?<years>(?:\b(?:19|20)\d{2}\b(?:\s*[-–]\s*\b(?:19|20)\d{2}\b)?)(?:\s*,\s*\b(?:19|20)\d{2}\b(?:\s*[-–]\s*\b(?:19|20)\d{2}\b)?)*)(?<post>.*)\z/i)
|
|
495
495
|
unless m
|
|
496
496
|
# No parsable year sequence on this line; leave as-is
|
|
497
497
|
next line
|
|
@@ -500,7 +500,7 @@ module Kettle
|
|
|
500
500
|
years_blob = m[:years]
|
|
501
501
|
# Reuse extraction logic on just the years blob
|
|
502
502
|
years = []
|
|
503
|
-
years_blob.scan(/\b(19\d{2}|20\d{2})\s*[
|
|
503
|
+
years_blob.scan(/\b(19\d{2}|20\d{2})\s*[-–]\s*(19\d{2}|20\d{2})\b/).each do |a, b|
|
|
504
504
|
s = a.to_i
|
|
505
505
|
e = b.to_i
|
|
506
506
|
s, e = e, s if e < s
|
|
@@ -567,7 +567,7 @@ module Kettle
|
|
|
567
567
|
|
|
568
568
|
act_ok = begin
|
|
569
569
|
system("act", "--version", out: File::NULL, err: File::NULL)
|
|
570
|
-
rescue
|
|
570
|
+
rescue => e
|
|
571
571
|
Kettle::Dev.debug_error(e, __method__)
|
|
572
572
|
false
|
|
573
573
|
end
|
|
@@ -648,7 +648,7 @@ module Kettle
|
|
|
648
648
|
series_versions = gversions.select { |gv| gv.segments[0, 2] == series }
|
|
649
649
|
latest_series = series_versions.last&.to_s
|
|
650
650
|
[latest_overall, latest_series]
|
|
651
|
-
rescue
|
|
651
|
+
rescue => e
|
|
652
652
|
Kettle::Dev.debug_error(e, __method__)
|
|
653
653
|
[nil, nil]
|
|
654
654
|
end
|
|
@@ -957,7 +957,7 @@ module Kettle
|
|
|
957
957
|
pkg = File.join(@root, "pkg")
|
|
958
958
|
pattern = File.join(pkg, "*.gem")
|
|
959
959
|
gems = Dir[pattern].select { |p| File.basename(p).include?("-#{version}.gem") }
|
|
960
|
-
gems.
|
|
960
|
+
gems.max
|
|
961
961
|
end
|
|
962
962
|
|
|
963
963
|
def compute_sha256(path)
|
|
@@ -1042,7 +1042,7 @@ module Kettle
|
|
|
1042
1042
|
compare_ref = compare_ref&.end_with?("\n") ? compare_ref : (compare_ref && compare_ref + "\n")
|
|
1043
1043
|
tag_ref = tag_ref&.end_with?("\n") ? tag_ref : (tag_ref && tag_ref + "\n")
|
|
1044
1044
|
[section, compare_ref, tag_ref]
|
|
1045
|
-
rescue
|
|
1045
|
+
rescue => e
|
|
1046
1046
|
warn("Failed to parse CHANGELOG.md: #{e.class}: #{e.message}")
|
|
1047
1047
|
[nil, nil, nil]
|
|
1048
1048
|
end
|
|
@@ -1063,7 +1063,7 @@ module Kettle
|
|
|
1063
1063
|
# Normalize: trim trailing whitespace but keep internal formatting
|
|
1064
1064
|
block = block.lstrip # drop leading newline/space
|
|
1065
1065
|
block.rstrip
|
|
1066
|
-
rescue
|
|
1066
|
+
rescue => e
|
|
1067
1067
|
warn("[kettle-release] Failed to extract release notes footer from FUNDING.md: #{e.class}: #{e.message}")
|
|
1068
1068
|
nil
|
|
1069
1069
|
end
|
|
@@ -1081,7 +1081,7 @@ module Kettle
|
|
|
1081
1081
|
name: title,
|
|
1082
1082
|
body: body,
|
|
1083
1083
|
draft: false,
|
|
1084
|
-
prerelease: false
|
|
1084
|
+
prerelease: false
|
|
1085
1085
|
})
|
|
1086
1086
|
|
|
1087
1087
|
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
|
@@ -1099,7 +1099,7 @@ module Kettle
|
|
|
1099
1099
|
[false, "HTTP #{res.code}: #{res.body}"]
|
|
1100
1100
|
end
|
|
1101
1101
|
end
|
|
1102
|
-
rescue
|
|
1102
|
+
rescue => e
|
|
1103
1103
|
[false, "#{e.class}: #{e.message}"]
|
|
1104
1104
|
end
|
|
1105
1105
|
end
|
|
@@ -84,7 +84,7 @@ module Kettle
|
|
|
84
84
|
else
|
|
85
85
|
puts "GHA status: request failed (#{res.code})"
|
|
86
86
|
end
|
|
87
|
-
rescue
|
|
87
|
+
rescue => e
|
|
88
88
|
puts "GHA status: error #{e.class}: #{e.message}"
|
|
89
89
|
end
|
|
90
90
|
end
|
|
@@ -130,7 +130,7 @@ module Kettle
|
|
|
130
130
|
else
|
|
131
131
|
puts "Latest GL (#{branch}) pipeline: none"
|
|
132
132
|
end
|
|
133
|
-
rescue
|
|
133
|
+
rescue => e
|
|
134
134
|
puts "GL status: error #{e.class}: #{e.message}"
|
|
135
135
|
end
|
|
136
136
|
end
|
|
@@ -174,7 +174,6 @@ module Kettle
|
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
# Interactive menu
|
|
177
|
-
require "thread"
|
|
178
177
|
tty = $stdout.tty?
|
|
179
178
|
options = mapping.to_a + dynamic_files.map { |f| [f, f] }
|
|
180
179
|
quit_code = "q"
|
|
@@ -190,14 +189,14 @@ module Kettle
|
|
|
190
189
|
upstream = begin
|
|
191
190
|
out, status = Open3.capture2("git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}")
|
|
192
191
|
status.success? ? out.strip : nil
|
|
193
|
-
rescue
|
|
192
|
+
rescue => e
|
|
194
193
|
Kettle::Dev.debug_error(e, __method__)
|
|
195
194
|
nil
|
|
196
195
|
end
|
|
197
196
|
sha = begin
|
|
198
197
|
out, status = Open3.capture2("git", "rev-parse", "--short", "HEAD")
|
|
199
198
|
status.success? ? out.strip : nil
|
|
200
|
-
rescue
|
|
199
|
+
rescue => e
|
|
201
200
|
Kettle::Dev.debug_error(e, __method__)
|
|
202
201
|
nil
|
|
203
202
|
end
|
|
@@ -235,7 +234,7 @@ module Kettle
|
|
|
235
234
|
end
|
|
236
235
|
end
|
|
237
236
|
end
|
|
238
|
-
rescue
|
|
237
|
+
rescue => e
|
|
239
238
|
Kettle::Dev.debug_error(e, __method__)
|
|
240
239
|
end
|
|
241
240
|
|
|
@@ -263,18 +262,20 @@ module Kettle
|
|
|
263
262
|
sleep(0.2)
|
|
264
263
|
|
|
265
264
|
selected = nil
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
input_thread = Thread.new do # rubocop:disable ThreadSafety/NewThread
|
|
265
|
+
input_thread = nil
|
|
266
|
+
read_input = proc do
|
|
269
267
|
begin
|
|
270
268
|
selected = Kettle::Dev::InputAdapter.gets&.strip
|
|
271
269
|
rescue StandardError, SystemExit, Interrupt => error
|
|
272
|
-
|
|
273
|
-
# NOTE: look into refactoring to minimize potential SystemExit.
|
|
274
|
-
puts "Error in background thread: #{error.class}: #{error.message}" if Kettle::Dev::DEBUGGING
|
|
270
|
+
puts "Error reading input: #{error.class}: #{error.message}" if Kettle::Dev::DEBUGGING
|
|
275
271
|
selected = :input_error
|
|
276
272
|
end
|
|
277
273
|
end
|
|
274
|
+
if tty
|
|
275
|
+
input_thread = Thread.new(&read_input) # rubocop:disable ThreadSafety/NewThread
|
|
276
|
+
else
|
|
277
|
+
read_input.call
|
|
278
|
+
end
|
|
278
279
|
|
|
279
280
|
status_q = Queue.new
|
|
280
281
|
workers = []
|
|
@@ -381,12 +382,12 @@ module Kettle
|
|
|
381
382
|
|
|
382
383
|
begin
|
|
383
384
|
workers.each { |t| t.kill if t&.alive? }
|
|
384
|
-
rescue
|
|
385
|
+
rescue => e
|
|
385
386
|
Kettle::Dev.debug_error(e, __method__)
|
|
386
387
|
end
|
|
387
388
|
begin
|
|
388
389
|
input_thread.kill if input_thread&.alive?
|
|
389
|
-
rescue
|
|
390
|
+
rescue => e
|
|
390
391
|
Kettle::Dev.debug_error(e, __method__)
|
|
391
392
|
end
|
|
392
393
|
|