kettle-dev 1.0.10 → 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 +0 -0
- data/.envrc +1 -1
- data/.github/workflows/coverage.yml +2 -2
- data/.github/workflows/coverage.yml.example +127 -0
- data/.github/workflows/discord-notifier.yml +2 -1
- data/.github/workflows/truffle.yml +0 -8
- data/Appraisals +3 -1
- data/Appraisals.example +102 -0
- data/CHANGELOG.md +63 -29
- data/CHANGELOG.md.example +4 -4
- data/CONTRIBUTING.md +37 -1
- data/Gemfile +3 -0
- data/README.md +47 -9
- data/README.md.example +515 -0
- data/{Rakefile → Rakefile.example} +13 -27
- data/exe/kettle-changelog +401 -0
- data/exe/kettle-commit-msg +2 -0
- data/exe/kettle-readme-backers +2 -0
- data/exe/kettle-release +2 -7
- data/gemfiles/modular/optional.gemfile +5 -0
- data/lib/kettle/dev/git_adapter.rb +98 -33
- data/lib/kettle/dev/git_commit_footer.rb +1 -1
- data/lib/kettle/dev/input_adapter.rb +40 -0
- data/lib/kettle/dev/release_cli.rb +24 -22
- data/lib/kettle/dev/tasks/ci_task.rb +4 -1
- data/lib/kettle/dev/tasks/install_task.rb +313 -95
- data/lib/kettle/dev/tasks/template_task.rb +175 -73
- data/lib/kettle/dev/template_helpers.rb +61 -8
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev/versioning.rb +68 -0
- data/sig/kettle/dev/input_adapter.rbs +8 -0
- data/sig/kettle/dev/template_helpers.rbs +3 -1
- data.tar.gz.sig +0 -0
- metadata +21 -22
- metadata.gz.sig +0 -0
- data/.gitlab-ci.yml +0 -45
@@ -47,42 +47,28 @@
|
|
47
47
|
# rake yard # Generate YARD Documentation
|
48
48
|
#
|
49
49
|
|
50
|
-
# External gems
|
51
50
|
require "bundler/gem_tasks" if !Dir[File.join(__dir__, "*.gemspec")].empty?
|
52
51
|
|
52
|
+
# External gems - add here!
|
53
|
+
require "kettle/dev"
|
54
|
+
|
53
55
|
# Define a base default task early so other files can enhance it.
|
54
56
|
desc "Default tasks aggregator"
|
55
57
|
task :default do
|
56
58
|
puts "Default task complete."
|
57
59
|
end
|
58
60
|
|
59
|
-
|
60
|
-
# which would load code before SimpleCov can start (when running `rake spec`).
|
61
|
-
invoked_tasks = Rake.application.top_level_tasks
|
62
|
-
running_specs = invoked_tasks.any? { |t| t == "spec" || t == "test" || t == "coverage" }
|
61
|
+
Kettle::Dev.install_tasks
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
desc("Run RSpec code examples")
|
69
|
-
RSpec::Core::RakeTask.new(:spec)
|
70
|
-
desc("Run tests")
|
71
|
-
task(test: :spec)
|
72
|
-
rescue LoadError
|
73
|
-
# If rspec isn't available, let it fail when the task is invoked
|
74
|
-
end
|
75
|
-
else
|
76
|
-
require "kettle-dev"
|
63
|
+
### RELEASE TASKS
|
64
|
+
# Setup stone_checksums
|
65
|
+
begin
|
66
|
+
require "stone_checksums"
|
77
67
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
desc("(stub) build:generate_checksums is unavailable")
|
84
|
-
task("build:generate_checksums") do
|
85
|
-
warn("NOTE: stone_checksums isn't installed, or is disabled for #{RUBY_VERSION} in the current environment")
|
86
|
-
end
|
68
|
+
GemChecksums.install_tasks
|
69
|
+
rescue LoadError
|
70
|
+
desc("(stub) build:generate_checksums is unavailable")
|
71
|
+
task("build:generate_checksums") do
|
72
|
+
warn("NOTE: stone_checksums isn't installed, or is disabled for #{RUBY_VERSION} in the current environment")
|
87
73
|
end
|
88
74
|
end
|
@@ -0,0 +1,401 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# vim: set syntax=ruby
|
5
|
+
|
6
|
+
# kettle-changelog: Generate a CHANGELOG.md entry for the current VERSION.
|
7
|
+
# - Reads VERSION from lib/**/version.rb (must be unique across files)
|
8
|
+
# - Moves entries from the "Unreleased" section into a new versioned section
|
9
|
+
# - Prepends 4 heading lines:
|
10
|
+
# - TAG
|
11
|
+
# - COVERAGE (line coverage)
|
12
|
+
# - BRANCH COVERAGE (branch coverage)
|
13
|
+
# - percent documented (parsed from `bin/yard` output)
|
14
|
+
# - Updates bottom link references to GitHub style, converts any existing
|
15
|
+
# GitLab links to GitHub links, and appends the new [X.Y.Z] and [X.Y.Zt] links.
|
16
|
+
#
|
17
|
+
# Notes:
|
18
|
+
# - Expects a JSON coverage report at coverage/coverage.json. If missing,
|
19
|
+
# it will instruct you to run: K_SOUP_COV_FORMATTERS="json" bin/rspec
|
20
|
+
# - Expects bin/yard to be available via Bundler.
|
21
|
+
|
22
|
+
$stdout.sync = true
|
23
|
+
|
24
|
+
# Depending library or project must be using bundler
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
require "json"
|
28
|
+
require "time"
|
29
|
+
require "open3"
|
30
|
+
require "shellwords"
|
31
|
+
|
32
|
+
begin
|
33
|
+
require "kettle/dev"
|
34
|
+
rescue LoadError => e
|
35
|
+
warn("kettle/dev: failed to load: #{e.message}")
|
36
|
+
warn("Hint: Ensure the host project includes kettle-dev and run bundle install.")
|
37
|
+
exit(1)
|
38
|
+
end
|
39
|
+
|
40
|
+
require "kettle/dev/versioning"
|
41
|
+
|
42
|
+
puts "== kettle-changelog v#{Kettle::Dev::Version::VERSION} =="
|
43
|
+
|
44
|
+
module Kettle
|
45
|
+
module Dev
|
46
|
+
class ChangelogCLI
|
47
|
+
def initialize
|
48
|
+
@root = Kettle::Dev::CIHelpers.project_root
|
49
|
+
@changelog_path = File.join(@root, "CHANGELOG.md")
|
50
|
+
@coverage_path = File.join(@root, "coverage", "coverage.json")
|
51
|
+
end
|
52
|
+
|
53
|
+
def run
|
54
|
+
version = Kettle::Dev::Versioning.detect_version(@root)
|
55
|
+
today = Time.now.strftime("%Y-%m-%d")
|
56
|
+
owner, repo = Kettle::Dev::CIHelpers.repo_info
|
57
|
+
unless owner && repo
|
58
|
+
warn("Could not determine GitHub owner/repo from origin remote.")
|
59
|
+
warn("Make sure 'origin' points to github.com. Alternatively, set origin or update links manually afterward.")
|
60
|
+
end
|
61
|
+
|
62
|
+
line_cov_line, branch_cov_line = coverage_lines
|
63
|
+
yard_line = yard_percent_documented
|
64
|
+
|
65
|
+
changelog = File.read(@changelog_path)
|
66
|
+
|
67
|
+
# If the detected version already exists in the changelog, abort to avoid duplicates
|
68
|
+
if changelog =~ /^## \[#{Regexp.escape(version)}\]/
|
69
|
+
abort("CHANGELOG.md already has a section for version #{version}. Bump version.rb or remove the duplicate.")
|
70
|
+
end
|
71
|
+
|
72
|
+
unreleased_block, before, after = extract_unreleased(changelog)
|
73
|
+
if unreleased_block.nil?
|
74
|
+
abort("Could not find '## [Unreleased]' section in CHANGELOG.md")
|
75
|
+
end
|
76
|
+
|
77
|
+
if unreleased_block.strip.empty?
|
78
|
+
warn("No entries found under Unreleased. Creating an empty version section anyway.")
|
79
|
+
end
|
80
|
+
|
81
|
+
prev_version = detect_previous_version(after)
|
82
|
+
|
83
|
+
new_section = +""
|
84
|
+
new_section << "## [#{version}] - #{today}\n"
|
85
|
+
new_section << "- TAG: [v#{version}][#{version}t]\n"
|
86
|
+
new_section << "- #{line_cov_line}\n" if line_cov_line
|
87
|
+
new_section << "- #{branch_cov_line}\n" if branch_cov_line
|
88
|
+
new_section << "- #{yard_line}\n" if yard_line
|
89
|
+
new_section << filter_unreleased_sections(unreleased_block)
|
90
|
+
# Ensure exactly one blank line separates this new section from the next section
|
91
|
+
new_section.rstrip!
|
92
|
+
new_section << "\n\n"
|
93
|
+
|
94
|
+
# Reset the Unreleased section to empty category headings
|
95
|
+
unreleased_reset = <<~MD
|
96
|
+
## [Unreleased]
|
97
|
+
### Added
|
98
|
+
### Changed
|
99
|
+
### Deprecated
|
100
|
+
### Removed
|
101
|
+
### Fixed
|
102
|
+
### Security
|
103
|
+
MD
|
104
|
+
|
105
|
+
updated = before + unreleased_reset + "\n" + new_section + after
|
106
|
+
|
107
|
+
updated = update_link_refs(updated, owner, repo, prev_version, version)
|
108
|
+
|
109
|
+
File.write(@changelog_path, updated)
|
110
|
+
puts "CHANGELOG.md updated with v#{version} section."
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def abort(msg)
|
116
|
+
Kettle::Dev::ExitAdapter.abort(msg)
|
117
|
+
rescue NameError
|
118
|
+
Kernel.abort(msg)
|
119
|
+
end
|
120
|
+
|
121
|
+
def detect_version
|
122
|
+
candidates = Dir[File.join(@root, "lib", "**", "version.rb")]
|
123
|
+
abort("Could not find version.rb under lib/**.") if candidates.empty?
|
124
|
+
versions = candidates.map do |path|
|
125
|
+
content = File.read(path)
|
126
|
+
m = content.match(/VERSION\s*=\s*(["'])([^"']+)\1/)
|
127
|
+
next unless m
|
128
|
+
m[2]
|
129
|
+
end.compact
|
130
|
+
abort("VERSION constant not found in #{@root}/lib/**/version.rb") if versions.none?
|
131
|
+
abort("Multiple VERSION constants found to be out of sync (#{versions.inspect}) in #{@root}/lib/**/version.rb") unless versions.uniq.length == 1
|
132
|
+
versions.first
|
133
|
+
end
|
134
|
+
|
135
|
+
def extract_unreleased(content)
|
136
|
+
lines = content.lines
|
137
|
+
start_i = lines.index { |l| l.start_with?("## [Unreleased]") }
|
138
|
+
return [nil, nil, nil] unless start_i
|
139
|
+
# Find the next version heading after Unreleased
|
140
|
+
next_i = (start_i + 1)
|
141
|
+
while next_i < lines.length && !lines[next_i].start_with?("## [")
|
142
|
+
next_i += 1
|
143
|
+
end
|
144
|
+
# Now next_i points to the next section heading or EOF
|
145
|
+
before = lines[0..(start_i - 1)].join
|
146
|
+
unreleased_block = lines[(start_i + 1)..(next_i - 1)].join
|
147
|
+
after = lines[next_i..-1]&.join || ""
|
148
|
+
[unreleased_block, before, after]
|
149
|
+
end
|
150
|
+
|
151
|
+
def detect_previous_version(after_text)
|
152
|
+
# after_text begins with the first released section following Unreleased
|
153
|
+
m = after_text.match(/^## \[(\d+\.\d+\.\d+)\]/)
|
154
|
+
return m[1] if m
|
155
|
+
nil
|
156
|
+
end
|
157
|
+
|
158
|
+
# From the Unreleased block, keep only sections that have content.
|
159
|
+
# We detect sections as lines starting with '### '. A section has content if there is at least
|
160
|
+
# one non-empty, non-heading line under it before the next '###' or '##'. Typically these are list items.
|
161
|
+
# Returns a string that includes only the non-empty sections with their content.
|
162
|
+
def filter_unreleased_sections(unreleased_block)
|
163
|
+
lines = unreleased_block.lines
|
164
|
+
out = []
|
165
|
+
i = 0
|
166
|
+
while i < lines.length
|
167
|
+
line = lines[i]
|
168
|
+
if line.start_with?("### ")
|
169
|
+
header = line
|
170
|
+
i += 1
|
171
|
+
chunk = []
|
172
|
+
while i < lines.length && !lines[i].start_with?("### ") && !lines[i].start_with?("## ")
|
173
|
+
chunk << lines[i]
|
174
|
+
i += 1
|
175
|
+
end
|
176
|
+
# Determine if chunk has any content (non-blank)
|
177
|
+
content_present = chunk.any? { |l| l.strip != "" }
|
178
|
+
if content_present
|
179
|
+
# Trim trailing blank lines
|
180
|
+
while chunk.any? && chunk.last.strip == ""
|
181
|
+
chunk.pop
|
182
|
+
end
|
183
|
+
out << header
|
184
|
+
out.concat(chunk)
|
185
|
+
out << "\n" unless out.last&.end_with?("\n")
|
186
|
+
end
|
187
|
+
next
|
188
|
+
else
|
189
|
+
# Lines outside sections are ignored for released sections
|
190
|
+
i += 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
out.join
|
194
|
+
end
|
195
|
+
|
196
|
+
def coverage_lines
|
197
|
+
unless File.file?(@coverage_path)
|
198
|
+
warn("Coverage JSON not found at #{@coverage_path}.")
|
199
|
+
warn("Run: K_SOUP_COV_FORMATTERS=\"json\" bin/rspec")
|
200
|
+
return [nil, nil]
|
201
|
+
end
|
202
|
+
data = JSON.parse(File.read(@coverage_path))
|
203
|
+
files = data["coverage"] || {}
|
204
|
+
file_count = 0
|
205
|
+
total_lines = 0
|
206
|
+
covered_lines = 0
|
207
|
+
total_branches = 0
|
208
|
+
covered_branches = 0
|
209
|
+
files.each_value do |h|
|
210
|
+
lines = h["lines"] || []
|
211
|
+
line_relevant = lines.count { |x| x.is_a?(Integer) }
|
212
|
+
line_covered = lines.count { |x| x.is_a?(Integer) && x > 0 }
|
213
|
+
if line_relevant > 0
|
214
|
+
file_count += 1
|
215
|
+
total_lines += line_relevant
|
216
|
+
covered_lines += line_covered
|
217
|
+
end
|
218
|
+
branches = h["branches"] || []
|
219
|
+
branches.each do |b|
|
220
|
+
next unless b.is_a?(Hash)
|
221
|
+
cov = b["coverage"]
|
222
|
+
next unless cov.is_a?(Numeric)
|
223
|
+
total_branches += 1
|
224
|
+
covered_branches += 1 if cov > 0
|
225
|
+
end
|
226
|
+
end
|
227
|
+
line_pct = (total_lines > 0) ? ((covered_lines.to_f / total_lines) * 100.0) : 0.0
|
228
|
+
branch_pct = (total_branches > 0) ? ((covered_branches.to_f / total_branches) * 100.0) : 0.0
|
229
|
+
line_str = format("COVERAGE: %.2f%% -- %d/%d lines in %d files", line_pct, covered_lines, total_lines, file_count)
|
230
|
+
branch_str = format("BRANCH COVERAGE: %.2f%% -- %d/%d branches in %d files", branch_pct, covered_branches, total_branches, file_count)
|
231
|
+
[line_str, branch_str]
|
232
|
+
rescue StandardError => e
|
233
|
+
warn("Failed to parse coverage: #{e.class}: #{e.message}")
|
234
|
+
[nil, nil]
|
235
|
+
end
|
236
|
+
|
237
|
+
def yard_percent_documented
|
238
|
+
cmd = File.join(@root, "bin", "yard")
|
239
|
+
unless File.executable?(cmd)
|
240
|
+
warn("bin/yard not found or not executable; ensure yard is installed via bundler")
|
241
|
+
return
|
242
|
+
end
|
243
|
+
out, _ = Open3.capture2(cmd)
|
244
|
+
# Look for a line containing e.g., "95.35% documented"
|
245
|
+
line = out.lines.find { |l| l =~ /\d+(?:\.\d+)?%\s+documented/ }
|
246
|
+
if line
|
247
|
+
line = line.strip
|
248
|
+
# Return exactly as requested: e.g. "95.35% documented"
|
249
|
+
line
|
250
|
+
else
|
251
|
+
warn("Could not find documented percentage in bin/yard output.")
|
252
|
+
nil
|
253
|
+
end
|
254
|
+
rescue StandardError => e
|
255
|
+
warn("Failed to run bin/yard: #{e.class}: #{e.message}")
|
256
|
+
nil
|
257
|
+
end
|
258
|
+
|
259
|
+
def update_link_refs(content, owner, repo, prev_version, new_version)
|
260
|
+
# Convert any GitLab links to GitHub
|
261
|
+
content = content.gsub(%r{https://gitlab\.com/([^/]+)/([^/]+)/-/compare/([^\.]+)\.\.\.([^\s]+)}) do
|
262
|
+
o = owner || Regexp.last_match(1)
|
263
|
+
r = repo || Regexp.last_match(2)
|
264
|
+
from = Regexp.last_match(3)
|
265
|
+
to = Regexp.last_match(4)
|
266
|
+
"https://github.com/#{o}/#{r}/compare/#{from}...#{to}"
|
267
|
+
end
|
268
|
+
content = content.gsub(%r{https://gitlab\.com/([^/]+)/([^/]+)/-/tags/(v[^\s\]]+)}) do
|
269
|
+
o = owner || Regexp.last_match(1)
|
270
|
+
r = repo || Regexp.last_match(2)
|
271
|
+
tag = Regexp.last_match(3)
|
272
|
+
"https://github.com/#{o}/#{r}/releases/tag/#{tag}"
|
273
|
+
end
|
274
|
+
|
275
|
+
# Append or update the bottom reference links
|
276
|
+
lines = content.lines
|
277
|
+
|
278
|
+
# Find the index of the Unreleased heading; only manipulate refs after this point
|
279
|
+
unreleased_idx = lines.index { |l| l.start_with?("## [Unreleased]") } || -1
|
280
|
+
|
281
|
+
# Find the first link-ref line (e.g., "[Unreleased]: http...") AFTER Unreleased
|
282
|
+
first_ref = nil
|
283
|
+
lines.each_with_index do |l, i|
|
284
|
+
if l =~ /^\[[^\]]+\]:\s+http/ && i > unreleased_idx
|
285
|
+
first_ref = i
|
286
|
+
break
|
287
|
+
end
|
288
|
+
end
|
289
|
+
unless first_ref
|
290
|
+
# Append at end if no ref block after Unreleased
|
291
|
+
first_ref = lines.length
|
292
|
+
lines << "\n"
|
293
|
+
end
|
294
|
+
|
295
|
+
# Ensure Unreleased points to GitHub compare from new tag to HEAD
|
296
|
+
if owner && repo
|
297
|
+
unreleased_ref = "[Unreleased]: https://github.com/#{owner}/#{repo}/compare/v#{new_version}...HEAD\n"
|
298
|
+
# Update an existing Unreleased ref only if it appears after Unreleased heading; otherwise append
|
299
|
+
idx = nil
|
300
|
+
lines.each_with_index do |l, i|
|
301
|
+
if l.start_with?("[Unreleased]:") && i >= first_ref
|
302
|
+
idx = i
|
303
|
+
break
|
304
|
+
end
|
305
|
+
end
|
306
|
+
if idx
|
307
|
+
lines[idx] = unreleased_ref
|
308
|
+
else
|
309
|
+
lines << unreleased_ref
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
if owner && repo
|
314
|
+
# Add compare link for the new version
|
315
|
+
from = prev_version ? "v#{prev_version}" : detect_initial_compare_base(lines)
|
316
|
+
new_compare = "[#{new_version}]: https://github.com/#{owner}/#{repo}/compare/#{from}...v#{new_version}\n"
|
317
|
+
unless lines.any? { |l| l.start_with?("[#{new_version}]:") }
|
318
|
+
lines << new_compare
|
319
|
+
end
|
320
|
+
# Add tag link for the new version
|
321
|
+
new_tag = "[#{new_version}t]: https://github.com/#{owner}/#{repo}/releases/tag/v#{new_version}\n"
|
322
|
+
unless lines.any? { |l| l.start_with?("[#{new_version}t]:") }
|
323
|
+
lines << new_tag
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
# Rebuild and sort the reference block so newest is at the bottom, preserving everything above first_ref
|
328
|
+
ref_lines = lines[first_ref..-1].select { |l| l =~ /^\[[^\]]+\]:\s+http/ }
|
329
|
+
# Deduplicate by key (text inside the square brackets)
|
330
|
+
by_key = {}
|
331
|
+
ref_lines.each do |l|
|
332
|
+
if l =~ /^\[([^\]]+)\]:\s+/
|
333
|
+
by_key[$1] = l
|
334
|
+
end
|
335
|
+
end
|
336
|
+
unreleased_line = by_key.delete("Unreleased")
|
337
|
+
# Separate version compare and tag links
|
338
|
+
compares = {}
|
339
|
+
tags = {}
|
340
|
+
by_key.each do |k, v|
|
341
|
+
if k =~ /^(\d+\.\d+\.\d+)$/
|
342
|
+
compares[$1] = v
|
343
|
+
elsif k =~ /^(\d+\.\d+\.\d+)t$/
|
344
|
+
tags[$1] = v
|
345
|
+
end
|
346
|
+
end
|
347
|
+
# Sort versions ascending so newest at bottom
|
348
|
+
sorted_versions = compares.keys.map { |s| Gem::Version.new(s) }.sort.map(&:to_s)
|
349
|
+
# In case some versions only have tags or only compares, include them as well
|
350
|
+
(tags.keys - compares.keys).each { |s| sorted_versions |= [s] }
|
351
|
+
sorted_versions = sorted_versions.map { |s| Gem::Version.new(s) }.sort.map(&:to_s)
|
352
|
+
|
353
|
+
new_ref_block = []
|
354
|
+
new_ref_block << unreleased_line if unreleased_line
|
355
|
+
sorted_versions.each do |v|
|
356
|
+
new_ref_block << compares[v] if compares[v]
|
357
|
+
new_ref_block << tags[v] if tags[v]
|
358
|
+
end
|
359
|
+
# Replace the old block
|
360
|
+
rebuilt = lines[0...first_ref] + new_ref_block + ["\n"]
|
361
|
+
rebuilt.join
|
362
|
+
end
|
363
|
+
|
364
|
+
def detect_initial_compare_base(lines)
|
365
|
+
# Fallback when prev_version is unknown: try to find the first compare base used historically
|
366
|
+
# e.g., for 1.0.0 it may be a commit SHA instead of a tag
|
367
|
+
ref = lines.find { |l| l =~ /^\[1\.0\.0\]:\s+https:\/\/github\.com\// }
|
368
|
+
if ref && (m = ref.match(%r{compare/([^\.]+)\.\.\.v\d+})).is_a?(MatchData)
|
369
|
+
m[1]
|
370
|
+
else
|
371
|
+
# Default to previous tag name if none found (unlikely to be correct, but better than empty)
|
372
|
+
"HEAD^"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
begin
|
380
|
+
if ARGV.include?("-h") || ARGV.include?("--help")
|
381
|
+
puts <<~USAGE
|
382
|
+
Usage: kettle-changelog
|
383
|
+
|
384
|
+
Generates a new CHANGELOG.md entry for the current version detected from lib/**/version.rb.
|
385
|
+
Moves entries from [Unreleased] into the new section, adds coverage and documentation stats,
|
386
|
+
and updates bottom link references to GitHub style, adding new compare/tag links.
|
387
|
+
|
388
|
+
Prerequisites:
|
389
|
+
- coverage/coverage.json present (run: K_SOUP_COV_FORMATTERS="json" bin/rspec)
|
390
|
+
- yard installed and available via bin/yard
|
391
|
+
USAGE
|
392
|
+
exit(0)
|
393
|
+
end
|
394
|
+
Kettle::Dev::ChangelogCLI.new.run
|
395
|
+
rescue SystemExit
|
396
|
+
raise
|
397
|
+
rescue StandardError => e
|
398
|
+
warn("kettle-changelog: unexpected error: #{e.class}: #{e.message}")
|
399
|
+
warn(e.backtrace.join("\n")) if ENV["DEBUG"]
|
400
|
+
exit(1)
|
401
|
+
end
|
data/exe/kettle-commit-msg
CHANGED
@@ -13,6 +13,8 @@ require "erb"
|
|
13
13
|
|
14
14
|
require "kettle/dev"
|
15
15
|
|
16
|
+
puts "== kettle-commit-msg v#{Kettle::Dev::Version::VERSION} =="
|
17
|
+
|
16
18
|
# ENV variable control (set in .envrc, or .env.local)
|
17
19
|
# BRANCH_RULE_TYPE = jira, or another type of branch rule validation, or false to disable
|
18
20
|
# FOOTER_APPEND = true/false append commit message footer
|
data/exe/kettle-readme-backers
CHANGED
data/exe/kettle-release
CHANGED
@@ -19,13 +19,7 @@ $stdout.sync = true
|
|
19
19
|
# Depending library or project must be using bundler
|
20
20
|
require "bundler/setup"
|
21
21
|
|
22
|
-
|
23
|
-
require "kettle/dev"
|
24
|
-
rescue LoadError => e
|
25
|
-
warn("kettle/dev: failed to load: #{e.message}")
|
26
|
-
warn("Hint: Ensure the host project includes kettle-dev and run bundle install.")
|
27
|
-
exit(1)
|
28
|
-
end
|
22
|
+
require "kettle/dev"
|
29
23
|
|
30
24
|
# Always execute when this file is loaded (e.g., via a Bundler binstub).
|
31
25
|
# Do not guard with __FILE__ == $PROGRAM_NAME because binstubs use Kernel.load.
|
@@ -51,6 +45,7 @@ if ARGV.include?("-h") || ARGV.include?("--help")
|
|
51
45
|
exit 0
|
52
46
|
end
|
53
47
|
|
48
|
+
puts "== kettle-release v#{Kettle::Dev::Version::VERSION} =="
|
54
49
|
begin
|
55
50
|
Kettle::Dev::ReleaseCLI.new.run
|
56
51
|
rescue LoadError => e
|
@@ -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
|