kettle-family 1.0.4 → 1.0.5
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 +22 -1
- data/README.md +1 -1
- data/lib/kettle/family/command_result.rb +8 -2
- data/lib/kettle/family/command_runner.rb +2 -1
- data/lib/kettle/family/release_state_check.rb +45 -26
- data/lib/kettle/family/report.rb +30 -1
- data/lib/kettle/family/version.rb +1 -1
- data/lib/kettle/family/workflow.rb +82 -0
- data.tar.gz.sig +2 -2
- metadata +9 -9
- 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: fceb2fadcbbc93ac056bf4a56e6efc3b628a5891c094af2fdf626886ea211acb
|
|
4
|
+
data.tar.gz: a3b0a7d51a2fc8d3c6ef63209fff25912f8d144d223de52d2649c2144c58c5e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0fbc13bfb0ed888c274d07cb7f59dacecb9aeeb0ef22fe6dcaf0e15632450d910000f6dc25dcacf1dc5bae5c603115073a0b48209c427a45508de40ecd2ba17
|
|
7
|
+
data.tar.gz: c684031130496ae7a414b4411fb62934bbdd6610f0f64cc27645b9074db07b03c7be05ab71aa033a1b5ecd19724e9601e6197c1c543b6bcaec2ee7b3ba93b84a
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,25 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [1.0.5] - 2026-07-23
|
|
34
|
+
|
|
35
|
+
- TAG: [v1.0.5][1.0.5t]
|
|
36
|
+
- COVERAGE: 94.41% -- 2772/2936 lines in 24 files
|
|
37
|
+
- BRANCH COVERAGE: 76.59% -- 978/1277 branches in 24 files
|
|
38
|
+
- 29.23% documented
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Family releases now retry `bundle update` for dependent members after
|
|
43
|
+
wave-aware dependency floor bumps, and reject empty lockfile checksum entries
|
|
44
|
+
for the just-published gems, so a registry version endpoint becoming visible
|
|
45
|
+
before Bundler's dependency index no longer breaks the next publish.
|
|
46
|
+
- Failed interactive release results now summarize streamed command output
|
|
47
|
+
instead of replaying the full child-process transcript in the final report.
|
|
48
|
+
- `kettle-family state` now reports per-gem release-state rows for monorepos
|
|
49
|
+
that use a shared root changelog, while still preferring member-local
|
|
50
|
+
changelogs when present and retaining branch-stack release-state output.
|
|
51
|
+
|
|
33
52
|
## [1.0.4] - 2026-07-21
|
|
34
53
|
|
|
35
54
|
- TAG: [v1.0.4][1.0.4t]
|
|
@@ -859,7 +878,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
859
878
|
- Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
|
|
860
879
|
- Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
|
|
861
880
|
|
|
862
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.0.
|
|
881
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.0.5...HEAD
|
|
882
|
+
[1.0.5]: https://github.com/kettle-dev/kettle-family/compare/v1.0.4...v1.0.5
|
|
883
|
+
[1.0.5t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.0.5
|
|
863
884
|
[1.0.4]: https://github.com/kettle-dev/kettle-family/compare/v1.0.3...v1.0.4
|
|
864
885
|
[1.0.4t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.0.4
|
|
865
886
|
[1.0.3]: https://github.com/kettle-dev/kettle-family/compare/v1.0.2...v1.0.3
|
data/README.md
CHANGED
|
@@ -669,7 +669,7 @@ Thanks for RTFM. ☺️
|
|
|
669
669
|
[📌gitmoji]: https://gitmoji.dev
|
|
670
670
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
671
671
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
672
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-2.
|
|
672
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-2.936-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
673
673
|
[🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
|
|
674
674
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
675
675
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -14,7 +14,8 @@ module Kettle
|
|
|
14
14
|
:elapsed_seconds,
|
|
15
15
|
:skipped,
|
|
16
16
|
:reason,
|
|
17
|
-
:branch
|
|
17
|
+
:branch,
|
|
18
|
+
:output_streamed
|
|
18
19
|
) do
|
|
19
20
|
def to_h
|
|
20
21
|
{
|
|
@@ -29,7 +30,8 @@ module Kettle
|
|
|
29
30
|
"stderr" => summarize(stderr),
|
|
30
31
|
"elapsed_seconds" => elapsed_seconds,
|
|
31
32
|
"skipped" => skipped,
|
|
32
|
-
"reason" => reason
|
|
33
|
+
"reason" => reason,
|
|
34
|
+
"output_streamed" => output_streamed?
|
|
33
35
|
}
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -37,6 +39,10 @@ module Kettle
|
|
|
37
39
|
success || skipped
|
|
38
40
|
end
|
|
39
41
|
|
|
42
|
+
def output_streamed?
|
|
43
|
+
!!output_streamed
|
|
44
|
+
end
|
|
45
|
+
|
|
40
46
|
private
|
|
41
47
|
|
|
42
48
|
def summarize(output)
|
|
@@ -139,7 +139,8 @@ module Kettle
|
|
|
139
139
|
stderr: stderr,
|
|
140
140
|
elapsed_seconds: elapsed.round(3),
|
|
141
141
|
skipped: false,
|
|
142
|
-
reason: status.success? ? nil : "command failed"
|
|
142
|
+
reason: status.success? ? nil : "command failed",
|
|
143
|
+
output_streamed: interactive
|
|
143
144
|
)
|
|
144
145
|
end
|
|
145
146
|
|
|
@@ -17,7 +17,7 @@ module Kettle
|
|
|
17
17
|
|
|
18
18
|
def results
|
|
19
19
|
return branch_results unless release_target_branches.empty?
|
|
20
|
-
return
|
|
20
|
+
return members.map { |member| check_shared_changelog_member_or_local(member) } if shared_changelog?
|
|
21
21
|
|
|
22
22
|
members.each_with_object([]) do |member, memo|
|
|
23
23
|
member_branch_results = member_local_branch_results(member)
|
|
@@ -38,12 +38,12 @@ module Kettle
|
|
|
38
38
|
selected_names = members.map(&:name)
|
|
39
39
|
release_target_branches.each_with_object([]) do |branch, memo|
|
|
40
40
|
with_branch_worktree(root: root, branch: branch) do |worktree_root|
|
|
41
|
+
branch_members = discover_branch_members(worktree_root: worktree_root, selected_names: selected_names)
|
|
41
42
|
if shared_changelog?
|
|
42
|
-
memo
|
|
43
|
+
memo.concat(branch_members.map { |member| check_shared_changelog_member_or_local(member, branch: branch) })
|
|
43
44
|
next
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
branch_members = discover_branch_members(worktree_root: worktree_root, selected_names: selected_names)
|
|
47
47
|
memo.concat(branch_members.map { |member| check_member(member, branch: branch) })
|
|
48
48
|
end
|
|
49
49
|
rescue Error => error
|
|
@@ -54,7 +54,7 @@ module Kettle
|
|
|
54
54
|
def check_member(member, branch: nil)
|
|
55
55
|
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
56
56
|
command = release_state_command
|
|
57
|
-
stdout, stderr, status = Open3.capture3(release_state_env, *command, chdir: release_state_workdir(member))
|
|
57
|
+
stdout, stderr, status = Open3.capture3(release_state_env(member), *command, chdir: release_state_workdir(member))
|
|
58
58
|
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
|
|
59
59
|
success = status.success?
|
|
60
60
|
state = success ? JSON.parse(stdout) : {}
|
|
@@ -69,26 +69,38 @@ module Kettle
|
|
|
69
69
|
[RbConfig.ruby, "-S", "kettle-changelog", "--release-state", "--json"]
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
def
|
|
73
|
-
member
|
|
72
|
+
def check_shared_changelog_member_or_local(member, branch: nil)
|
|
73
|
+
return check_member(member, branch: branch) if member_local_changelog?(member)
|
|
74
|
+
|
|
75
|
+
check_shared_changelog_member(member, branch: branch)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def check_shared_changelog_member(member, branch: nil)
|
|
74
79
|
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
75
|
-
|
|
80
|
+
command = release_state_command
|
|
81
|
+
stdout, stderr, status = Open3.capture3(shared_changelog_env(member), *command, chdir: config.root)
|
|
76
82
|
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
|
|
83
|
+
success = status.success?
|
|
84
|
+
state = success ? JSON.parse(stdout) : {}
|
|
85
|
+
state = branch_filtered_state(member, state, branch) if success && branch
|
|
86
|
+
state = enrich_git_state(member.root, state) if success
|
|
77
87
|
result(
|
|
78
88
|
member: member,
|
|
79
|
-
command:
|
|
80
|
-
stdout:
|
|
81
|
-
stderr:
|
|
82
|
-
status:
|
|
89
|
+
command: command,
|
|
90
|
+
stdout: stdout,
|
|
91
|
+
stderr: stderr,
|
|
92
|
+
status: status.exitstatus,
|
|
83
93
|
elapsed: elapsed,
|
|
84
|
-
success:
|
|
94
|
+
success: success,
|
|
85
95
|
state: state,
|
|
86
96
|
branch: branch
|
|
87
97
|
)
|
|
98
|
+
rescue JSON::ParserError => error
|
|
99
|
+
result(member: member, command: command || release_state_command, stdout: stdout, stderr: stderr, status: 1, elapsed: elapsed || 0.0, success: false, state: {}, reason: "invalid release-state JSON: #{error.message}", branch: branch)
|
|
88
100
|
rescue Error => error
|
|
89
101
|
result(
|
|
90
102
|
member: member,
|
|
91
|
-
command:
|
|
103
|
+
command: command || release_state_command,
|
|
92
104
|
stdout: "",
|
|
93
105
|
stderr: error.message,
|
|
94
106
|
status: 1,
|
|
@@ -100,28 +112,35 @@ module Kettle
|
|
|
100
112
|
)
|
|
101
113
|
end
|
|
102
114
|
|
|
103
|
-
def family_member(root:)
|
|
104
|
-
Member.new(
|
|
105
|
-
name: config.family_name,
|
|
106
|
-
root: root,
|
|
107
|
-
gemspec_path: nil,
|
|
108
|
-
version_file: nil,
|
|
109
|
-
version: nil,
|
|
110
|
-
dependencies: []
|
|
111
|
-
)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
115
|
def release_state_workdir(member)
|
|
115
116
|
return member.root unless config
|
|
116
|
-
return
|
|
117
|
+
return config.root if config.shared_changelog? && !member_local_changelog?(member)
|
|
117
118
|
|
|
118
119
|
config.changelog_workdir(member) || member.root
|
|
119
120
|
end
|
|
120
121
|
|
|
121
|
-
def release_state_env
|
|
122
|
+
def release_state_env(member = nil)
|
|
123
|
+
return member_changelog_env(member) if member && shared_changelog? && member_local_changelog?(member)
|
|
124
|
+
|
|
122
125
|
config ? config.changelog_env : {}
|
|
123
126
|
end
|
|
124
127
|
|
|
128
|
+
def shared_changelog_env(member)
|
|
129
|
+
env = release_state_env(member).merge("K_CHANGELOG_GEM_NAME" => member.name.to_s)
|
|
130
|
+
env["K_CHANGELOG_VERSION_FILE"] = member.version_file.to_s if member.version_file
|
|
131
|
+
env
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def member_changelog_env(member)
|
|
135
|
+
env = {"K_CHANGELOG_GEM_NAME" => member.name.to_s}
|
|
136
|
+
env["K_CHANGELOG_VERSION_FILE"] = member.version_file.to_s if member.version_file
|
|
137
|
+
env
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def member_local_changelog?(member)
|
|
141
|
+
File.file?(File.join(member.root, "CHANGELOG.md"))
|
|
142
|
+
end
|
|
143
|
+
|
|
125
144
|
def branch_filtered_state(member, state, _branch)
|
|
126
145
|
latest_released = branch_latest_released(member, state["latest_changelog_version"])
|
|
127
146
|
return state unless latest_released
|
data/lib/kettle/family/report.rb
CHANGED
|
@@ -162,7 +162,9 @@ module Kettle
|
|
|
162
162
|
def append_result_stdout(lines, result)
|
|
163
163
|
return if suppress_success_output?(result)
|
|
164
164
|
|
|
165
|
-
if
|
|
165
|
+
if output_streamed?(result)
|
|
166
|
+
append_streamed_output_summary(lines, result) unless result.ok?
|
|
167
|
+
elsif template_event_stdout?(result)
|
|
166
168
|
append_template_event_failure_summary(lines, result.stdout) unless result.ok?
|
|
167
169
|
else
|
|
168
170
|
append_indented_output(lines, result.stdout)
|
|
@@ -177,6 +179,33 @@ module Kettle
|
|
|
177
179
|
command == "template" && result.phase == "template" && template_events(result.stdout).any?
|
|
178
180
|
end
|
|
179
181
|
|
|
182
|
+
def output_streamed?(result)
|
|
183
|
+
result.respond_to?(:output_streamed?) && result.output_streamed?
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def append_streamed_output_summary(lines, result)
|
|
187
|
+
summary = streamed_output_summary(result)
|
|
188
|
+
lines << " summary: #{summary}" if summary
|
|
189
|
+
recommended_fix = streamed_recommended_fix(result)
|
|
190
|
+
lines << " recommended fix: #{recommended_fix}" if recommended_fix
|
|
191
|
+
lines << " output: omitted because it was already streamed"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def streamed_output_summary(result)
|
|
195
|
+
streamed_output_lines(result).reverse.find do |line|
|
|
196
|
+
line.match?(/(?:failed|failure|error|exited|aborted)/i) && !line.match?(/\A(?:Files|CI|Actions)/)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def streamed_recommended_fix(result)
|
|
201
|
+
line = streamed_output_lines(result).reverse.find { |candidate| candidate.match?(/\ARecommended fix:\s+/) }
|
|
202
|
+
line&.sub(/\ARecommended fix:\s+/, "")
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def streamed_output_lines(result)
|
|
206
|
+
[result.stdout, result.stderr].join("\n").lines.map(&:strip).reject(&:empty?)
|
|
207
|
+
end
|
|
208
|
+
|
|
180
209
|
def append_template_event_failure_summary(lines, output)
|
|
181
210
|
diagnostics = template_events(output).filter_map do |event|
|
|
182
211
|
next unless event["type"] == "diagnostic"
|
|
@@ -542,6 +542,9 @@ module Kettle
|
|
|
542
542
|
return if memo.any? && !memo.last.ok?
|
|
543
543
|
|
|
544
544
|
append_registry_wait_result(released_members: released_members, dependent_members: affected_dependent_members, memo: memo)
|
|
545
|
+
return if memo.any? && !memo.last.ok?
|
|
546
|
+
|
|
547
|
+
append_dependency_floor_lockfile_results(released_members: released_members, dependent_members: affected_dependent_members, runner: runner, memo: memo)
|
|
545
548
|
end
|
|
546
549
|
|
|
547
550
|
def dependent_members_depending_on(released_members:, dependent_members:)
|
|
@@ -562,6 +565,85 @@ module Kettle
|
|
|
562
565
|
memo << wait_for_registry_result(released_members: released_members, dependent_members: dependent_members)
|
|
563
566
|
end
|
|
564
567
|
|
|
568
|
+
def append_dependency_floor_lockfile_results(released_members:, dependent_members:, runner:, memo:)
|
|
569
|
+
return unless execute && publish
|
|
570
|
+
return if dependent_members.empty?
|
|
571
|
+
|
|
572
|
+
dependent_members.each do |member|
|
|
573
|
+
memo << wait_for_dependency_floor_lockfiles_result(member: member, released_members: released_members, runner: runner)
|
|
574
|
+
break unless memo.last.ok?
|
|
575
|
+
end
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
def wait_for_dependency_floor_lockfiles_result(member:, released_members:, runner:)
|
|
579
|
+
result = nil
|
|
580
|
+
REGISTRY_WAIT_ATTEMPTS.times do |index|
|
|
581
|
+
result = runner.call(
|
|
582
|
+
member: member,
|
|
583
|
+
phase: "dependency_floor_lockfiles",
|
|
584
|
+
command: ["bundle", "update", *released_members.map(&:name)],
|
|
585
|
+
env: release_lockfile_env
|
|
586
|
+
)
|
|
587
|
+
validate_dependency_floor_lockfile_result(result: result, member: member, released_members: released_members) if result.ok?
|
|
588
|
+
annotate_dependency_floor_lockfile_result(result, index + 1)
|
|
589
|
+
break if result.ok?
|
|
590
|
+
|
|
591
|
+
sleep(REGISTRY_WAIT_INTERVAL_SECONDS) if index + 1 < REGISTRY_WAIT_ATTEMPTS
|
|
592
|
+
end
|
|
593
|
+
result
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
def validate_dependency_floor_lockfile_result(result:, member:, released_members:)
|
|
597
|
+
diagnostics = dependency_floor_lockfile_diagnostics(member: member, released_members: released_members)
|
|
598
|
+
return if diagnostics.empty?
|
|
599
|
+
|
|
600
|
+
result.status = 1
|
|
601
|
+
result.success = false
|
|
602
|
+
result.stderr = [result.stderr, *diagnostics].reject(&:empty?).join("\n")
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
def dependency_floor_lockfile_diagnostics(member:, released_members:)
|
|
606
|
+
lockfile = File.join(member.root, "Gemfile.lock")
|
|
607
|
+
return ["Gemfile.lock was not created by dependency floor lockfile refresh"] unless File.file?(lockfile)
|
|
608
|
+
|
|
609
|
+
lockfile_source = File.read(lockfile)
|
|
610
|
+
released_members.filter_map do |released_member|
|
|
611
|
+
checksum_line = checksum_line_for(lockfile_source: lockfile_source, member: released_member)
|
|
612
|
+
if checksum_line.nil?
|
|
613
|
+
"Gemfile.lock CHECKSUMS is missing #{released_member.name} #{released_member.version}"
|
|
614
|
+
elsif !checksum_line.include?("sha256=")
|
|
615
|
+
"Gemfile.lock CHECKSUMS has no sha256 for #{released_member.name} #{released_member.version}"
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
def checksum_line_for(lockfile_source:, member:)
|
|
621
|
+
in_checksums = false
|
|
622
|
+
lockfile_source.each_line do |line|
|
|
623
|
+
stripped = line.chomp
|
|
624
|
+
if stripped == "CHECKSUMS"
|
|
625
|
+
in_checksums = true
|
|
626
|
+
next
|
|
627
|
+
end
|
|
628
|
+
next unless in_checksums
|
|
629
|
+
break if !stripped.empty? && stripped == stripped.upcase && !stripped.start_with?(" ")
|
|
630
|
+
|
|
631
|
+
return stripped if stripped.start_with?(" #{member.name} (#{member.version})")
|
|
632
|
+
end
|
|
633
|
+
nil
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
def annotate_dependency_floor_lockfile_result(result, attempts)
|
|
637
|
+
return unless result
|
|
638
|
+
|
|
639
|
+
if result.ok?
|
|
640
|
+
message = "refreshed dependency floor lockfiles after #{attempts} attempt(s)"
|
|
641
|
+
result.stdout = [result.stdout, message].reject(&:empty?).join("\n")
|
|
642
|
+
else
|
|
643
|
+
result.reason = "dependency floor lockfile refresh failed after #{attempts} attempt(s)"
|
|
644
|
+
end
|
|
645
|
+
end
|
|
646
|
+
|
|
565
647
|
def commit_dependency_floor_changes(dependent_members:, runner:, memo:)
|
|
566
648
|
by_name = members.to_h { |member| [member.name, member] }
|
|
567
649
|
dependent_members.each do |member_name|
|
data.tar.gz.sig
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
�
|
|
2
|
-
|
|
1
|
+
i�n��xD�˯6�-kԇC!:A���G�K��%���!~�n>�25c�:�0<��s��?}���ĈrP0���Bz�%��j��Ffs9�8��2����B�{�#�@ �<��\u�J�B�d�`�'��q��v�J��&�B_k��}��͟#��Ǣ�
|
|
2
|
+
����y���8
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-family
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -74,7 +74,7 @@ dependencies:
|
|
|
74
74
|
version: '2.3'
|
|
75
75
|
- - ">="
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
|
-
version: 2.3.
|
|
77
|
+
version: 2.3.10
|
|
78
78
|
type: :runtime
|
|
79
79
|
prerelease: false
|
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -84,7 +84,7 @@ dependencies:
|
|
|
84
84
|
version: '2.3'
|
|
85
85
|
- - ">="
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: 2.3.
|
|
87
|
+
version: 2.3.10
|
|
88
88
|
- !ruby/object:Gem::Dependency
|
|
89
89
|
name: kettle-test
|
|
90
90
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,7 +94,7 @@ dependencies:
|
|
|
94
94
|
version: '2.0'
|
|
95
95
|
- - ">="
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
|
-
version: 2.0.
|
|
97
|
+
version: 2.0.12
|
|
98
98
|
type: :runtime
|
|
99
99
|
prerelease: false
|
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -104,7 +104,7 @@ dependencies:
|
|
|
104
104
|
version: '2.0'
|
|
105
105
|
- - ">="
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
|
-
version: 2.0.
|
|
107
|
+
version: 2.0.12
|
|
108
108
|
- !ruby/object:Gem::Dependency
|
|
109
109
|
name: tsort
|
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -304,10 +304,10 @@ licenses:
|
|
|
304
304
|
- AGPL-3.0-only
|
|
305
305
|
metadata:
|
|
306
306
|
homepage_uri: https://kettle-family.galtzo.com
|
|
307
|
-
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.0.
|
|
308
|
-
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.0.
|
|
307
|
+
source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.0.5
|
|
308
|
+
changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.0.5/CHANGELOG.md
|
|
309
309
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
|
|
310
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.0.
|
|
310
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.0.5
|
|
311
311
|
funding_uri: https://github.com/sponsors/pboling
|
|
312
312
|
wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
|
|
313
313
|
news_uri: https://www.railsbling.com/tags/kettle-family
|
|
@@ -337,7 +337,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
337
337
|
- !ruby/object:Gem::Version
|
|
338
338
|
version: '0'
|
|
339
339
|
requirements: []
|
|
340
|
-
rubygems_version: 4.0.
|
|
340
|
+
rubygems_version: 4.0.17
|
|
341
341
|
specification_version: 4
|
|
342
342
|
summary: "\U0001F469\U0001F469\U0001F467\U0001F467 CLI helpers for managing related
|
|
343
343
|
Ruby gems as a family."
|
metadata.gz.sig
CHANGED
|
Binary file
|