maquina-generators 0.2.0 → 0.3.0

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +120 -1
  3. data/lib/generators/maquina/app/USAGE +11 -0
  4. data/lib/generators/maquina/app/app_generator.rb +290 -0
  5. data/lib/generators/maquina/app/templates/Procfile.dev.tt +2 -0
  6. data/lib/generators/maquina/app/templates/README.md.erb +32 -0
  7. data/lib/generators/maquina/app/templates/app/controllers/home_controller.rb +6 -0
  8. data/lib/generators/maquina/app/templates/app/views/home/index.html.erb +4 -0
  9. data/lib/generators/maquina/app/templates/bin/ci +16 -0
  10. data/lib/generators/maquina/app/templates/bin/setup.tt +22 -0
  11. data/lib/generators/maquina/app/templates/config/initializers/generators.rb +4 -0
  12. data/lib/generators/maquina/mission_control_jobs/mission_control_jobs_generator.rb +3 -1
  13. data/lib/generators/maquina/mission_control_jobs/templates/config/initializers/mission_control.rb.tt +2 -1
  14. data/lib/generators/maquina/rack_attack/rack_attack_generator.rb +3 -1
  15. data/lib/generators/maquina/registration/USAGE +10 -0
  16. data/lib/generators/maquina/registration/registration_generator.rb +111 -0
  17. data/lib/generators/maquina/registration/templates/app/controllers/registrations_controller.rb.tt +37 -0
  18. data/lib/generators/maquina/registration/templates/app/models/account.rb.tt +5 -0
  19. data/lib/generators/maquina/registration/templates/app/models/current.rb.tt +5 -0
  20. data/lib/generators/maquina/registration/templates/app/models/user.rb.tt +12 -0
  21. data/lib/generators/maquina/registration/templates/app/views/registrations/new.html.erb.tt +67 -0
  22. data/lib/generators/maquina/registration/templates/app/views/sessions/new.html.erb.tt +44 -0
  23. data/lib/generators/maquina/registration/templates/config/locales/registration.en.yml +43 -0
  24. data/lib/generators/maquina/registration/templates/config/locales/registration.es.yml +43 -0
  25. data/lib/generators/maquina/registration/templates/migration_add_account_fields_to_users.rb.tt +7 -0
  26. data/lib/generators/maquina/registration/templates/migration_create_accounts.rb.tt +9 -0
  27. data/lib/generators/maquina/solid_errors/solid_errors_generator.rb +7 -10
  28. data/lib/generators/maquina/solid_errors/templates/config/initializers/solid_errors.rb.tt +1 -1
  29. data/lib/generators/maquina/solid_queue/USAGE +11 -0
  30. data/lib/generators/maquina/solid_queue/solid_queue_generator.rb +102 -0
  31. data/lib/generators/maquina/solid_queue/templates/config/solid_queue.yml +17 -0
  32. data/lib/maquina_generators/version.rb +1 -1
  33. data/test/generators/maquina/app_generator_test.rb +260 -0
  34. data/test/generators/maquina/mission_control_jobs_generator_test.rb +2 -1
  35. data/test/generators/maquina/registration_generator_test.rb +138 -0
  36. data/test/generators/maquina/solid_queue_generator_test.rb +133 -0
  37. data/test/tmp/Gemfile +1 -1
  38. data/test/tmp/app/controllers/backstage_controller.rb +4 -0
  39. data/test/tmp/config/initializers/solid_errors.rb +10 -0
  40. data/test/tmp/config/routes.rb +1 -0
  41. metadata +30 -2
  42. data/test/tmp/config/initializers/rack_attack.rb +0 -95
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce5b50ab1d409ff8e66103ffd248866536fb97868694f514fc63e622a091d3e9
4
- data.tar.gz: 991f0a0f392196b14285b68ec027cf120f4b610f172c6772e095343ff032bf1d
3
+ metadata.gz: 93ceefd73d3c9ff6cc2672408b697f8bd89557a1d1b069121b3eb4aeb237169a
4
+ data.tar.gz: 8bf8072079ccbd44ccc74e6ed9278df905704d1826fb442d5fe965880b7184c5
5
5
  SHA512:
6
- metadata.gz: 0f151ba3435ab5cb9be0cf0ddbe8d864b18d3f59f2c403e08a9653998fbe95b384947d315f99bc155d5337603d931b839d1408aa2b227eb41562490e07082d87
7
- data.tar.gz: 1caf6b0eb21b9eefb9ada1806e6af396fd435224edce1bf7dd1a1899a7243164b1baa599eebb28d91c2d142e26e19bcbe66da8db2032abea937804698ca46c26
6
+ metadata.gz: d09ece2ec179ec0ca30ce5a0b426c52f50f791afee3a8a8ef877fe05779c50f367b341667199d73ea49204420dfd1d94c2bdf3acff45df5a9b695592d8f1e103
7
+ data.tar.gz: 70698a7c84c71c8a734592262f67f935ccd0cf1daa36820d7e3368878aa7d448a4352d94038db9aba3b71c1beabae38db50d895fc0f75b54b1f8dbb4ca9ed10b
data/README.md CHANGED
@@ -60,6 +60,52 @@ All generated code lives in your app -- edit it directly:
60
60
  - **Email sender:** Edit `app/mailers/verification_mailer.rb`
61
61
  - **Translations:** Edit `config/locales/clave.*.yml`
62
62
 
63
+ ### Registration -- Password-Based Authentication with Accounts
64
+
65
+ **Registration** generates a password-based authentication system with multi-tenant account support. It builds on top of the Rails 8 authentication generator, adding an Account model (tenant), user roles, and a registration flow.
66
+
67
+ #### What it generates
68
+
69
+ - **Runs Rails authentication generator** first (`bin/rails generate authentication`)
70
+ - **Account model:** `Account` with `name` field and `has_many :users`
71
+ - **Updated User model:** Adds `belongs_to :account`, `role` enum (admin/member), `name` field
72
+ - **Updated Current model:** Adds `account` delegation through the user
73
+ - **Registration controller:** Creates Account + User (admin role) together in a transaction
74
+ - **Views:** Tailwind-styled registration form and updated login form with indigo color scheme
75
+ - **Locale files:** English and Spanish translations
76
+ - **Migrations:** `create_accounts` and `add_account_fields_to_users`
77
+
78
+ #### Usage
79
+
80
+ ```bash
81
+ rails g maquina:registration
82
+ ```
83
+
84
+ Then:
85
+
86
+ ```bash
87
+ rails db:migrate # Run migrations
88
+ ```
89
+
90
+ #### Options
91
+
92
+ ```bash
93
+ rails g maquina:registration # Full install
94
+ rails g maquina:registration --skip-views # Skip view templates
95
+ ```
96
+
97
+ #### Customization
98
+
99
+ All generated code lives in your app -- edit it directly:
100
+
101
+ - **Account fields:** Edit `app/models/account.rb` to add more tenant fields
102
+ - **User roles:** Edit `app/models/user.rb` to customize the role enum
103
+ - **Registration flow:** Edit `app/controllers/registrations_controller.rb`
104
+ - **Colors/styling:** Edit view templates (default: indigo)
105
+ - **Translations:** Edit `config/locales/registration.*.yml`
106
+
107
+ ---
108
+
63
109
  ### Solid Errors -- Error Tracking Dashboard
64
110
 
65
111
  **Solid Errors** installs the [solid_errors](https://github.com/fractaledmind/solid_errors) gem with HTTP authentication and engine mounting.
@@ -78,7 +124,7 @@ rails g maquina:solid_errors --prefix /admin
78
124
  rails g maquina:solid_errors --prefix /admin --copy-views # Include custom views
79
125
  ```
80
126
 
81
- The generator automatically runs `bundle install` and `solid_errors:install`. After running, execute `bin/rails db:migrate`.
127
+ The generator automatically runs `bundle install`. After running, execute `bin/rails generate solid_errors:install` (decline the initializer overwrite to keep your config), then `bin/rails db:migrate`.
82
128
 
83
129
  #### Options
84
130
 
@@ -133,6 +179,34 @@ Credentials are resolved in order:
133
179
 
134
180
  ---
135
181
 
182
+ ### Solid Queue -- Background Job Processing
183
+
184
+ **Solid Queue** installs the [solid_queue](https://github.com/rails/solid_queue) gem as the Active Job backend with configuration and Procfile.dev integration.
185
+
186
+ #### What it generates
187
+
188
+ - **Config:** `config/solid_queue.yml` with default dispatcher/worker settings
189
+ - **Application config:** Sets `config.active_job.queue_adapter = :solid_queue` (skipped in test environment)
190
+ - **Procfile.dev:** Appends `solid_queue: bin/rails solid_queue:start`
191
+ - **Migrations:** Runs `solid_queue:install:migrations`
192
+
193
+ #### Usage
194
+
195
+ ```bash
196
+ rails g maquina:solid_queue
197
+ ```
198
+
199
+ The generator automatically runs `bundle install` and installs migrations.
200
+
201
+ #### Options
202
+
203
+ ```bash
204
+ rails g maquina:solid_queue # Default (sqlite3)
205
+ rails g maquina:solid_queue --database postgresql # PostgreSQL
206
+ ```
207
+
208
+ ---
209
+
136
210
  ### Rack Attack -- Request Protection
137
211
 
138
212
  **Rack Attack** installs the [rack-attack](https://github.com/rack/rack-attack) gem with default security rules to block common vulnerability scans and throttle abusive requests.
@@ -160,6 +234,51 @@ Customize rules in `config/initializers/rack_attack.rb`.
160
234
 
161
235
  ---
162
236
 
237
+ ### App -- Full Application Setup (Orchestrator)
238
+
239
+ **App** is a meta-generator that sets up a complete Rails application in one command. Run it after `rails new myapp --css tailwind`.
240
+
241
+ #### What it does
242
+
243
+ 1. Adds development, runtime, and production gems (brakeman, standard, rails-i18n, maquina_components, aws-sdk-s3, etc.)
244
+ 2. Creates `Procfile.dev`
245
+ 3. Creates `.rubocop.yml`, `.standard.yml`, appends to `.gitignore`
246
+ 4. Creates `bin/setup` and `bin/ci` scripts
247
+ 5. Creates `config/initializers/generators.rb`
248
+ 6. Configures development (letter_opener) and production (APPLICATION_HOST) environments
249
+ 7. Configures `field_error_proc` in application
250
+ 8. Installs Action Text and Active Storage
251
+ 9. Sets up ActiveStorage JavaScript imports
252
+ 10. Adds turbo morphing and `yield :head` to layout
253
+ 11. Invokes sub-generators: `maquina:rack_attack`, `maquina:solid_queue`, `maquina:mission_control_jobs`, `maquina:solid_errors`, `maquina_components:install`
254
+ 12. Creates a HomeController with root route
255
+ 13. Generates a README and `database.yml.example`
256
+
257
+ #### Usage
258
+
259
+ ```bash
260
+ rails g maquina:app
261
+ rails g maquina:app --prefix /backstage --port 3100
262
+ rails g maquina:app --auth registration
263
+ ```
264
+
265
+ #### Options
266
+
267
+ - `--prefix` (default: `/admin`) -- Base path prefix for backstage tools (Solid Errors, Mission Control Jobs)
268
+ - `--port` (default: `3000`) -- Default port for the development server
269
+ - `--auth` (default: `none`) -- Authentication type: `none`, `clave`, or `registration`
270
+
271
+ #### After running
272
+
273
+ ```bash
274
+ bin/rails generate solid_errors:install # decline initializer overwrite
275
+ bin/rails db:migrate
276
+ bin/rails credentials:edit # set backstage username/password
277
+ bin/dev
278
+ ```
279
+
280
+ ---
281
+
163
282
  ## Adding New Generators
164
283
 
165
284
  Create a new folder under `lib/generators/maquina/`:
@@ -0,0 +1,11 @@
1
+ Description:
2
+ Sets up a complete Rails application with standard development tools,
3
+ Solid Queue, Mission Control Jobs, Solid Errors, Rack Attack, and
4
+ maquina_components.
5
+
6
+ Run this after `rails new myapp --css tailwind`.
7
+
8
+ Examples:
9
+ rails g maquina:app
10
+
11
+ rails g maquina:app --prefix /backstage --port 3100
@@ -0,0 +1,290 @@
1
+ require "rails/generators"
2
+
3
+ module Maquina
4
+ module Generators
5
+ class AppGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ class_option :prefix, type: :string, default: "/admin",
9
+ desc: "Base path prefix for backstage tools"
10
+ class_option :port, type: :string, default: "3000",
11
+ desc: "Default port for development server"
12
+ class_option :auth, type: :string, default: "none",
13
+ desc: "Authentication type: none, clave, or registration"
14
+
15
+ # 1. Add gems
16
+ def add_gems
17
+ gemfile_path = File.join(destination_root, "Gemfile")
18
+ return unless File.exist?(gemfile_path)
19
+
20
+ content = File.read(gemfile_path)
21
+
22
+ dev_gems = {"brakeman" => nil, "bundle-audit" => nil, "letter_opener" => nil, "standard" => nil}
23
+ runtime_gems = {"rails-i18n" => nil, "maquina_components" => nil}
24
+ production_gems = {"aws-sdk-s3" => nil}
25
+
26
+ dev_gems.each do |gem_name, _|
27
+ unless content.include?("gem \"#{gem_name}\"")
28
+ append_to_file "Gemfile", "\ngem \"#{gem_name}\", group: :development\n"
29
+ end
30
+ end
31
+
32
+ runtime_gems.each do |gem_name, _|
33
+ unless content.include?("gem \"#{gem_name}\"")
34
+ append_to_file "Gemfile", "\ngem \"#{gem_name}\"\n"
35
+ end
36
+ end
37
+
38
+ production_gems.each do |gem_name, _|
39
+ unless content.include?("gem \"#{gem_name}\"")
40
+ append_to_file "Gemfile", "\ngem \"#{gem_name}\", group: :production\n"
41
+ end
42
+ end
43
+
44
+ return unless rails_app?
45
+
46
+ Bundler.with_unbundled_env do
47
+ system("bundle install", chdir: destination_root)
48
+ end
49
+ end
50
+
51
+ # 2. Create Procfile.dev
52
+ def create_procfile
53
+ template "Procfile.dev.tt", "Procfile.dev"
54
+ end
55
+
56
+ # 3. Config files
57
+ def create_config_files
58
+ copy_file ".rubocop.yml", ".rubocop.yml"
59
+ copy_file ".standard.yml", ".standard.yml"
60
+
61
+ gitignore_path = File.join(destination_root, ".gitignore")
62
+ if File.exist?(gitignore_path)
63
+ content = File.read(gitignore_path)
64
+ unless content.include?("config/database.yml")
65
+ append_to_file ".gitignore", "\n# Ignore database configuration\nconfig/database.yml\n"
66
+ end
67
+ end
68
+ end
69
+
70
+ # 4. Scripts
71
+ def create_scripts
72
+ template "bin/setup.tt", "bin/setup"
73
+ copy_file "bin/ci", "bin/ci"
74
+ chmod "bin/setup", 0o755
75
+ chmod "bin/ci", 0o755
76
+ end
77
+
78
+ # 5. Initializers
79
+ def create_initializers
80
+ copy_file "config/initializers/generators.rb",
81
+ "config/initializers/generators.rb"
82
+ end
83
+
84
+ # 6. Configure environments
85
+ def configure_environments
86
+ configure_development
87
+ configure_production
88
+ end
89
+
90
+ # 7. Configure application
91
+ def configure_application
92
+ application_file = File.join(destination_root, "config/application.rb")
93
+ return unless File.exist?(application_file)
94
+
95
+ content = File.read(application_file)
96
+
97
+ unless content.include?("field_error_proc")
98
+ inject_into_file "config/application.rb",
99
+ after: /class Application < Rails::Application\n/ do
100
+ <<~RUBY.indent(4)
101
+
102
+ # Don't wrap form fields with errors in an extra div
103
+ config.action_view.field_error_proc = proc { |html_tag, _instance| html_tag }
104
+ RUBY
105
+ end
106
+ end
107
+ end
108
+
109
+ # 8. Install Rails features
110
+ def install_rails_features
111
+ return unless rails_app?
112
+
113
+ Bundler.with_unbundled_env do
114
+ system("bin/rails action_text:install", chdir: destination_root)
115
+ system("bin/rails active_storage:install", chdir: destination_root)
116
+ system("bin/rails db:migrate", chdir: destination_root)
117
+ end
118
+ end
119
+
120
+ # 9. Setup JavaScript
121
+ def setup_javascript
122
+ return unless rails_app?
123
+
124
+ importmap_path = File.join(destination_root, "config/importmap.rb")
125
+ if File.exist?(importmap_path)
126
+ content = File.read(importmap_path)
127
+ unless content.include?("activestorage")
128
+ append_to_file "config/importmap.rb",
129
+ "\npin \"@rails/activestorage\", to: \"activestorage.esm.js\"\n"
130
+ end
131
+ end
132
+
133
+ js_path = File.join(destination_root, "app/javascript/application.js")
134
+ if File.exist?(js_path)
135
+ content = File.read(js_path)
136
+ unless content.include?("ActiveStorage")
137
+ append_to_file "app/javascript/application.js", <<~JS
138
+
139
+ import * as ActiveStorage from "@rails/activestorage"
140
+ ActiveStorage.start()
141
+ JS
142
+ end
143
+ end
144
+ end
145
+
146
+ # 10. Setup layout
147
+ def setup_layout
148
+ layout_path = File.join(destination_root, "app/views/layouts/application.html.erb")
149
+ return unless File.exist?(layout_path)
150
+
151
+ content = File.read(layout_path)
152
+
153
+ unless content.include?("yield :head")
154
+ gsub_file "app/views/layouts/application.html.erb",
155
+ "</head>",
156
+ " <%= yield :head %>\n </head>"
157
+ end
158
+
159
+ unless content.include?("data-turbo-refresh-method")
160
+ gsub_file "app/views/layouts/application.html.erb",
161
+ "<body>",
162
+ '<body data-turbo-refresh-method="morph" data-turbo-refresh-scroll="preserve">'
163
+ end
164
+ end
165
+
166
+ # 11. Install authentication
167
+ def install_authentication
168
+ return unless rails_app?
169
+
170
+ case options[:auth]
171
+ when "clave"
172
+ generate "maquina:clave"
173
+ when "registration"
174
+ generate "maquina:registration"
175
+ end
176
+ end
177
+
178
+ # 12. Install maquina generators
179
+ def install_maquina_generators
180
+ return unless rails_app?
181
+
182
+ generate "maquina:rack_attack"
183
+ generate "maquina:solid_queue"
184
+ generate "maquina:mission_control_jobs", "--prefix", options[:prefix]
185
+ generate "maquina:solid_errors", "--prefix", options[:prefix]
186
+
187
+ Bundler.with_unbundled_env do
188
+ system("bin/rails maquina_components:install", chdir: destination_root)
189
+ end
190
+ end
191
+
192
+ # 13. Create home page
193
+ def create_home_page
194
+ template "app/controllers/home_controller.rb",
195
+ "app/controllers/home_controller.rb"
196
+ template "app/views/home/index.html.erb",
197
+ "app/views/home/index.html.erb"
198
+
199
+ route_file = File.join(destination_root, "config/routes.rb")
200
+ if File.exist?(route_file)
201
+ content = File.read(route_file)
202
+ unless content.include?("root")
203
+ route 'root "home#index"'
204
+ end
205
+ end
206
+ end
207
+
208
+ # 14. Create README
209
+ def create_readme
210
+ template "README.md.erb", "README.md"
211
+ end
212
+
213
+ # 15. Create database.yml.example
214
+ def create_database_sample
215
+ db_config = File.join(destination_root, "config/database.yml")
216
+ if File.exist?(db_config)
217
+ copy_file db_config, "config/database.yml.example"
218
+ end
219
+ end
220
+
221
+ # 16. Post-install message
222
+ def show_post_install
223
+ say ""
224
+ say "Your Rails app is ready!", :green
225
+ say ""
226
+ say "Manual steps:", :yellow
227
+ say " 1. bin/rails generate solid_errors:install"
228
+ say " (decline initializer overwrite to keep your config)"
229
+ say " 2. bin/rails db:migrate"
230
+ say " 3. Set credentials: bin/rails credentials:edit"
231
+ say " backstage:"
232
+ say " username: your_user"
233
+ say " password: your_password"
234
+ say " 4. Start the app: bin/dev"
235
+ if options[:auth] != "none"
236
+ say ""
237
+ say "Authentication (#{options[:auth]}):", :yellow
238
+ say " - Run bin/rails db:migrate if you haven't already"
239
+ say " - Visit /registrations/new to sign up" if options[:auth] == "registration"
240
+ say " - Visit /session/new to sign in"
241
+ end
242
+ say ""
243
+ end
244
+
245
+ private
246
+
247
+ def rails_app?
248
+ File.exist?(File.join(destination_root, "bin/rails"))
249
+ end
250
+
251
+ def configure_development
252
+ dev_file = File.join(destination_root, "config/environments/development.rb")
253
+ return unless File.exist?(dev_file)
254
+
255
+ content = File.read(dev_file)
256
+
257
+ unless content.include?("letter_opener")
258
+ inject_into_file "config/environments/development.rb",
259
+ before: /^end/ do
260
+ <<~RUBY.indent(2)
261
+
262
+ # Use letter_opener for email delivery
263
+ config.action_mailer.delivery_method = :letter_opener
264
+ config.action_mailer.perform_deliveries = true
265
+ config.action_mailer.default_url_options = {host: "localhost", port: #{options[:port]}}
266
+ RUBY
267
+ end
268
+ end
269
+ end
270
+
271
+ def configure_production
272
+ prod_file = File.join(destination_root, "config/environments/production.rb")
273
+ return unless File.exist?(prod_file)
274
+
275
+ content = File.read(prod_file)
276
+
277
+ unless content.include?("APPLICATION_HOST")
278
+ inject_into_file "config/environments/production.rb",
279
+ before: /^end/ do
280
+ <<~RUBY.indent(2)
281
+
282
+ # Set host for URL generation
283
+ config.action_mailer.default_url_options = {host: ENV.fetch("APPLICATION_HOST", "example.com")}
284
+ RUBY
285
+ end
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,2 @@
1
+ web: bin/rails server -p <%= options[:port] %>
2
+ css: bin/rails tailwindcss:watch
@@ -0,0 +1,32 @@
1
+ # <%= File.basename(destination_root).titleize %>
2
+
3
+ ## Getting Started
4
+
5
+ ```bash
6
+ bin/setup
7
+ bin/dev
8
+ ```
9
+
10
+ ## Development
11
+
12
+ - **Server:** http://localhost:<%= options[:port] %>
13
+ - **Jobs dashboard:** http://localhost:<%= options[:port] %><%= options[:prefix] %>/mission_control_jobs
14
+ - **Errors dashboard:** http://localhost:<%= options[:port] %><%= options[:prefix] %>/solid_errors
15
+
16
+ ## Scripts
17
+
18
+ - `bin/setup` — Install dependencies and prepare database
19
+ - `bin/ci` — Run full CI suite (lint, security, tests)
20
+ - `bin/dev` — Start all processes (web, css, solid_queue)
21
+
22
+ ## Credentials
23
+
24
+ ```bash
25
+ bin/rails credentials:edit
26
+ ```
27
+
28
+ ```yaml
29
+ backstage:
30
+ username: your_user
31
+ password: your_password
32
+ ```
@@ -0,0 +1,6 @@
1
+ class HomeController < ApplicationController
2
+ allow_unauthenticated_access if respond_to?(:allow_unauthenticated_access)
3
+
4
+ def index
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ <div class="max-w-2xl mx-auto py-16 px-4 text-center">
2
+ <h1 class="text-4xl font-bold text-gray-900 mb-4">Welcome</h1>
3
+ <p class="text-lg text-gray-600">Your application is running.</p>
4
+ </div>
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ echo "== Running Standard Ruby =="
5
+ bundle exec standardrb
6
+
7
+ echo "== Running Brakeman =="
8
+ bundle exec brakeman --no-pager -q
9
+
10
+ echo "== Running Bundle Audit =="
11
+ bundle exec bundle-audit check --update
12
+
13
+ echo "== Running tests =="
14
+ bin/rails test
15
+
16
+ echo "== All checks passed =="
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ require "fileutils"
3
+
4
+ APP_ROOT = File.expand_path("..", __dir__)
5
+
6
+ def system!(*args)
7
+ system(*args, exception: true)
8
+ end
9
+
10
+ FileUtils.chdir APP_ROOT do
11
+ puts "== Installing dependencies =="
12
+ system! "gem install bundler --conservative"
13
+ system("bundle check") || system!("bundle install")
14
+
15
+ puts "\n== Preparing database =="
16
+ system! "bin/rails db:prepare"
17
+
18
+ puts "\n== Removing old logs and tempfiles =="
19
+ system! "bin/rails log:clear tmp:clear"
20
+
21
+ puts "\n== Done! Start the app with: bin/dev =="
22
+ end
@@ -0,0 +1,4 @@
1
+ Rails.application.config.generators do |g|
2
+ g.stylesheets false
3
+ g.helper false
4
+ end
@@ -48,7 +48,9 @@ module Maquina
48
48
  def run_bundle_install
49
49
  return unless rails_app?
50
50
 
51
- run "bundle install", capture: true
51
+ Bundler.with_unbundled_env do
52
+ system("bundle install", chdir: destination_root)
53
+ end
52
54
  end
53
55
 
54
56
  # 6. Post-install message
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.configure do
4
- config.mission_control.jobs.base_controller_class = "BackstageController"
4
+ MissionControl::Jobs.base_controller_class = "BackstageController"
5
+ MissionControl::Jobs.adapters = [:solid_queue]
5
6
 
6
7
  backstage = Rails.application.credentials.backstage || {}
7
8
 
@@ -26,7 +26,9 @@ module Maquina
26
26
  def run_bundle_install
27
27
  return unless rails_app?
28
28
 
29
- run "bundle install", capture: true
29
+ Bundler.with_unbundled_env do
30
+ system("bundle install", chdir: destination_root)
31
+ end
30
32
  end
31
33
 
32
34
  # 4. Post-install message
@@ -0,0 +1,10 @@
1
+ Description:
2
+ Generates password-based authentication with account registration.
3
+
4
+ Runs the Rails authentication generator first, then adds an Account model
5
+ (tenant), updates the User model with account association and roles, and
6
+ creates a registration controller with Tailwind-styled views.
7
+
8
+ Examples:
9
+ rails g maquina:registration # Full install
10
+ rails g maquina:registration --skip-views # No view templates (API-only or custom views)