kettle-dev 2.2.9 → 2.2.10
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 +16 -1
- data/README.md +1 -1
- data/lib/kettle/dev/pre_release_cli.rb +113 -0
- data/lib/kettle/dev/version.rb +1 -1
- data/sig/kettle/dev/pre_release_cli.rbs +10 -0
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9216115bc5448b3e08cfcd393c22029d70e7b6d31bcb80617b44b7d97644b649
|
|
4
|
+
data.tar.gz: e86c38ac97fbac63e1258bf15d6454f408e62ffe927af628bc5f7090472f98fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52d369f7c70a48bf3c2fde5898cc7f99ac9eda0b6e09319d7166976e20057d95360a56f29bf00dbd226976a853dd212e915fd31026b7c647df1f68bee6331cd4
|
|
7
|
+
data.tar.gz: 7ab61300d6f489ddc25636e10dcea667998a20c5ef3755a9b7773e2ccb0fde69871c8ba5607303a618501a55c2c05289dc3585905c6243e1ca524a7de1cb7c8a
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,19 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [2.2.10] - 2026-06-16
|
|
34
|
+
|
|
35
|
+
- TAG: [v2.2.10][2.2.10t]
|
|
36
|
+
- COVERAGE: 92.24% -- 3911/4240 lines in 28 files
|
|
37
|
+
- BRANCH COVERAGE: 73.87% -- 1552/2101 branches in 28 files
|
|
38
|
+
- 64.35% documented
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- `kettle-pre-release` now caches successful Markdown image URL validations in
|
|
43
|
+
the global kettle-dev state cache for seven days to avoid repeated network
|
|
44
|
+
HEAD requests during release readiness checks.
|
|
45
|
+
|
|
33
46
|
## [2.2.9] - 2026-06-14
|
|
34
47
|
|
|
35
48
|
- TAG: [v2.2.9][2.2.9t]
|
|
@@ -2126,7 +2139,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
2126
2139
|
- Selecting will run the selected workflow via `act`
|
|
2127
2140
|
- This may move to its own gem in the future.
|
|
2128
2141
|
|
|
2129
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.
|
|
2142
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.10...HEAD
|
|
2143
|
+
[2.2.10]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.9...v2.2.10
|
|
2144
|
+
[2.2.10t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.2.10
|
|
2130
2145
|
[2.2.9]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.8...v2.2.9
|
|
2131
2146
|
[2.2.9t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.2.9
|
|
2132
2147
|
[2.2.8]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.7...v2.2.8
|
data/README.md
CHANGED
|
@@ -854,7 +854,7 @@ Thanks for RTFM. ☺️
|
|
|
854
854
|
[📌gitmoji]: https://gitmoji.dev
|
|
855
855
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
856
856
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
857
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.
|
|
857
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.240-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
858
858
|
[🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
|
|
859
859
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
860
860
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
require "optparse"
|
|
4
4
|
require "English"
|
|
5
|
+
require "json"
|
|
6
|
+
require "fileutils"
|
|
5
7
|
require "uri"
|
|
6
8
|
require "net/http"
|
|
7
9
|
require "openssl"
|
|
10
|
+
require "time"
|
|
8
11
|
begin
|
|
9
12
|
require "addressable/uri"
|
|
10
13
|
rescue LoadError
|
|
@@ -21,6 +24,8 @@ module Kettle
|
|
|
21
24
|
#
|
|
22
25
|
# Usage: Kettle::Dev::PreReleaseCLI.new(check_num: 1).run
|
|
23
26
|
class PreReleaseCLI
|
|
27
|
+
IMAGE_URL_CACHE_TTL_SECONDS = 7 * 24 * 60 * 60
|
|
28
|
+
|
|
24
29
|
# Simple HTTP helpers for link validation
|
|
25
30
|
module HTTP
|
|
26
31
|
module_function
|
|
@@ -93,6 +98,85 @@ module Kettle
|
|
|
93
98
|
end
|
|
94
99
|
end
|
|
95
100
|
|
|
101
|
+
# Persistent cache of successfully validated Markdown image URLs.
|
|
102
|
+
class ImageUrlCache
|
|
103
|
+
VERSION = 1
|
|
104
|
+
|
|
105
|
+
def self.default_path
|
|
106
|
+
state_home = ENV["XDG_STATE_HOME"]
|
|
107
|
+
state_home = File.join(Dir.home, ".local", "state") if state_home.to_s.empty?
|
|
108
|
+
File.join(state_home, "kettle-dev", "image-url-cache.json")
|
|
109
|
+
rescue ArgumentError
|
|
110
|
+
nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def initialize(path:, ttl_seconds: IMAGE_URL_CACHE_TTL_SECONDS, clock: -> { Time.now })
|
|
114
|
+
@path = path
|
|
115
|
+
@ttl_seconds = ttl_seconds
|
|
116
|
+
@clock = clock
|
|
117
|
+
@data = nil
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def fresh_success?(url)
|
|
121
|
+
entry = data.fetch("images")[url.to_s]
|
|
122
|
+
return false unless entry.is_a?(Hash)
|
|
123
|
+
return false unless entry["ok"] == true
|
|
124
|
+
|
|
125
|
+
fresh_entry?(entry)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def write_success(url)
|
|
129
|
+
return if @path.to_s.empty?
|
|
130
|
+
return if url.to_s.empty?
|
|
131
|
+
|
|
132
|
+
data.fetch("images")[url.to_s] = {
|
|
133
|
+
"ok" => true,
|
|
134
|
+
"cached_at" => @clock.call.utc.iso8601
|
|
135
|
+
}
|
|
136
|
+
save!
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def to_h
|
|
140
|
+
data
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
private
|
|
144
|
+
|
|
145
|
+
def data
|
|
146
|
+
@data ||= load_data
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def load_data
|
|
150
|
+
parsed = if @path && File.file?(@path)
|
|
151
|
+
JSON.parse(File.read(@path))
|
|
152
|
+
end
|
|
153
|
+
return empty_data unless parsed.is_a?(Hash)
|
|
154
|
+
return empty_data unless parsed["version"].to_i == VERSION
|
|
155
|
+
|
|
156
|
+
parsed["version"] ||= VERSION
|
|
157
|
+
parsed["images"] = {} unless parsed["images"].is_a?(Hash)
|
|
158
|
+
parsed
|
|
159
|
+
rescue JSON::ParserError, Errno::EACCES
|
|
160
|
+
empty_data
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def empty_data
|
|
164
|
+
{"version" => VERSION, "images" => {}}
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def save!
|
|
168
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
|
169
|
+
File.write(@path, JSON.pretty_generate(data) + "\n")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def fresh_entry?(entry)
|
|
173
|
+
cached_at = Time.iso8601(entry["cached_at"].to_s)
|
|
174
|
+
cached_at >= @clock.call - @ttl_seconds
|
|
175
|
+
rescue ArgumentError
|
|
176
|
+
false
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
96
180
|
# Markdown parsing helpers
|
|
97
181
|
module Markdown
|
|
98
182
|
module_function
|
|
@@ -184,6 +268,8 @@ module Kettle
|
|
|
184
268
|
def initialize(check_num: 1)
|
|
185
269
|
@check_num = (check_num || 1).to_i
|
|
186
270
|
@check_num = 1 if @check_num < 1
|
|
271
|
+
@image_url_cache_path = configured_image_url_cache_path
|
|
272
|
+
@refresh_image_url_cache = env_truthy?(ENV["KETTLE_IMAGE_URL_CACHE_REFRESH"])
|
|
187
273
|
end
|
|
188
274
|
|
|
189
275
|
# Execute configured checks starting from @check_num.
|
|
@@ -272,12 +358,19 @@ module Kettle
|
|
|
272
358
|
puts "[kettle-pre-release] Check 3: Validate Markdown image links (HTTP HEAD)"
|
|
273
359
|
urls = Markdown.extract_image_urls_from_files
|
|
274
360
|
puts "[kettle-pre-release] Found #{urls.size} unique image URL(s)."
|
|
361
|
+
cache = image_url_cache
|
|
275
362
|
failures = []
|
|
276
363
|
urls.each do |url|
|
|
277
364
|
print(" -> #{url} … ")
|
|
365
|
+
if cache && !@refresh_image_url_cache && cache.fresh_success?(url)
|
|
366
|
+
puts "OK (cached)"
|
|
367
|
+
next
|
|
368
|
+
end
|
|
369
|
+
|
|
278
370
|
ok = HTTP.head_ok?(url)
|
|
279
371
|
if ok
|
|
280
372
|
puts "OK"
|
|
373
|
+
cache&.write_success(url)
|
|
281
374
|
else
|
|
282
375
|
puts "FAIL"
|
|
283
376
|
failures << url
|
|
@@ -292,6 +385,26 @@ module Kettle
|
|
|
292
385
|
end
|
|
293
386
|
nil
|
|
294
387
|
end
|
|
388
|
+
|
|
389
|
+
private
|
|
390
|
+
|
|
391
|
+
def image_url_cache
|
|
392
|
+
return nil if @image_url_cache_path.to_s.empty?
|
|
393
|
+
|
|
394
|
+
@image_url_cache ||= ImageUrlCache.new(path: @image_url_cache_path)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def configured_image_url_cache_path
|
|
398
|
+
value = ENV.fetch("KETTLE_IMAGE_URL_CACHE", nil)
|
|
399
|
+
return ImageUrlCache.default_path if value.nil? || value.to_s.strip.empty?
|
|
400
|
+
return nil if value.to_s.strip.match?(Kettle::Dev::ENV_FALSE_RE)
|
|
401
|
+
|
|
402
|
+
value
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def env_truthy?(value)
|
|
406
|
+
!!value.to_s.strip.match?(/\A(true|y|yes|1|on)\z/i)
|
|
407
|
+
end
|
|
295
408
|
end
|
|
296
409
|
end
|
|
297
410
|
end
|
data/lib/kettle/dev/version.rb
CHANGED
|
@@ -11,6 +11,16 @@ module Kettle
|
|
|
11
11
|
def self.extract_image_urls_from_files: (?String glob_pattern) -> Array[String]
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
class ImageUrlCache
|
|
15
|
+
VERSION: Integer
|
|
16
|
+
|
|
17
|
+
def self.default_path: () -> String?
|
|
18
|
+
def initialize: (path: String?, ?ttl_seconds: Integer, ?clock: ^() -> Time) -> void
|
|
19
|
+
def fresh_success?: (String url) -> bool
|
|
20
|
+
def write_success: (String url) -> void
|
|
21
|
+
def to_h: () -> Hash[String, untyped]
|
|
22
|
+
end
|
|
23
|
+
|
|
14
24
|
def initialize: (?check_num: Integer) -> void
|
|
15
25
|
def run: () -> void
|
|
16
26
|
def check_markdown_uri_normalization!: () -> void
|
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: 2.2.
|
|
4
|
+
version: 2.2.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -338,10 +338,10 @@ licenses:
|
|
|
338
338
|
- AGPL-3.0-only
|
|
339
339
|
metadata:
|
|
340
340
|
homepage_uri: https://kettle-dev.galtzo.com
|
|
341
|
-
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.2.
|
|
342
|
-
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.2.
|
|
341
|
+
source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.2.10
|
|
342
|
+
changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.2.10/CHANGELOG.md
|
|
343
343
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
|
|
344
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.2.
|
|
344
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.2.10
|
|
345
345
|
funding_uri: https://github.com/sponsors/pboling
|
|
346
346
|
wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
|
|
347
347
|
news_uri: https://www.railsbling.com/tags/kettle-dev
|
metadata.gz.sig
CHANGED
|
Binary file
|