regolith 0.1.19 → 0.1.21
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
- data/lib/regolith/cli.rb +145 -884
- data/lib/regolith/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d590506b9d76a0cae7c0b4cc1355860e601c42740d8f4de852e41c001cee08e8
|
4
|
+
data.tar.gz: 412b231f3860a025d6f48c6f96aeb2dc5b60d9368d298e05849d490221f0092d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f22e33c9f838f9a2c61af3808e8c7e0ba5f65e3729653e4674d8e3562dd184d6184f9b284fdcd657ad0f3ac6327521ccd2edbbea5e9a478b8e822f14edcb523d
|
7
|
+
data.tar.gz: a79ff4e21eba13f58cbed3d598dad134cf34df9ee9e3d7c99d0209397fec42b58ba180c636c7d8f2984902a49b8fd614335d819de156ea1e5bcd76128990122a
|
data/lib/regolith/cli.rb
CHANGED
@@ -1,62 +1,10 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'yaml'
|
3
|
-
require 'psych'
|
4
3
|
require 'erb'
|
5
4
|
require 'timeout'
|
6
5
|
require 'rubygems'
|
7
|
-
require 'net/http'
|
8
|
-
require 'uri'
|
9
|
-
require 'json'
|
10
|
-
require 'ostruct'
|
11
|
-
require 'set'
|
12
|
-
require 'rbconfig'
|
13
|
-
require 'shellwords'
|
14
6
|
|
15
7
|
module Regolith
|
16
|
-
# NOTE: VERSION is defined in lib/regolith/version.rb.
|
17
|
-
# Do not define Regolith::VERSION here to avoid constant redefinition warnings.
|
18
|
-
|
19
|
-
class << self
|
20
|
-
# Lightweight configuration with sane defaults
|
21
|
-
def configuration
|
22
|
-
@configuration ||= OpenStruct.new(
|
23
|
-
timeout: 10,
|
24
|
-
default_port: 3001
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
def service_registry
|
29
|
-
@service_registry ||= begin
|
30
|
-
path = find_regolith_config
|
31
|
-
if path && File.exist?(path)
|
32
|
-
config = YAML.load_file(path) || {}
|
33
|
-
config['services'] || {}
|
34
|
-
else
|
35
|
-
{}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def reload_service_registry!
|
41
|
-
@service_registry = nil
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def find_regolith_config
|
47
|
-
current_dir = Dir.pwd
|
48
|
-
loop do
|
49
|
-
config_path = File.join(current_dir, 'config', 'regolith.yml')
|
50
|
-
return config_path if File.exist?(config_path)
|
51
|
-
|
52
|
-
parent = File.dirname(current_dir)
|
53
|
-
break if parent == current_dir
|
54
|
-
current_dir = parent
|
55
|
-
end
|
56
|
-
nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
8
|
class CLI
|
61
9
|
def initialize(args)
|
62
10
|
@args = args
|
@@ -71,47 +19,11 @@ module Regolith
|
|
71
19
|
create_new_app(@subcommand)
|
72
20
|
when 'generate'
|
73
21
|
generate_resource(@subcommand, @name)
|
74
|
-
when 'server'
|
75
|
-
start_server
|
76
|
-
when 'down'
|
77
|
-
stop_services
|
78
|
-
when 'restart'
|
79
|
-
restart_service(@subcommand)
|
80
|
-
when 'stop'
|
81
|
-
stop_service(@subcommand)
|
82
|
-
when 'ps', 'status'
|
83
|
-
show_status
|
84
|
-
when 'logs'
|
85
|
-
show_logs(@subcommand, parse_flags(@args[2..-1]))
|
86
|
-
when 'exec'
|
87
|
-
exec_command(@subcommand, @args[2..-1])
|
88
|
-
when 'shell'
|
89
|
-
shell_service(@subcommand)
|
22
|
+
when 'server'
|
23
|
+
start_server
|
90
24
|
when 'console'
|
91
25
|
open_console(@subcommand)
|
92
|
-
when '
|
93
|
-
rails_passthrough(@subcommand, @args[2..-1])
|
94
|
-
when 'routes'
|
95
|
-
show_routes(@subcommand)
|
96
|
-
when 'open'
|
97
|
-
open_service(@subcommand)
|
98
|
-
when 'db'
|
99
|
-
db_command(@subcommand, @name, parse_flags(@args[3..-1]))
|
100
|
-
when 'test'
|
101
|
-
run_tests(@subcommand, parse_flags(@args[2..-1]))
|
102
|
-
when 'health'
|
103
|
-
health_check
|
104
|
-
when 'config'
|
105
|
-
show_config(parse_flags(@args[1..-1]))
|
106
|
-
when 'prune'
|
107
|
-
prune_system
|
108
|
-
when 'rebuild'
|
109
|
-
rebuild_service(@subcommand)
|
110
|
-
when 'doctor'
|
111
|
-
run_doctor
|
112
|
-
when 'inspect'
|
113
|
-
inspect_services(parse_flags(@args[1..-1]))
|
114
|
-
when 'version', '--version', '-v'
|
26
|
+
when 'version'
|
115
27
|
puts "Regolith #{Regolith::VERSION}"
|
116
28
|
else
|
117
29
|
show_help
|
@@ -120,23 +32,6 @@ module Regolith
|
|
120
32
|
|
121
33
|
private
|
122
34
|
|
123
|
-
def parse_flags(args)
|
124
|
-
flags = {}
|
125
|
-
return flags unless args
|
126
|
-
|
127
|
-
args.each do |arg|
|
128
|
-
if arg.start_with?('--')
|
129
|
-
key, value = arg[2..-1].split('=', 2)
|
130
|
-
flags[key.to_sym] = value || true
|
131
|
-
elsif arg == '-f'
|
132
|
-
flags[:follow] = true
|
133
|
-
elsif arg == '--all'
|
134
|
-
flags[:all] = true
|
135
|
-
end
|
136
|
-
end
|
137
|
-
flags
|
138
|
-
end
|
139
|
-
|
140
35
|
def create_new_app(app_name)
|
141
36
|
unless app_name
|
142
37
|
puts "❌ Error: App name required"
|
@@ -174,9 +69,7 @@ module Regolith
|
|
174
69
|
File.write('docker-compose.yml', generate_docker_compose(app_name))
|
175
70
|
File.write('Makefile', generate_makefile)
|
176
71
|
File.write('.bin/regolith', generate_regolith_shim)
|
177
|
-
|
178
|
-
File.write('README.md', generate_readme(app_name))
|
179
|
-
FileUtils.chmod(0755, '.bin/regolith')
|
72
|
+
FileUtils.chmod(0o755, '.bin/regolith')
|
180
73
|
end
|
181
74
|
|
182
75
|
def generate_resource(resource_type, resource_name)
|
@@ -190,16 +83,9 @@ module Regolith
|
|
190
83
|
end
|
191
84
|
|
192
85
|
def generate_service(service_name)
|
193
|
-
# Validate service name
|
194
|
-
unless service_name =~ /\A[a-z][a-z0-9_]*\z/
|
195
|
-
puts "❌ Invalid service name. Use lowercase, digits, and underscores only."
|
196
|
-
puts "Examples: users, user_profiles, api_gateway"
|
197
|
-
exit 1
|
198
|
-
end
|
199
|
-
|
200
86
|
puts "🔧 Creating service '#{service_name}'..."
|
201
87
|
config = load_regolith_config
|
202
|
-
port =
|
88
|
+
port = 3001 + (config['services']&.size || 0)
|
203
89
|
service_dir = "services/#{service_name}_service"
|
204
90
|
|
205
91
|
puts " → Generating Rails API app..."
|
@@ -230,542 +116,154 @@ module Regolith
|
|
230
116
|
exit 1
|
231
117
|
end
|
232
118
|
|
233
|
-
|
119
|
+
# Overwrite Gemfile before bundle install
|
120
|
+
puts "🔧 Overwriting Gemfile to remove sqlite3 and other defaults..."
|
234
121
|
|
235
|
-
|
236
|
-
'port' => port,
|
237
|
-
'root' => "./#{service_dir}"
|
238
|
-
}
|
122
|
+
major_minor = `ruby -e 'print RUBY_VERSION.split(".")[0..1].join(".")'`.strip
|
239
123
|
|
240
|
-
|
241
|
-
|
124
|
+
custom_gemfile = <<~GEMFILE
|
125
|
+
source "https://rubygems.org"
|
242
126
|
|
243
|
-
|
244
|
-
puts "🚀 Service will run on port #{port}"
|
245
|
-
puts "→ Next: regolith generate service <another_service> or regolith server"
|
246
|
-
end
|
127
|
+
ruby "~> #{major_minor}.0"
|
247
128
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
port
|
253
|
-
end
|
129
|
+
gem "rails", "~> 7.2.2.1"
|
130
|
+
gem "pg", "~> 1.5"
|
131
|
+
gem "puma", ">= 5.0"
|
132
|
+
gem "rack-cors"
|
254
133
|
|
255
|
-
|
256
|
-
|
257
|
-
|
134
|
+
group :development, :test do
|
135
|
+
gem "debug", platforms: %i[ mri mswin mswin64 mingw x64_mingw ], require: "debug/prelude"
|
136
|
+
gem "brakeman", require: false
|
137
|
+
gem "rubocop-rails-omakase", require: false
|
138
|
+
end
|
139
|
+
|
140
|
+
# Regolith vendored gem so the container can build without network access to your local gem
|
141
|
+
gem "regolith", path: "vendor/regolith"
|
142
|
+
GEMFILE
|
258
143
|
|
259
|
-
# Write Gemfile (no vendoring; pull from RubyGems)
|
260
|
-
custom_gemfile = generate_gemfile(major_minor)
|
261
144
|
File.write("#{service_dir}/Gemfile", custom_gemfile)
|
262
145
|
|
146
|
+
# Vendor Regolith gem into service for Docker compatibility
|
147
|
+
vendor_dir = File.join(service_dir, "vendor")
|
148
|
+
FileUtils.mkdir_p(vendor_dir)
|
149
|
+
FileUtils.cp_r(File.expand_path("../..", __dir__), File.join(vendor_dir, "regolith"))
|
150
|
+
puts "📦 Vendored Regolith gem into #{File.join(service_dir, 'vendor', 'regolith')}"
|
151
|
+
|
263
152
|
puts " → Running bundle install..."
|
264
153
|
Dir.chdir(service_dir) do
|
265
154
|
unless system("bundle install")
|
266
155
|
puts "❌ bundle install failed"
|
267
|
-
puts "→ You may be missing system libraries like libyaml-dev build-essential"
|
156
|
+
puts "→ You may be missing system libraries like libyaml-dev libsqlite3-dev build-essential pkg-config"
|
157
|
+
puts "→ Try: sudo apt install -y libyaml-dev libsqlite3-dev build-essential pkg-config"
|
268
158
|
exit 1
|
269
159
|
end
|
270
160
|
end
|
271
161
|
|
272
162
|
patch_rails_app(service_dir, service_name, port)
|
273
|
-
|
274
|
-
|
275
|
-
def generate_gemfile(ruby_version)
|
276
|
-
<<~GEMFILE
|
277
|
-
source "https://rubygems.org"
|
163
|
+
patch_bootsnap(service_dir)
|
278
164
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
gem "bootsnap", require: false
|
286
|
-
|
287
|
-
group :development, :test do
|
288
|
-
gem "debug", platforms: %i[mri mswin mswin64 mingw x64_mingw], require: "debug/prelude"
|
289
|
-
gem "brakeman", require: false
|
290
|
-
gem "rubocop-rails-omakase", require: false
|
291
|
-
end
|
165
|
+
config['services'][service_name] = {
|
166
|
+
'port' => port,
|
167
|
+
'root' => "./#{service_dir}"
|
168
|
+
}
|
169
|
+
save_regolith_config(config)
|
170
|
+
update_docker_compose(config)
|
292
171
|
|
293
|
-
|
294
|
-
|
172
|
+
puts "✅ Created service '#{service_name}'"
|
173
|
+
puts "🚀 Service running on port #{port}"
|
174
|
+
puts "→ Next: regolith generate service <another_service> or regolith server"
|
295
175
|
end
|
296
176
|
|
297
177
|
def patch_rails_app(service_dir, service_name, port)
|
298
|
-
create_initializers(service_dir, service_name)
|
299
|
-
create_health_controller(service_dir)
|
300
|
-
add_health_route(service_dir)
|
301
|
-
File.write("#{service_dir}/Dockerfile", generate_dockerfile)
|
302
|
-
patch_application_rb(service_dir, service_name, port)
|
303
|
-
end
|
304
|
-
|
305
|
-
def create_initializers(service_dir, service_name)
|
306
178
|
initializer_dir = "#{service_dir}/config/initializers"
|
307
179
|
FileUtils.mkdir_p(initializer_dir)
|
308
|
-
|
309
180
|
File.write("#{initializer_dir}/regolith.rb", generate_regolith_initializer(service_name))
|
310
|
-
File.write("#{
|
311
|
-
end
|
312
|
-
|
313
|
-
def create_health_controller(service_dir)
|
314
|
-
controller_dir = "#{service_dir}/app/controllers/regolith"
|
315
|
-
FileUtils.mkdir_p(controller_dir)
|
316
|
-
|
317
|
-
File.write("#{controller_dir}/health_controller.rb", generate_health_controller)
|
318
|
-
end
|
319
|
-
|
320
|
-
def add_health_route(service_dir)
|
321
|
-
routes_path = File.join(service_dir, "config/routes.rb")
|
322
|
-
content = File.read(routes_path)
|
323
|
-
|
324
|
-
# Try to inject before the final end, or append if no clear structure
|
325
|
-
if content.sub!(/end\s*\z/, " get '/health', to: 'regolith/health#show'\nend\n")
|
326
|
-
File.write(routes_path, content)
|
327
|
-
else
|
328
|
-
# Fallback: append inside the draw block
|
329
|
-
File.open(routes_path, "a") { |f| f.puts "get '/health', to: 'regolith/health#show'" }
|
330
|
-
end
|
331
|
-
end
|
181
|
+
File.write("#{service_dir}/Dockerfile", generate_dockerfile)
|
332
182
|
|
333
|
-
def patch_application_rb(service_dir, service_name, port)
|
334
183
|
app_rb_path = "#{service_dir}/config/application.rb"
|
335
184
|
app_rb_content = File.read(app_rb_path)
|
336
185
|
|
337
186
|
cors_config = <<~RUBY
|
338
187
|
|
339
188
|
# Regolith configuration
|
189
|
+
config.middleware.insert_before 0, Rack::Cors do
|
190
|
+
allow do
|
191
|
+
origins '*'
|
192
|
+
resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head]
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
340
196
|
config.regolith_service_name = '#{service_name}'
|
341
197
|
config.regolith_service_port = #{port}
|
342
198
|
RUBY
|
343
199
|
|
344
|
-
app_rb_content.gsub!(/
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
# Service management commands
|
349
|
-
def start_server(_flags = {})
|
350
|
-
unless File.exist?('docker-compose.yml')
|
351
|
-
puts "❌ Error: Not in a Regolith app directory"
|
352
|
-
exit 1
|
200
|
+
app_rb_content.gsub!(/class Application < Rails::Application.*?
|
201
|
+
end/m) do |match|
|
202
|
+
match.gsub(/(\n end)$/, "#{cors_config}\1")
|
353
203
|
end
|
354
204
|
|
355
|
-
|
356
|
-
|
357
|
-
config = load_regolith_config
|
358
|
-
show_service_info(config)
|
359
|
-
|
360
|
-
exec_compose('up', '--build')
|
361
|
-
end
|
362
|
-
|
363
|
-
def stop_services
|
364
|
-
puts "🛑 Stopping all services..."
|
365
|
-
exec_compose('down', '-v')
|
205
|
+
File.write(app_rb_path, app_rb_content)
|
366
206
|
end
|
367
207
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
exec_compose('restart', service_name)
|
373
|
-
else
|
374
|
-
puts "🔄 Restarting all services..."
|
375
|
-
exec_compose('restart')
|
376
|
-
end
|
377
|
-
end
|
208
|
+
# ---- Bootsnap Patch: make it optional & non-fatal ----
|
209
|
+
def patch_bootsnap(service_dir)
|
210
|
+
boot_path = File.join(service_dir, "config", "boot.rb")
|
211
|
+
return unless File.exist?(boot_path)
|
378
212
|
|
379
|
-
|
380
|
-
if service_name
|
381
|
-
ensure_service_exists!(service_name)
|
382
|
-
puts "⏹ Stopping service '#{service_name}'..."
|
383
|
-
exec_compose('stop', service_name)
|
384
|
-
else
|
385
|
-
puts "⏹ Stopping all services..."
|
386
|
-
exec_compose('stop')
|
387
|
-
end
|
388
|
-
end
|
213
|
+
content = File.read(boot_path)
|
389
214
|
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
system_compose('ps', '--format', 'json') ||
|
397
|
-
system_compose('ps')
|
398
|
-
|
399
|
-
# Show summary counts and health check for exit code
|
400
|
-
if success
|
401
|
-
config = load_regolith_config
|
402
|
-
service_count = config['services'].size
|
403
|
-
ports = config['services'].values.map { |s| s['port'] }.sort
|
404
|
-
|
405
|
-
puts
|
406
|
-
puts "📋 Summary: #{service_count} services configured"
|
407
|
-
puts "🚪 Ports: #{ports.join(', ')}" if ports.any?
|
408
|
-
|
409
|
-
# Check health for proper exit code
|
410
|
-
healthy_services = 0
|
411
|
-
config['services'].each do |name, service_config|
|
412
|
-
port = service_config['port']
|
413
|
-
status = check_service_health(port)
|
414
|
-
healthy_services += 1 if status[:healthy]
|
215
|
+
# Remove any unconditional bootsnap require and replace with guarded load
|
216
|
+
content.gsub!(/^\s*require\s+["']bootsnap\/setup["']\s*$/, <<~RUBY.strip)
|
217
|
+
begin
|
218
|
+
require "bootsnap/setup"
|
219
|
+
rescue LoadError
|
220
|
+
warn "[regolith] bootsnap not found; continuing without it"
|
415
221
|
end
|
222
|
+
RUBY
|
416
223
|
|
417
|
-
|
418
|
-
puts "⚠️ #{service_count - healthy_services} services unhealthy"
|
419
|
-
exit 1
|
420
|
-
end
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
def show_logs(service_name = nil, flags = {})
|
425
|
-
args = ['logs']
|
426
|
-
args << '--follow' if flags[:follow] || flags[:f]
|
427
|
-
args << service_name if service_name
|
428
|
-
|
429
|
-
exec_compose(*args)
|
430
|
-
end
|
431
|
-
|
432
|
-
def exec_command(service_name, command_args)
|
433
|
-
ensure_service_exists!(service_name)
|
434
|
-
|
435
|
-
if command_args.empty?
|
436
|
-
command_args = ['bash']
|
437
|
-
end
|
438
|
-
|
439
|
-
exec_compose('exec', service_name, *command_args)
|
440
|
-
end
|
441
|
-
|
442
|
-
def shell_service(service_name)
|
443
|
-
unless service_name
|
444
|
-
puts "❌ Error: Service name required"
|
445
|
-
puts "Usage: regolith shell <service_name>"
|
446
|
-
exit 1
|
447
|
-
end
|
448
|
-
|
449
|
-
ensure_service_exists!(service_name)
|
450
|
-
puts "🐚 Opening shell for #{service_name}_service..."
|
451
|
-
exec_compose('exec', service_name, 'bash')
|
452
|
-
end
|
453
|
-
|
454
|
-
# Rails integration commands
|
455
|
-
def rails_passthrough(service_name, rails_args)
|
456
|
-
ensure_service_exists!(service_name)
|
457
|
-
|
458
|
-
if rails_args.empty?
|
459
|
-
puts "❌ Error: Rails command required"
|
460
|
-
puts "Usage: regolith rails <service> <command>"
|
461
|
-
exit 1
|
462
|
-
end
|
463
|
-
|
464
|
-
exec_compose('exec', service_name, 'bash', '-lc',
|
465
|
-
"bundle exec rails #{Shellwords.join(rails_args)}")
|
466
|
-
end
|
467
|
-
|
468
|
-
def open_console(service_name)
|
469
|
-
unless service_name
|
470
|
-
puts "❌ Error: Service name required"
|
471
|
-
puts "Usage: regolith console <service_name>"
|
472
|
-
exit 1
|
473
|
-
end
|
474
|
-
|
475
|
-
ensure_service_exists!(service_name)
|
476
|
-
puts "🧪 Opening Rails console for #{service_name}_service..."
|
477
|
-
exec_compose('exec', service_name, 'rails', 'console')
|
224
|
+
File.write(boot_path, content)
|
478
225
|
end
|
226
|
+
# ------------------------------------------------------
|
479
227
|
|
480
|
-
def
|
481
|
-
unless
|
482
|
-
puts "❌ Error:
|
483
|
-
puts "Usage: regolith open <service_name>"
|
228
|
+
def start_server
|
229
|
+
unless File.exist?('docker-compose.yml')
|
230
|
+
puts "❌ Error: Not in a Regolith app directory"
|
484
231
|
exit 1
|
485
232
|
end
|
486
233
|
|
487
|
-
|
234
|
+
puts "🚀 Starting Regolith services..."
|
488
235
|
config = load_regolith_config
|
489
|
-
port = config['services'][service_name]['port']
|
490
|
-
url = "http://localhost:#{port}"
|
491
|
-
|
492
|
-
puts "🌐 Opening #{url}..."
|
493
236
|
|
494
|
-
|
495
|
-
|
496
|
-
when /mswin|mingw|cygwin/
|
497
|
-
system(%{start "" "#{url}"})
|
498
|
-
when /darwin/
|
499
|
-
system("open #{url}")
|
500
|
-
else
|
501
|
-
system("xdg-open #{url}") || puts("Visit: #{url}")
|
502
|
-
end
|
503
|
-
end
|
504
|
-
|
505
|
-
# Database commands
|
506
|
-
def db_command(action, target, flags = {})
|
507
|
-
case action
|
508
|
-
when 'create', 'migrate', 'seed', 'reset', 'setup', 'drop'
|
509
|
-
each_target_service(target, flags) do |service|
|
510
|
-
puts "🗄 Running db:#{action} for #{service}..."
|
511
|
-
success = system_compose('exec', service, 'bash', '-lc', "bundle exec rails db:#{action}")
|
512
|
-
|
513
|
-
unless success
|
514
|
-
puts "❌ db:#{action} failed for #{service} (exit code: #{$?.exitstatus})"
|
515
|
-
exit 1 unless flags[:continue_on_failure]
|
516
|
-
end
|
517
|
-
end
|
518
|
-
else
|
519
|
-
puts "❌ Unknown db action: #{action}"
|
520
|
-
puts "Available: create, migrate, seed, reset, setup, drop"
|
521
|
-
exit 1
|
237
|
+
config['services'].each do |name, service|
|
238
|
+
puts "🚀 #{name}_service running at http://localhost:#{service['port']}"
|
522
239
|
end
|
523
|
-
end
|
524
240
|
|
525
|
-
|
526
|
-
|
527
|
-
each_target_service(target, flags) do |service|
|
528
|
-
puts "🧪 Running tests for #{service}..."
|
529
|
-
success = system_compose('exec', service, 'bash', '-lc', 'bundle exec rails test')
|
241
|
+
puts "🧭 Service registry loaded from config/regolith.yml"
|
242
|
+
puts ""
|
530
243
|
|
531
|
-
|
532
|
-
puts "❌ Tests failed for #{service} (exit code: #{$?.exitstatus})"
|
533
|
-
exit 1 unless flags[:continue_on_failure]
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
|
-
puts "✅ All tests passed!" if flags[:all]
|
244
|
+
exec("docker-compose up --build")
|
538
245
|
end
|
539
246
|
|
540
|
-
def
|
247
|
+
def open_console(service_name)
|
541
248
|
unless service_name
|
542
249
|
puts "❌ Error: Service name required"
|
543
|
-
puts "Usage: regolith
|
250
|
+
puts "Usage: regolith console <service_name>"
|
544
251
|
exit 1
|
545
252
|
end
|
546
253
|
|
547
|
-
ensure_service_exists!(service_name)
|
548
|
-
puts "🛤 Routes for #{service_name}:"
|
549
|
-
system_compose('exec', service_name, 'bash', '-lc', 'bundle exec rails routes')
|
550
|
-
end
|
551
|
-
|
552
|
-
# Health and monitoring
|
553
|
-
def health_check
|
554
|
-
puts "🔍 Health Check Results:"
|
555
|
-
puts
|
556
|
-
|
557
|
-
config = load_regolith_config
|
558
|
-
|
559
|
-
config['services'].each do |name, service_config|
|
560
|
-
port = service_config['port']
|
561
|
-
status = check_service_health(port)
|
562
|
-
|
563
|
-
status_icon = status[:healthy] ? '✅' : '❌'
|
564
|
-
puts "#{status_icon} #{name} (port #{port}) - #{status[:message]}"
|
565
|
-
|
566
|
-
# Show additional health data if available
|
567
|
-
if status[:data] && status[:data]['version']
|
568
|
-
puts " Version: #{status[:data]['version']}"
|
569
|
-
end
|
570
|
-
if status[:data] && status[:data]['time']
|
571
|
-
puts " Last seen: #{Time.at(status[:data]['time']).strftime('%H:%M:%S')}"
|
572
|
-
end
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
def check_service_health(port)
|
577
|
-
begin
|
578
|
-
uri = URI("http://localhost:#{port}/health")
|
579
|
-
response = Net::HTTP.get_response(uri)
|
580
|
-
|
581
|
-
if response.code.to_i == 200
|
582
|
-
# Try to parse structured health data
|
583
|
-
health_data = JSON.parse(response.body) rescue {}
|
584
|
-
{
|
585
|
-
healthy: true,
|
586
|
-
message: 'healthy',
|
587
|
-
data: health_data
|
588
|
-
}
|
589
|
-
else
|
590
|
-
{ healthy: false, message: "HTTP #{response.code}" }
|
591
|
-
end
|
592
|
-
rescue
|
593
|
-
{ healthy: false, message: 'unreachable' }
|
594
|
-
end
|
595
|
-
end
|
596
|
-
|
597
|
-
# Configuration
|
598
|
-
def show_config(flags = {})
|
599
|
-
config = load_regolith_config
|
600
|
-
|
601
|
-
if flags[:json]
|
602
|
-
puts JSON.pretty_generate(config)
|
603
|
-
else
|
604
|
-
puts "📋 Current Configuration:"
|
605
|
-
puts
|
606
|
-
puts YAML.dump(config)
|
607
|
-
end
|
608
|
-
end
|
609
|
-
|
610
|
-
# Maintenance commands
|
611
|
-
def prune_system
|
612
|
-
puts "🧹 Pruning Docker system..."
|
613
|
-
exec_compose('down', '-v')
|
614
|
-
system('docker', 'system', 'prune', '-f')
|
615
|
-
puts "✅ System pruned"
|
616
|
-
end
|
617
|
-
|
618
|
-
def rebuild_service(service_name = nil)
|
619
|
-
if service_name
|
620
|
-
ensure_service_exists!(service_name)
|
621
|
-
puts "🔨 Rebuilding service '#{service_name}'..."
|
622
|
-
exec_compose('build', '--no-cache', service_name)
|
623
|
-
else
|
624
|
-
puts "🔨 Rebuilding all services..."
|
625
|
-
exec_compose('build', '--no-cache')
|
626
|
-
end
|
627
|
-
end
|
628
|
-
|
629
|
-
# System diagnostics
|
630
|
-
def run_doctor
|
631
|
-
puts "🩺 Regolith System Doctor"
|
632
|
-
puts "=" * 40
|
633
|
-
|
634
|
-
checks = [
|
635
|
-
{ name: "Docker", check: -> { system('docker --version > /dev/null 2>&1') } },
|
636
|
-
{ name: "Docker Compose", check: -> { docker_compose_available? } },
|
637
|
-
{ name: "Ruby", check: -> { system('ruby --version > /dev/null 2>&1') } },
|
638
|
-
{ name: "Rails", check: -> { system('rails --version > /dev/null 2>&1') } },
|
639
|
-
{ name: "PostgreSQL Client", check: -> { system('psql --version > /dev/null 2>&1') } }
|
640
|
-
]
|
641
|
-
|
642
|
-
checks.each do |check|
|
643
|
-
status = check[:check].call ? "✅" : "❌"
|
644
|
-
puts "#{status} #{check[:name]}"
|
645
|
-
end
|
646
|
-
|
647
|
-
puts
|
648
|
-
check_regolith_config
|
649
|
-
end
|
650
|
-
|
651
|
-
def check_regolith_config
|
652
|
-
puts "📋 Checking Regolith configuration..."
|
653
|
-
|
654
|
-
if File.exist?('config/regolith.yml')
|
655
|
-
config = load_regolith_config
|
656
|
-
|
657
|
-
if config['services'].empty?
|
658
|
-
puts "⚠️ No services configured"
|
659
|
-
else
|
660
|
-
puts "✅ Configuration valid (#{config['services'].size} services)"
|
661
|
-
end
|
662
|
-
else
|
663
|
-
puts "❌ No regolith.yml found - not in a Regolith project?"
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
|
-
def inspect_services(flags = {})
|
668
|
-
puts "🔍 Regolith Services Inspection"
|
669
|
-
puts "=" * 40
|
670
|
-
|
671
254
|
config = load_regolith_config
|
672
|
-
|
673
|
-
|
674
|
-
puts "No services configured yet."
|
675
|
-
return
|
676
|
-
end
|
677
|
-
|
678
|
-
if flags[:json]
|
679
|
-
# JSON output for automation
|
680
|
-
inspection_data = {
|
681
|
-
services: config['services'].map do |name, service_config|
|
682
|
-
{
|
683
|
-
name: name,
|
684
|
-
port: service_config['port'],
|
685
|
-
endpoint: "http://localhost:#{service_config['port']}",
|
686
|
-
root: service_config['root']
|
687
|
-
}
|
688
|
-
end,
|
689
|
-
config: config
|
690
|
-
}
|
691
|
-
puts JSON.pretty_generate(inspection_data)
|
692
|
-
else
|
693
|
-
# Human-readable output
|
694
|
-
puts "\n📊 Service Endpoints:"
|
695
|
-
config['services'].each do |name, service_config|
|
696
|
-
port = service_config['port']
|
697
|
-
puts " #{name}: http://localhost:#{port}"
|
698
|
-
end
|
699
|
-
|
700
|
-
puts "\n📋 Full Configuration:"
|
701
|
-
puts YAML.dump(config)
|
702
|
-
end
|
703
|
-
end
|
704
|
-
|
705
|
-
# Helper methods
|
706
|
-
def docker_compose_available?
|
707
|
-
system('docker compose version > /dev/null 2>&1') ||
|
708
|
-
system('docker-compose version > /dev/null 2>&1')
|
709
|
-
end
|
710
|
-
|
711
|
-
def docker_compose_command
|
712
|
-
if system('docker compose version > /dev/null 2>&1')
|
713
|
-
%w[docker compose]
|
714
|
-
elsif system('docker-compose version > /dev/null 2>&1')
|
715
|
-
%w[docker-compose]
|
716
|
-
else
|
717
|
-
puts "❌ Docker Compose not found"
|
255
|
+
unless config['services'][service_name]
|
256
|
+
puts "❌ Error: Service '#{service_name}' not found"
|
718
257
|
exit 1
|
719
258
|
end
|
720
|
-
end
|
721
|
-
|
722
|
-
def exec_compose(*args)
|
723
|
-
cmd = docker_compose_command + args
|
724
|
-
exec(*cmd)
|
725
|
-
end
|
726
|
-
|
727
|
-
def system_compose(*args)
|
728
|
-
cmd = docker_compose_command + args
|
729
|
-
system(*cmd)
|
730
|
-
end
|
731
|
-
|
732
|
-
def each_target_service(target, flags = {})
|
733
|
-
services = if target == '--all' || target.nil? || flags[:all]
|
734
|
-
load_regolith_config['services'].keys
|
735
|
-
else
|
736
|
-
[target]
|
737
|
-
end
|
738
259
|
|
739
|
-
|
740
|
-
|
741
|
-
yield(service)
|
742
|
-
end
|
743
|
-
end
|
744
|
-
|
745
|
-
def ensure_service_exists!(service_name)
|
746
|
-
config = load_regolith_config
|
747
|
-
unless config['services'].key?(service_name)
|
748
|
-
puts "❌ Service '#{service_name}' not found"
|
749
|
-
puts "Available services: #{config['services'].keys.join(', ')}"
|
750
|
-
exit 1
|
751
|
-
end
|
752
|
-
end
|
753
|
-
|
754
|
-
def show_service_info(config)
|
755
|
-
config['services'].each do |name, service|
|
756
|
-
puts "🚀 #{name}_service: http://localhost:#{service['port']}"
|
757
|
-
end
|
758
|
-
|
759
|
-
puts "🧭 Service registry: config/regolith.yml"
|
760
|
-
puts
|
260
|
+
puts "🧪 Opening Rails console for #{service_name}_service..."
|
261
|
+
exec("docker-compose exec #{service_name} rails console")
|
761
262
|
end
|
762
263
|
|
763
264
|
def load_regolith_config
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
# Use safe YAML loading
|
768
|
-
config = Psych.safe_load(File.read(config_path), permitted_classes: [], aliases: false) || {}
|
265
|
+
return({ 'services' => {} }) unless File.exist?('config/regolith.yml')
|
266
|
+
config = YAML.load_file('config/regolith.yml') || {}
|
769
267
|
config['services'] ||= {}
|
770
268
|
config
|
771
269
|
end
|
@@ -773,7 +271,6 @@ module Regolith
|
|
773
271
|
def save_regolith_config(config)
|
774
272
|
FileUtils.mkdir_p('config')
|
775
273
|
File.write('config/regolith.yml', YAML.dump(config))
|
776
|
-
Regolith.reload_service_registry!
|
777
274
|
end
|
778
275
|
|
779
276
|
def update_docker_compose(config)
|
@@ -781,91 +278,57 @@ module Regolith
|
|
781
278
|
File.write('docker-compose.yml', docker_compose)
|
782
279
|
end
|
783
280
|
|
784
|
-
# File generators
|
785
281
|
def generate_docker_compose(app_name, services = {})
|
786
|
-
|
787
|
-
'
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
'volumes' => ["#{service['root']}:/app"],
|
823
|
-
'command' => 'bash -c "rm -f tmp/pids/server.pid && bundle install && rails db:prepare && rails server -b 0.0.0.0"',
|
824
|
-
'healthcheck' => {
|
825
|
-
'test' => ['CMD-SHELL', 'curl -f http://localhost:3000/health || exit 1'],
|
826
|
-
'interval' => '30s', 'timeout' => '10s', 'retries' => 3, 'start_period' => '40s'
|
827
|
-
}
|
828
|
-
}
|
829
|
-
end
|
830
|
-
|
831
|
-
|
832
|
-
{
|
833
|
-
'version' => '3.8',
|
834
|
-
'networks' => {
|
835
|
-
'regolith' => {}
|
836
|
-
},
|
837
|
-
'services' => compose_services,
|
838
|
-
'volumes' => {
|
839
|
-
'postgres_data' => nil
|
840
|
-
}
|
841
|
-
}.to_yaml
|
282
|
+
template = <<~YAML
|
283
|
+
version: '3.8'
|
284
|
+
|
285
|
+
services:
|
286
|
+
db:
|
287
|
+
image: postgres:14
|
288
|
+
environment:
|
289
|
+
POSTGRES_DB: #{app_name}_development
|
290
|
+
POSTGRES_USER: postgres
|
291
|
+
POSTGRES_PASSWORD: password
|
292
|
+
ports:
|
293
|
+
- "5432:5432"
|
294
|
+
volumes:
|
295
|
+
- postgres_data:/var/lib/postgresql/data
|
296
|
+
|
297
|
+
<% services.each do |name, service| %>
|
298
|
+
<%= name %>:
|
299
|
+
build: <%= service['root'] %>
|
300
|
+
ports:
|
301
|
+
- "<%= service['port'] %>:3000"
|
302
|
+
depends_on:
|
303
|
+
- db
|
304
|
+
environment:
|
305
|
+
DATABASE_URL: postgres://postgres:password@db:5432/<%= app_name %>_development
|
306
|
+
REGOLITH_SERVICE_NAME: <%= name %>
|
307
|
+
REGOLITH_SERVICE_PORT: <%= service['port'] %>
|
308
|
+
volumes:
|
309
|
+
- <%= service['root'] %>:/app
|
310
|
+
command: bash -c "rm -f tmp/pids/server.pid && bundle install && rails server -b 0.0.0.0"
|
311
|
+
<% end %>
|
312
|
+
|
313
|
+
volumes:
|
314
|
+
postgres_data:
|
315
|
+
YAML
|
316
|
+
|
317
|
+
ERB.new(template).result(binding)
|
842
318
|
end
|
843
319
|
|
844
320
|
def generate_dockerfile
|
845
321
|
<<~DOCKERFILE
|
846
|
-
FROM ruby:3.1
|
847
|
-
|
848
|
-
# Install system dependencies
|
849
|
-
RUN apt-get update -qq && \\
|
850
|
-
apt-get install -y nodejs postgresql-client libyaml-dev build-essential pkg-config curl && \\
|
851
|
-
apt-get clean && \\
|
852
|
-
rm -rf /var/lib/apt/lists/*
|
322
|
+
FROM ruby:3.1
|
853
323
|
|
854
324
|
WORKDIR /app
|
855
325
|
|
856
|
-
|
857
|
-
COPY Gemfile Gemfile.lock* ./
|
326
|
+
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client libyaml-dev libsqlite3-dev build-essential pkg-config
|
858
327
|
|
859
|
-
# Conditional bundler config for dev vs prod
|
860
|
-
ARG BUILD_ENV=development
|
861
|
-
RUN if [ "$BUILD_ENV" = "production" ]; then \\
|
862
|
-
bundle config set --local deployment 'true' && \\
|
863
|
-
bundle config set --local without 'development test'; \\
|
864
|
-
fi && bundle install
|
865
|
-
|
866
|
-
# Copy application code
|
867
328
|
COPY . .
|
868
329
|
|
330
|
+
RUN bundle install
|
331
|
+
|
869
332
|
EXPOSE 3000
|
870
333
|
|
871
334
|
CMD ["rails", "server", "-b", "0.0.0.0"]
|
@@ -875,17 +338,15 @@ module Regolith
|
|
875
338
|
def generate_regolith_initializer(service_name)
|
876
339
|
<<~RUBY
|
877
340
|
require 'ostruct'
|
878
|
-
|
341
|
+
|
879
342
|
# Regolith service configuration
|
880
343
|
Rails.application.configure do
|
881
344
|
config.regolith = OpenStruct.new(
|
882
345
|
service_name: '#{service_name}',
|
883
|
-
service_registry: Rails.root.join('../../config/regolith.yml')
|
884
|
-
version: Regolith::VERSION
|
346
|
+
service_registry: Rails.root.join('../../config/regolith.yml')
|
885
347
|
)
|
886
348
|
end
|
887
349
|
|
888
|
-
# Load service registry if available
|
889
350
|
if File.exist?(Rails.application.config.regolith.service_registry)
|
890
351
|
REGOLITH_SERVICES = YAML.load_file(Rails.application.config.regolith.service_registry)['services'] || {}
|
891
352
|
else
|
@@ -894,184 +355,22 @@ module Regolith
|
|
894
355
|
RUBY
|
895
356
|
end
|
896
357
|
|
897
|
-
def generate_cors_initializer
|
898
|
-
<<~RUBY
|
899
|
-
# CORS configuration for microservices
|
900
|
-
Rails.application.config.middleware.insert_before 0, Rack::Cors do
|
901
|
-
allow do
|
902
|
-
origins '*' # Configure appropriately for production
|
903
|
-
resource '*',
|
904
|
-
headers: :any,
|
905
|
-
methods: %i[get post put patch delete options head],
|
906
|
-
expose: %w[Authorization Content-Type],
|
907
|
-
max_age: 600
|
908
|
-
end
|
909
|
-
end
|
910
|
-
RUBY
|
911
|
-
end
|
912
|
-
|
913
|
-
def generate_health_controller
|
914
|
-
<<~RUBY
|
915
|
-
module Regolith
|
916
|
-
class HealthController < ActionController::API
|
917
|
-
def show
|
918
|
-
render json: {
|
919
|
-
ok: true,
|
920
|
-
service: Rails.application.config.regolith_service_name,
|
921
|
-
time: Time.now.to_i,
|
922
|
-
version: Rails.application.config.regolith.version
|
923
|
-
}
|
924
|
-
end
|
925
|
-
end
|
926
|
-
end
|
927
|
-
RUBY
|
928
|
-
end
|
929
|
-
|
930
|
-
def generate_gitignore
|
931
|
-
<<~GITIGNORE
|
932
|
-
# Regolith
|
933
|
-
/services/*/log/*
|
934
|
-
/services/*/tmp/*
|
935
|
-
/services/*/.env*
|
936
|
-
.DS_Store
|
937
|
-
|
938
|
-
# Docker
|
939
|
-
docker-compose.override.yml
|
940
|
-
|
941
|
-
# Logs
|
942
|
-
*.log
|
943
|
-
|
944
|
-
# Runtime data
|
945
|
-
pids
|
946
|
-
*.pid
|
947
|
-
*.seed
|
948
|
-
|
949
|
-
# Environment variables
|
950
|
-
.env*
|
951
|
-
!.env.example
|
952
|
-
GITIGNORE
|
953
|
-
end
|
954
|
-
|
955
|
-
def generate_readme(app_name)
|
956
|
-
<<~MARKDOWN
|
957
|
-
# #{app_name.capitalize}
|
958
|
-
|
959
|
-
A Regolith microservices application built with Rails and Docker.
|
960
|
-
|
961
|
-
## Getting Started
|
962
|
-
|
963
|
-
```bash
|
964
|
-
# Start all services
|
965
|
-
regolith server
|
966
|
-
|
967
|
-
# Generate a new service
|
968
|
-
regolith generate service users
|
969
|
-
|
970
|
-
# Open service in browser
|
971
|
-
regolith open users
|
972
|
-
|
973
|
-
# View service logs
|
974
|
-
regolith logs users -f
|
975
|
-
|
976
|
-
# Run database migrations
|
977
|
-
regolith db:migrate --all
|
978
|
-
|
979
|
-
# Health check
|
980
|
-
regolith health
|
981
|
-
```
|
982
|
-
|
983
|
-
## Services
|
984
|
-
|
985
|
-
#{services_documentation}
|
986
|
-
|
987
|
-
## Development
|
988
|
-
|
989
|
-
```bash
|
990
|
-
# Open Rails console for a service
|
991
|
-
regolith console users
|
992
|
-
|
993
|
-
# Run Rails commands
|
994
|
-
regolith rails users db:migrate
|
995
|
-
regolith rails users routes
|
996
|
-
|
997
|
-
# Run tests
|
998
|
-
regolith test --all
|
999
|
-
|
1000
|
-
# Execute commands in service
|
1001
|
-
regolith exec users bash
|
1002
|
-
```
|
1003
|
-
|
1004
|
-
## Architecture
|
1005
|
-
|
1006
|
-
- **Rails 7** API-only applications
|
1007
|
-
- **PostgreSQL** for persistence
|
1008
|
-
- **Docker Compose** for orchestration
|
1009
|
-
- **Service registry** for inter-service communication
|
1010
|
-
|
1011
|
-
Built with [Regolith](https://regolith.bio) - Rails for distributed systems.
|
1012
|
-
MARKDOWN
|
1013
|
-
end
|
1014
|
-
|
1015
|
-
def services_documentation
|
1016
|
-
config = load_regolith_config
|
1017
|
-
return "No services yet. Run `regolith generate service <name>` to create one." if config['services'].empty?
|
1018
|
-
|
1019
|
-
config['services'].map do |name, service|
|
1020
|
-
"- **#{name}** - http://localhost:#{service['port']}"
|
1021
|
-
end.join("\n")
|
1022
|
-
end
|
1023
|
-
|
1024
358
|
def generate_makefile
|
1025
359
|
<<~MAKEFILE
|
1026
|
-
.PHONY: server
|
360
|
+
.PHONY: server console build clean
|
1027
361
|
|
1028
|
-
|
1029
|
-
|
1030
|
-
\tregolith server
|
362
|
+
server:
|
363
|
+
regolith server
|
1031
364
|
|
1032
|
-
# Stop services
|
1033
|
-
down:
|
1034
|
-
\tregolith down
|
1035
|
-
|
1036
|
-
# Restart services
|
1037
|
-
restart:
|
1038
|
-
\tregolith restart
|
1039
|
-
|
1040
|
-
# View logs
|
1041
|
-
logs:
|
1042
|
-
\tregolith logs -f
|
1043
|
-
|
1044
|
-
# Open console (usage: make console SERVICE=users)
|
1045
365
|
console:
|
1046
|
-
|
1047
|
-
\tregolith console $(SERVICE)
|
1048
|
-
|
1049
|
-
# Run tests
|
1050
|
-
test:
|
1051
|
-
\tregolith test --all
|
1052
|
-
|
1053
|
-
# Health check
|
1054
|
-
health:
|
1055
|
-
\tregolith health
|
366
|
+
regolith console
|
1056
367
|
|
1057
|
-
|
1058
|
-
|
1059
|
-
\tregolith doctor
|
368
|
+
build:
|
369
|
+
docker-compose build
|
1060
370
|
|
1061
|
-
# Database operations
|
1062
|
-
db-migrate:
|
1063
|
-
\tregolith db:migrate --all
|
1064
|
-
|
1065
|
-
db-setup:
|
1066
|
-
\tregolith db:setup --all
|
1067
|
-
|
1068
|
-
# Cleanup
|
1069
371
|
clean:
|
1070
|
-
|
1071
|
-
|
1072
|
-
# Shortcuts
|
1073
|
-
dev: up
|
1074
|
-
stop: down
|
372
|
+
docker-compose down -v
|
373
|
+
docker system prune -f
|
1075
374
|
MAKEFILE
|
1076
375
|
end
|
1077
376
|
|
@@ -1084,62 +383,24 @@ module Regolith
|
|
1084
383
|
|
1085
384
|
def show_help
|
1086
385
|
puts <<~HELP
|
1087
|
-
Regolith #{Regolith::VERSION} -
|
386
|
+
Regolith #{Regolith::VERSION} - Microservices framework
|
1088
387
|
|
1089
388
|
USAGE:
|
1090
389
|
regolith <command> [options]
|
1091
390
|
|
1092
|
-
|
391
|
+
COMMANDS:
|
1093
392
|
new <app_name> Create a new Regolith application
|
1094
393
|
generate service <name> Generate a new microservice
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
down Stop and remove all services
|
1099
|
-
restart [service] Restart one or all services
|
1100
|
-
stop [service] Stop one or all services
|
1101
|
-
ps, status Show running containers
|
1102
|
-
logs [service] [-f] View service logs
|
1103
|
-
exec <service> [cmd] Execute command in service container
|
1104
|
-
shell <service> Open shell in service container
|
1105
|
-
rebuild [service] Rebuild service images
|
1106
|
-
|
1107
|
-
RAILS INTEGRATION:
|
1108
|
-
console <service> Open Rails console for service
|
1109
|
-
rails <service> <cmd> Run Rails command in service
|
1110
|
-
routes <service> Show routes for service
|
1111
|
-
open <service> Open service in browser
|
1112
|
-
|
1113
|
-
DATABASE OPERATIONS:
|
1114
|
-
db:migrate [service|--all] Run migrations
|
1115
|
-
db:create [service|--all] Create databases
|
1116
|
-
db:seed [service|--all] Seed databases
|
1117
|
-
db:reset [service|--all] Reset databases
|
1118
|
-
db:setup [service|--all] Setup databases
|
1119
|
-
db:drop [service|--all] Drop databases
|
1120
|
-
|
1121
|
-
TESTING & HEALTH:
|
1122
|
-
test [service|--all] Run tests
|
1123
|
-
health Health check all services
|
1124
|
-
|
1125
|
-
UTILITIES:
|
1126
|
-
config [--json] Show current configuration
|
1127
|
-
inspect [--json] Show services and resolved endpoints
|
1128
|
-
prune Clean up Docker system
|
1129
|
-
doctor Run system diagnostics
|
1130
|
-
version Show version
|
394
|
+
server Start all services with Docker Compose
|
395
|
+
console <service_name> Open Rails console for a service
|
396
|
+
version Show version information
|
1131
397
|
|
1132
398
|
EXAMPLES:
|
1133
|
-
regolith new
|
1134
|
-
regolith generate service
|
399
|
+
regolith new observatory
|
400
|
+
regolith generate service telescope
|
401
|
+
regolith generate service records
|
1135
402
|
regolith server
|
1136
|
-
regolith
|
1137
|
-
regolith routes products
|
1138
|
-
regolith open products
|
1139
|
-
regolith shell products
|
1140
|
-
regolith inspect --json
|
1141
|
-
regolith config --json | jq '.services'
|
1142
|
-
regolith test --all
|
403
|
+
regolith console telescope
|
1143
404
|
|
1144
405
|
Get started:
|
1145
406
|
regolith new myapp
|
@@ -1149,4 +410,4 @@ module Regolith
|
|
1149
410
|
HELP
|
1150
411
|
end
|
1151
412
|
end
|
1152
|
-
end
|
413
|
+
end
|
data/lib/regolith/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: regolith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Regolith Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|