suspenders 20250317.0 → 20251219.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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/CODEOWNERS +9 -0
- data/CONTRIBUTING.md +71 -0
- data/FEATURES.md +177 -0
- data/GOALS.md +65 -0
- data/LICENSE +21 -0
- data/NEWS.md +808 -0
- data/README.md +59 -67
- data/RELEASING.md +18 -0
- data/Rakefile +6 -13
- data/SECURITY.md +19 -0
- data/exe/suspenders +38 -0
- data/lib/suspenders/cli.rb +64 -0
- data/lib/suspenders/version.rb +4 -4
- data/lib/suspenders.rb +5 -6
- data/lib/templates/Procfile +3 -0
- data/lib/templates/Procfile.dev +2 -0
- data/lib/{generators/templates/views/flashes.html.erb → templates/app/views/application/_flashes.html.erb} +4 -2
- data/lib/templates/app/views/application/_form_errors.html.erb +11 -0
- data/lib/templates/config/initializers/sidekiq.rb +14 -0
- data/lib/templates/lib/development/seeder.rb +21 -0
- data/lib/templates/lib/tasks/development.rake +15 -0
- data/lib/templates/spec/support/action_mailer.rb +11 -0
- data/lib/{generators/templates/factories/factory_bot_rspec.rb → templates/spec/support/factory_bot.rb} +0 -2
- data/lib/templates/web.rb +544 -0
- data/sig/suspenders.rbs +4 -0
- metadata +34 -119
- data/lib/generators/suspenders/accessibility_generator.rb +0 -24
- data/lib/generators/suspenders/advisories_generator.rb +0 -32
- data/lib/generators/suspenders/ci_generator.rb +0 -54
- data/lib/generators/suspenders/email_generator.rb +0 -56
- data/lib/generators/suspenders/environments/development_generator.rb +0 -50
- data/lib/generators/suspenders/environments/production_generator.rb +0 -27
- data/lib/generators/suspenders/environments/test_generator.rb +0 -39
- data/lib/generators/suspenders/factories_generator.rb +0 -64
- data/lib/generators/suspenders/inline_svg_generator.rb +0 -24
- data/lib/generators/suspenders/install/web_generator.rb +0 -85
- data/lib/generators/suspenders/jobs_generator.rb +0 -34
- data/lib/generators/suspenders/lint_generator.rb +0 -94
- data/lib/generators/suspenders/prerequisites_generator.rb +0 -19
- data/lib/generators/suspenders/rake_generator.rb +0 -25
- data/lib/generators/suspenders/setup_generator.rb +0 -14
- data/lib/generators/suspenders/styles_generator.rb +0 -84
- data/lib/generators/suspenders/tasks_generator.rb +0 -20
- data/lib/generators/suspenders/testing_generator.rb +0 -113
- data/lib/generators/suspenders/views_generator.rb +0 -38
- data/lib/generators/templates/ci/ci.yml.tt +0 -148
- data/lib/generators/templates/email/email_interceptor.rb +0 -11
- data/lib/generators/templates/factories/factories.rb +0 -2
- data/lib/generators/templates/factories/factories_test.rb +0 -9
- data/lib/generators/templates/inline_svg/inline_svg.rb +0 -3
- data/lib/generators/templates/install/web/CONTRIBUTING.md +0 -94
- data/lib/generators/templates/lint/config_better_html.yml +0 -2
- data/lib/generators/templates/lint/config_initializers_better_html.rb +0 -9
- data/lib/generators/templates/lint/erb-lint.yml +0 -63
- data/lib/generators/templates/lint/erblint.rake +0 -47
- data/lib/generators/templates/lint/eslintrc.json +0 -7
- data/lib/generators/templates/lint/package.json +0 -4
- data/lib/generators/templates/lint/prettierignore +0 -1
- data/lib/generators/templates/lint/prettierrc +0 -11
- data/lib/generators/templates/lint/rubocop.yml.tt +0 -7
- data/lib/generators/templates/lint/stylelintrc.json +0 -3
- data/lib/generators/templates/prerequisites/node-version.tt +0 -1
- data/lib/generators/templates/setup/bin_setup.rb +0 -39
- data/lib/generators/templates/styles/postcss.config.js +0 -11
- data/lib/generators/templates/tasks/dev.rake +0 -12
- data/lib/generators/templates/testing/action_mailer.rb +0 -5
- data/lib/install/web.rb +0 -70
- data/lib/suspenders/cleanup/generate_readme.rb +0 -165
- data/lib/suspenders/cleanup/organize_gemfile.rb +0 -134
- data/lib/suspenders/engine.rb +0 -5
- data/lib/suspenders/generators.rb +0 -126
- data/lib/suspenders/railtie.rb +0 -4
- data/lib/tasks/suspenders.rake +0 -37
- /data/lib/{generators/templates/factories → templates/spec}/factories_spec.rb +0 -0
- /data/lib/{generators/templates/testing → templates/spec/support}/driver.rb +0 -0
- /data/lib/{generators/templates/testing → templates/spec/support}/i18n.rb +0 -0
- /data/lib/{generators/templates/testing → templates/spec/support}/shoulda_matchers.rb +0 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
# Methods like `copy_file` will accept relative paths to the template's location.
|
|
2
|
+
def source_paths
|
|
3
|
+
Array(super) + [__dir__]
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def install_gems
|
|
7
|
+
gem "inline_svg"
|
|
8
|
+
gem "sidekiq"
|
|
9
|
+
gem "strong_migrations"
|
|
10
|
+
|
|
11
|
+
gem_group :test do
|
|
12
|
+
# TODO: How can we ensure we're notified of new releases?
|
|
13
|
+
gem "action_dispatch-testing-integration-capybara",
|
|
14
|
+
github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.2.0",
|
|
15
|
+
require: "action_dispatch/testing/integration/capybara/rspec"
|
|
16
|
+
gem "capybara"
|
|
17
|
+
gem "capybara_accessibility_audit"
|
|
18
|
+
# TODO: How can we ensure we're notified of new releases?
|
|
19
|
+
gem "capybara_accessible_selectors",
|
|
20
|
+
git: "https://github.com/citizensadvice/capybara_accessible_selectors", tag: "v0.12.0"
|
|
21
|
+
gem "selenium-webdriver"
|
|
22
|
+
gem "shoulda-matchers", "~> 6.0"
|
|
23
|
+
gem "webmock"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
gem_group :development, :test do
|
|
27
|
+
gem "factory_bot_rails"
|
|
28
|
+
gem "rspec-rails", "~> 8.0.0"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
install_gems
|
|
33
|
+
|
|
34
|
+
after_bundle do
|
|
35
|
+
commit_initial_application_state
|
|
36
|
+
|
|
37
|
+
# Initializers & Configuration
|
|
38
|
+
configure_database
|
|
39
|
+
configure_test_suite
|
|
40
|
+
configure_ci
|
|
41
|
+
configure_sidekiq
|
|
42
|
+
configure_strong_migrations
|
|
43
|
+
configure_mailer_intercepter
|
|
44
|
+
configure_inline_svg
|
|
45
|
+
configure_development_seeder
|
|
46
|
+
|
|
47
|
+
# Environments
|
|
48
|
+
setup_test_environment
|
|
49
|
+
setup_development_environment
|
|
50
|
+
setup_production_environment
|
|
51
|
+
setup_application
|
|
52
|
+
|
|
53
|
+
# Deployment and server
|
|
54
|
+
update_bin_dev
|
|
55
|
+
add_procfiles
|
|
56
|
+
|
|
57
|
+
# Views
|
|
58
|
+
update_layout
|
|
59
|
+
|
|
60
|
+
# Finalization
|
|
61
|
+
run_migrations
|
|
62
|
+
update_readme
|
|
63
|
+
lint_codebase
|
|
64
|
+
|
|
65
|
+
print_message
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def commit_initial_application_state
|
|
69
|
+
git add: ".", commit: %(-m 'Initial commit') if ENV["SUSPENDERS_ENV"] == "development"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def configure_database
|
|
73
|
+
gsub_file "config/database.yml", /^production:.*?password:.*?\n/m, <<~YAML
|
|
74
|
+
production:
|
|
75
|
+
<<: *default
|
|
76
|
+
url: <%= ENV["DATABASE_URL"] %>
|
|
77
|
+
YAML
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def configure_test_suite
|
|
81
|
+
rails_command "generate rspec:install"
|
|
82
|
+
|
|
83
|
+
# Update default configuration
|
|
84
|
+
uncomment_lines "spec/rails_helper.rb", /config\.infer_spec_type_from_file_location!/
|
|
85
|
+
uncomment_lines "spec/rails_helper.rb", /Rails\.root\.glob/
|
|
86
|
+
gsub_file "spec/spec_helper.rb", /^=begin\n/, ""
|
|
87
|
+
gsub_file "spec/spec_helper.rb", /^=end\n/, ""
|
|
88
|
+
|
|
89
|
+
# Configure Webmock
|
|
90
|
+
inject_into_file "spec/spec_helper.rb", "require \"webmock/rspec\"\n", before: /^RSpec\.configure/
|
|
91
|
+
append_to_file "spec/spec_helper.rb", <<~RUBY
|
|
92
|
+
|
|
93
|
+
WebMock.disable_net_connect!(
|
|
94
|
+
allow_localhost: true,
|
|
95
|
+
allow: [
|
|
96
|
+
/(chromedriver|storage).googleapis.com/,
|
|
97
|
+
"googlechromelabs.github.io"
|
|
98
|
+
]
|
|
99
|
+
)
|
|
100
|
+
RUBY
|
|
101
|
+
|
|
102
|
+
# Custom configuration
|
|
103
|
+
copy_file "spec/support/action_mailer.rb"
|
|
104
|
+
copy_file "spec/support/driver.rb"
|
|
105
|
+
copy_file "spec/support/i18n.rb"
|
|
106
|
+
copy_file "spec/support/factory_bot.rb"
|
|
107
|
+
copy_file "spec/support/shoulda_matchers.rb"
|
|
108
|
+
|
|
109
|
+
# Custom specs
|
|
110
|
+
copy_file "spec/factories_spec.rb"
|
|
111
|
+
empty_directory "spec/system"
|
|
112
|
+
create_file "spec/system/.gitkeep"
|
|
113
|
+
|
|
114
|
+
# Ignore spec/examples.txt
|
|
115
|
+
append_to_file ".gitignore", "/spec/examples.txt"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def configure_ci
|
|
119
|
+
# https://thoughtbot.com/blog/rspec-rails-github-actions-configuration
|
|
120
|
+
append_to_file ".github/workflows/ci.yml", "\n" + <<~YAML.gsub(/^/, " ")
|
|
121
|
+
test:
|
|
122
|
+
runs-on: ubuntu-latest
|
|
123
|
+
|
|
124
|
+
services:
|
|
125
|
+
postgres:
|
|
126
|
+
image: postgres
|
|
127
|
+
env:
|
|
128
|
+
POSTGRES_USER: postgres
|
|
129
|
+
POSTGRES_PASSWORD: postgres
|
|
130
|
+
ports:
|
|
131
|
+
- 5432:5432
|
|
132
|
+
options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
|
|
133
|
+
|
|
134
|
+
# redis:
|
|
135
|
+
# image: valkey/valkey:8
|
|
136
|
+
# ports:
|
|
137
|
+
# - 6379:6379
|
|
138
|
+
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
|
|
139
|
+
|
|
140
|
+
steps:
|
|
141
|
+
- name: Install packages
|
|
142
|
+
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y libpq-dev
|
|
143
|
+
|
|
144
|
+
- name: Checkout code
|
|
145
|
+
uses: actions/checkout@v5
|
|
146
|
+
|
|
147
|
+
- name: Set up Ruby
|
|
148
|
+
uses: ruby/setup-ruby@v1
|
|
149
|
+
with:
|
|
150
|
+
bundler-cache: true
|
|
151
|
+
|
|
152
|
+
- name: Run Tests
|
|
153
|
+
env:
|
|
154
|
+
RAILS_ENV: test
|
|
155
|
+
DATABASE_URL: postgres://postgres:postgres@localhost:5432
|
|
156
|
+
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
|
|
157
|
+
# REDIS_URL: redis://localhost:6379/0
|
|
158
|
+
run: bin/rails db:setup spec
|
|
159
|
+
|
|
160
|
+
- name: Keep screenshots from failed system tests
|
|
161
|
+
uses: actions/upload-artifact@v4
|
|
162
|
+
if: failure()
|
|
163
|
+
with:
|
|
164
|
+
name: screenshots
|
|
165
|
+
path: ${{ github.workspace }}/tmp/capybara
|
|
166
|
+
if-no-files-found: ignore
|
|
167
|
+
YAML
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def configure_sidekiq
|
|
171
|
+
# TODO: Use #initializer instead
|
|
172
|
+
copy_file "config/initializers/sidekiq.rb"
|
|
173
|
+
|
|
174
|
+
prepend_to_file "config/routes.rb", "require \"sidekiq/web\"\n\n"
|
|
175
|
+
sidekiq_route = <<-RUBY
|
|
176
|
+
if Rails.env.local?
|
|
177
|
+
mount Sidekiq::Web => "/sidekiq"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
RUBY
|
|
181
|
+
insert_into_file "config/routes.rb", sidekiq_route, after: "Rails.application.routes.draw do\n # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html\n"
|
|
182
|
+
|
|
183
|
+
# https://github.com/sidekiq/sidekiq/wiki/Active+Job
|
|
184
|
+
environment "config.active_job.queue_adapter = :sidekiq"
|
|
185
|
+
environment "config.active_job.queue_adapter = :inline", env: "test"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def configure_strong_migrations
|
|
189
|
+
rails_command "generate strong_migrations:install"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def configure_mailer_intercepter
|
|
193
|
+
lib "email_interceptor.rb", <<~RUBY
|
|
194
|
+
class EmailInterceptor
|
|
195
|
+
def self.delivering_email(message)
|
|
196
|
+
message.to = ENV.fetch("INTERCEPTOR_ADDRESSES", "").split(",")
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
RUBY
|
|
200
|
+
|
|
201
|
+
initializer "email_interceptor.rb", <<~RUBY
|
|
202
|
+
Rails.application.configure do
|
|
203
|
+
if ENV.fetch("INTERCEPTOR_ADDRESSES", "").split(",").any?
|
|
204
|
+
config.action_mailer.interceptors = %w[EmailInterceptor]
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
RUBY
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def configure_inline_svg
|
|
211
|
+
initializer "inline_svg.rb", <<~RUBY
|
|
212
|
+
InlineSvg.configure do |config|
|
|
213
|
+
config.raise_on_file_not_found = true
|
|
214
|
+
end
|
|
215
|
+
RUBY
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def configure_development_seeder
|
|
219
|
+
copy_file "lib/development/seeder.rb"
|
|
220
|
+
copy_file "lib/tasks/development.rake"
|
|
221
|
+
gsub_file "config/application.rb", /config\.autoload_lib\(ignore: %w\[assets tasks\]\)/, "config.autoload_lib(ignore: %w[assets tasks development])"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def setup_test_environment
|
|
225
|
+
gsub_file "config/environments/test.rb", /config\.action_dispatch\.show_exceptions = :rescuable/, "config.action_dispatch.show_exceptions = :none"
|
|
226
|
+
uncomment_lines "config/environments/test.rb", /config\.i18n\.raise_on_missing_translations/
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def setup_development_environment
|
|
230
|
+
environment "config.active_model.i18n_customize_full_message = true", env: "development"
|
|
231
|
+
uncomment_lines "config/environments/development.rb", /config\.i18n\.raise_on_missing_translations/
|
|
232
|
+
uncomment_lines "config/environments/development.rb", /config\.generators\.apply_rubocop_autocorrect_after_generate!/
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def setup_production_environment
|
|
236
|
+
environment "config.sandbox_by_default = true", env: "production"
|
|
237
|
+
environment "config.active_record.action_on_strict_loading_violation = :log", env: "production"
|
|
238
|
+
gsub_file "config/environments/production.rb", /# config\.asset_host =.*$/, 'config.asset_host = ENV["ASSET_HOST"]'
|
|
239
|
+
gsub_file "config/environments/production.rb", /config\.action_mailer\.default_url_options = \{ host: .*? \}/, 'config.action_mailer.default_url_options = { host: ENV.fetch("APPLICATION_HOST") }'
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def setup_application
|
|
243
|
+
environment "config.active_record.strict_loading_by_default = true"
|
|
244
|
+
environment "config.active_record.strict_loading_mode = :n_plus_one_only"
|
|
245
|
+
environment "config.require_master_key = true"
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def update_bin_dev
|
|
249
|
+
# https://github.com/rails/jsbundling-rails/blob/main/lib/install/dev
|
|
250
|
+
# rubocop:disable Style/RedundantStringEscape
|
|
251
|
+
create_file "bin/dev", force: true do
|
|
252
|
+
<<~BASH
|
|
253
|
+
#!/usr/bin/env sh
|
|
254
|
+
|
|
255
|
+
if gem list --no-installed --exact --silent foreman; then
|
|
256
|
+
echo "Installing foreman..."
|
|
257
|
+
gem install foreman
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
# Default to port 3000 if not specified
|
|
261
|
+
export PORT="\${PORT:-3000}"
|
|
262
|
+
|
|
263
|
+
exec foreman start -f Procfile.dev --env /dev/null "$@"
|
|
264
|
+
BASH
|
|
265
|
+
end
|
|
266
|
+
# rubocop:enable Style/RedundantStringEscape
|
|
267
|
+
|
|
268
|
+
# rubocop:disable Style/NumericLiteralPrefix
|
|
269
|
+
chmod "bin/dev", 0755
|
|
270
|
+
# rubocop:enable Style/NumericLiteralPrefix
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def add_procfiles
|
|
274
|
+
copy_file "Procfile"
|
|
275
|
+
copy_file "Procfile.dev"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def update_layout
|
|
279
|
+
# General partials
|
|
280
|
+
copy_file "app/views/application/_form_errors.html.erb"
|
|
281
|
+
copy_file "app/views/application/_flashes.html.erb"
|
|
282
|
+
|
|
283
|
+
# Application Layout
|
|
284
|
+
gsub_file "app/views/layouts/application.html.erb", /<html>/, "<html lang=\"<%= I18n.locale %>\">"
|
|
285
|
+
application_html_erb = <<-ERB
|
|
286
|
+
<main>
|
|
287
|
+
<%= render "flashes" %>
|
|
288
|
+
<%= yield %>
|
|
289
|
+
</main>
|
|
290
|
+
ERB
|
|
291
|
+
gsub_file "app/views/layouts/application.html.erb", /^ <%= yield %>\n/, application_html_erb
|
|
292
|
+
insert_into_file "app/views/layouts/application.html.erb", " <meta name=\"turbo-prefetch\" content=\"false\">\n", after: "</title>\n"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def run_migrations
|
|
296
|
+
rails_command "db:create"
|
|
297
|
+
rails_command "db:migrate"
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def update_readme
|
|
301
|
+
create_file "README.md", force: true do
|
|
302
|
+
<<~MARKDOWN
|
|
303
|
+
# README
|
|
304
|
+
|
|
305
|
+
This application was initially generated with [Suspenders][].
|
|
306
|
+
|
|
307
|
+
[Suspenders]: https://github.com/thoughtbot/suspenders
|
|
308
|
+
|
|
309
|
+
## Local Development
|
|
310
|
+
|
|
311
|
+
Run `bin/dev` to start the web server and Sidekiq worker. Then, navigate to [http://localhost:3000][local]
|
|
312
|
+
|
|
313
|
+
[local]: http://localhost:3000
|
|
314
|
+
|
|
315
|
+
### Strong Migrations
|
|
316
|
+
|
|
317
|
+
Uses [Strong Migrations][] to catch unsafe migrations in development.
|
|
318
|
+
|
|
319
|
+
[Strong Migrations]: https://github.com/ankane/strong_migrations
|
|
320
|
+
|
|
321
|
+
### Seed Data
|
|
322
|
+
|
|
323
|
+
Follows [our guidance][seed-data-guide] for managing seed data.
|
|
324
|
+
|
|
325
|
+
Use `db/seeds.rb` for data required in **all** environments, and `development:db:seed` for data specific to development environments.
|
|
326
|
+
|
|
327
|
+
Place idempotent seed data in `Development::Seeder`.
|
|
328
|
+
|
|
329
|
+
To load development seed data:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
bin/rails development:db:seed
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
To reset your database and reload seed data:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
bin/rails development:db:seed:replant
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The `replant` command truncates all tables and reloads the seed data, providing
|
|
342
|
+
a clean slate for development.
|
|
343
|
+
|
|
344
|
+
[seed-data-guide]: https://github.com/thoughtbot/guides/blob/main/rails/how-to/seed-data.md
|
|
345
|
+
|
|
346
|
+
## Environment Variables
|
|
347
|
+
|
|
348
|
+
The following environment variables are available in `production`:
|
|
349
|
+
|
|
350
|
+
- `APPLICATION_HOST` - The domain where your application is hosted (required)
|
|
351
|
+
- `ASSET_HOST` - CDN or asset host URL (optional)
|
|
352
|
+
- `RAILS_MASTER_KEY` - Used for decrypting credentials (required)
|
|
353
|
+
|
|
354
|
+
## Rails Console
|
|
355
|
+
|
|
356
|
+
In deployed environments, the Rails console starts in sandbox mode by default. This means any changes made in the console will be rolled back when you exit.
|
|
357
|
+
|
|
358
|
+
To modify data in deployed environments, you must explicitly disable sandbox mode:
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
bin/rails console --no-sandbox
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
This configuration helps prevent accidental data modifications in production.
|
|
365
|
+
|
|
366
|
+
## Configuration
|
|
367
|
+
|
|
368
|
+
### All Environments
|
|
369
|
+
|
|
370
|
+
- Enables [strict_loading_by_default][].
|
|
371
|
+
- Sets [strict_loading_mode][] to `:n_plus_one`.
|
|
372
|
+
- Enables [require_master_key][].
|
|
373
|
+
|
|
374
|
+
[strict_loading_by_default]: https://guides.rubyonrails.org/configuring.html#config-active-record-strict-loading-by-default
|
|
375
|
+
[strict_loading_mode]: https://guides.rubyonrails.org/configuring.html#config-active-record-strict-loading-mode
|
|
376
|
+
[require_master_key]: https://guides.rubyonrails.org/configuring.html#config-require-master-key
|
|
377
|
+
|
|
378
|
+
### Test
|
|
379
|
+
|
|
380
|
+
- Enables [raise_on_missing_translations][].
|
|
381
|
+
- Sets [action_dispatch.show_exceptions][] to `:none`.
|
|
382
|
+
|
|
383
|
+
[raise_on_missing_translations]: https://guides.rubyonrails.org/configuring.html#config-i18n-raise-on-missing-translations
|
|
384
|
+
[action_dispatch.show_exceptions]: https://edgeguides.rubyonrails.org/configuring.html#config-action-dispatch-show-exceptions
|
|
385
|
+
|
|
386
|
+
### Development
|
|
387
|
+
|
|
388
|
+
- Enables [raise_on_missing_translations][].
|
|
389
|
+
- Enables [i18n_customize_full_message][].
|
|
390
|
+
- Enables [apply_rubocop_autocorrect_after_generate!][].
|
|
391
|
+
|
|
392
|
+
[raise_on_missing_translations]: https://guides.rubyonrails.org/configuring.html#config-i18n-raise-on-missing-translations
|
|
393
|
+
[i18n_customize_full_message]: https://guides.rubyonrails.org/configuring.html#config-active-model-i18n-customize-full-message
|
|
394
|
+
[apply_rubocop_autocorrect_after_generate!]: https://guides.rubyonrails.org/configuring.html#configuring-generators
|
|
395
|
+
|
|
396
|
+
### Production
|
|
397
|
+
|
|
398
|
+
- Enables [sandbox_by_default][].
|
|
399
|
+
- Sets [action_on_strict_loading_violation][] to `:log`.
|
|
400
|
+
|
|
401
|
+
[sandbox_by_default]: https://guides.rubyonrails.org/configuring.html#config-sandbox-by-default
|
|
402
|
+
[action_on_strict_loading_violation]: https://guides.rubyonrails.org/configuring.html#config-active-record-action-on-strict-loading-violation
|
|
403
|
+
|
|
404
|
+
## Testing
|
|
405
|
+
|
|
406
|
+
Uses [RSpec][] and [RSpec Rails][] in favor of the [default test suite][].
|
|
407
|
+
|
|
408
|
+
The test suite can be run with `bin/rails spec`.
|
|
409
|
+
|
|
410
|
+
Configuration can be found in the following files:
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
spec/rails_helper.rb
|
|
414
|
+
spec/spec_helper.rb
|
|
415
|
+
spec/support/action_mailer.rb
|
|
416
|
+
spec/support/driver.rb
|
|
417
|
+
spec/support/i18n.rb
|
|
418
|
+
spec/support/shoulda_matchers.rb
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
- Uses [action_dispatch-testing-integration-capybara][] to introduce Capybara assertions into Request specs.
|
|
422
|
+
- Uses [shoulda-matchers][] for simple one-liner tests for common Rails functionality.
|
|
423
|
+
- Uses [webmock][] for stubbing and setting expectations on HTTP requests in Ruby.
|
|
424
|
+
|
|
425
|
+
[RSpec]: http://rspec.info
|
|
426
|
+
[RSpec Rails]: https://github.com/rspec/rspec-rails
|
|
427
|
+
[default test suite]: https://guides.rubyonrails.org/testing.html
|
|
428
|
+
[action_dispatch-testing-integration-capybara]: https://github.com/thoughtbot/action_dispatch-testing-integration-capybara
|
|
429
|
+
[shoulda-matchers]: https://github.com/thoughtbot/shoulda-matchers
|
|
430
|
+
[webmock]: https://github.com/bblimke/webmock
|
|
431
|
+
|
|
432
|
+
### Factories
|
|
433
|
+
|
|
434
|
+
Uses [FactoryBot][] as an alternative to [Fixtures][] to help you define
|
|
435
|
+
dummy and test data for your test suite. The `create`, `build`, and
|
|
436
|
+
`build_stubbed` class methods are directly available to all tests.
|
|
437
|
+
|
|
438
|
+
Place FactoryBot definitions in `spec/factories.rb`, at least until it
|
|
439
|
+
grows unwieldy. This helps reduce confusion around circular dependencies and
|
|
440
|
+
makes it easy to jump between definitions.
|
|
441
|
+
|
|
442
|
+
[FactoryBot]: https://github.com/thoughtbot/factory_bot
|
|
443
|
+
[Fixtures]: https://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures
|
|
444
|
+
|
|
445
|
+
## Accessibility
|
|
446
|
+
|
|
447
|
+
Uses [capybara_accessibility_audit][] and
|
|
448
|
+
[capybara_accessible_selectors][] to encourage and enforce accessibility best
|
|
449
|
+
practices.
|
|
450
|
+
|
|
451
|
+
[capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit
|
|
452
|
+
[capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors
|
|
453
|
+
|
|
454
|
+
## Mailers
|
|
455
|
+
|
|
456
|
+
[Intercept][] emails in non-production environments by setting `INTERCEPTOR_ADDRESSES`.
|
|
457
|
+
|
|
458
|
+
```sh
|
|
459
|
+
INTERCEPTOR_ADDRESSES="user_1@example.com,user_2@example.com" bin/rails s
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Configuration can be found at `config/initializers/email_interceptor.rb`.
|
|
463
|
+
|
|
464
|
+
Interceptor can be found at `lib/email_interceptor.rb`.
|
|
465
|
+
|
|
466
|
+
[Intercept]: https://guides.rubyonrails.org/action_mailer_basics.html#intercepting-emails
|
|
467
|
+
|
|
468
|
+
## Jobs
|
|
469
|
+
|
|
470
|
+
Uses [Sidekiq][] for [background job][] processing.
|
|
471
|
+
|
|
472
|
+
Configures the `test` environment to use the [inline][] adapter.
|
|
473
|
+
|
|
474
|
+
[Sidekiq]: https://github.com/sidekiq/sidekiq
|
|
475
|
+
[background job]: https://guides.rubyonrails.org/active_job_basics.html
|
|
476
|
+
[inline]: https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html
|
|
477
|
+
|
|
478
|
+
## Layout and Assets
|
|
479
|
+
|
|
480
|
+
### Inline SVG
|
|
481
|
+
|
|
482
|
+
Uses [inline_svg][] for embedding SVG documents into views.
|
|
483
|
+
|
|
484
|
+
Configuration can be found at `config/initializers/inline_svg.rb`
|
|
485
|
+
|
|
486
|
+
[inline_svg]: https://github.com/jamesmartin/inline_svg
|
|
487
|
+
|
|
488
|
+
### Layout
|
|
489
|
+
|
|
490
|
+
- A [partial][] for [flash messages][] is located in `app/views/application/_flashes.html.erb`.
|
|
491
|
+
- A [partial][] for form errors is located in `app/views/application/_form_errors.html.erb`.
|
|
492
|
+
- Sets [lang][] attribute on `<html>` element to `en` via `I18n.local`.
|
|
493
|
+
- Disables Turbo's [Prefetch][] in an effort to reduce unnecessary network requests.
|
|
494
|
+
|
|
495
|
+
[partial]: https://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
|
|
496
|
+
[flash messages]: https://guides.rubyonrails.org/action_controller_overview.html#the-flash
|
|
497
|
+
[lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang
|
|
498
|
+
[title]: https://github.com/calebhearth/title
|
|
499
|
+
[Prefetch]: https://turbo.hotwired.dev/handbook/drive#prefetching-links-on-hover
|
|
500
|
+
MARKDOWN
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def lint_codebase
|
|
505
|
+
run "bin/rubocop -a"
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
def print_message
|
|
509
|
+
say ""
|
|
510
|
+
say "Congratulations! You just pulled our suspenders."
|
|
511
|
+
say ""
|
|
512
|
+
say ralph
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def ralph
|
|
516
|
+
<<~ASCII
|
|
517
|
+
##################################################
|
|
518
|
+
################+ ################
|
|
519
|
+
############ -###########
|
|
520
|
+
######### =################*. :########
|
|
521
|
+
#######- =####= =#### #######
|
|
522
|
+
########+ ###+ +##+ ########
|
|
523
|
+
###########. .###############- ##########
|
|
524
|
+
###########= +####= :+####* ###########
|
|
525
|
+
###############= *##############
|
|
526
|
+
############## +###########- ##############
|
|
527
|
+
###############=*#################+###############
|
|
528
|
+
##################################################
|
|
529
|
+
#########: #########
|
|
530
|
+
######### ########
|
|
531
|
+
######### ########
|
|
532
|
+
######### ##. +#= ########
|
|
533
|
+
######### #= # #* #. ########
|
|
534
|
+
######### #. # #= #: ########
|
|
535
|
+
######### :##+ ### ########
|
|
536
|
+
######### ########
|
|
537
|
+
######### ########
|
|
538
|
+
######### ########
|
|
539
|
+
######### ########
|
|
540
|
+
#########+ #########
|
|
541
|
+
##################################################
|
|
542
|
+
##################################################
|
|
543
|
+
ASCII
|
|
544
|
+
end
|
data/sig/suspenders.rbs
ADDED