kettle-dev 1.1.10 → 1.1.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/CHANGELOG.md +13 -1
- data/README.md +1 -1
- data/README.md.example +1 -1
- data/Rakefile.example +1 -1
- data/exe/kettle-dev-setup +29 -265
- data/lib/kettle/dev/setup_cli.rb +252 -0
- data/lib/kettle/dev/version.rb +1 -1
- data/lib/kettle/dev.rb +1 -0
- data/sig/kettle/dev/setup_cli.rbs +8 -0
- data.tar.gz.sig +0 -0
- metadata +6 -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: 84d3d2f6671ddba20e5cc07cb1b56051e9b6acaf6d3cb1157b8fc2bb3c76bb76
|
4
|
+
data.tar.gz: f962f26bb64d242f670899b45831a66036c4ff1db497702f0446669374f1f580
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6f1fc475a0aa076e614c7c612ba2d6fc06327de919af2c29c01173dc6a7191c25a57a0d8392b2847c75931804b60a5360bcd610c4acac8a42c6ae835f36275f
|
7
|
+
data.tar.gz: d6163488e6f32e9633074faed8d8243f85edf29766871797678e84393a2d2dd575cad9c16ceccc7074a2e149256f2ea5861e4d739ac61381cd34a2a0e488556b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -24,6 +24,16 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
24
24
|
### Fixed
|
25
25
|
### Security
|
26
26
|
|
27
|
+
## [1.1.11] - 2025-09-08
|
28
|
+
- TAG: [v1.1.11][1.1.11t]
|
29
|
+
- COVERAGE: 96.56% -- 3396/3517 lines in 24 files
|
30
|
+
- BRANCH COVERAGE: 81.33% -- 1385/1703 branches in 24 files
|
31
|
+
- 77.06% documented
|
32
|
+
### Changed
|
33
|
+
- move kettle-dev-setup logic into Kettle::Dev::SetupCLI
|
34
|
+
### Fixed
|
35
|
+
- gem dependency detection in kettle-dev-setup to prevent duplication
|
36
|
+
|
27
37
|
## [1.1.10] - 2025-09-08
|
28
38
|
- TAG: [v1.1.10][1.1.10t]
|
29
39
|
- COVERAGE: 97.14% -- 3256/3352 lines in 23 files
|
@@ -571,7 +581,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
571
581
|
- Selecting will run the selected workflow via `act`
|
572
582
|
- This may move to its own gem in the future.
|
573
583
|
|
574
|
-
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.
|
584
|
+
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.11...HEAD
|
585
|
+
[1.1.11]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.10...v1.1.11
|
586
|
+
[1.1.11t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.11
|
575
587
|
[1.1.10]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.9...v1.1.10
|
576
588
|
[1.1.10t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.10
|
577
589
|
[1.1.9]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.8...v1.1.9
|
data/README.md
CHANGED
@@ -907,7 +907,7 @@ Thanks for RTFM. ☺️
|
|
907
907
|
[📌gitmoji]:https://gitmoji.dev
|
908
908
|
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
909
909
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
910
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.
|
910
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.517-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
911
911
|
[🔐security]: SECURITY.md
|
912
912
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
913
913
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/README.md.example
CHANGED
@@ -507,7 +507,7 @@ Thanks for RTFM. ☺️
|
|
507
507
|
[📌gitmoji]:https://gitmoji.dev
|
508
508
|
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
509
509
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
510
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.
|
510
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-3.517-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
511
511
|
[🔐security]: SECURITY.md
|
512
512
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
513
513
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/Rakefile.example
CHANGED
data/exe/kettle-dev-setup
CHANGED
@@ -19,7 +19,7 @@ $stdout.sync = true
|
|
19
19
|
$stderr.sync = true
|
20
20
|
|
21
21
|
script_basename = File.basename(__FILE__)
|
22
|
-
|
22
|
+
File.basename($PROGRAM_NAME)
|
23
23
|
|
24
24
|
begin
|
25
25
|
require "kettle/dev"
|
@@ -31,273 +31,37 @@ rescue StandardError => e
|
|
31
31
|
warn("[kettle-dev-setup] Warning: could not fully load kettle/dev (#{e.class}: #{e.message}). Proceeding with limited features.")
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@argv = argv
|
40
|
-
@passthrough = []
|
41
|
-
@options = {}
|
42
|
-
parse!
|
43
|
-
end
|
34
|
+
# Always execute when this file is loaded (e.g., via a Bundler binstub).
|
35
|
+
# Do not guard with __FILE__ == $PROGRAM_NAME because binstubs use Kernel.load.
|
36
|
+
if ARGV.include?("-h") || ARGV.include?("--help")
|
37
|
+
puts <<~USAGE
|
38
|
+
Usage: kettle-dev-setup [options]
|
44
39
|
|
45
|
-
|
46
|
-
debug("run!")
|
47
|
-
say("Starting kettle-dev setup…")
|
48
|
-
prechecks!
|
49
|
-
ensure_dev_deps!
|
50
|
-
ensure_bin_setup!
|
51
|
-
ensure_rakefile!
|
52
|
-
run_bin_setup!
|
53
|
-
run_bundle_binstubs!
|
54
|
-
commit_bootstrap_changes!
|
55
|
-
run_kettle_install!
|
56
|
-
say("kettle-dev setup complete.")
|
57
|
-
end
|
40
|
+
Bootstraps a host gem repository to use kettle-dev tooling.
|
58
41
|
|
59
|
-
|
42
|
+
Options (passed through to rake kettle:dev:install):
|
43
|
+
--allowed=VAL
|
44
|
+
--force
|
45
|
+
--hook_templates=VAL
|
46
|
+
--only=VAL
|
60
47
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def parse!
|
67
|
-
debug("parse! argv_before=#{@argv.inspect}")
|
68
|
-
parser = OptionParser.new do |opts|
|
69
|
-
opts.banner = "Usage: kettle-dev-setup [options]"
|
70
|
-
# Map CLI flags to environment-style assignments for Rake (key=value)
|
71
|
-
opts.on("--allowed=VAL", "Pass through to kettle:dev:install") { |v| @passthrough << "allowed=#{v}" }
|
72
|
-
opts.on("--force", "Pass through to kettle:dev:install") { @passthrough << "force=true" }
|
73
|
-
opts.on("--hook_templates=VAL", "Pass through to kettle:dev:install") { |v| @passthrough << "hook_templates=#{v}" }
|
74
|
-
opts.on("--only=VAL", "Pass through to kettle:dev:install") { |v| @passthrough << "only=#{v}" }
|
75
|
-
opts.on("-h", "--help", "Show help") do
|
76
|
-
puts opts
|
77
|
-
exit(0)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
begin
|
81
|
-
parser.parse!(@argv)
|
82
|
-
rescue OptionParser::ParseError => e
|
83
|
-
warn("[kettle-dev-setup] #{e.class}: #{e.message}")
|
84
|
-
puts parser
|
85
|
-
exit(2)
|
86
|
-
end
|
87
|
-
# Any remaining args pass through as-is
|
88
|
-
@passthrough.concat(@argv)
|
89
|
-
debug("parse! argv_after=#{@argv.inspect} passthrough=#{@passthrough.inspect}")
|
90
|
-
end
|
91
|
-
|
92
|
-
def say(msg)
|
93
|
-
puts "[kettle-dev-setup] #{msg}"
|
94
|
-
end
|
95
|
-
|
96
|
-
def abort!(msg)
|
97
|
-
debug("abort!(msg=#{msg.inspect})")
|
98
|
-
raise SystemExit, "[kettle-dev-setup] ERROR: #{msg}"
|
99
|
-
end
|
100
|
-
|
101
|
-
def sh!(cmd, env: {})
|
102
|
-
debug("sh!(cmd=#{cmd.inspect}, env_keys=#{env.keys.inspect})")
|
103
|
-
say("exec: #{cmd}")
|
104
|
-
stdout_str, stderr_str, status = Open3.capture3(env, cmd)
|
105
|
-
$stdout.print(stdout_str) unless stdout_str.empty?
|
106
|
-
$stderr.print(stderr_str) unless stderr_str.empty?
|
107
|
-
abort!("Command failed: #{cmd}") unless status.success?
|
108
|
-
end
|
109
|
-
|
110
|
-
# 1. Prechecks
|
111
|
-
def prechecks!
|
112
|
-
debug("prechecks!")
|
113
|
-
abort!("Not inside a git repository (missing .git).") unless Dir.exist?(".git")
|
114
|
-
|
115
|
-
# 1a. git clean
|
116
|
-
begin
|
117
|
-
# Use GitAdapter if available; otherwise shell out
|
118
|
-
if defined?(Kettle::Dev::GitAdapter)
|
119
|
-
ga = Kettle::Dev::GitAdapter.new
|
120
|
-
dirty = !ga.clean?
|
121
|
-
else
|
122
|
-
stdout, _stderr, _status = Open3.capture3("git status --porcelain")
|
123
|
-
dirty = !stdout.strip.empty?
|
124
|
-
end
|
125
|
-
abort!("Git working tree is not clean. Please commit/stash changes and try again.") if dirty
|
126
|
-
rescue StandardError
|
127
|
-
# Fallback if anything goes wrong: be conservative and require clean tree via shell
|
128
|
-
stdout, _stderr, _status = Open3.capture3("git status --porcelain")
|
129
|
-
abort!("Git working tree is not clean. Please commit/stash changes and try again.") unless stdout.strip.empty?
|
130
|
-
end
|
131
|
-
|
132
|
-
# 1b. target is a gem (has *.gemspec)
|
133
|
-
gemspecs = Dir["*.gemspec"]
|
134
|
-
abort!("No gemspec found in current directory.") if gemspecs.empty?
|
135
|
-
@gemspec_path = gemspecs.first
|
136
|
-
|
137
|
-
# 1c. target uses bundler (Gemfile)
|
138
|
-
abort!("No Gemfile found; bundler is required.") unless File.exist?("Gemfile")
|
139
|
-
end
|
140
|
-
|
141
|
-
# 3. Sync dev dependencies from this gem's example gemspec into target gemspec
|
142
|
-
def ensure_dev_deps!
|
143
|
-
debug("ensure_dev_deps!")
|
144
|
-
source_example = installed_path("kettle-dev.gemspec.example")
|
145
|
-
abort!("Internal error: kettle-dev.gemspec.example not found within the installed gem.") unless source_example && File.exist?(source_example)
|
146
|
-
|
147
|
-
example = File.read(source_example)
|
148
|
-
example = example.gsub("{KETTLE|DEV|GEM}", "kettle-dev")
|
149
|
-
|
150
|
-
wanted_lines = example.each_line.map(&:rstrip).select do |line|
|
151
|
-
line =~ /add_development_dependency\s*\(/
|
152
|
-
end
|
153
|
-
|
154
|
-
return if wanted_lines.empty?
|
155
|
-
|
156
|
-
target = File.read(@gemspec_path)
|
157
|
-
|
158
|
-
# Build a map from gem name to the desired line
|
159
|
-
wanted = {}
|
160
|
-
wanted_lines.each do |line|
|
161
|
-
if (m = line.match(/add_development_dependency\s*\(\s*["']([^"']+)["']/))
|
162
|
-
wanted[m[1]] = line
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
modified = target.dup
|
167
|
-
wanted.each do |gem_name, desired_line|
|
168
|
-
# Replace existing add_development_dependency for this gem, else append near the end
|
169
|
-
if /add_development_dependency\s*\(\s*["']#{Regexp.escape(gem_name)}["']/ =~ modified
|
170
|
-
modified = modified.gsub(/^[^\n]*add_development_dependency\s*\(\s*["']#{Regexp.escape(gem_name)}["'][^\n]*\)$/) do |_|
|
171
|
-
desired_line
|
172
|
-
end
|
173
|
-
elsif (idx = modified.rindex(/\nend\s*\z/))
|
174
|
-
# Insert before the last end, if present, otherwise append
|
175
|
-
before = modified[0...idx]
|
176
|
-
after = modified[idx..-1]
|
177
|
-
insertion = "\n #{desired_line.strip}\n"
|
178
|
-
modified = before + insertion + after
|
179
|
-
else
|
180
|
-
modified << "\n#{desired_line}\n"
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
if modified != target
|
185
|
-
File.write(@gemspec_path, modified)
|
186
|
-
say("Updated development dependencies in #{@gemspec_path}.")
|
187
|
-
else
|
188
|
-
say("Development dependencies already up to date.")
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
# 4. Ensure bin/setup present (copy from gem if missing)
|
193
|
-
def ensure_bin_setup!
|
194
|
-
debug("ensure_bin_setup!")
|
195
|
-
target = File.join("bin", "setup")
|
196
|
-
return say("bin/setup present.") if File.exist?(target)
|
197
|
-
|
198
|
-
source = installed_path(File.join("bin", "setup"))
|
199
|
-
abort!("Internal error: source bin/setup not found within installed gem.") unless source && File.exist?(source)
|
200
|
-
FileUtils.mkdir_p("bin")
|
201
|
-
FileUtils.cp(source, target)
|
202
|
-
FileUtils.chmod("+x", target)
|
203
|
-
say("Copied bin/setup.")
|
204
|
-
end
|
205
|
-
|
206
|
-
# 5. Ensure Rakefile matches example (replace or create)
|
207
|
-
def ensure_rakefile!
|
208
|
-
debug("ensure_rakefile!")
|
209
|
-
source = installed_path("Rakefile.example")
|
210
|
-
abort!("Internal error: Rakefile.example not found within installed gem.") unless source && File.exist?(source)
|
211
|
-
|
212
|
-
content = File.read(source)
|
213
|
-
if File.exist?("Rakefile")
|
214
|
-
say("Replacing existing Rakefile with kettle-dev Rakefile.example.")
|
215
|
-
else
|
216
|
-
say("Creating Rakefile from kettle-dev Rakefile.example.")
|
217
|
-
end
|
218
|
-
File.write("Rakefile", content)
|
219
|
-
end
|
220
|
-
|
221
|
-
# 6. Run bin/setup
|
222
|
-
def run_bin_setup!
|
223
|
-
debug("run_bin_setup!")
|
224
|
-
sh!(Shellwords.join([File.join("bin", "setup")]))
|
225
|
-
end
|
226
|
-
|
227
|
-
# 7. Run bundle binstubs --all
|
228
|
-
def run_bundle_binstubs!
|
229
|
-
debug("run_bundle_binstubs!")
|
230
|
-
sh!("bundle exec bundle binstubs --all")
|
231
|
-
end
|
232
|
-
|
233
|
-
# 8. Stage and commit any changes made by the setup before install
|
234
|
-
def commit_bootstrap_changes!
|
235
|
-
debug("commit_bootstrap_changes!")
|
236
|
-
# Only operate if we are inside a git repo (prechecked earlier), and if dirty
|
237
|
-
dirty = begin
|
238
|
-
if defined?(Kettle::Dev::GitAdapter)
|
239
|
-
!Kettle::Dev::GitAdapter.new.clean?
|
240
|
-
else
|
241
|
-
out, _st = Open3.capture2("git", "status", "--porcelain")
|
242
|
-
!out.strip.empty?
|
243
|
-
end
|
244
|
-
rescue StandardError
|
245
|
-
out, _st = Open3.capture2("git", "status", "--porcelain")
|
246
|
-
!out.strip.empty?
|
247
|
-
end
|
248
|
-
unless dirty
|
249
|
-
say("No changes to commit from template bootstrap.")
|
250
|
-
return
|
251
|
-
end
|
252
|
-
# Stage all changes
|
253
|
-
sh!(Shellwords.join(["git", "add", "-A"]))
|
254
|
-
# Compose commit message exactly as required
|
255
|
-
script_name = File.basename(__FILE__)
|
256
|
-
msg = "🎨 Template bootstrap by #{script_name} v#{Kettle::Dev::Version::VERSION}"
|
257
|
-
# Commit; allow empty to be false (we already detected dirty)
|
258
|
-
sh!(Shellwords.join(["git", "commit", "-m", msg]))
|
259
|
-
say("Committed template bootstrap changes.")
|
260
|
-
end
|
261
|
-
|
262
|
-
# 9. Run rake kettle:dev:install with passthrough args
|
263
|
-
def run_kettle_install!
|
264
|
-
debug("run_kettle_install! passthrough=#{@passthrough.inspect}")
|
265
|
-
cmd = ["bin/rake", "kettle:dev:install"] + @passthrough
|
266
|
-
sh!(Shellwords.join(cmd))
|
267
|
-
end
|
268
|
-
|
269
|
-
# Locate files shipped with this gem installation. Handles execution under a checkout as well.
|
270
|
-
def installed_path(rel)
|
271
|
-
debug("installed_path(rel=#{rel.inspect})")
|
272
|
-
# Prefer real gem installation location
|
273
|
-
if defined?(Gem) && (spec = Gem.loaded_specs["kettle-dev"])
|
274
|
-
path = File.join(spec.full_gem_path, rel)
|
275
|
-
return path if File.exist?(path)
|
276
|
-
end
|
277
|
-
# Fallback: relative to this file (useful when running from repo)
|
278
|
-
here = File.expand_path(File.join(__dir__, "..")) # move from exe/ to project root
|
279
|
-
path = File.join(here, rel)
|
280
|
-
return path if File.exist?(path)
|
281
|
-
nil
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
48
|
+
Environment:
|
49
|
+
DEBUG=true # print backtraces on errors
|
50
|
+
USAGE
|
51
|
+
exit 0
|
285
52
|
end
|
286
53
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
end
|
301
|
-
else
|
302
|
-
puts "== #{script_basename} v#{Kettle::Dev::Version::VERSION} fin (#{running_as_script}) == (#{script_basename}) =="
|
54
|
+
begin
|
55
|
+
Kettle::Dev::SetupCLI.new(ARGV).run!
|
56
|
+
rescue LoadError => e
|
57
|
+
warn("#{script_basename}: could not load dependency: #{e.class}: #{e.message}")
|
58
|
+
warn(e.backtrace.join("\n")) if ENV["DEBUG"]
|
59
|
+
exit(1)
|
60
|
+
rescue SystemExit => e
|
61
|
+
warn("#{script_basename}: exited (status=#{e.status}, msg=#{e.message})") if e.status != 0
|
62
|
+
raise
|
63
|
+
rescue StandardError => e
|
64
|
+
warn("#{script_basename}: unexpected error: #{e.class}: #{e.message}")
|
65
|
+
warn(e.backtrace.join("\n")) if ENV["DEBUG"]
|
66
|
+
exit(1)
|
303
67
|
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "shellwords"
|
5
|
+
require "open3"
|
6
|
+
require "optparse"
|
7
|
+
|
8
|
+
module Kettle
|
9
|
+
module Dev
|
10
|
+
# SetupCLI bootstraps a host gem repository to use kettle-dev tooling.
|
11
|
+
# It performs prechecks, syncs development dependencies, ensures bin/setup and
|
12
|
+
# Rakefile templates, runs setup tasks, and invokes kettle:dev:install.
|
13
|
+
#
|
14
|
+
# Usage:
|
15
|
+
# Kettle::Dev::SetupCLI.new(ARGV).run!
|
16
|
+
#
|
17
|
+
# Options are parsed from argv and passed through to the rake task as
|
18
|
+
# key=value pairs (e.g., --force => force=true).
|
19
|
+
class SetupCLI
|
20
|
+
# @param argv [Array<String>] CLI arguments
|
21
|
+
def initialize(argv)
|
22
|
+
@argv = argv
|
23
|
+
@passthrough = []
|
24
|
+
@options = {}
|
25
|
+
parse!
|
26
|
+
end
|
27
|
+
|
28
|
+
# Execute the full setup workflow.
|
29
|
+
# @return [void]
|
30
|
+
def run!
|
31
|
+
say("Starting kettle-dev setup…")
|
32
|
+
prechecks!
|
33
|
+
ensure_dev_deps!
|
34
|
+
ensure_bin_setup!
|
35
|
+
ensure_rakefile!
|
36
|
+
run_bin_setup!
|
37
|
+
run_bundle_binstubs!
|
38
|
+
commit_bootstrap_changes!
|
39
|
+
run_kettle_install!
|
40
|
+
say("kettle-dev setup complete.")
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def debug(msg)
|
46
|
+
return if ENV.fetch("DEBUG", "false").casecmp("true").nonzero?
|
47
|
+
$stderr.puts("[kettle-dev-setup] DEBUG: #{msg}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse!
|
51
|
+
parser = OptionParser.new do |opts|
|
52
|
+
opts.banner = "Usage: kettle-dev-setup [options]"
|
53
|
+
opts.on("--allowed=VAL", "Pass through to kettle:dev:install") { |v| @passthrough << "allowed=#{v}" }
|
54
|
+
opts.on("--force", "Pass through to kettle:dev:install") { @passthrough << "force=true" }
|
55
|
+
opts.on("--hook_templates=VAL", "Pass through to kettle:dev:install") { |v| @passthrough << "hook_templates=#{v}" }
|
56
|
+
opts.on("--only=VAL", "Pass through to kettle:dev:install") { |v| @passthrough << "only=#{v}" }
|
57
|
+
opts.on("-h", "--help", "Show help") do
|
58
|
+
puts opts
|
59
|
+
Kettle::Dev::ExitAdapter.exit(0)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
begin
|
63
|
+
parser.parse!(@argv)
|
64
|
+
rescue OptionParser::ParseError => e
|
65
|
+
warn("[kettle-dev-setup] #{e.class}: #{e.message}")
|
66
|
+
puts parser
|
67
|
+
Kettle::Dev::ExitAdapter.exit(2)
|
68
|
+
end
|
69
|
+
@passthrough.concat(@argv)
|
70
|
+
end
|
71
|
+
|
72
|
+
def say(msg)
|
73
|
+
puts "[kettle-dev-setup] #{msg}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def abort!(msg)
|
77
|
+
Kettle::Dev::ExitAdapter.abort("[kettle-dev-setup] ERROR: #{msg}")
|
78
|
+
end
|
79
|
+
|
80
|
+
def sh!(cmd, env: {})
|
81
|
+
say("exec: #{cmd}")
|
82
|
+
stdout_str, stderr_str, status = Open3.capture3(env, cmd)
|
83
|
+
$stdout.print(stdout_str) unless stdout_str.empty?
|
84
|
+
$stderr.print(stderr_str) unless stderr_str.empty?
|
85
|
+
abort!("Command failed: #{cmd}") unless status.success?
|
86
|
+
end
|
87
|
+
|
88
|
+
# 1. Prechecks
|
89
|
+
def prechecks!
|
90
|
+
abort!("Not inside a git repository (missing .git).") unless Dir.exist?(".git")
|
91
|
+
|
92
|
+
# Ensure clean working tree
|
93
|
+
begin
|
94
|
+
if defined?(Kettle::Dev::GitAdapter)
|
95
|
+
dirty = !Kettle::Dev::GitAdapter.new.clean?
|
96
|
+
else
|
97
|
+
stdout, _stderr, _status = Open3.capture3("git status --porcelain")
|
98
|
+
dirty = !stdout.strip.empty?
|
99
|
+
end
|
100
|
+
abort!("Git working tree is not clean. Please commit/stash changes and try again.") if dirty
|
101
|
+
rescue StandardError
|
102
|
+
stdout, _stderr, _status = Open3.capture3("git status --porcelain")
|
103
|
+
abort!("Git working tree is not clean. Please commit/stash changes and try again.") unless stdout.strip.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
# gemspec
|
107
|
+
gemspecs = Dir["*.gemspec"]
|
108
|
+
abort!("No gemspec found in current directory.") if gemspecs.empty?
|
109
|
+
@gemspec_path = gemspecs.first
|
110
|
+
|
111
|
+
# Gemfile
|
112
|
+
abort!("No Gemfile found; bundler is required.") unless File.exist?("Gemfile")
|
113
|
+
end
|
114
|
+
|
115
|
+
# 3. Sync dev dependencies from this gem's example gemspec into target gemspec
|
116
|
+
def ensure_dev_deps!
|
117
|
+
source_example = installed_path("kettle-dev.gemspec.example")
|
118
|
+
abort!("Internal error: kettle-dev.gemspec.example not found within the installed gem.") unless source_example && File.exist?(source_example)
|
119
|
+
|
120
|
+
example = File.read(source_example)
|
121
|
+
example = example.gsub("{KETTLE|DEV|GEM}", "kettle-dev")
|
122
|
+
|
123
|
+
wanted_lines = example.each_line.map(&:rstrip).select { |line| line =~ /add_development_dependency\s*\(?/ }
|
124
|
+
return if wanted_lines.empty?
|
125
|
+
|
126
|
+
target = File.read(@gemspec_path)
|
127
|
+
|
128
|
+
# Build gem=>desired line map
|
129
|
+
wanted = {}
|
130
|
+
wanted_lines.each do |line|
|
131
|
+
if (m = line.match(/add_development_dependency\s*\(?\s*["']([^"']+)["']/))
|
132
|
+
wanted[m[1]] = line
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
modified = target.dup
|
137
|
+
wanted.each do |gem_name, desired_line|
|
138
|
+
lines = modified.lines
|
139
|
+
found = false
|
140
|
+
lines.map! do |ln|
|
141
|
+
if ln =~ /add_development_dependency\s*\(?\s*["']#{Regexp.escape(gem_name)}["']/
|
142
|
+
found = true
|
143
|
+
indent = ln[/^\s*/] || ""
|
144
|
+
"#{indent}#{desired_line.strip}\n"
|
145
|
+
else
|
146
|
+
ln
|
147
|
+
end
|
148
|
+
end
|
149
|
+
modified = lines.join
|
150
|
+
|
151
|
+
next if found
|
152
|
+
|
153
|
+
if (idx = modified.rindex(/\nend\s*\z/))
|
154
|
+
before = modified[0...idx]
|
155
|
+
after = modified[idx..-1]
|
156
|
+
insertion = "\n #{desired_line.strip}\n"
|
157
|
+
modified = before + insertion + after
|
158
|
+
else
|
159
|
+
modified << "\n#{desired_line}\n"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
if modified != target
|
164
|
+
File.write(@gemspec_path, modified)
|
165
|
+
say("Updated development dependencies in #{@gemspec_path}.")
|
166
|
+
else
|
167
|
+
say("Development dependencies already up to date.")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# 4. Ensure bin/setup present (copy from gem if missing)
|
172
|
+
def ensure_bin_setup!
|
173
|
+
target = File.join("bin", "setup")
|
174
|
+
return say("bin/setup present.") if File.exist?(target)
|
175
|
+
|
176
|
+
source = installed_path(File.join("bin", "setup"))
|
177
|
+
abort!("Internal error: source bin/setup not found within installed gem.") unless source && File.exist?(source)
|
178
|
+
FileUtils.mkdir_p("bin")
|
179
|
+
FileUtils.cp(source, target)
|
180
|
+
FileUtils.chmod("+x", target)
|
181
|
+
say("Copied bin/setup.")
|
182
|
+
end
|
183
|
+
|
184
|
+
# 5. Ensure Rakefile matches example (replace or create)
|
185
|
+
def ensure_rakefile!
|
186
|
+
source = installed_path("Rakefile.example")
|
187
|
+
abort!("Internal error: Rakefile.example not found within installed gem.") unless source && File.exist?(source)
|
188
|
+
|
189
|
+
content = File.read(source)
|
190
|
+
if File.exist?("Rakefile")
|
191
|
+
say("Replacing existing Rakefile with kettle-dev Rakefile.example.")
|
192
|
+
else
|
193
|
+
say("Creating Rakefile from kettle-dev Rakefile.example.")
|
194
|
+
end
|
195
|
+
File.write("Rakefile", content)
|
196
|
+
end
|
197
|
+
|
198
|
+
# 6. Run bin/setup
|
199
|
+
def run_bin_setup!
|
200
|
+
sh!(Shellwords.join([File.join("bin", "setup")]))
|
201
|
+
end
|
202
|
+
|
203
|
+
# 7. Run bundle binstubs --all
|
204
|
+
def run_bundle_binstubs!
|
205
|
+
sh!("bundle exec bundle binstubs --all")
|
206
|
+
end
|
207
|
+
|
208
|
+
# 8. Commit template bootstrap changes if any
|
209
|
+
def commit_bootstrap_changes!
|
210
|
+
dirty = begin
|
211
|
+
if defined?(Kettle::Dev::GitAdapter)
|
212
|
+
!Kettle::Dev::GitAdapter.new.clean?
|
213
|
+
else
|
214
|
+
out, _st = Open3.capture2("git", "status", "--porcelain")
|
215
|
+
!out.strip.empty?
|
216
|
+
end
|
217
|
+
rescue StandardError
|
218
|
+
out, _st = Open3.capture2("git", "status", "--porcelain")
|
219
|
+
!out.strip.empty?
|
220
|
+
end
|
221
|
+
unless dirty
|
222
|
+
say("No changes to commit from template bootstrap.")
|
223
|
+
return
|
224
|
+
end
|
225
|
+
sh!(Shellwords.join(["git", "add", "-A"]))
|
226
|
+
msg = "🎨 Template bootstrap by kettle-dev-setup v#{Kettle::Dev::Version::VERSION}"
|
227
|
+
sh!(Shellwords.join(["git", "commit", "-m", msg]))
|
228
|
+
say("Committed template bootstrap changes.")
|
229
|
+
end
|
230
|
+
|
231
|
+
# 9. Invoke rake install task with passthrough
|
232
|
+
def run_kettle_install!
|
233
|
+
cmd = ["bin/rake", "kettle:dev:install"] + @passthrough
|
234
|
+
sh!(Shellwords.join(cmd))
|
235
|
+
end
|
236
|
+
|
237
|
+
# Resolve a path to files shipped within the gem or repo checkout
|
238
|
+
# @param rel [String]
|
239
|
+
# @return [String, nil]
|
240
|
+
def installed_path(rel)
|
241
|
+
if defined?(Gem) && (spec = Gem.loaded_specs["kettle-dev"])
|
242
|
+
path = File.join(spec.full_gem_path, rel)
|
243
|
+
return path if File.exist?(path)
|
244
|
+
end
|
245
|
+
here = File.expand_path(File.join(__dir__, "..", "..", "..")) # lib/kettle/dev/ -> project root
|
246
|
+
path = File.join(here, rel)
|
247
|
+
return path if File.exist?(path)
|
248
|
+
nil
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
data/lib/kettle/dev/version.rb
CHANGED
data/lib/kettle/dev.rb
CHANGED
@@ -24,6 +24,7 @@ module Kettle
|
|
24
24
|
autoload :ReadmeBackers, "kettle/dev/readme_backers"
|
25
25
|
autoload :ReleaseCLI, "kettle/dev/release_cli"
|
26
26
|
autoload :PreReleaseCLI, "kettle/dev/pre_release_cli"
|
27
|
+
autoload :SetupCLI, "kettle/dev/setup_cli"
|
27
28
|
autoload :TemplateHelpers, "kettle/dev/template_helpers"
|
28
29
|
autoload :Version, "kettle/dev/version"
|
29
30
|
autoload :Versioning, "kettle/dev/versioning"
|
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: 1.1.
|
4
|
+
version: 1.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter H. Boling
|
@@ -347,6 +347,7 @@ files:
|
|
347
347
|
- lib/kettle/dev/rakelib/yard.rake
|
348
348
|
- lib/kettle/dev/readme_backers.rb
|
349
349
|
- lib/kettle/dev/release_cli.rb
|
350
|
+
- lib/kettle/dev/setup_cli.rb
|
350
351
|
- lib/kettle/dev/tasks.rb
|
351
352
|
- lib/kettle/dev/tasks/ci_task.rb
|
352
353
|
- lib/kettle/dev/tasks/install_task.rb
|
@@ -369,6 +370,7 @@ files:
|
|
369
370
|
- sig/kettle/dev/pre_release_cli.rbs
|
370
371
|
- sig/kettle/dev/readme_backers.rbs
|
371
372
|
- sig/kettle/dev/release_cli.rbs
|
373
|
+
- sig/kettle/dev/setup_cli.rbs
|
372
374
|
- sig/kettle/dev/tasks.rbs
|
373
375
|
- sig/kettle/dev/tasks/ci_task.rbs
|
374
376
|
- sig/kettle/dev/tasks/install_task.rbs
|
@@ -381,10 +383,10 @@ licenses:
|
|
381
383
|
- MIT
|
382
384
|
metadata:
|
383
385
|
homepage_uri: https://kettle-dev.galtzo.com/
|
384
|
-
source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.
|
385
|
-
changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.
|
386
|
+
source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.11
|
387
|
+
changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.11/CHANGELOG.md
|
386
388
|
bug_tracker_uri: https://github.com/kettle-rb/kettle-dev/issues
|
387
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.
|
389
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.11
|
388
390
|
funding_uri: https://github.com/sponsors/pboling
|
389
391
|
wiki_uri: https://github.com/kettle-rb/kettle-dev/wiki
|
390
392
|
news_uri: https://www.railsbling.com/tags/kettle-dev
|
metadata.gz.sig
CHANGED
Binary file
|