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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe9114ae5eae07811ec911b967cef33620ebf62c7df4f30c202f3743f7d6bea5
4
- data.tar.gz: 91920b483e2c26e58d1ef7ca7c786ea5cf91a4849ac16ec276fee4cdbf72d878
3
+ metadata.gz: f092ba86af858aef49a2de7704a7039e3f25accafaf9028254469e9621c754ea
4
+ data.tar.gz: 4ab71b60ae850c74508c790cf0fce5b14c2d12e0c8f2ec793a6b5e5234a95529
5
5
  SHA512:
6
- metadata.gz: dbdc4b736300bd5a395f67b9138e3aa7410a0184d4f5ea2be6f5e3445934fcf57588b526e5b957ee0c551247ab3013febd29eaffd96cc7bde43f982df91e3b53
7
- data.tar.gz: 19e8dd338cd34dd6621159785171c970468d43b0f423048c4c3fc10bd4ab4851cedd59091a03e1748acf990fa1853a7b1da33bbadba552bae186a71a69799f3e
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(name: @name, path: app_path, domain: domain, port: port, ruby: ruby, started_at: nil,
19
- pid: nil)
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 + gemset ---
25
+ # --- Ensure Ruby version & RVM ---
24
26
  Ruby.ensure_version(ruby)
25
27
  Ruby.ensure_rvm!
26
- System::Shell.run("bash -lc 'source #{Ruby.rvm_script} && rvm #{ruby}@#{@name} --create do true'")
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 Rails into gemset if missing ---
31
- rails_version = @options[:rails]
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'} in gemset..."
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('Failed to install Rails')
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 and bundle install inside 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 = if @options[:mysql]
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
- # ensure gem is installed inside gemset
76
- System::Shell.run("bash -lc 'cd #{app_path} && #{rvm_cmd} bundle install --jobs=4 --retry=3'")
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
- # --- Refresh bundle and prepare DB (idempotent) ---
84
- System::Shell.run("bash -lc 'cd #{app_path} && #{rvm_cmd} bundle check || #{rvm_cmd} bundle install'")
85
- System::Shell.run("bash -lc 'cd #{app_path} && #{rvm_cmd} bundle exec rails db:prepare'")
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 the app ---
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('bash', '-lc', "cd \"#{app_path}\" && #{rvm_cmd} bundle exec rails s -p #{port} -b 127.0.0.1",
101
- out: log_file, err: log_file)
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
- "cd #{@app_path} && bundle exec rails db:prepare"
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
@@ -97,6 +97,15 @@ module Stable
97
97
  "rvm #{ruby} do"
98
98
  end
99
99
  end
100
+
101
+ def self.clean_rvm_exec(ruby, gemset, cmd)
102
+ <<~CMD
103
+ bash -lc '
104
+ source #{rvm_script};
105
+ rvm #{ruby}@#{gemset} --create do #{cmd}
106
+ '
107
+ CMD
108
+ end
100
109
  end
101
110
  end
102
111
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stable-cli-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.11
4
+ version: 0.7.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Simfukwe