suspenders 20230113.0 → 20240516.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/README.md +83 -176
- data/Rakefile +13 -0
- data/lib/generators/suspenders/accessibility_generator.rb +24 -0
- data/lib/generators/suspenders/advisories_generator.rb +32 -0
- data/lib/generators/suspenders/ci_generator.rb +57 -0
- data/lib/generators/suspenders/email_generator.rb +56 -0
- data/lib/generators/suspenders/environments/development_generator.rb +50 -0
- data/lib/generators/suspenders/environments/production_generator.rb +27 -0
- data/lib/generators/suspenders/environments/test_generator.rb +39 -0
- data/lib/generators/suspenders/factories_generator.rb +64 -0
- data/lib/generators/suspenders/inline_svg_generator.rb +24 -0
- data/lib/generators/suspenders/install/web_generator.rb +71 -0
- data/lib/generators/suspenders/jobs_generator.rb +34 -0
- data/lib/generators/suspenders/lint_generator.rb +94 -0
- data/lib/generators/suspenders/prerequisites_generator.rb +19 -0
- data/lib/generators/suspenders/rake_generator.rb +25 -0
- data/lib/generators/suspenders/setup_generator.rb +14 -0
- data/lib/generators/suspenders/styles_generator.rb +84 -0
- data/lib/generators/suspenders/tasks_generator.rb +20 -0
- data/lib/generators/suspenders/testing_generator.rb +113 -0
- data/lib/generators/suspenders/views_generator.rb +38 -0
- data/lib/generators/templates/ci/ci.yml.tt +148 -0
- data/lib/generators/templates/ci/dependabot.yml +7 -0
- data/lib/generators/templates/email/email_interceptor.rb +11 -0
- data/lib/generators/templates/factories/factories_spec.rb +7 -0
- data/lib/generators/templates/factories/factories_test.rb +9 -0
- data/lib/generators/templates/install/web/CONTRIBUTING.md +94 -0
- data/lib/generators/templates/lint/config_better_html.yml +2 -0
- data/lib/generators/templates/lint/config_initializers_better_html.rb +9 -0
- data/lib/generators/templates/lint/erb-lint.yml +63 -0
- data/lib/generators/templates/lint/erblint.rake +47 -0
- data/lib/generators/templates/lint/eslintrc.json +7 -0
- data/lib/generators/templates/lint/package.json +4 -0
- data/lib/generators/templates/lint/prettierignore +1 -0
- data/lib/generators/templates/lint/prettierrc +11 -0
- data/lib/generators/templates/lint/rubocop.yml.tt +7 -0
- data/lib/generators/templates/prerequisites/node-version.tt +1 -0
- data/lib/generators/templates/setup/bin_setup.rb +39 -0
- data/lib/generators/templates/styles/postcss.config.js +11 -0
- data/lib/generators/templates/testing/driver.rb +5 -0
- data/lib/generators/templates/views/flashes.html.erb +7 -0
- data/lib/install/web.rb +54 -0
- data/lib/suspenders/cleanup/generate_readme.rb +165 -0
- data/lib/suspenders/cleanup/organize_gemfile.rb +134 -0
- data/lib/suspenders/engine.rb +5 -0
- data/lib/suspenders/generators.rb +126 -0
- data/lib/suspenders/railtie.rb +4 -0
- data/lib/suspenders/version.rb +4 -6
- data/lib/suspenders.rb +9 -33
- data/lib/tasks/suspenders.rake +37 -0
- metadata +82 -173
- data/.ruby-version +0 -1
- data/CONTRIBUTING.md +0 -59
- data/GOALS.md +0 -65
- data/LICENSE +0 -21
- data/NEWS.md +0 -738
- data/RELEASING.md +0 -18
- data/bin/suspenders +0 -50
- data/docs/heroku_deploy.md +0 -19
- data/docs/rails_7.md +0 -5
- data/lib/suspenders/actions/strip_comments_action.rb +0 -254
- data/lib/suspenders/actions.rb +0 -106
- data/lib/suspenders/adapters/heroku.rb +0 -136
- data/lib/suspenders/app_builder.rb +0 -267
- data/lib/suspenders/exit_on_failure.rb +0 -19
- data/lib/suspenders/generators/accessibility_generator.rb +0 -12
- data/lib/suspenders/generators/advisories_generator.rb +0 -15
- data/lib/suspenders/generators/analytics_generator.rb +0 -24
- data/lib/suspenders/generators/app_generator.rb +0 -215
- data/lib/suspenders/generators/base.rb +0 -60
- data/lib/suspenders/generators/ci_generator.rb +0 -32
- data/lib/suspenders/generators/db_optimizations_generator.rb +0 -18
- data/lib/suspenders/generators/factories_generator.rb +0 -22
- data/lib/suspenders/generators/forms_generator.rb +0 -18
- data/lib/suspenders/generators/inline_svg_generator.rb +0 -14
- data/lib/suspenders/generators/jobs_generator.rb +0 -37
- data/lib/suspenders/generators/js_driver_generator.rb +0 -18
- data/lib/suspenders/generators/json_generator.rb +0 -14
- data/lib/suspenders/generators/lint_generator.rb +0 -14
- data/lib/suspenders/generators/production/compression_generator.rb +0 -14
- data/lib/suspenders/generators/production/deployment_generator.rb +0 -16
- data/lib/suspenders/generators/production/email_generator.rb +0 -34
- data/lib/suspenders/generators/production/force_tls_generator.rb +0 -11
- data/lib/suspenders/generators/production/manifest_generator.rb +0 -25
- data/lib/suspenders/generators/production/single_redirect.rb +0 -15
- data/lib/suspenders/generators/production/timeout_generator.rb +0 -22
- data/lib/suspenders/generators/profiler_generator.rb +0 -35
- data/lib/suspenders/generators/runner_generator.rb +0 -48
- data/lib/suspenders/generators/staging/pull_requests_generator.rb +0 -25
- data/lib/suspenders/generators/static_generator.rb +0 -14
- data/lib/suspenders/generators/stylelint_generator.rb +0 -71
- data/lib/suspenders/generators/stylesheet_base_generator.rb +0 -15
- data/lib/suspenders/generators/testing_generator.rb +0 -43
- data/lib/suspenders/generators/views_generator.rb +0 -25
- data/templates/Gemfile.erb +0 -49
- data/templates/Procfile +0 -2
- data/templates/README.md.erb +0 -28
- data/templates/_analytics.html.erb +0 -8
- data/templates/_css_overrides.html.erb +0 -7
- data/templates/_flashes.html.erb +0 -7
- data/templates/active_job.rb +0 -14
- data/templates/application.postcss.css +0 -1
- data/templates/bin_auto_migrate +0 -5
- data/templates/bin_deploy +0 -10
- data/templates/bin_setup +0 -28
- data/templates/bin_setup_review_app.erb +0 -21
- data/templates/bin_yarn +0 -18
- data/templates/bundler_audit.rake +0 -4
- data/templates/capybara_silence_puma.rb +0 -1
- data/templates/chromedriver.rb +0 -27
- data/templates/circle.yml.erb +0 -6
- data/templates/config_locales_en.yml.erb +0 -19
- data/templates/descriptions/advisories.md +0 -5
- data/templates/descriptions/analytics.md +0 -4
- data/templates/descriptions/ci.md +0 -4
- data/templates/descriptions/compression.md +0 -4
- data/templates/descriptions/db_optimizations.md +0 -2
- data/templates/descriptions/deployment.md +0 -5
- data/templates/descriptions/email.md +0 -9
- data/templates/descriptions/factories.md +0 -12
- data/templates/descriptions/force_tls.md +0 -1
- data/templates/descriptions/forms.md +0 -1
- data/templates/descriptions/inline_svg.md +0 -2
- data/templates/descriptions/jobs.md +0 -3
- data/templates/descriptions/js_driver.md +0 -4
- data/templates/descriptions/json.md +0 -1
- data/templates/descriptions/lint.md +0 -3
- data/templates/descriptions/manifest.md +0 -2
- data/templates/descriptions/profiler.md +0 -7
- data/templates/descriptions/pull_requests.md +0 -4
- data/templates/descriptions/runner.md +0 -10
- data/templates/descriptions/single_redirect.md +0 -1
- data/templates/descriptions/static.md +0 -5
- data/templates/descriptions/stylelint.md +0 -3
- data/templates/descriptions/stylesheet_base.md +0 -1
- data/templates/descriptions/testing.md +0 -9
- data/templates/descriptions/timeout.md +0 -4
- data/templates/descriptions/views.md +0 -8
- data/templates/email.rb +0 -3
- data/templates/errors.rb +0 -35
- data/templates/flashes_helper.rb +0 -5
- data/templates/hound.yml +0 -15
- data/templates/json_encoding.rb +0 -1
- data/templates/oj.rb +0 -3
- data/templates/partials/ci_simplecov.rb +0 -14
- data/templates/partials/db_optimizations_configuration.rb +0 -7
- data/templates/partials/deployment_readme.md +0 -8
- data/templates/partials/email_smtp.rb +0 -2
- data/templates/partials/profiler_readme.md +0 -8
- data/templates/partials/pull_requests_config.rb +0 -5
- data/templates/partials/runner_readme.md +0 -31
- data/templates/partials/runner_setup.rb +0 -2
- data/templates/postcss.config.js +0 -8
- data/templates/postgresql_database.yml.erb +0 -20
- data/templates/rack_mini_profiler.rb +0 -7
- data/templates/rails_helper.rb +0 -25
- data/templates/sample_env +0 -12
- data/templates/secrets.yml +0 -8
- data/templates/smtp.rb +0 -9
- data/templates/spec_helper.rb +0 -25
- data/templates/suspenders_gitignore +0 -18
- data/templates/suspenders_layout.html.erb.erb +0 -23
- /data/{templates → lib/generators/templates/factories}/factories.rb +0 -0
- /data/{templates → lib/generators/templates/factories}/factory_bot_rspec.rb +0 -0
- /data/{templates → lib/generators/templates/inline_svg}/inline_svg.rb +0 -0
- /data/{templates → lib/generators/templates/lint}/stylelintrc.json +0 -0
- /data/{templates → lib/generators/templates/tasks}/dev.rake +0 -0
- /data/{templates → lib/generators/templates/testing}/action_mailer.rb +0 -0
- /data/{templates → lib/generators/templates/testing}/i18n.rb +0 -0
- /data/{templates/shoulda_matchers_config_rspec.rb → lib/generators/templates/testing/shoulda_matchers.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8c2709f640163cac9a711d3fbc428db7771bf0082f8052f0e37cf1b60357fcbf
|
|
4
|
+
data.tar.gz: 8a2d49d93399ead80a3ef658124bd3657fb68bc923b3091bc42f390c22b9abf4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad3ba6902b12457e407ac81beade17ec912918d64a0e58eb7874c8214f861deead37497e06214fbae8effc30e7dfff02b4c0006a23a7b6bf0a03f4977538a18b
|
|
7
|
+
data.tar.gz: f3e992788aa0424a1b198ae611a9bed2542d80c12b321946a02fdf17fc05126f6f9b7a86fccbe2470aba77a72bc02612603fcfa072fba621b458e5c3d9981afe
|
data/README.md
CHANGED
|
@@ -1,225 +1,132 @@
|
|
|
1
1
|
# Suspenders
|
|
2
2
|
|
|
3
|
-
[](https://houndci.com)
|
|
5
|
-
|
|
6
|
-
Suspenders is the base Rails application used at
|
|
7
|
-
[thoughtbot](https://thoughtbot.com/).
|
|
8
|
-
|
|
9
|
-

|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
First install the suspenders gem:
|
|
14
|
-
|
|
15
|
-
gem install suspenders
|
|
16
|
-
|
|
17
|
-
Then run:
|
|
18
|
-
|
|
19
|
-
suspenders projectname
|
|
20
|
-
|
|
21
|
-
This will create a Rails app in `projectname` using the latest version of Rails.
|
|
22
|
-
|
|
23
|
-
### Associated services
|
|
24
|
-
|
|
25
|
-
* Enable [Circle CI](https://circleci.com/) Continuous Integration
|
|
26
|
-
* Enable [GitHub auto deploys to Heroku staging and review
|
|
27
|
-
apps](https://dashboard.heroku.com/apps/app-name-staging/deploy/github).
|
|
28
|
-
|
|
29
|
-
## Gemfile
|
|
30
|
-
|
|
31
|
-
To see the latest and greatest gems, look at Suspenders'
|
|
32
|
-
[Gemfile](templates/Gemfile.erb), which will be appended to the default
|
|
33
|
-
generated projectname/Gemfile.
|
|
34
|
-
|
|
35
|
-
It includes application gems like:
|
|
36
|
-
|
|
37
|
-
* [Sidekiq](https://github.com/mperham/sidekiq) for background
|
|
38
|
-
processing
|
|
39
|
-
* [High Voltage](https://github.com/thoughtbot/high_voltage) for static pages
|
|
40
|
-
* [Honeybadger](https://www.honeybadger.io/?affiliate=A43uwl) for exception notification
|
|
41
|
-
* [Oj](http://www.ohler.com/oj/)
|
|
42
|
-
* [Postgres](https://github.com/ged/ruby-pg) for access to the Postgres database
|
|
43
|
-
* [Rack Canonical Host](https://github.com/tylerhunt/rack-canonical-host) to
|
|
44
|
-
ensure all requests are served from the same domain
|
|
45
|
-
* [Rack Timeout](https://github.com/heroku/rack-timeout) to abort requests that are
|
|
46
|
-
taking too long
|
|
47
|
-
* [Recipient Interceptor](https://github.com/croaky/recipient_interceptor) to
|
|
48
|
-
avoid accidentally sending emails to real people from staging
|
|
49
|
-
* [Simple Form](https://github.com/plataformatec/simple_form) for form markup
|
|
50
|
-
and style
|
|
51
|
-
* [Skylight](https://www.skylight.io/) for monitoring performance
|
|
52
|
-
* [Title](https://github.com/calebthompson/title) for storing titles in
|
|
53
|
-
translations
|
|
54
|
-
|
|
55
|
-
And development gems like:
|
|
56
|
-
|
|
57
|
-
* [Dotenv](https://github.com/bkeepers/dotenv) for loading environment variables
|
|
58
|
-
* [Pry Rails](https://github.com/rweng/pry-rails) for interactively exploring
|
|
59
|
-
objects
|
|
60
|
-
* [ByeBug](https://github.com/deivid-rodriguez/byebug) for interactively
|
|
61
|
-
debugging behavior
|
|
62
|
-
* [Bullet](https://github.com/flyerhzm/bullet) for help to kill N+1 queries and
|
|
63
|
-
unused eager loading
|
|
64
|
-
* [Bundler Audit](https://github.com/rubysec/bundler-audit) for scanning the
|
|
65
|
-
Gemfile for insecure dependencies based on published CVEs
|
|
66
|
-
* [Web Console](https://github.com/rails/web-console) for better debugging via
|
|
67
|
-
in-browser IRB consoles.
|
|
3
|
+
[](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml)
|
|
68
4
|
|
|
69
|
-
|
|
5
|
+
Suspenders is a [Rails Engine][] containing generators for configuring Rails
|
|
6
|
+
applications with these [features][].
|
|
70
7
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
* [capybara_accessibility_audit](https://github.com/thoughtbot/capybara_accessibility_audit) and
|
|
75
|
-
[capybara_accessible_selectors](https://github.com/citizensadvice/capybara_accessible_selectors)
|
|
76
|
-
* [Factory Bot](https://github.com/thoughtbot/factory_bot) for test data
|
|
77
|
-
* [Formulaic](https://github.com/thoughtbot/formulaic) for integration testing
|
|
78
|
-
HTML forms
|
|
79
|
-
* [RSpec](https://github.com/rspec/rspec) for unit testing
|
|
80
|
-
* [RSpec Mocks](https://github.com/rspec/rspec-mocks) for stubbing and spying
|
|
81
|
-
* [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) for common
|
|
82
|
-
RSpec matchers
|
|
83
|
-
* [Timecop](https://github.com/travisjeffery/timecop) for testing time
|
|
8
|
+
It is used by thoughtbot to get a jump start on a new or existing app. Use
|
|
9
|
+
Suspenders if you're in a rush to build something amazing; don't use it if you
|
|
10
|
+
like missing deadlines.
|
|
84
11
|
|
|
85
|
-
|
|
12
|
+
[Rails Engine]: https://guides.rubyonrails.org/engines.html
|
|
13
|
+
[features]: ./FEATURES.md
|
|
86
14
|
|
|
87
|
-
Suspenders
|
|
15
|
+

|
|
88
16
|
|
|
89
|
-
|
|
90
|
-
* The `./bin/deploy` convention for deploying to Heroku
|
|
91
|
-
* Rails' flashes set up and in application layout
|
|
92
|
-
* A few nice time formats set up for localization
|
|
93
|
-
* `Rack::Deflater` to [compress responses with Gzip][compress]
|
|
94
|
-
* A [low database connection pool limit][pool]
|
|
95
|
-
* [Safe binstubs][binstub]
|
|
96
|
-
* [t() and l() in specs without prefixing with I18n][i18n]
|
|
97
|
-
* An automatically-created `SECRET_KEY_BASE` environment variable in all
|
|
98
|
-
environments
|
|
99
|
-
* Configuration for [CircleCI][circle] Continuous Integration (tests)
|
|
100
|
-
* Configuration for [Hound][hound] Continuous Integration (style)
|
|
101
|
-
* Configuration for [stylelint][stylelint]
|
|
102
|
-
* The analytics adapter [Segment][segment] (and therefore config for Google
|
|
103
|
-
Analytics, Intercom, Facebook Ads, Twitter Ads, etc.)
|
|
104
|
-
* [PostCSS Autoprefixer][autoprefixer] for CSS vendor prefixes
|
|
105
|
-
* [PostCSS Normalize][normalize] for resetting browser styles
|
|
17
|
+
## Requirements
|
|
106
18
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
[binstub]: https://github.com/thoughtbot/suspenders/pull/282
|
|
111
|
-
[i18n]: https://github.com/thoughtbot/suspenders/pull/304
|
|
112
|
-
[circle]: https://circleci.com/docs
|
|
113
|
-
[hound]: https://houndci.com
|
|
114
|
-
[stylelint]: https://stylelint.io/
|
|
115
|
-
[segment]: https://segment.com
|
|
116
|
-
[autoprefixer]: https://github.com/postcss/autoprefixer
|
|
117
|
-
[normalize]: https://github.com/csstools/postcss-normalize
|
|
19
|
+
- Rails `~> 7.0`
|
|
20
|
+
- Ruby `>= 3.1`
|
|
21
|
+
- Node `>= 20.0.0`
|
|
118
22
|
|
|
119
|
-
##
|
|
23
|
+
## Usage
|
|
120
24
|
|
|
121
|
-
|
|
25
|
+
Suspenders can be used to create a new Rails application, or to enhance an
|
|
26
|
+
existing Rails application.
|
|
122
27
|
|
|
123
|
-
|
|
28
|
+
### With New Rails Applications
|
|
124
29
|
|
|
125
|
-
|
|
30
|
+
This approach uses an [application template][] to generate a new Rails
|
|
31
|
+
application with Suspenders.
|
|
126
32
|
|
|
127
|
-
|
|
33
|
+
We skip the [default test framework][] in favor of [RSpec][], and [prefer
|
|
34
|
+
PostgreSQL][] as our database.
|
|
128
35
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
36
|
+
```
|
|
37
|
+
rails new app_name \
|
|
38
|
+
--skip-test \
|
|
39
|
+
-d=postgresql \
|
|
40
|
+
-m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
|
|
41
|
+
```
|
|
135
42
|
|
|
136
|
-
|
|
137
|
-
[heroku deploy]: https://github.com/thoughtbot/suspenders/blob/master/docs/heroku_deploy.md
|
|
43
|
+
Then run `bin/setup` within the newly generated application.
|
|
138
44
|
|
|
139
|
-
|
|
45
|
+
Alternatively, if you're using our [dotfiles][], then you can just run `rails new
|
|
46
|
+
app_name`, or create your own [railsrc][] file with the following configuration:
|
|
140
47
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
48
|
+
```
|
|
49
|
+
--skip-test
|
|
50
|
+
--database=postgresql
|
|
51
|
+
-m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
|
|
52
|
+
```
|
|
144
53
|
|
|
145
|
-
|
|
54
|
+
[application template]: https://guides.rubyonrails.org/rails_application_templates.html
|
|
55
|
+
[default test framework]: https://guides.rubyonrails.org/testing.html
|
|
56
|
+
[RSpec]: http://rspec.info
|
|
57
|
+
[prefer PostgreSQL]: https://github.com/thoughtbot/dotfiles/pull/728
|
|
58
|
+
[dotfiles]: https://github.com/thoughtbot/dotfiles
|
|
59
|
+
[railsrc]: https://github.com/rails/rails/blob/7f7f9df8641e35a076fe26bd097f6a1b22cb4e2d/railties/lib/rails/generators/rails/app/USAGE#L5C1-L7
|
|
146
60
|
|
|
147
|
-
|
|
61
|
+
### With Existing Rails Applications
|
|
148
62
|
|
|
149
|
-
|
|
63
|
+
Suspenders can be used on an existing Rails application by adding it to the
|
|
64
|
+
`:development` and `:test` group.
|
|
150
65
|
|
|
151
|
-
|
|
152
|
-
|
|
66
|
+
```ruby
|
|
67
|
+
group :development, :test do
|
|
68
|
+
gem "suspenders"
|
|
69
|
+
end
|
|
70
|
+
```
|
|
153
71
|
|
|
154
|
-
|
|
72
|
+
Once installed, you can invoke the web installation generator, which will
|
|
73
|
+
invoke all generators.
|
|
155
74
|
|
|
156
|
-
|
|
75
|
+
```
|
|
76
|
+
bin/rails g suspenders:install:web
|
|
77
|
+
```
|
|
157
78
|
|
|
158
|
-
|
|
159
|
-
|
|
79
|
+
Or, you can invoke generators individually. To see a list of available
|
|
80
|
+
generators run:
|
|
160
81
|
|
|
161
|
-
|
|
162
|
-
|
|
82
|
+
```
|
|
83
|
+
bin/rails g | grep suspenders
|
|
84
|
+
```
|
|
163
85
|
|
|
164
|
-
|
|
86
|
+
To learn more about a generator, run:
|
|
165
87
|
|
|
166
|
-
|
|
88
|
+
```
|
|
89
|
+
bin/rails g suspenders:[generator_name] --help
|
|
90
|
+
```
|
|
167
91
|
|
|
168
|
-
|
|
92
|
+
### Available Tasks
|
|
169
93
|
|
|
170
|
-
Suspenders
|
|
94
|
+
Suspenders ships with several custom Rake tasks.
|
|
171
95
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
Use [Command Line Tools for Xcode](https://developer.apple.com/downloads/index.action)
|
|
179
|
-
for Lion (OS X 10.7) or Mountain Lion (OS X 10.8).
|
|
180
|
-
|
|
181
|
-
We use [Google Chromedriver] for full-stack JavaScript integration testing. It
|
|
182
|
-
requires Google Chrome or Chromium.
|
|
183
|
-
|
|
184
|
-
[Google Chromedriver]: https://sites.google.com/a/chromium.org/chromedriver/home
|
|
185
|
-
|
|
186
|
-
PostgreSQL needs to be installed and running for the `db:create` rake task.
|
|
187
|
-
|
|
188
|
-
Redis needs to be installed and running for Sidekiq
|
|
189
|
-
|
|
190
|
-
## Issues
|
|
191
|
-
|
|
192
|
-
If you have problems, please create a
|
|
193
|
-
[GitHub Issue](https://github.com/thoughtbot/suspenders/issues).
|
|
96
|
+
```
|
|
97
|
+
bin/rails suspenders:rake
|
|
98
|
+
bin/rails suspenders:db:migrate
|
|
99
|
+
bin/rails suspenders:cleanup:organize_gemfile
|
|
100
|
+
```
|
|
194
101
|
|
|
195
102
|
## Contributing
|
|
196
103
|
|
|
197
|
-
See [CONTRIBUTING
|
|
198
|
-
|
|
104
|
+
See the [CONTRIBUTING] document.
|
|
199
105
|
Thank you, [contributors]!
|
|
200
106
|
|
|
107
|
+
[CONTRIBUTING]: CONTRIBUTING.md
|
|
201
108
|
[contributors]: https://github.com/thoughtbot/suspenders/graphs/contributors
|
|
202
109
|
|
|
203
110
|
## License
|
|
204
111
|
|
|
205
|
-
Suspenders is Copyright
|
|
206
|
-
It is free software,
|
|
207
|
-
|
|
112
|
+
Suspenders is Copyright (c) thoughtbot, inc.
|
|
113
|
+
It is free software, and may be redistributed
|
|
114
|
+
under the terms specified in the [LICENSE] file.
|
|
115
|
+
|
|
116
|
+
[LICENSE]: /LICENSE
|
|
208
117
|
|
|
209
|
-
|
|
118
|
+
## About
|
|
210
119
|
|
|
211
|
-
|
|
120
|
+
Suspenders is maintained by [thoughtbot].
|
|
212
121
|
|
|
213
|
-
|
|
122
|
+

|
|
214
123
|
|
|
215
124
|
Suspenders is maintained and funded by thoughtbot, inc.
|
|
216
125
|
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
|
217
126
|
|
|
218
127
|
We love open source software!
|
|
219
|
-
See [our other projects][community]
|
|
220
|
-
|
|
128
|
+
See [our other projects][community]
|
|
129
|
+
or [hire us][hire] to help build your product.
|
|
221
130
|
|
|
222
|
-
[thoughtbot]: https://thoughtbot.com?utm_source=github
|
|
223
|
-
[thoughtbot-logo]: https://thoughtbot.com/brand_assets/93:44.svg
|
|
224
131
|
[community]: https://thoughtbot.com/community?utm_source=github
|
|
225
|
-
[hire]: https://thoughtbot.com?utm_source=github
|
|
132
|
+
[hire]: https://thoughtbot.com/hire-us?utm_source=github
|
data/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "bundler/setup"
|
|
2
|
+
require "bundler/gem_tasks"
|
|
3
|
+
require "minitest/test_task"
|
|
4
|
+
require "standard/rake"
|
|
5
|
+
|
|
6
|
+
Minitest::TestTask.create(:test) do |t|
|
|
7
|
+
t.libs << "test"
|
|
8
|
+
t.libs << "lib"
|
|
9
|
+
t.warning = false
|
|
10
|
+
t.test_globs = ["test/**/*_test.rb"]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
task default: %i[test standard]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
class AccessibilityGenerator < Rails::Generators::Base
|
|
4
|
+
include Suspenders::Generators::APIAppUnsupported
|
|
5
|
+
|
|
6
|
+
desc <<~MARKDOWN
|
|
7
|
+
Uses [capybara_accessibility_audit][] and
|
|
8
|
+
[capybara_accessible_selectors][] to encourage and enforce accessibility best
|
|
9
|
+
practices.
|
|
10
|
+
|
|
11
|
+
[capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit
|
|
12
|
+
[capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors
|
|
13
|
+
MARKDOWN
|
|
14
|
+
|
|
15
|
+
def add_capybara_gems
|
|
16
|
+
gem_group :test do
|
|
17
|
+
gem "capybara_accessibility_audit", github: "thoughtbot/capybara_accessibility_audit"
|
|
18
|
+
gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors"
|
|
19
|
+
end
|
|
20
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
class AdvisoriesGenerator < Rails::Generators::Base
|
|
4
|
+
source_root File.expand_path("../../templates/advisories", __FILE__)
|
|
5
|
+
desc <<~MARKDOWN
|
|
6
|
+
Uses [bundler-audit][] to update the local security database and show
|
|
7
|
+
any relevant issues with the app's dependencies via a Rake task.
|
|
8
|
+
|
|
9
|
+
[bundler-audit]: https://github.com/rubysec/bundler-audit
|
|
10
|
+
MARKDOWN
|
|
11
|
+
|
|
12
|
+
def add_bundler_audit
|
|
13
|
+
gem_group :development, :test do
|
|
14
|
+
gem "bundler-audit", ">= 0.7.0", require: false
|
|
15
|
+
end
|
|
16
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def modify_rakefile
|
|
20
|
+
content = <<~RUBY
|
|
21
|
+
|
|
22
|
+
if Rails.env.local?
|
|
23
|
+
require "bundler/audit/task"
|
|
24
|
+
Bundler::Audit::Task.new
|
|
25
|
+
end
|
|
26
|
+
RUBY
|
|
27
|
+
|
|
28
|
+
insert_into_file "Rakefile", content, after: /require_relative "config\/application"\n/
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
class CiGenerator < Rails::Generators::Base
|
|
4
|
+
include Suspenders::Generators::DatabaseUnsupported
|
|
5
|
+
include Suspenders::Generators::Helpers
|
|
6
|
+
|
|
7
|
+
source_root File.expand_path("../../templates/ci", __FILE__)
|
|
8
|
+
desc <<~MARKDOWN
|
|
9
|
+
Uses [GitHub Actions][] for CI, and [Dependabot][] for dependency updates.
|
|
10
|
+
|
|
11
|
+
[GitHub Actions]: https://docs.github.com/en/actions
|
|
12
|
+
[Dependabot]: https://docs.github.com/en/code-security/dependabot/working-with-dependabot
|
|
13
|
+
MARKDOWN
|
|
14
|
+
|
|
15
|
+
def ci_files
|
|
16
|
+
empty_directory ".github/workflows"
|
|
17
|
+
template "ci.yml", ".github/workflows/ci.yaml"
|
|
18
|
+
template "dependabot.yml", ".github/dependabot.yaml"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def scan_ruby?
|
|
24
|
+
has_gem? "bundler-audit"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def scan_js?
|
|
28
|
+
File.exist?("bin/importmap") && using_node?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def lint?
|
|
32
|
+
using_node? && has_gem?("standard") && has_yarn_script?("lint")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def using_node?
|
|
36
|
+
File.exist? "package.json"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def has_gem?(name)
|
|
40
|
+
Bundler.rubygems.find_name(name).any?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def using_rspec?
|
|
44
|
+
File.exist? "spec"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def has_yarn_script?(name)
|
|
48
|
+
return false if !using_node?
|
|
49
|
+
|
|
50
|
+
content = File.read("package.json")
|
|
51
|
+
json = JSON.parse(content)
|
|
52
|
+
|
|
53
|
+
json.dig("scripts", name)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
class EmailGenerator < Rails::Generators::Base
|
|
4
|
+
source_root File.expand_path("../../templates/email", __FILE__)
|
|
5
|
+
desc <<~MARKDOWN
|
|
6
|
+
[Intercept][] emails in non-production environments by setting `INTERCEPTOR_ADDRESSES`.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
INTERCEPTOR_ADDRESSES="user_1@example.com,user_2@example.com" bin/rails s
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Configuration can be found at `config/initializers/email_interceptor.rb`.
|
|
13
|
+
|
|
14
|
+
Interceptor can be found at `app/mailers/email_interceptor.rb`.
|
|
15
|
+
|
|
16
|
+
[Intercept]: https://guides.rubyonrails.org/action_mailer_basics.html#intercepting-emails
|
|
17
|
+
MARKDOWN
|
|
18
|
+
|
|
19
|
+
def create_email_interceptor
|
|
20
|
+
copy_file "email_interceptor.rb", "app/mailers/email_interceptor.rb"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create_email_interceptor_initializer
|
|
24
|
+
initializer "email_interceptor.rb", <<~RUBY
|
|
25
|
+
Rails.application.configure do
|
|
26
|
+
if ENV["INTERCEPTOR_ADDRESSES"].present?
|
|
27
|
+
config.action_mailer.interceptors = %w[EmailInterceptor]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
RUBY
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def configure_email_interceptor
|
|
34
|
+
environment do
|
|
35
|
+
%(
|
|
36
|
+
config.to_prepare do
|
|
37
|
+
EmailInterceptor.config.interceptor_addresses = ENV.fetch("INTERCEPTOR_ADDRESSES", "").split(",")
|
|
38
|
+
end
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# TODO: Remove once https://github.com/rails/rails/pull/51191 is in latest
|
|
44
|
+
# Rails release
|
|
45
|
+
def configure_development_environment
|
|
46
|
+
environment %(config.action_mailer.default_url_options = { host: "localhost", port: 3000 }), env: "development"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# TODO: Remove once https://github.com/rails/rails/pull/51191 is in latest
|
|
50
|
+
# Rails release
|
|
51
|
+
def configure_test_environment
|
|
52
|
+
environment %(config.action_mailer.default_url_options = { host: "www.example.com" }), env: "test"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
module Environments
|
|
4
|
+
class DevelopmentGenerator < Rails::Generators::Base
|
|
5
|
+
desc <<~MARKDOWN
|
|
6
|
+
- Enables [raise_on_missing_translations][].
|
|
7
|
+
- Enables [annotate_rendered_view_with_filenames][].
|
|
8
|
+
- Enables [i18n_customize_full_message][].
|
|
9
|
+
- Enables [query_log_tags_enabled][].
|
|
10
|
+
|
|
11
|
+
[raise_on_missing_translations]: https://guides.rubyonrails.org/configuring.html#config-i18n-raise-on-missing-translations
|
|
12
|
+
[annotate_rendered_view_with_filenames]: https://guides.rubyonrails.org/configuring.html#config-action-view-annotate-rendered-view-with-filenames
|
|
13
|
+
[i18n_customize_full_message]: https://guides.rubyonrails.org/configuring.html#config-active-model-i18n-customize-full-message
|
|
14
|
+
[query_log_tags_enabled]: https://guides.rubyonrails.org/configuring.html#config-active-record-query-log-tags-enabled
|
|
15
|
+
MARKDOWN
|
|
16
|
+
|
|
17
|
+
def raise_on_missing_translations
|
|
18
|
+
if development_config.match?(/^\s#\s*config\.i18n\.raise_on_missing_translations/)
|
|
19
|
+
uncomment_lines "config/environments/development.rb", "config.i18n.raise_on_missing_translations = true"
|
|
20
|
+
else
|
|
21
|
+
environment %(config.i18n.raise_on_missing_translations = true), env: "development"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def annotate_render_view_with_filename
|
|
26
|
+
if development_config.match?(/^\s#\s*config\.action_view\.annotate_render_view_with_filename/)
|
|
27
|
+
uncomment_lines "config/environments/development.rb",
|
|
28
|
+
"config.action_view.annotate_rendered_view_with_filenames = true"
|
|
29
|
+
else
|
|
30
|
+
environment %(config.action_view.annotate_rendered_view_with_filenames = true), env: "development"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def enable_i18n_customize_full_message
|
|
35
|
+
environment %(config.active_model.i18n_customize_full_message = true), env: "development"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def enable_query_log_tags_enabled
|
|
39
|
+
environment %(config.active_record.query_log_tags_enabled = true), env: "development"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def development_config
|
|
45
|
+
File.read(Rails.root.join("config/environments/development.rb"))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
module Environments
|
|
4
|
+
class ProductionGenerator < Rails::Generators::Base
|
|
5
|
+
desc <<~MARKDOWN
|
|
6
|
+
- Enables [require_master_key][].
|
|
7
|
+
|
|
8
|
+
[require_master_key]: https://guides.rubyonrails.org/configuring.html#config-require-master-key
|
|
9
|
+
MARKDOWN
|
|
10
|
+
|
|
11
|
+
def require_master_key
|
|
12
|
+
if production_config.match?(/^\s*#\s*config\.require_master_key\s*=\s*true/)
|
|
13
|
+
uncomment_lines "config/environments/production.rb", /config\.require_master_key\s*=\s*true/
|
|
14
|
+
else
|
|
15
|
+
environment %(config.require_master_key = true), env: "production"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def production_config
|
|
22
|
+
File.read(Rails.root.join("config/environments/production.rb"))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Suspenders
|
|
2
|
+
module Generators
|
|
3
|
+
module Environments
|
|
4
|
+
class TestGenerator < Rails::Generators::Base
|
|
5
|
+
desc <<~MARKDOWN
|
|
6
|
+
- Enables [raise_on_missing_translations][].
|
|
7
|
+
- Disables [action_dispatch.show_exceptions][].
|
|
8
|
+
|
|
9
|
+
[raise_on_missing_translations]: https://guides.rubyonrails.org/configuring.html#config-i18n-raise-on-missing-translations
|
|
10
|
+
[action_dispatch.show_exceptions]: https://edgeguides.rubyonrails.org/configuring.html#config-action-dispatch-show-exceptions
|
|
11
|
+
MARKDOWN
|
|
12
|
+
|
|
13
|
+
def raise_on_missing_translations
|
|
14
|
+
if test_config.match?(/^\s*#\s*config\.i18n\.raise_on_missing_translations\s*=\s*true/)
|
|
15
|
+
uncomment_lines "config/environments/test.rb", /config\.i18n\.raise_on_missing_translations\s*=\s*true/
|
|
16
|
+
else
|
|
17
|
+
environment %(config.i18n.raise_on_missing_translations = true), env: "test"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def disable_action_dispatch_show_exceptions
|
|
22
|
+
if test_config.match?(/^\s*config\.action_dispatch\.show_exceptions\s*=\s*:rescuable/)
|
|
23
|
+
gsub_file "config/environments/test.rb", /^\s*config\.action_dispatch\.show_exceptions\s*=\s*:rescuable/,
|
|
24
|
+
"config.action_dispatch.show_exceptions = :none"
|
|
25
|
+
gsub_file "config/environments/test.rb", /^\s*#\s*Raise exceptions instead of rendering exception templates/i, ""
|
|
26
|
+
else
|
|
27
|
+
environment %(config.action_dispatch.show_exceptions = :none), env: "test"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def test_config
|
|
34
|
+
File.read(Rails.root.join("config/environments/test.rb"))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|