stable-cli-rails 0.7.11 → 0.7.12
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/stable/cli.rb +1 -0
- data/lib/stable/services/app_creator.rb +113 -58
- data/lib/stable/services/database/base.rb +11 -2
- data/lib/stable/services/ruby.rb +9 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f092ba86af858aef49a2de7704a7039e3f25accafaf9028254469e9621c754ea
|
|
4
|
+
data.tar.gz: 4ab71b60ae850c74508c790cf0fce5b14c2d12e0c8f2ec793a6b5e5234a95529
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 830108d826c9a63cdbaabf2c539b083795d7cf2772e1d8cea0c91d39dcefcaf06e792e1865793d7c7ab1da428b810228a36bbba34038555bcf20aefe03d2c295
|
|
7
|
+
data.tar.gz: acdf43e4787cf9115eb29b4900f670cb9e2ce0a0fed29ba3f251cf40f00948897a3ed1c1edff3109053031c3ed6d238e4632d28f681fc591548635f9f03951ac
|
data/lib/stable/cli.rb
CHANGED
|
@@ -29,6 +29,7 @@ module Stable
|
|
|
29
29
|
method_option :db, type: :string, desc: 'Database name to create and integrate'
|
|
30
30
|
method_option :postgres, type: :boolean, default: false, desc: 'Use Postgres for the database'
|
|
31
31
|
method_option :mysql, type: :boolean, default: false, desc: 'Use MySQL for the database'
|
|
32
|
+
method_option :full, type: :boolean, default: false, desc: 'Setup full Rails app common generators'
|
|
32
33
|
def new(name, ruby: RUBY_VERSION, rails: nil, port: nil)
|
|
33
34
|
safe_name = Validators::AppName.call!(name)
|
|
34
35
|
Commands::New.new(safe_name, options).call
|
|
@@ -15,55 +15,54 @@ module Stable
|
|
|
15
15
|
domain = "#{@name}.test"
|
|
16
16
|
|
|
17
17
|
# --- Register app in registry ---
|
|
18
|
-
Services::AppRegistry.add(
|
|
19
|
-
|
|
18
|
+
Services::AppRegistry.add(
|
|
19
|
+
name: @name, path: app_path, domain: domain, port: port,
|
|
20
|
+
ruby: ruby, started_at: nil, pid: nil
|
|
21
|
+
)
|
|
20
22
|
|
|
21
23
|
abort "Folder already exists: #{app_path}" if File.exist?(app_path)
|
|
22
24
|
|
|
23
|
-
# --- Ensure Ruby
|
|
25
|
+
# --- Ensure Ruby version & RVM ---
|
|
24
26
|
Ruby.ensure_version(ruby)
|
|
25
27
|
Ruby.ensure_rvm!
|
|
26
|
-
|
|
28
|
+
|
|
29
|
+
# --- Create gemset ---
|
|
30
|
+
System::Shell.run("bash -lc 'source #{Ruby.rvm_script} && rvm #{ruby} do rvm gemset create #{@name} || true'")
|
|
27
31
|
|
|
28
32
|
rvm_cmd = Ruby.rvm_prefix(ruby, @name)
|
|
29
33
|
|
|
30
|
-
# --- Install
|
|
31
|
-
|
|
32
|
-
rails_check_cmd = if rails_version
|
|
33
|
-
"#{rvm_cmd} gem list -i rails -v #{rails_version}"
|
|
34
|
-
else
|
|
35
|
-
"#{rvm_cmd} gem list -i rails"
|
|
36
|
-
end
|
|
34
|
+
# --- Install Bundler ---
|
|
35
|
+
System::Shell.run("bash -lc '#{rvm_cmd} gem install bundler --no-document'")
|
|
37
36
|
|
|
37
|
+
# --- Install Rails if missing ---
|
|
38
|
+
rails_version = @options[:rails]
|
|
39
|
+
rails_check_cmd = rails_version ? "#{rvm_cmd} gem list -i rails -v #{rails_version}" : "#{rvm_cmd} gem list -i rails"
|
|
38
40
|
unless system("bash -lc '#{rails_check_cmd}'")
|
|
39
|
-
puts "Installing Rails #{rails_version || 'latest'}
|
|
41
|
+
puts "Installing Rails #{rails_version || 'latest'}..."
|
|
40
42
|
install_cmd = rails_version ? "#{rvm_cmd} gem install rails -v #{rails_version}" : "#{rvm_cmd} gem install rails"
|
|
41
|
-
system("bash -lc '#{install_cmd}'") or abort(
|
|
43
|
+
system("bash -lc '#{install_cmd}'") or abort("Failed to install Rails #{rails_version || ''}")
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
# --- Create Rails app ---
|
|
45
47
|
puts "Creating Rails app #{@name} (Ruby #{ruby})..."
|
|
46
|
-
System::Shell.run("bash -lc '#{rvm_cmd} rails new #{app_path}
|
|
48
|
+
System::Shell.run("bash -lc '#{rvm_cmd} rails new #{app_path} \
|
|
49
|
+
--skip-importmap \
|
|
50
|
+
--skip-hotwire \
|
|
51
|
+
--skip-javascript \
|
|
52
|
+
--skip-solid'")
|
|
47
53
|
|
|
48
|
-
# --- Write ruby version/gemset
|
|
54
|
+
# --- Write ruby version/gemset ---
|
|
49
55
|
Dir.chdir(app_path) do
|
|
50
56
|
File.write('.ruby-version', "#{ruby}\n")
|
|
51
57
|
File.write('.ruby-gemset', "#{@name}\n")
|
|
52
|
-
|
|
53
|
-
puts 'Running bundle install...'
|
|
54
|
-
System::Shell.run("bash -lc '#{rvm_cmd} bundle install --jobs=4 --retry=3'")
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
# --- Database integration ---
|
|
58
61
|
if @options[:db]
|
|
59
|
-
adapter =
|
|
60
|
-
:mysql
|
|
61
|
-
else
|
|
62
|
-
:postgresql
|
|
63
|
-
end
|
|
64
|
-
|
|
62
|
+
adapter = @options[:mysql] ? :mysql : :postgresql
|
|
65
63
|
gem_name = adapter == :postgresql ? 'pg' : 'mysql2'
|
|
66
64
|
gemfile_path = File.join(app_path, 'Gemfile')
|
|
65
|
+
|
|
67
66
|
unless File.read(gemfile_path).include?(gem_name)
|
|
68
67
|
File.open(gemfile_path, 'a') do |f|
|
|
69
68
|
f.puts "\n# Added by Stable CLI"
|
|
@@ -72,17 +71,85 @@ module Stable
|
|
|
72
71
|
puts "✅ Added '#{gem_name}' gem to Gemfile"
|
|
73
72
|
end
|
|
74
73
|
|
|
75
|
-
#
|
|
76
|
-
System::Shell.run(
|
|
74
|
+
# Use correct Ruby/gemset for bundle install
|
|
75
|
+
System::Shell.run(rvm_run('bundle install --jobs=4 --retry=3', chdir: app_path))
|
|
77
76
|
|
|
78
|
-
# run adapter setup which will write database.yml and prepare
|
|
79
77
|
db_adapter = adapter == :mysql ? Database::MySQL : Database::Postgres
|
|
80
|
-
db_adapter.new(app_name: @name, app_path: app_path).setup
|
|
78
|
+
db_adapter.new(app_name: @name, app_path: app_path, ruby: ruby).setup
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# --- Run bundle & DB prepare ---
|
|
82
|
+
System::Shell.run(rvm_run('bundle install --jobs=4 --retry=3', chdir: app_path))
|
|
83
|
+
System::Shell.run(rvm_run('bundle exec rails db:prepare', chdir: app_path))
|
|
84
|
+
|
|
85
|
+
rails_version = `bash -lc 'cd #{app_path} && #{rvm_cmd} bundle exec rails runner "puts Rails.version"'`.strip.to_f
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
rails_ver = Gem::Version.new(rails_version)
|
|
89
|
+
rescue ArgumentError
|
|
90
|
+
rails_ver = Gem::Version.new('0.0.0')
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# only if Rails >= 7
|
|
94
|
+
if rails_ver >= Gem::Version.new('7.0.0')
|
|
95
|
+
# Gems to re-add
|
|
96
|
+
optional_gems = {
|
|
97
|
+
'importmap-rails' => nil,
|
|
98
|
+
'turbo-rails' => nil,
|
|
99
|
+
'stimulus-rails' => nil,
|
|
100
|
+
'solid_cache' => nil,
|
|
101
|
+
'solid_queue' => nil,
|
|
102
|
+
'solid_cable' => nil
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
gemfile = File.join(app_path, 'Gemfile')
|
|
106
|
+
|
|
107
|
+
# Add gems if not already present
|
|
108
|
+
optional_gems.each do |gem_name, version|
|
|
109
|
+
next if File.read(gemfile).match?(/^gem ['"]#{gem_name}['"]/)
|
|
110
|
+
|
|
111
|
+
File.open(gemfile, 'a') do |f|
|
|
112
|
+
f.puts version ? "gem '#{gem_name}', '#{version}'" : "gem '#{gem_name}'"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Install all new gems
|
|
117
|
+
System::Shell.run(rvm_run('bundle install', chdir: app_path))
|
|
118
|
+
|
|
119
|
+
# Run generators for installed gems
|
|
120
|
+
generators = [
|
|
121
|
+
'importmap:install',
|
|
122
|
+
'turbo:install stimulus:install',
|
|
123
|
+
'solid_cache:install solid_queue:install solid_cable:install'
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
generators.each do |cmd|
|
|
127
|
+
System::Shell.run(rvm_run("bundle exec rails #{cmd}", chdir: app_path))
|
|
128
|
+
end
|
|
81
129
|
end
|
|
82
130
|
|
|
83
|
-
# ---
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
# --- Add allowed host for Rails < 7.2 ---
|
|
132
|
+
if @options[:rails] && @options[:rails].to_f < 7.2
|
|
133
|
+
env_file = File.join(app_path, 'config/environments/development.rb')
|
|
134
|
+
|
|
135
|
+
if File.exist?(env_file)
|
|
136
|
+
content = File.read(env_file)
|
|
137
|
+
|
|
138
|
+
# Append host config inside the Rails.application.configure block
|
|
139
|
+
updated_content = content.gsub(/Rails\.application\.configure do(.*?)end/mm) do |_match|
|
|
140
|
+
inner = Regexp.last_match(1)
|
|
141
|
+
# Prevent duplicate entries
|
|
142
|
+
unless inner.include?(domain)
|
|
143
|
+
inner += " # allow local .test host for this app\n config.hosts << '#{domain}'\n"
|
|
144
|
+
end
|
|
145
|
+
"Rails.application.configure do#{inner}end"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
File.write(env_file, updated_content)
|
|
149
|
+
else
|
|
150
|
+
warn "Development environment file not found: #{env_file}"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
86
153
|
|
|
87
154
|
# --- Hosts, certs, caddy ---
|
|
88
155
|
Services::HostsManager.add(domain)
|
|
@@ -90,50 +157,31 @@ module Stable
|
|
|
90
157
|
Services::CaddyManager.ensure_running!
|
|
91
158
|
Services::CaddyManager.reload
|
|
92
159
|
|
|
93
|
-
# --- Start
|
|
160
|
+
# --- Start Rails server ---
|
|
94
161
|
puts "Starting Rails server for #{@name} on port #{port}..."
|
|
95
162
|
log_file = File.join(app_path, 'log', 'stable.log')
|
|
96
163
|
FileUtils.mkdir_p(File.dirname(log_file))
|
|
97
164
|
|
|
98
165
|
abort "Port #{port} is already in use. Choose another port." if port_in_use?(port)
|
|
99
166
|
|
|
100
|
-
pid = spawn(
|
|
101
|
-
|
|
167
|
+
pid = spawn(
|
|
168
|
+
'bash', '-lc',
|
|
169
|
+
"cd \"#{app_path}\" && #{rvm_cmd} bundle exec rails s -p #{port} -b 127.0.0.1",
|
|
170
|
+
out: log_file, err: log_file
|
|
171
|
+
)
|
|
102
172
|
Process.detach(pid)
|
|
103
|
-
|
|
104
173
|
AppRegistry.update(@name, started_at: Time.now.to_i, pid: pid)
|
|
105
174
|
|
|
106
175
|
sleep 1.5
|
|
107
176
|
wait_for_port(port)
|
|
108
|
-
prefix = @options[:skip_ssl] ? 'http' : 'https'
|
|
109
|
-
display_domain = if @options[:skip_ssl]
|
|
110
|
-
"#{domain}:#{port}"
|
|
111
|
-
else
|
|
112
|
-
domain
|
|
113
|
-
end
|
|
114
177
|
|
|
178
|
+
prefix = @options[:skip_ssl] ? 'http' : 'https'
|
|
179
|
+
display_domain = @options[:skip_ssl] ? "#{domain}:#{port}" : domain
|
|
115
180
|
puts "✔ #{@name} running at #{prefix}://#{display_domain}"
|
|
116
181
|
end
|
|
117
182
|
|
|
118
183
|
private
|
|
119
184
|
|
|
120
|
-
def create_rails_app
|
|
121
|
-
System::Shell.run("rails new #{@name}")
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def setup_database
|
|
125
|
-
return unless @options[:mysql] || @options[:postgres]
|
|
126
|
-
|
|
127
|
-
adapter =
|
|
128
|
-
if @options[:mysql]
|
|
129
|
-
Database::MySQL
|
|
130
|
-
else
|
|
131
|
-
Database::Postgres
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
adapter.new(@name).setup
|
|
135
|
-
end
|
|
136
|
-
|
|
137
185
|
def next_free_port
|
|
138
186
|
used_ports = Services::AppRegistry.all.map { |a| a[:port] }
|
|
139
187
|
port = 3000
|
|
@@ -158,6 +206,13 @@ module Stable
|
|
|
158
206
|
sleep 0.5
|
|
159
207
|
end
|
|
160
208
|
end
|
|
209
|
+
|
|
210
|
+
def rvm_run(cmd, chdir: nil, ruby: nil)
|
|
211
|
+
ruby ||= @options[:ruby] || RUBY_VERSION
|
|
212
|
+
gemset = @name
|
|
213
|
+
cd = chdir ? "cd #{chdir} && " : ''
|
|
214
|
+
"bash -lc '#{cd}source #{Dir.home}/.rvm/scripts/rvm && rvm #{ruby}@#{gemset} do #{cmd}'"
|
|
215
|
+
end
|
|
161
216
|
end
|
|
162
217
|
end
|
|
163
218
|
end
|
|
@@ -4,9 +4,10 @@ module Stable
|
|
|
4
4
|
module Services
|
|
5
5
|
module Database
|
|
6
6
|
class Base
|
|
7
|
-
def initialize(app_name:, app_path:)
|
|
7
|
+
def initialize(app_name:, app_path:, ruby:)
|
|
8
8
|
@app_name = app_name
|
|
9
9
|
@app_path = app_path
|
|
10
|
+
@ruby = ruby
|
|
10
11
|
@database_name = @app_name
|
|
11
12
|
.downcase
|
|
12
13
|
.gsub(/[^a-z0-9_]/, '_')
|
|
@@ -16,7 +17,7 @@ module Stable
|
|
|
16
17
|
|
|
17
18
|
def prepare
|
|
18
19
|
System::Shell.run(
|
|
19
|
-
|
|
20
|
+
bash_rvm('bundle exec rails db:prepare')
|
|
20
21
|
)
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -41,6 +42,14 @@ module Stable
|
|
|
41
42
|
def base_config(_creds)
|
|
42
43
|
raise NotImplementedError
|
|
43
44
|
end
|
|
45
|
+
|
|
46
|
+
def bash_rvm(cmd)
|
|
47
|
+
raise 'ruby not set' unless @ruby
|
|
48
|
+
raise 'app_name not set' unless @app_name
|
|
49
|
+
raise 'app_path not set' unless @app_path
|
|
50
|
+
|
|
51
|
+
"bash -lc 'cd #{@app_path} && source #{Ruby.rvm_script} && rvm #{@ruby}@#{@app_name} do #{cmd}'"
|
|
52
|
+
end
|
|
44
53
|
end
|
|
45
54
|
end
|
|
46
55
|
end
|
data/lib/stable/services/ruby.rb
CHANGED