suspenders 20230113.0 → 20240516.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +83 -176
  3. data/Rakefile +13 -0
  4. data/lib/generators/suspenders/accessibility_generator.rb +24 -0
  5. data/lib/generators/suspenders/advisories_generator.rb +32 -0
  6. data/lib/generators/suspenders/ci_generator.rb +57 -0
  7. data/lib/generators/suspenders/email_generator.rb +56 -0
  8. data/lib/generators/suspenders/environments/development_generator.rb +50 -0
  9. data/lib/generators/suspenders/environments/production_generator.rb +27 -0
  10. data/lib/generators/suspenders/environments/test_generator.rb +39 -0
  11. data/lib/generators/suspenders/factories_generator.rb +64 -0
  12. data/lib/generators/suspenders/inline_svg_generator.rb +24 -0
  13. data/lib/generators/suspenders/install/web_generator.rb +71 -0
  14. data/lib/generators/suspenders/jobs_generator.rb +34 -0
  15. data/lib/generators/suspenders/lint_generator.rb +94 -0
  16. data/lib/generators/suspenders/prerequisites_generator.rb +19 -0
  17. data/lib/generators/suspenders/rake_generator.rb +25 -0
  18. data/lib/generators/suspenders/setup_generator.rb +14 -0
  19. data/lib/generators/suspenders/styles_generator.rb +84 -0
  20. data/lib/generators/suspenders/tasks_generator.rb +20 -0
  21. data/lib/generators/suspenders/testing_generator.rb +113 -0
  22. data/lib/generators/suspenders/views_generator.rb +38 -0
  23. data/lib/generators/templates/ci/ci.yml.tt +148 -0
  24. data/lib/generators/templates/ci/dependabot.yml +7 -0
  25. data/lib/generators/templates/email/email_interceptor.rb +11 -0
  26. data/lib/generators/templates/factories/factories_spec.rb +7 -0
  27. data/lib/generators/templates/factories/factories_test.rb +9 -0
  28. data/lib/generators/templates/install/web/CONTRIBUTING.md +94 -0
  29. data/lib/generators/templates/lint/config_better_html.yml +2 -0
  30. data/lib/generators/templates/lint/config_initializers_better_html.rb +9 -0
  31. data/lib/generators/templates/lint/erb-lint.yml +63 -0
  32. data/lib/generators/templates/lint/erblint.rake +47 -0
  33. data/lib/generators/templates/lint/eslintrc.json +7 -0
  34. data/lib/generators/templates/lint/package.json +4 -0
  35. data/lib/generators/templates/lint/prettierignore +1 -0
  36. data/lib/generators/templates/lint/prettierrc +11 -0
  37. data/lib/generators/templates/lint/rubocop.yml.tt +7 -0
  38. data/lib/generators/templates/prerequisites/node-version.tt +1 -0
  39. data/lib/generators/templates/setup/bin_setup.rb +39 -0
  40. data/lib/generators/templates/styles/postcss.config.js +11 -0
  41. data/lib/generators/templates/testing/driver.rb +5 -0
  42. data/lib/generators/templates/views/flashes.html.erb +7 -0
  43. data/lib/install/web.rb +54 -0
  44. data/lib/suspenders/cleanup/generate_readme.rb +165 -0
  45. data/lib/suspenders/cleanup/organize_gemfile.rb +134 -0
  46. data/lib/suspenders/engine.rb +5 -0
  47. data/lib/suspenders/generators.rb +126 -0
  48. data/lib/suspenders/railtie.rb +4 -0
  49. data/lib/suspenders/version.rb +4 -6
  50. data/lib/suspenders.rb +9 -33
  51. data/lib/tasks/suspenders.rake +37 -0
  52. metadata +82 -173
  53. data/.ruby-version +0 -1
  54. data/CONTRIBUTING.md +0 -59
  55. data/GOALS.md +0 -65
  56. data/LICENSE +0 -21
  57. data/NEWS.md +0 -738
  58. data/RELEASING.md +0 -18
  59. data/bin/suspenders +0 -50
  60. data/docs/heroku_deploy.md +0 -19
  61. data/docs/rails_7.md +0 -5
  62. data/lib/suspenders/actions/strip_comments_action.rb +0 -254
  63. data/lib/suspenders/actions.rb +0 -106
  64. data/lib/suspenders/adapters/heroku.rb +0 -136
  65. data/lib/suspenders/app_builder.rb +0 -267
  66. data/lib/suspenders/exit_on_failure.rb +0 -19
  67. data/lib/suspenders/generators/accessibility_generator.rb +0 -12
  68. data/lib/suspenders/generators/advisories_generator.rb +0 -15
  69. data/lib/suspenders/generators/analytics_generator.rb +0 -24
  70. data/lib/suspenders/generators/app_generator.rb +0 -215
  71. data/lib/suspenders/generators/base.rb +0 -60
  72. data/lib/suspenders/generators/ci_generator.rb +0 -32
  73. data/lib/suspenders/generators/db_optimizations_generator.rb +0 -18
  74. data/lib/suspenders/generators/factories_generator.rb +0 -22
  75. data/lib/suspenders/generators/forms_generator.rb +0 -18
  76. data/lib/suspenders/generators/inline_svg_generator.rb +0 -14
  77. data/lib/suspenders/generators/jobs_generator.rb +0 -37
  78. data/lib/suspenders/generators/js_driver_generator.rb +0 -18
  79. data/lib/suspenders/generators/json_generator.rb +0 -14
  80. data/lib/suspenders/generators/lint_generator.rb +0 -14
  81. data/lib/suspenders/generators/production/compression_generator.rb +0 -14
  82. data/lib/suspenders/generators/production/deployment_generator.rb +0 -16
  83. data/lib/suspenders/generators/production/email_generator.rb +0 -34
  84. data/lib/suspenders/generators/production/force_tls_generator.rb +0 -11
  85. data/lib/suspenders/generators/production/manifest_generator.rb +0 -25
  86. data/lib/suspenders/generators/production/single_redirect.rb +0 -15
  87. data/lib/suspenders/generators/production/timeout_generator.rb +0 -22
  88. data/lib/suspenders/generators/profiler_generator.rb +0 -35
  89. data/lib/suspenders/generators/runner_generator.rb +0 -48
  90. data/lib/suspenders/generators/staging/pull_requests_generator.rb +0 -25
  91. data/lib/suspenders/generators/static_generator.rb +0 -14
  92. data/lib/suspenders/generators/stylelint_generator.rb +0 -71
  93. data/lib/suspenders/generators/stylesheet_base_generator.rb +0 -15
  94. data/lib/suspenders/generators/testing_generator.rb +0 -43
  95. data/lib/suspenders/generators/views_generator.rb +0 -25
  96. data/templates/Gemfile.erb +0 -49
  97. data/templates/Procfile +0 -2
  98. data/templates/README.md.erb +0 -28
  99. data/templates/_analytics.html.erb +0 -8
  100. data/templates/_css_overrides.html.erb +0 -7
  101. data/templates/_flashes.html.erb +0 -7
  102. data/templates/active_job.rb +0 -14
  103. data/templates/application.postcss.css +0 -1
  104. data/templates/bin_auto_migrate +0 -5
  105. data/templates/bin_deploy +0 -10
  106. data/templates/bin_setup +0 -28
  107. data/templates/bin_setup_review_app.erb +0 -21
  108. data/templates/bin_yarn +0 -18
  109. data/templates/bundler_audit.rake +0 -4
  110. data/templates/capybara_silence_puma.rb +0 -1
  111. data/templates/chromedriver.rb +0 -27
  112. data/templates/circle.yml.erb +0 -6
  113. data/templates/config_locales_en.yml.erb +0 -19
  114. data/templates/descriptions/advisories.md +0 -5
  115. data/templates/descriptions/analytics.md +0 -4
  116. data/templates/descriptions/ci.md +0 -4
  117. data/templates/descriptions/compression.md +0 -4
  118. data/templates/descriptions/db_optimizations.md +0 -2
  119. data/templates/descriptions/deployment.md +0 -5
  120. data/templates/descriptions/email.md +0 -9
  121. data/templates/descriptions/factories.md +0 -12
  122. data/templates/descriptions/force_tls.md +0 -1
  123. data/templates/descriptions/forms.md +0 -1
  124. data/templates/descriptions/inline_svg.md +0 -2
  125. data/templates/descriptions/jobs.md +0 -3
  126. data/templates/descriptions/js_driver.md +0 -4
  127. data/templates/descriptions/json.md +0 -1
  128. data/templates/descriptions/lint.md +0 -3
  129. data/templates/descriptions/manifest.md +0 -2
  130. data/templates/descriptions/profiler.md +0 -7
  131. data/templates/descriptions/pull_requests.md +0 -4
  132. data/templates/descriptions/runner.md +0 -10
  133. data/templates/descriptions/single_redirect.md +0 -1
  134. data/templates/descriptions/static.md +0 -5
  135. data/templates/descriptions/stylelint.md +0 -3
  136. data/templates/descriptions/stylesheet_base.md +0 -1
  137. data/templates/descriptions/testing.md +0 -9
  138. data/templates/descriptions/timeout.md +0 -4
  139. data/templates/descriptions/views.md +0 -8
  140. data/templates/email.rb +0 -3
  141. data/templates/errors.rb +0 -35
  142. data/templates/flashes_helper.rb +0 -5
  143. data/templates/hound.yml +0 -15
  144. data/templates/json_encoding.rb +0 -1
  145. data/templates/oj.rb +0 -3
  146. data/templates/partials/ci_simplecov.rb +0 -14
  147. data/templates/partials/db_optimizations_configuration.rb +0 -7
  148. data/templates/partials/deployment_readme.md +0 -8
  149. data/templates/partials/email_smtp.rb +0 -2
  150. data/templates/partials/profiler_readme.md +0 -8
  151. data/templates/partials/pull_requests_config.rb +0 -5
  152. data/templates/partials/runner_readme.md +0 -31
  153. data/templates/partials/runner_setup.rb +0 -2
  154. data/templates/postcss.config.js +0 -8
  155. data/templates/postgresql_database.yml.erb +0 -20
  156. data/templates/rack_mini_profiler.rb +0 -7
  157. data/templates/rails_helper.rb +0 -25
  158. data/templates/sample_env +0 -12
  159. data/templates/secrets.yml +0 -8
  160. data/templates/smtp.rb +0 -9
  161. data/templates/spec_helper.rb +0 -25
  162. data/templates/suspenders_gitignore +0 -18
  163. data/templates/suspenders_layout.html.erb.erb +0 -23
  164. /data/{templates → lib/generators/templates/factories}/factories.rb +0 -0
  165. /data/{templates → lib/generators/templates/factories}/factory_bot_rspec.rb +0 -0
  166. /data/{templates → lib/generators/templates/inline_svg}/inline_svg.rb +0 -0
  167. /data/{templates → lib/generators/templates/lint}/stylelintrc.json +0 -0
  168. /data/{templates → lib/generators/templates/tasks}/dev.rake +0 -0
  169. /data/{templates → lib/generators/templates/testing}/action_mailer.rb +0 -0
  170. /data/{templates → lib/generators/templates/testing}/i18n.rb +0 -0
  171. /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: 606737b8d87f3fe7ccfae7c15d214df27de810600e1cb77873025d1af0f17f3d
4
- data.tar.gz: 10ab96b1b4eb893b86cb9ddd40146fdb49c99d51fe03aecf579148ca7a6cbf46
3
+ metadata.gz: 8c2709f640163cac9a711d3fbc428db7771bf0082f8052f0e37cf1b60357fcbf
4
+ data.tar.gz: 8a2d49d93399ead80a3ef658124bd3657fb68bc923b3091bc42f390c22b9abf4
5
5
  SHA512:
6
- metadata.gz: 8d8f0be9c9c48c24cbd459575552dba6f3a93ad669472235e3e2a00bbe26c7cd114a798a527b8b0faeb226aaeb91bad8a98930502e82cf4e2995c90f40070d02
7
- data.tar.gz: '08f52691df274a0187571d59020ca241a564ce442ac5b60427eb7a93087563fc3bb73b1719042ec957d38ed84071d0c06260a2cd18c2ca0124a7cbfd57e05ad1'
6
+ metadata.gz: ad3ba6902b12457e407ac81beade17ec912918d64a0e58eb7874c8214f861deead37497e06214fbae8effc30e7dfff02b4c0006a23a7b6bf0a03f4977538a18b
7
+ data.tar.gz: f3e992788aa0424a1b198ae611a9bed2542d80c12b321946a02fdf17fc05126f6f9b7a86fccbe2470aba77a72bc02612603fcfa072fba621b458e5c3d9981afe
data/README.md CHANGED
@@ -1,225 +1,132 @@
1
1
  # Suspenders
2
2
 
3
- [![Build Status](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/thoughtbot/suspenders/actions)
4
- [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
5
-
6
- Suspenders is the base Rails application used at
7
- [thoughtbot](https://thoughtbot.com/).
8
-
9
- ![Suspenders boy](http://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png)
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
+ [![CI](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml/badge.svg)](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml)
68
4
 
69
- And testing gems like:
5
+ Suspenders is a [Rails Engine][] containing generators for configuring Rails
6
+ applications with these [features][].
70
7
 
71
- * [Capybara](https://github.com/jnicklas/capybara) and
72
- [Google Chromedriver]
73
- integration testing
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
- ## Other goodies
12
+ [Rails Engine]: https://guides.rubyonrails.org/engines.html
13
+ [features]: ./FEATURES.md
86
14
 
87
- Suspenders also comes with:
15
+ ![Suspenders boy](https://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png)
88
16
 
89
- * The [`./bin/setup`][setup] convention for new developer setup
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
- [setup]: https://robots.thoughtbot.com/bin-setup
108
- [compress]: https://robots.thoughtbot.com/content-compression-with-rack-deflater
109
- [pool]: https://devcenter.heroku.com/articles/concurrency-and-database-connections
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
- ## Heroku
23
+ ## Usage
120
24
 
121
- Read the documentation on [deploying to Heroku][heroku deploy]
25
+ Suspenders can be used to create a new Rails application, or to enhance an
26
+ existing Rails application.
122
27
 
123
- You can optionally create Heroku staging and production apps:
28
+ ### With New Rails Applications
124
29
 
125
- suspenders app --heroku true
30
+ This approach uses an [application template][] to generate a new Rails
31
+ application with Suspenders.
126
32
 
127
- This:
33
+ We skip the [default test framework][] in favor of [RSpec][], and [prefer
34
+ PostgreSQL][] as our database.
128
35
 
129
- * Creates a staging and production Heroku app
130
- * Sets them as `staging` and `production` Git remotes
131
- * Configures staging with `HONEYBADGER_ENV` environment variable set
132
- to `staging`
133
- * Creates a [Heroku Pipeline] for review apps
134
- * Schedules automated backups for 10AM UTC for both `staging` and `production`
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
- [Heroku Pipeline]: https://devcenter.heroku.com/articles/pipelines
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
- You can optionally specify alternate Heroku flags:
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
- suspenders app \
142
- --heroku true \
143
- --heroku-flags "--region eu --addons sendgrid,ssl"
48
+ ```
49
+ --skip-test
50
+ --database=postgresql
51
+ -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
52
+ ```
144
53
 
145
- See all possible Heroku flags:
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
- heroku help create
61
+ ### With Existing Rails Applications
148
62
 
149
- ## Git
63
+ Suspenders can be used on an existing Rails application by adding it to the
64
+ `:development` and `:test` group.
150
65
 
151
- This will initialize a new git repository for your Rails app. You can
152
- bypass this with the `--skip-git` option:
66
+ ```ruby
67
+ group :development, :test do
68
+ gem "suspenders"
69
+ end
70
+ ```
153
71
 
154
- suspenders app --skip-git true
72
+ Once installed, you can invoke the web installation generator, which will
73
+ invoke all generators.
155
74
 
156
- ## GitHub
75
+ ```
76
+ bin/rails g suspenders:install:web
77
+ ```
157
78
 
158
- You can optionally create a GitHub repository for the suspended Rails app. It
159
- requires that you have [Hub](https://github.com/github/hub) on your system:
79
+ Or, you can invoke generators individually. To see a list of available
80
+ generators run:
160
81
 
161
- brew install hub # macOS, for other systems see https://github.com/github/hub#installation
162
- suspenders app --github organization/project
82
+ ```
83
+ bin/rails g | grep suspenders
84
+ ```
163
85
 
164
- This has the same effect as running:
86
+ To learn more about a generator, run:
165
87
 
166
- hub create organization/project
88
+ ```
89
+ bin/rails g suspenders:[generator_name] --help
90
+ ```
167
91
 
168
- ## Dependencies
92
+ ### Available Tasks
169
93
 
170
- Suspenders requires the latest version of Ruby.
94
+ Suspenders ships with several custom Rake tasks.
171
95
 
172
- Some gems included in Suspenders have native extensions. You should have GCC
173
- installed on your machine before generating an app with Suspenders.
174
-
175
- Use [OS X GCC Installer](https://github.com/kennethreitz/osx-gcc-installer/) for
176
- Snow Leopard (OS X 10.6).
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.md](CONTRIBUTING.md).
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 © 2008-2017 thoughtbot.
206
- It is free software,
207
- and may be redistributed under the terms specified in the [LICENSE] file.
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
- [LICENSE]: LICENSE
118
+ ## About
210
119
 
211
- ## About thoughtbot
120
+ Suspenders is maintained by [thoughtbot].
212
121
 
213
- [![thoughtbot][thoughtbot-logo]][thoughtbot]
122
+ ![thoughtbot](https://thoughtbot.com/brand_assets/93:44.svg)
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
- We are [available for hire][hire].
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