kettle-dev 3.1.14 → 3.1.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f91c0c4ef8cfb88983835109c778d084a739a78ed4cfc83318be404cd2ba9eee
4
- data.tar.gz: c16964dc845379bc31fa3106af5567d950d00a2a2741bb79e50f816235420f41
3
+ metadata.gz: 16802c87427ef8443571014a94b2d7720f246f01ea22cf2821b2b9598f4b804b
4
+ data.tar.gz: 9ced61074b0241db2b225d5bbbe6d3c1e359a16e587a949e47339a4b8a65f144
5
5
  SHA512:
6
- metadata.gz: 7b9d783784e66864cd733aa63abdfb15161b93224b81bd8d5db9a2a2dc71cd3ca45ef1bd87f389895b9ef3e78d2d7c3432b4ea78ef176e70c3e6936eac9e5ce7
7
- data.tar.gz: a7fb4dedb0aeb325ffca2a717e0700ae2d37a73ef38bde1006bfd5b8926bf6b6d9ebedefbe45400ba885c1aaa523db229854b6a0f0174a42ca0229ce5b47d925
6
+ metadata.gz: 78fab6bbe0cca35be2a872350840b9bcbdc907bbd697ba245c5a47e406790bc72663161bd42518268386bf7df7c8e50900f31ddae2b4b2818670b259db7a7aee
7
+ data.tar.gz: 6f2fc6046be6343e41ce2b917f274b0f6e726a145a09c6273bace66ecf525fee5567bb3ea4a25cce9fa344e9061e1f6d6cc7327efa8946804191eac783aee588
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,32 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [3.1.16] - 2026-10-18
34
+
35
+ - TAG: [v3.1.16][3.1.16t]
36
+ - COVERAGE: 91.33% -- 5728/6272 lines in 48 files
37
+ - BRANCH COVERAGE: 75.41% -- 2202/2920 branches in 48 files
38
+ - 53.60% documented
39
+
40
+ ### Fixed
41
+
42
+ - kettle-release surfaces spec failures instead of a bare exit status: kettle-changelog commands now stream output while retaining the last 30 lines, and a failure abort appends an OUTPUT tail, so a failed coverage suite reads as a spec failure in the release summary. BundlerPinning.installed_stable also reads bundler gemspecs from disk under every Gem.path: under bundle exec the spec index is scoped to the active bundle, so a lockfile that pinned a prerelease bundler (4.1.0.betaN) hid every stable version and broke update-bundler/bupb and normalize lockfiles.
43
+
44
+ ## [3.1.15] - 2026-10-16
45
+
46
+ - TAG: [v3.1.15][3.1.15t]
47
+ - COVERAGE: 91.74% -- 5733/6249 lines in 48 files
48
+ - BRANCH COVERAGE: 75.88% -- 2209/2911 branches in 48 files
49
+ - 53.60% documented
50
+
51
+ ### Added
52
+
53
+ - RubyGemsVersions confirm reads: fetch and published_version_numbers accept confirm: true for answers feeding destructive or commit-producing decisions — the registry is always contacted, revalidation rides the cached entrys ETag/Last-Modified (a 304 re-arms the TTL without rewriting the payload, even past expiry), and an unconfirmable answer returns nil instead of the stale entry
54
+
55
+ - kettle-release step 1 now pins release lockfiles to the newest STABLE Bundler the registry serves instead of the executing Bundler: when the registry is newer it installs that version (rubygems.org only, prereleases excluded) and runs the bundler update under it, so BUNDLED WITH stops drifting behind CI images; a registry outage fails open to the executing Bundler
56
+
57
+ - New Kettle::Dev::BundlerPinning module: shared stable-Bundler resolution (installed_stable, published_stable, install_stable, ensure_latest_stable, update_argv) so kettle-release step 1 and kettle-family bupb/update-bundler can share one implementation instead of divergent copies; kettle-release now delegates to it
58
+
33
59
  ## [3.1.14] - 2026-10-16
34
60
 
35
61
  - TAG: [v3.1.14][3.1.14t]
@@ -4130,7 +4156,11 @@ Please file a bug if you notice a violation of semantic versioning.
4130
4156
  - Selecting will run the selected workflow via `act`
4131
4157
  - This may move to its own gem in the future.
4132
4158
 
4133
- [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.14...HEAD
4159
+ [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.16...HEAD
4160
+ [3.1.16]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.15...v3.1.16
4161
+ [3.1.16t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.1.16
4162
+ [3.1.15]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.14...v3.1.15
4163
+ [3.1.15t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.1.15
4134
4164
  [3.1.14]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.13...v3.1.14
4135
4165
  [3.1.14t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.1.14
4136
4166
  [3.1.13]: https://github.com/kettle-dev/kettle-dev/compare/v3.1.12...v3.1.13
data/README.md CHANGED
@@ -1084,7 +1084,7 @@ Thanks for RTFM. ☺️
1084
1084
  [📌gitmoji]: https://gitmoji.dev
1085
1085
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1086
1086
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1087
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.177-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1087
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.272-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1088
1088
  [🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
1089
1089
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1090
1090
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler"
4
+ require "rubygems/dependency_installer"
5
+
6
+ module Kettle
7
+ module Dev
8
+ # Shared Bundler version resolution and maintenance for the release
9
+ # toolchain. Both kettle-release (release prep pins BUNDLED WITH) and
10
+ # kettle-family (bupb / update-bundler pin every member lockfile) need the
11
+ # same three answers — what stable Bundler is installed, what stable
12
+ # Bundler the registry serves, and how to install/pin one — and divergent
13
+ # copies are how lockfiles drifted behind CI images.
14
+ #
15
+ # Every lookup rejects prereleases: bundler betas ship as "latest" and a
16
+ # beta in BUNDLED WITH reinfects every child that boots the bundle.
17
+ module BundlerPinning
18
+ RUBYGEMS_SOURCE = "https://rubygems.org"
19
+
20
+ module_function
21
+
22
+ # Newest stable Bundler installed locally. Consults BOTH sources —
23
+ # the activated spec and every installed spec — because bundler/setup
24
+ # scoping can hide one from the other depending on how the process booted.
25
+ #
26
+ # The spec index itself is not enough: under `bundle exec`, Bundler
27
+ # replaces the index with the ACTIVE BUNDLE's specs, so a lockfile that
28
+ # pinned a prerelease (the 4.1.0.betaN reinfection vector) makes this
29
+ # lookup see only that prerelease and wrongly report "no stable bundler".
30
+ # The gemspec files on disk are read directly from every Gem.path to
31
+ # escape that scoping.
32
+ def installed_stable
33
+ active = Gem.loaded_specs["bundler"]&.version
34
+ versions = Gem::Specification.find_all_by_name("bundler").map(&:version)
35
+ Array(Gem.path).each do |base|
36
+ Dir.glob(File.join(base, "specifications", "bundler-*.gemspec")).each do |path|
37
+ begin
38
+ versions << Gem::Version.new(File.basename(path, ".gemspec").delete_prefix("bundler-"))
39
+ rescue ArgumentError
40
+ nil
41
+ end
42
+ end
43
+ end
44
+ versions.push(active) if active
45
+ versions.reject(&:prerelease?).max
46
+ end
47
+
48
+ # Newest stable Bundler the registry serves; nil when the registry
49
+ # cannot be consulted, so callers can fail open to local state.
50
+ def published_stable
51
+ numbers = Kettle::Dev::RubyGemsVersions.published_version_numbers("bundler")
52
+ return nil unless numbers
53
+
54
+ numbers.filter_map { |number| published_candidate(number) }.max
55
+ end
56
+
57
+ # Install a stable Bundler — the exact version given, or the latest
58
+ # stable when nil. rubygems.org only, never prereleases, and a spec
59
+ # reset so the just-installed version is visible to later gem lookups
60
+ # in this process. Returns the installed specs.
61
+ def install_stable(version = nil)
62
+ original_sources = Gem.sources.to_a
63
+ Gem.sources = [RUBYGEMS_SOURCE]
64
+ requirements = version ? ["= #{version}"] : []
65
+ specs = Gem::DependencyInstaller.new(domain: :remote, prerelease: false, document: []).install("bundler", *requirements)
66
+ Gem::Specification.reset
67
+ specs
68
+ ensure
69
+ Gem.sources = original_sources if original_sources
70
+ end
71
+
72
+ # The version a release should pin BUNDLED WITH to: the registry's
73
+ # newest stable, installing it first when the executing Bundler lags.
74
+ # A registry outage fails open to the executing Bundler rather than
75
+ # blocking the release.
76
+ def ensure_latest_stable(executing: Bundler::VERSION)
77
+ current = Gem::Version.new(executing)
78
+ latest = published_stable
79
+ return current.to_s if latest.nil? || latest <= current
80
+
81
+ install_stable(latest)
82
+ latest.to_s
83
+ end
84
+
85
+ # Pinned argv for a bundler-update spawn. A bare `--bundler` lets
86
+ # RubyGems resolve the newest bundler INCLUDING prereleases (the
87
+ # recurring 4.1.0.betaN infection vector), so the version is pinned on
88
+ # both the executable selector and the flag.
89
+ def update_argv(version, extra_gems: [])
90
+ ["bundle", "_#{version}_", "update", *extra_gems, "--bundler=#{version}"]
91
+ end
92
+
93
+ def published_candidate(number)
94
+ candidate = Gem::Version.new(number)
95
+ candidate unless candidate.prerelease?
96
+ rescue ArgumentError
97
+ nil
98
+ end
99
+ end
100
+ end
101
+ end
@@ -91,8 +91,20 @@ module Kettle
91
91
  # so they inherit the current TTY and can read the user's input.
92
92
  interactive_words = effective_command_words(cmd)
93
93
  interactive = interactive_words.first(4) == ["bundle", "exec", "rake", "release"] ||
94
- interactive_words.first(2) == ["gem", "push"] ||
95
- interactive_words.first(2) == ["bundle", "exec"] && interactive_words[2] == "kettle-changelog"
94
+ interactive_words.first(2) == ["gem", "push"]
95
+ if interactive_words.first(3) == ["bundle", "exec", "kettle-changelog"]
96
+ # kettle-changelog runs the test suite for coverage data; when that
97
+ # suite fails, the spec summary must surface in the abort message,
98
+ # not just the exit status. Stream output (so the release log keeps
99
+ # its live tail) while retaining the last lines for diagnostics.
100
+ # With --yes the child never reads stdin, so a pipe is safe here.
101
+ ok, diag = stream_with_capture(env_hash, cmd)
102
+ unless ok
103
+ exit_code = $?.respond_to?(:exitstatus) ? $?.exitstatus : 1
104
+ Kettle::Dev::ExitAdapter.abort("Command failed: #{cmd} (exit #{exit_code})#{diag}")
105
+ end
106
+ return
107
+ end
96
108
  if interactive
97
109
  ok = system(env_hash, cmd)
98
110
  unless ok
@@ -124,6 +136,28 @@ module Kettle
124
136
 
125
137
  private
126
138
 
139
+ # Runs cmd with output streamed to $stdout (preserving the live release
140
+ # log tail) while retaining the last `tail_lines` lines. Returns
141
+ # [success, diagnostic] where diagnostic is an empty string on success
142
+ # and a formatted output tail on failure, mirroring the STDERR tail the
143
+ # non-interactive path appends to its abort message.
144
+ def stream_with_capture(env_hash, cmd, tail_lines: 30)
145
+ recent = []
146
+ success = Open3.popen2e(env_hash, cmd) do |_stdin, output, thread|
147
+ output.each_line do |line|
148
+ $stdout.print(line)
149
+ recent << line
150
+ recent.shift while recent.length > tail_lines
151
+ end
152
+ thread.value.success?
153
+ end
154
+ diag = ""
155
+ if !success && recent.any?
156
+ diag = "\n--- OUTPUT (last #{tail_lines} lines) ---\n#{recent.join}".rstrip
157
+ end
158
+ [success, diag]
159
+ end
160
+
127
161
  def command_env
128
162
  env_hash = ENV.respond_to?(:to_hash) ? ENV.to_hash : ENV.to_h
129
163
  return env_hash if debug_env_enabled?
@@ -1891,23 +1925,30 @@ module Kettle
1891
1925
  end
1892
1926
  end
1893
1927
 
1928
+ # The release must pin BUNDLED WITH to the newest stable Bundler the
1929
+ # registry serves; BundlerPinning installs it first when the executing
1930
+ # Bundler lags and fails open to the executing Bundler on a registry
1931
+ # outage. kettle-family's bupb/update-bundler delegate to the same
1932
+ # module once the floor reaches the version shipping it.
1933
+ def ensure_latest_stable_bundler!
1934
+ Kettle::Dev::BundlerPinning.ensure_latest_stable
1935
+ end
1936
+
1894
1937
  # Keep Bundler maintenance separate from the release metadata commit.
1895
1938
  # The project lockfiles are shared development state, so the update must
1896
1939
  # be real and committed rather than hidden behind a temporary lockfile.
1897
1940
  #
1898
- # The version is pinned to the Bundler actually executing rather than left
1899
- # bare. `bundle update --bundler` resolves to whatever RubyGems reports as
1900
- # bundler's "latest", which includes prereleases: bundler published
1901
- # 4.1.0.beta1 as latest, so a bare update installed the beta and rewrote
1902
- # BUNDLED WITH to it. That beta vendors its own copy of rubygems' URI
1903
- # constants, and loading it against rubygems' copy emits a wall of
1904
- # "already initialized constant Gem::URI::..." warnings on stderr, which
1905
- # broke any spec shelling out to the executable and asserting clean stderr
1906
- # — failing a later release at its coverage step. Pinning matches
1907
- # LockfileReset#lockfile_command, which already documents this hazard.
1941
+ # The version is pinned to the newest STABLE Bundler the registry
1942
+ # serves, not whatever is executing: a bare `bundle update --bundler`
1943
+ # resolves "latest" including prereleases (bundler 4.1.0.beta1 shipped
1944
+ # as latest and its vendored rubygems URI constants broke specs
1945
+ # asserting clean stderr), while pinning to the executing Bundler
1946
+ # quietly re-records a stale BUNDLED WITH whenever the releasing
1947
+ # machine lags the registry — and CI images carrying a newer default
1948
+ # Bundler then drift from the committed lockfile.
1908
1949
  def update_bundler_and_commit!
1909
- bundler_version = Shellwords.escape(Bundler::VERSION)
1910
- run_cmd!(release_project_command("bundle update --bundler=#{bundler_version}"))
1950
+ bundler_version = Shellwords.escape(ensure_latest_stable_bundler!)
1951
+ run_cmd!(release_project_command("bundle _#{bundler_version}_ update --bundler=#{bundler_version}"))
1911
1952
 
1912
1953
  appraisal_gemfile = File.join(@root, "Appraisal.root.gemfile")
1913
1954
  if File.file?(appraisal_gemfile)
@@ -1923,7 +1964,7 @@ module Kettle
1923
1964
  unless File.file?(appraisal_lockfile)
1924
1965
  run_cmd!(release_project_command("#{appraisal_env} bundle install"))
1925
1966
  end
1926
- appraisal_command = "#{appraisal_env} bundle update --bundler=#{bundler_version}"
1967
+ appraisal_command = "#{appraisal_env} bundle _#{bundler_version}_ update --bundler=#{bundler_version}"
1927
1968
  run_cmd!(release_project_command(appraisal_command))
1928
1969
  run_cmd!(release_project_command("bundle exec rake appraisal:reset"))
1929
1970
  end
@@ -70,11 +70,21 @@ module Kettle
70
70
  # such as gem.coop can lag rubygems.org: a version present on one may
71
71
  # be absent from the other. Cache entries are keyed by source for the
72
72
  # same reason, so the two registries cannot poison each other.
73
- def fetch(gem_name, version_hint: nil, refresh: false, source: DEFAULT_SOURCE)
73
+ #
74
+ # +confirm: true+ is the consequence-based read: the answer feeds a
75
+ # destructive or commit-producing decision (uninstalling a gem,
76
+ # resetting a lockfile), so the TTL'd cache is never trusted on its
77
+ # own. The registry is always contacted, but revalidation is cheap:
78
+ # the cached entry's ETag/Last-Modified go out as conditional headers
79
+ # and a 304 re-arms the cached answer instead of replacing it. When
80
+ # the network cannot confirm freshness, +nil+ is returned — never the
81
+ # stale entry — because a destructive caller must read that as
82
+ # "unknown", and absence is the dangerous answer to get wrong.
83
+ def fetch(gem_name, version_hint: nil, refresh: false, source: DEFAULT_SOURCE, confirm: false)
74
84
  name = gem_name.to_s
75
85
  key = cache_key(name, source)
76
86
  cached = cached_versions(key)
77
- cache_bust = refresh || env_refresh? || fresh_release_marker?(name, version_hint) || cached_behind_version?(cached, version_hint)
87
+ cache_bust = refresh || confirm || env_refresh? || fresh_release_marker?(name, version_hint) || cached_behind_version?(cached, version_hint)
78
88
  return cached if cached && !cache_bust
79
89
 
80
90
  uri = versions_uri(gem_name, source: source, cache_bust: cache_bust)
@@ -82,6 +92,9 @@ module Kettle
82
92
  if cache_bust
83
93
  request["Cache-Control"] = "no-cache"
84
94
  request["Pragma"] = "no-cache"
95
+ validators = cache_validators(key)
96
+ request["If-None-Match"] = validators["etag"] if validators["etag"]
97
+ request["If-Modified-Since"] = validators["last_modified"] if validators["last_modified"]
85
98
  end
86
99
  response = Net::HTTP.start(
87
100
  uri.host,
@@ -92,16 +105,28 @@ module Kettle
92
105
  ) do |http|
93
106
  http.request(request)
94
107
  end
108
+ if response.is_a?(Net::HTTPNotModified)
109
+ stored = stored_entry(key)
110
+ if stored
111
+ rearm_versions(key)
112
+ return Array(stored["entries"])
113
+ end
114
+ end
95
115
  if response.code.to_i == 404
96
116
  write_versions(key, [])
97
117
  return []
98
118
  end
99
- return cached unless response.is_a?(Net::HTTPSuccess)
119
+ unless response.is_a?(Net::HTTPSuccess)
120
+ return nil if confirm
121
+
122
+ return cached
123
+ end
100
124
 
101
125
  data = JSON.parse(response.body)
102
- write_versions(key, data) if data.is_a?(Array)
126
+ write_versions(key, data, etag: response["etag"], last_modified: response["last-modified"]) if data.is_a?(Array)
103
127
  data
104
128
  rescue => error
129
+ return nil if confirm
105
130
  return cached if cached
106
131
 
107
132
  raise error
@@ -121,8 +146,12 @@ module Kettle
121
146
  # within the marker TTL. Without it a caller cannot tell "this version
122
147
  # was published moments ago in this very run" from "this gem was
123
148
  # released at some point in the last month".
124
- def published_version_numbers(gem_name, source: DEFAULT_SOURCE, version: nil)
125
- versions = fetch(gem_name, version_hint: version, source: normalize_source(source))
149
+ # +confirm: true+ marks the read as feeding a destructive or
150
+ # commit-producing decision; it always revalidates against the
151
+ # registry (cheaply, via the cached entry's validators) and returns
152
+ # nil when freshness cannot be confirmed.
153
+ def published_version_numbers(gem_name, source: DEFAULT_SOURCE, version: nil, confirm: false)
154
+ versions = fetch(gem_name, version_hint: version, source: normalize_source(source), confirm: confirm)
126
155
  return nil if versions.nil?
127
156
 
128
157
  versions.filter_map { |entry| entry["number"] if entry.is_a?(Hash) }
@@ -246,26 +275,69 @@ module Kettle
246
275
  end
247
276
 
248
277
  def cached_versions(cache_key)
278
+ entry = cached_entry(cache_key)
279
+ return nil unless entry
280
+
281
+ Array(entry["entries"])
282
+ end
283
+
284
+ # Validators from the last successful fetch, sent as conditional
285
+ # headers on revalidation so a 304 can confirm freshness cheaply.
286
+ # Deliberately TTL-agnostic: an expired entry's validators still prove
287
+ # payload currency when the server answers 304, which is the entire
288
+ # point of carrying them.
289
+ def cache_validators(cache_key)
290
+ entry = stored_entry(cache_key)
291
+ return {} unless entry
292
+
293
+ {"etag" => entry["etag"], "last_modified" => entry["last_modified"]}.compact
294
+ end
295
+
296
+ def cached_entry(cache_key)
297
+ entry = stored_entry(cache_key)
298
+ return nil unless entry
299
+ return nil unless fresh_version_cache_entry?(entry)
300
+
301
+ entry
302
+ end
303
+
304
+ def stored_entry(cache_key)
249
305
  path = version_cache_path
250
306
  return nil if path.empty?
251
307
 
252
308
  entry = read_version_cache(path).fetch("versions", {})[cache_key]
253
- return nil unless entry.is_a?(Hash)
254
- return nil unless fresh_version_cache_entry?(entry)
309
+ entry.is_a?(Hash) ? entry : nil
310
+ end
255
311
 
256
- Array(entry["entries"])
312
+ # A 304 means the cached payload is still current; re-arming the TTL
313
+ # without rewriting the payload keeps the entry valid for TTL reads.
314
+ def rearm_versions(cache_key)
315
+ path = version_cache_path
316
+ return if path.empty?
317
+
318
+ data = read_version_cache(path)
319
+ entry = data.fetch("versions", {})[cache_key]
320
+ return unless entry.is_a?(Hash)
321
+
322
+ entry["cached_at"] = Time.now.utc.iso8601
323
+ File.write(path, JSON.pretty_generate(data) << "\n")
324
+ rescue => error
325
+ warn("[kettle-dev] could not re-arm RubyGems version cache: #{error.class}: #{error.message}") if Kettle::Dev::DEBUGGING
257
326
  end
258
327
 
259
- def write_versions(cache_key, entries)
328
+ def write_versions(cache_key, entries, etag: nil, last_modified: nil)
260
329
  path = version_cache_path
261
330
  return if path.empty?
262
331
 
263
332
  data = read_version_cache(path)
264
333
  data["versions"] ||= {}
265
- data["versions"][cache_key] = {
334
+ entry = {
266
335
  "cached_at" => Time.now.utc.iso8601,
267
336
  "entries" => entries
268
337
  }
338
+ entry["etag"] = etag if etag
339
+ entry["last_modified"] = last_modified if last_modified
340
+ data["versions"][cache_key] = entry
269
341
  FileUtils.mkdir_p(File.dirname(path))
270
342
  File.write(path, JSON.pretty_generate(data) << "\n")
271
343
  rescue => error
@@ -5,7 +5,7 @@ module Kettle
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = "3.1.14"
8
+ VERSION = "3.1.16"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
data/lib/kettle/dev.rb CHANGED
@@ -30,6 +30,7 @@ module Kettle
30
30
  autoload :ChangelogEntryAdder, "kettle/dev/changelog_entry_adder"
31
31
  autoload :BumpCLI, "kettle/dev/bump_cli"
32
32
  autoload :BundlerEnvGuard, "kettle/dev/bundler_env_guard"
33
+ autoload :BundlerPinning, "kettle/dev/bundler_pinning"
33
34
  autoload :CIHelpers, "kettle/dev/ci_helpers"
34
35
  autoload :CIMonitor, "kettle/dev/ci_monitor"
35
36
  autoload :CommitMsg, "kettle/dev/commit_msg"
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kettle-dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.14
4
+ version: 3.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -371,6 +371,7 @@ files:
371
371
  - lib/kettle/dev.rb
372
372
  - lib/kettle/dev/bump_cli.rb
373
373
  - lib/kettle/dev/bundler_env_guard.rb
374
+ - lib/kettle/dev/bundler_pinning.rb
374
375
  - lib/kettle/dev/cache_progress.rb
375
376
  - lib/kettle/dev/changelog_cli.rb
376
377
  - lib/kettle/dev/changelog_entry_adder.rb
@@ -422,10 +423,10 @@ licenses:
422
423
  - AGPL-3.0-only
423
424
  metadata:
424
425
  homepage_uri: https://kettle-dev.galtzo.com
425
- source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.1.14
426
- changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.1.14/CHANGELOG.md
426
+ source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.1.16
427
+ changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.1.16/CHANGELOG.md
427
428
  bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
428
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.1.14
429
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.1.16
429
430
  funding_uri: https://github.com/sponsors/pboling
430
431
  wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
431
432
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
@@ -1,4 +1,6 @@
1
- ��)���3? }�n$��L����T���B��´��&@�ع�՝�qox��3eyg��l�9~�.�g�n�/*�?gf�a�����]��|�VЏB+�5��",�C(��� �1!.o&��L��w9�Xl#
2
- �i��Uѐ�nn֟�
3
- gt� ���xB�*��C�۾�WV��C���dY�LזX���$
4
- �C��P��9�T���3sW�c`5���7�@�݀�f�pJ�v�D09&@��@I� e7�ɢ�-"g�d^d@Ѝ5�'�4���-�"���EU]+���[�+�gmq��t7�w�F��Zs�-�n�h����<fu1�"���{�~=���R � ���j� �� p )�W�LI�4��6�����u
1
+ fA�J &쨞��/�4�C(gZ��?o��u��%yT��g �Ç�Zyo�i1�������ȬҚ�IU���
2
+ �T�mc4�>୴V;<����DR*j��d�)i�}
3
+ �d�{�������L[��6�_�F��ļ$@
4
+ �B�ᣡk���vqa�Z(�IU������l>���Z*�?ң�N���{']���!'���N�p�ٚ�t��@IϪ�I�0�P��lA� �'���̴e���� �D��e3������$|DvA��Qqj�� �R�����=K*&��s��-x��
5
+ o
6
+ hP��& �i�dw����$"�t��0��W����ՠ�B�^��ץ-I<�~l�B6�7{ �