suspenders 1.54.1 → 1.55.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/NEWS.md +6 -0
  4. data/Rakefile +6 -5
  5. data/lib/suspenders/adapters/heroku.rb +16 -16
  6. data/lib/suspenders/app_builder.rb +40 -40
  7. data/lib/suspenders/generators/advisories_generator.rb +1 -1
  8. data/lib/suspenders/generators/analytics_generator.rb +1 -1
  9. data/lib/suspenders/generators/app_generator.rb +25 -25
  10. data/lib/suspenders/generators/base.rb +2 -2
  11. data/lib/suspenders/generators/db_optimizations_generator.rb +2 -2
  12. data/lib/suspenders/generators/factories_generator.rb +1 -1
  13. data/lib/suspenders/generators/jobs_generator.rb +3 -3
  14. data/lib/suspenders/generators/js_driver_generator.rb +1 -1
  15. data/lib/suspenders/generators/lint_generator.rb +5 -0
  16. data/lib/suspenders/generators/preloader_generator.rb +4 -4
  17. data/lib/suspenders/generators/production/compression_generator.rb +1 -1
  18. data/lib/suspenders/generators/production/email_generator.rb +6 -6
  19. data/lib/suspenders/generators/production/manifest_generator.rb +8 -8
  20. data/lib/suspenders/generators/production/single_redirect.rb +1 -1
  21. data/lib/suspenders/generators/production/timeout_generator.rb +2 -2
  22. data/lib/suspenders/generators/profiler_generator.rb +4 -4
  23. data/lib/suspenders/generators/runner_generator.rb +4 -4
  24. data/lib/suspenders/generators/staging/pull_requests_generator.rb +2 -2
  25. data/lib/suspenders/generators/stylelint_generator.rb +2 -1
  26. data/lib/suspenders/generators/stylesheet_base_generator.rb +1 -1
  27. data/lib/suspenders/generators/testing_generator.rb +2 -2
  28. data/lib/suspenders/version.rb +5 -5
  29. data/spec/adapters/heroku_spec.rb +16 -16
  30. data/spec/expand_json_spec.rb +9 -9
  31. data/spec/fakes/bin/heroku +1 -1
  32. data/spec/fakes/bin/hub +1 -1
  33. data/spec/features/cli_help_spec.rb +4 -4
  34. data/spec/features/heroku_spec.rb +3 -3
  35. data/spec/features/lint_spec.rb +26 -0
  36. data/spec/features/new_project_spec.rb +33 -33
  37. data/spec/features/production/compression_spec.rb +2 -2
  38. data/spec/features/production/email_spec.rb +10 -10
  39. data/spec/features/production/manifest_spec.rb +16 -16
  40. data/spec/features/production/single_redirect_spec.rb +2 -2
  41. data/spec/features/profiler_spec.rb +2 -2
  42. data/spec/features/stylelint_spec.rb +7 -7
  43. data/spec/spec_helper.rb +3 -3
  44. data/spec/support/fake_github.rb +3 -3
  45. data/spec/support/fake_heroku.rb +8 -8
  46. data/spec/support/project_files.rb +1 -1
  47. data/spec/support/suspenders.rb +3 -4
  48. data/suspenders.gemspec +20 -20
  49. data/templates/capybara_silence_puma.rb +1 -1
  50. data/templates/errors.rb +3 -3
  51. data/templates/hound.yml +1 -2
  52. data/templates/partials/ci_simplecov.rb +0 -2
  53. data/templates/partials/db_optimizations_configuration.rb +5 -7
  54. data/templates/partials/email_smtp.rb +2 -3
  55. data/templates/partials/pull_requests_config.rb +0 -1
  56. data/templates/partials/runner_setup.rb +1 -2
  57. data/templates/spec_helper.rb +1 -1
  58. data/templates/spring.rb +1 -1
  59. metadata +18 -2
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require File.expand_path(File.join('..', '..', 'support', 'fake_heroku'), File.dirname(__FILE__))
3
+ require File.expand_path(File.join("..", "..", "support", "fake_heroku"), File.dirname(__FILE__))
4
4
 
5
5
  FakeHeroku.new(ARGV).run!
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require File.expand_path(File.join('..', '..', 'support', 'fake_github'), File.dirname(__FILE__))
3
+ require File.expand_path(File.join("..", "..", "support", "fake_github"), File.dirname(__FILE__))
4
4
 
5
5
  FakeGithub.new(ARGV).run!
@@ -20,10 +20,10 @@ RSpec.describe "Command line help output" do
20
20
 
21
21
  it "provides help and version usage within the suspenders group" do
22
22
  expect(help_text).to include <<~EOH
23
- Suspenders options:
24
- -h, [--help], [--no-help] # Show this help message and quit
25
- -v, [--version], [--no-version] # Show Suspenders version number and quit
26
- EOH
23
+ Suspenders options:
24
+ -h, [--help], [--no-help] # Show this help message and quit
25
+ -v, [--version], [--no-version] # Show Suspenders version number and quit
26
+ EOH
27
27
  end
28
28
 
29
29
  it "does not show the default extended rails help section" do
@@ -16,9 +16,9 @@ RSpec.describe "Heroku" do
16
16
  expect(FakeHeroku).to have_configured_vars("staging", "SECRET_KEY_BASE")
17
17
  expect(FakeHeroku).to have_configured_vars(
18
18
  "production",
19
- "SECRET_KEY_BASE",
19
+ "SECRET_KEY_BASE"
20
20
  )
21
- %w(staging production).each do |env|
21
+ %w[staging production].each do |env|
22
22
  expect(FakeHeroku).to have_configured_vars(env, "APPLICATION_HOST")
23
23
  expect(FakeHeroku).to have_configured_vars(env, "HONEYBADGER_ENV")
24
24
  end
@@ -42,7 +42,7 @@ RSpec.describe "Heroku" do
42
42
  context "--heroku with region flag" do
43
43
  before(:all) do
44
44
  clean_up
45
- run_suspenders(%{--heroku=true --heroku-flags="--region eu"})
45
+ run_suspenders(%(--heroku=true --heroku-flags="--region eu"))
46
46
  setup_app_dependencies
47
47
  end
48
48
 
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "suspenders:lint", type: :generator do
4
+ it "sets up standard" do
5
+ with_app { generate("suspenders:lint") }
6
+
7
+ expect("Gemfile").to match_contents(/standard/)
8
+
9
+ run_in_project do
10
+ expect(`rake -T`).to include("rake standard")
11
+ end
12
+ end
13
+
14
+ it "removes standard" do
15
+ with_app do
16
+ generate("suspenders:lint")
17
+ destroy("suspenders:lint")
18
+ end
19
+
20
+ expect("Gemfile").not_to match_contents(/standard/)
21
+
22
+ run_in_project do
23
+ expect(`rake -T`).not_to include("rake standard")
24
+ end
25
+ end
26
+ end
@@ -11,20 +11,20 @@ RSpec.describe "Suspend a new project with default configuration" do
11
11
  it "uses custom Gemfile" do
12
12
  gemfile_file = IO.read("#{project_path}/Gemfile")
13
13
  expect(gemfile_file).to match(
14
- /^ruby "#{Suspenders::RUBY_VERSION}"$/,
14
+ /^ruby "#{Suspenders::RUBY_VERSION}"$/
15
15
  )
16
16
  expect(gemfile_file).to match(
17
- /^gem "autoprefixer-rails"$/,
17
+ /^gem "autoprefixer-rails"$/
18
18
  )
19
19
  expect(gemfile_file).to match(
20
- /^gem "rails", "#{Suspenders::RAILS_VERSION}"$/,
20
+ /^gem "rails", "#{Suspenders::RAILS_VERSION}"$/
21
21
  )
22
22
  end
23
23
 
24
24
  it "ensures project specs pass" do
25
25
  Dir.chdir(project_path) do
26
26
  Bundler.with_unbundled_env do
27
- expect(`rake`).to include('0 failures')
27
+ expect(`rake`).to include("0 failures")
28
28
  end
29
29
  end
30
30
  end
@@ -44,7 +44,7 @@ RSpec.describe "Suspend a new project with default configuration" do
44
44
  end
45
45
 
46
46
  it "copies dotfiles" do
47
- expect(File).to exist("#{project_path}/.env")
47
+ expect(File).to exist("#{project_path}/.sample.env")
48
48
  end
49
49
 
50
50
  it "doesn't generate test directory" do
@@ -54,8 +54,8 @@ RSpec.describe "Suspend a new project with default configuration" do
54
54
  it "loads secret_key_base from env" do
55
55
  secrets_file = IO.read("#{project_path}/config/secrets.yml")
56
56
 
57
- expect(secrets_file).
58
- to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
57
+ expect(secrets_file)
58
+ .to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
59
59
  end
60
60
 
61
61
  it "adds bin/setup file" do
@@ -85,15 +85,15 @@ RSpec.describe "Suspend a new project with default configuration" do
85
85
  end
86
86
 
87
87
  it "initializes ActiveJob to avoid memory bloat" do
88
- expect(File).
89
- to exist("#{project_path}/config/initializers/active_job.rb")
88
+ expect(File)
89
+ .to exist("#{project_path}/config/initializers/active_job.rb")
90
90
  end
91
91
 
92
92
  it "records pageviews through Segment if ENV variable set" do
93
- expect(analytics_partial).
94
- to include(%{<% if ENV["SEGMENT_KEY"] %>})
95
- expect(analytics_partial).
96
- to include(%{analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
93
+ expect(analytics_partial)
94
+ .to include(%(<% if ENV["SEGMENT_KEY"] %>))
95
+ expect(analytics_partial)
96
+ .to include(%{analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
97
97
  end
98
98
 
99
99
  it "raises on unpermitted parameters in all environments" do
@@ -112,13 +112,13 @@ RSpec.describe "Suspend a new project with default configuration" do
112
112
 
113
113
  it "configures public_file_server.headers in production" do
114
114
  expect(production_config).to match(
115
- /^ +config.public_file_server.headers = {\n +"Cache-Control" => "public,/,
115
+ /^ +config.public_file_server.headers = {\n +"Cache-Control" => "public,/
116
116
  )
117
117
  end
118
118
 
119
119
  it "configures production environment to enforce SSL" do
120
120
  expect(production_config).to match(
121
- /^ +config.force_ssl = true/,
121
+ /^ +config.force_ssl = true/
122
122
  )
123
123
  end
124
124
 
@@ -141,8 +141,8 @@ RSpec.describe "Suspend a new project with default configuration" do
141
141
  end
142
142
 
143
143
  it "configs :test email delivery method for development" do
144
- expect(development_config).
145
- to match(/^ +config.action_mailer.delivery_method = :file$/)
144
+ expect(development_config)
145
+ .to match(/^ +config.action_mailer.delivery_method = :file$/)
146
146
  end
147
147
 
148
148
  it "sets action mailer default host and asset host" do
@@ -161,8 +161,8 @@ RSpec.describe "Suspend a new project with default configuration" do
161
161
  email_file = File.join(project_path, "config", "initializers", "email.rb")
162
162
  email_config = IO.read(email_file)
163
163
 
164
- expect(email_config).
165
- to include(%{RecipientInterceptor.new(ENV["EMAIL_RECIPIENTS"])})
164
+ expect(email_config)
165
+ .to include(%{RecipientInterceptor.new(ENV["EMAIL_RECIPIENTS"])})
166
166
  end
167
167
 
168
168
  it "configures language in html element" do
@@ -186,26 +186,26 @@ RSpec.describe "Suspend a new project with default configuration" do
186
186
  delayed_job = IO.read("#{project_path}/bin/delayed_job")
187
187
 
188
188
  expect(delayed_job).to match(
189
- /^require 'delayed\/command'$/,
189
+ /^require 'delayed\/command'$/
190
190
  )
191
191
  end
192
192
 
193
193
  it "configs bullet gem in development" do
194
- expect(development_config).to match /^ +Bullet.enable = true$/
195
- expect(development_config).to match /^ +Bullet.bullet_logger = true$/
196
- expect(development_config).to match /^ +Bullet.rails_logger = true$/
194
+ expect(development_config).to match(/^ +Bullet.enable = true$/)
195
+ expect(development_config).to match(/^ +Bullet.bullet_logger = true$/)
196
+ expect(development_config).to match(/^ +Bullet.rails_logger = true$/)
197
197
  end
198
198
 
199
199
  it "configs missing assets to raise in test" do
200
200
  expect(test_config).to match(
201
- /^ +config.assets.raise_runtime_errors = true$/,
201
+ /^ +config.assets.raise_runtime_errors = true$/
202
202
  )
203
203
  end
204
204
 
205
205
  it "adds spring to binstubs" do
206
206
  expect(File).to exist("#{project_path}/bin/spring")
207
207
 
208
- bin_stubs = %w(rake rails rspec)
208
+ bin_stubs = %w[rake rails rspec]
209
209
  bin_stubs.each do |bin_stub|
210
210
  expect(IO.read("#{project_path}/bin/#{bin_stub}")).to match(/spring/)
211
211
  end
@@ -217,7 +217,7 @@ RSpec.describe "Suspend a new project with default configuration" do
217
217
  IO.read("#{project_path}/config/environment.rb"),
218
218
  development_config,
219
219
  test_config,
220
- production_config,
220
+ production_config
221
221
  ]
222
222
 
223
223
  config_files.each do |file|
@@ -279,34 +279,34 @@ RSpec.describe "Suspend a new project with default configuration" do
279
279
  end
280
280
 
281
281
  it "configures bourbon, and bitters" do
282
- app_css = read_project_file(%w(app assets stylesheets application.scss))
282
+ app_css = read_project_file(%w[app assets stylesheets application.scss])
283
283
  expect(app_css).to match(
284
- /normalize\.css\/normalize.*bourbon.*base/m,
284
+ /normalize\.css\/normalize.*bourbon.*base/m
285
285
  )
286
286
  end
287
287
 
288
288
  it "doesn't use turbolinks" do
289
- app_js = read_project_file(%w(app javascript packs application.js))
289
+ app_js = read_project_file(%w[app javascript packs application.js])
290
290
  expect(app_js).not_to match(/turbolinks/)
291
291
  end
292
292
 
293
293
  it "configures Timecop safe mode" do
294
- spec_helper = read_project_file(%w(spec spec_helper.rb))
294
+ spec_helper = read_project_file(%w[spec spec_helper.rb])
295
295
  expect(spec_helper).to match(/Timecop.safe_mode = true/)
296
296
  end
297
297
 
298
298
  def development_config
299
299
  @_development_config ||=
300
- read_project_file %w(config environments development.rb)
300
+ read_project_file %w[config environments development.rb]
301
301
  end
302
302
 
303
303
  def test_config
304
- @_test_config ||= read_project_file %w(config environments test.rb)
304
+ @_test_config ||= read_project_file %w[config environments test.rb]
305
305
  end
306
306
 
307
307
  def production_config
308
308
  @_production_config ||=
309
- read_project_file %w(config environments production.rb)
309
+ read_project_file %w[config environments production.rb]
310
310
  end
311
311
 
312
312
  def analytics_partial
@@ -6,7 +6,7 @@ RSpec.describe "suspenders:production:compression", type: :generator do
6
6
  with_app { generate("suspenders:production:compression") }
7
7
 
8
8
  expect("config/environments/production.rb").to match_contents(
9
- %r{config.middleware.use Rack::Deflater},
9
+ %r{config.middleware.use Rack::Deflater}
10
10
  )
11
11
  end
12
12
  end
@@ -16,7 +16,7 @@ RSpec.describe "suspenders:production:compression", type: :generator do
16
16
  with_app { destroy("suspenders:production:compression") }
17
17
 
18
18
  expect("config/environments/production.rb").not_to match_contents(
19
- %r{Rack::Deflater},
19
+ %r{Rack::Deflater}
20
20
  )
21
21
  end
22
22
  end
@@ -15,11 +15,11 @@ RSpec.describe "suspenders:production:email", type: :generator do
15
15
 
16
16
  expect("app.json").to contain_json(
17
17
  env: {
18
- SMTP_ADDRESS: { required: true },
19
- SMTP_DOMAIN: { required: true },
20
- SMTP_PASSWORD: { required: true },
21
- SMTP_USERNAME: { required: true },
22
- },
18
+ SMTP_ADDRESS: {required: true},
19
+ SMTP_DOMAIN: {required: true},
20
+ SMTP_PASSWORD: {required: true},
21
+ SMTP_USERNAME: {required: true}
22
+ }
23
23
  )
24
24
  end
25
25
 
@@ -37,11 +37,11 @@ RSpec.describe "suspenders:production:email", type: :generator do
37
37
 
38
38
  expect("app.json").not_to contain_json(
39
39
  env: {
40
- SMTP_ADDRESS: { required: true },
41
- SMTP_DOMAIN: { required: true },
42
- SMTP_PASSWORD: { required: true },
43
- SMTP_USERNAME: { required: true },
44
- },
40
+ SMTP_ADDRESS: {required: true},
41
+ SMTP_DOMAIN: {required: true},
42
+ SMTP_PASSWORD: {required: true},
43
+ SMTP_USERNAME: {required: true}
44
+ }
45
45
  )
46
46
  end
47
47
  end
@@ -7,14 +7,14 @@ RSpec.describe "suspenders:production:manifest", type: :generator do
7
7
  expect("app.json").to contain_json(
8
8
  name: SuspendersTestHelpers::APP_NAME.dasherize,
9
9
  env: {
10
- APPLICATION_HOST: { required: true },
11
- AUTO_MIGRATE_DB: { value: true },
12
- EMAIL_RECIPIENTS: { required: true },
13
- HEROKU_APP_NAME: { required: true },
14
- HEROKU_PARENT_APP_NAME: { required: true },
15
- RACK_ENV: { required: true },
16
- SECRET_KEY_BASE: { generator: "secret" },
17
- },
10
+ APPLICATION_HOST: {required: true},
11
+ AUTO_MIGRATE_DB: {value: true},
12
+ EMAIL_RECIPIENTS: {required: true},
13
+ HEROKU_APP_NAME: {required: true},
14
+ HEROKU_PARENT_APP_NAME: {required: true},
15
+ RACK_ENV: {required: true},
16
+ SECRET_KEY_BASE: {generator: "secret"}
17
+ }
18
18
  )
19
19
  end
20
20
 
@@ -24,14 +24,14 @@ RSpec.describe "suspenders:production:manifest", type: :generator do
24
24
  expect("app.json").not_to contain_json(
25
25
  name: SuspendersTestHelpers::APP_NAME.dasherize,
26
26
  env: {
27
- APPLICATION_HOST: { required: true },
28
- AUTO_MIGRATE_DB: { value: true },
29
- EMAIL_RECIPIENTS: { required: true },
30
- HEROKU_APP_NAME: { required: true },
31
- HEROKU_PARENT_APP_NAME: { required: true },
32
- RACK_ENV: { required: true },
33
- SECRET_KEY_BASE: { generator: "secret" },
34
- },
27
+ APPLICATION_HOST: {required: true},
28
+ AUTO_MIGRATE_DB: {value: true},
29
+ EMAIL_RECIPIENTS: {required: true},
30
+ HEROKU_APP_NAME: {required: true},
31
+ HEROKU_PARENT_APP_NAME: {required: true},
32
+ RACK_ENV: {required: true},
33
+ SECRET_KEY_BASE: {generator: "secret"}
34
+ }
35
35
  )
36
36
  end
37
37
  end
@@ -7,7 +7,7 @@ RSpec.describe "suspenders:production:single_redirect", type: :generator do
7
7
  middleware_canonical_host = %r{config.middleware.use Rack::CanonicalHost, ENV.fetch\("APPLICATION_HOST"\)}
8
8
 
9
9
  expect("config/environments/production.rb").to match_contents(
10
- middleware_canonical_host,
10
+ middleware_canonical_host
11
11
  )
12
12
  end
13
13
  end
@@ -18,7 +18,7 @@ RSpec.describe "suspenders:production:single_redirect", type: :generator do
18
18
  middleware_canonical_host = %r{config.middleware.use Rack::CanonicalHost, ENV.fetch\("APPLICATION_HOST"\)}
19
19
 
20
20
  expect("config/environments/production.rb").not_to match_contents(
21
- middleware_canonical_host,
21
+ middleware_canonical_host
22
22
  )
23
23
  end
24
24
  end
@@ -7,7 +7,7 @@ RSpec.describe "suspenders:profiler", type: :generator do
7
7
  expect("config/initializers/rack_mini_profiler.rb").to \
8
8
  match_contents(/Rack::MiniProfilerRails.initialize/)
9
9
  expect("Gemfile").to match_contents(/rack-mini-profiler/)
10
- expect(".env").to match_contents(/RACK_MINI_PROFILER=0/)
10
+ expect(".sample.env").to match_contents(/RACK_MINI_PROFILER=0/)
11
11
  end
12
12
 
13
13
  it "removes rack-min-profiler" do
@@ -15,6 +15,6 @@ RSpec.describe "suspenders:profiler", type: :generator do
15
15
 
16
16
  expect("config/initializers/rack_mini_profiler.rb").not_to exist_as_a_file
17
17
  expect("Gemfile").not_to match_contents(/rack-mini-profiler/)
18
- expect(".env").not_to exist_as_a_file
18
+ expect(".sample.env").not_to exist_as_a_file
19
19
  end
20
20
  end
@@ -5,8 +5,8 @@ RSpec.describe "suspenders:stylelint", type: :generator do
5
5
  it "creates .stylelintrc.json" do
6
6
  with_app { generate("suspenders:stylelint") }
7
7
 
8
- expect(".stylelintrc.json").
9
- to match_contents(%r{"extends": "@thoughtbot/stylelint-config"})
8
+ expect(".stylelintrc.json")
9
+ .to match_contents(%r{"extends": "@thoughtbot/stylelint-config"})
10
10
  end
11
11
 
12
12
  it "adds stylelint and @thoughtbot/stylelint-config to the package.json" do
@@ -21,7 +21,7 @@ RSpec.describe "suspenders:stylelint", type: :generator do
21
21
  with_app { generate("suspenders:stylelint") }
22
22
 
23
23
  expect(".hound.yml").to(
24
- match_contents(/^ config_file: \.stylelintrc\.json/),
24
+ match_contents(/^ config_file: \.stylelintrc\.json/)
25
25
  )
26
26
  end
27
27
  end
@@ -43,8 +43,8 @@ RSpec.describe "suspenders:stylelint", type: :generator do
43
43
  end
44
44
 
45
45
  expect("package.json").not_to match_contents(/stylelint/)
46
- expect("package.json").
47
- not_to match_contents(%r{@thoughtbot/stylelint-config})
46
+ expect("package.json")
47
+ .not_to match_contents(%r{@thoughtbot/stylelint-config})
48
48
  end
49
49
 
50
50
  it "comments in the hound config_file option" do
@@ -53,8 +53,8 @@ RSpec.describe "suspenders:stylelint", type: :generator do
53
53
  destroy("suspenders:stylelint")
54
54
  end
55
55
 
56
- expect(".hound.yml").
57
- to match_contents(/^ # config_file: \.stylelintrc\.json/)
56
+ expect(".hound.yml")
57
+ .to match_contents(/^ # config_file: \.stylelintrc\.json/)
58
58
  end
59
59
  end
60
60
  end
@@ -1,10 +1,10 @@
1
- require 'bundler/setup'
1
+ require "bundler/setup"
2
2
 
3
3
  Bundler.require(:default, :test)
4
4
 
5
- require (Pathname.new(__FILE__).dirname + '../lib/suspenders').expand_path
5
+ require (Pathname.new(__FILE__).dirname + "../lib/suspenders").expand_path
6
6
 
7
- Dir['./spec/support/**/*.rb'].each { |file| require file }
7
+ Dir["./spec/support/**/*.rb"].sort.each { |file| require file }
8
8
 
9
9
  RSpec.configure do |config|
10
10
  config.include SuspendersTestHelpers