suspenders 1.44.0 → 1.45.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c484e3bcdd101a9754109743b48f4bd1365667af
4
- data.tar.gz: 8172832bc1d310452d31368dd98b32c5563932d5
3
+ metadata.gz: 253fc6f3c173bce9e7858831161cf75924094222
4
+ data.tar.gz: 947de81dd1fc955c04f13ea1260e4391b505b0f2
5
5
  SHA512:
6
- metadata.gz: 21e949d9c811b1264ee995b4fd5238f3690f294e41adbad8ac59ee1d8d0d720f32aae3b42eb8be074f2b7ad410068179b8ee8fa196c40ca54c077af075df2e0a
7
- data.tar.gz: ee9e71d1473f0bd77f30192dfcfd462454c0cec67fabfedf794f1fec331fa0e75d6b4e328eb062d141cb6e93e5dae00c09c64832c74eb800af66bf67917551fe
6
+ metadata.gz: 003c8627d76eaad3f8a51f404608dc1cd66ee35dbaba8b45cf6f5ef0e9a06fc4fe7f826f9f387a51118d2670df7499a46b83a7441541e21f5a0b691a08a0e063
7
+ data.tar.gz: 3a08ab29152033941e6a1b2baba20743d2992ab9872e590e7815007cadcbba37514700cc6f9deaed72f02408458a21d1ed020f15c1e060e16250bd7da01a5553
@@ -1 +1 @@
1
- 2.4.0
1
+ 2.4.1
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
- rvm: 2.4.0
2
+ rvm: 2.4.1
3
3
  cache: bundler
4
4
  sudo: false
5
5
  before_install:
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2008-2016 thoughtbot, inc.
3
+ Copyright (c) 2008-2017 thoughtbot, inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/NEWS.md CHANGED
@@ -1,3 +1,30 @@
1
+ 1.45.0 (September 8, 2017)
2
+
3
+ * Bump Rails to 5.1.3 (#857)
4
+ * Configure HONEYBADGER_ENV for staging, production (#861)
5
+ * Remove vestigial `staging` references (#860)
6
+ * Prevent memory bloat in ActiveJob children (#856)
7
+ * .git/safe is opt-in (#837)
8
+ * Enforce SSL in production environment (#855)
9
+ * Configures action mailer asset host (#853)
10
+ * Install normalize.css via yarn (#851)
11
+ * Update Rails to 5.1 (#847)
12
+ * Update bourbon from 5.0.0.beta.7 to 5.0.0.beta.8 (#848)
13
+ * Update Neat to 2.1 (#849)
14
+ * Update Bitters to 1.7 (#850)
15
+ * Fix incorrect Timecop link (#845)
16
+ * Update Ruby to 2.4.1 (#841)
17
+ * Update rspec-rails to 3.6 (#842)
18
+ * Configure TimeCop safe mode (#840)
19
+ * Pull normalize.css through Rails Assets (#839)
20
+ * Fix fatal git failures in tests (#832)
21
+ * Schedule Heroku Backups and Capture backup of existing staging database for
22
+ Review Apps (#826)
23
+ * Use bundle-audit rake task from the gem (#831)
24
+ * Update thoughtbot logo (#829)
25
+ * Change terminal symbol in README's deploying section (#828)
26
+ * Update Segment snippet to 4.0.0 (#822)
27
+
1
28
  1.44.0 (January 25, 2017)
2
29
 
3
30
  * Improve readability of `bin/setup-review-app` (#819)
data/README.md CHANGED
@@ -87,7 +87,7 @@ And testing gems like:
87
87
  * [RSpec Mocks](https://github.com/rspec/rspec-mocks) for stubbing and spying
88
88
  * [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) for common
89
89
  RSpec matchers
90
- * [Timecop](https://github.com/ferndopolis/timecop-console) for testing time
90
+ * [Timecop](https://github.com/travisjeffery/timecop) for testing time
91
91
 
92
92
  ## Other goodies
93
93
 
@@ -127,9 +127,10 @@ This:
127
127
 
128
128
  * Creates a staging and production Heroku app
129
129
  * Sets them as `staging` and `production` Git remotes
130
- * Configures staging with `RACK_ENV` environment variable set
130
+ * Configures staging with `HONEYBADGER_ENV` environment variable set
131
131
  to `staging`
132
132
  * Creates a [Heroku Pipeline] for review apps
133
+ * Schedules automated backups for 10AM UTC for both `staging` and `production`
133
134
 
134
135
  [Heroku Pipeline]: https://devcenter.heroku.com/articles/pipelines
135
136
 
@@ -205,7 +206,7 @@ Thank you, [contributors]!
205
206
 
206
207
  ## License
207
208
 
208
- Suspenders is Copyright © 2008-2016 thoughtbot.
209
+ Suspenders is Copyright © 2008-2017 thoughtbot.
209
210
  It is free software,
210
211
  and may be redistributed under the terms specified in the [LICENSE] file.
211
212
 
@@ -213,7 +214,7 @@ and may be redistributed under the terms specified in the [LICENSE] file.
213
214
 
214
215
  ## About thoughtbot
215
216
 
216
- ![thoughtbot](https://thoughtbot.com/logo.png)
217
+ [![thoughtbot][thoughtbot-logo]][thoughtbot]
217
218
 
218
219
  Suspenders is maintained and funded by thoughtbot, inc.
219
220
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
@@ -222,5 +223,7 @@ We love open source software!
222
223
  See [our other projects][community].
223
224
  We are [available for hire][hire].
224
225
 
226
+ [thoughtbot]: https://thoughtbot.com?utm_source=github
227
+ [thoughtbot-logo]: http://presskit.thoughtbot.com/images/thoughtbot-logo-for-readmes.svg
225
228
  [community]: https://thoughtbot.com/community?utm_source=github
226
229
  [hire]: https://thoughtbot.com?utm_source=github
@@ -1,5 +1,7 @@
1
1
  require 'suspenders/version'
2
2
  require 'suspenders/generators/app_generator'
3
+ require "suspenders/generators/enforce_ssl_generator"
4
+ require "suspenders/generators/initialize_active_job_generator"
3
5
  require 'suspenders/generators/static_generator'
4
6
  require 'suspenders/generators/stylesheet_base_generator'
5
7
  require 'suspenders/actions'
@@ -14,6 +14,11 @@ module Suspenders
14
14
  configure_environment(rails_env, config)
15
15
  end
16
16
 
17
+ def action_mailer_asset_host(rails_env, host)
18
+ config = "config.action_mailer.asset_host = { host: #{host} }"
19
+ configure_environment(rails_env, config)
20
+ end
21
+
17
22
  def configure_application_file(config)
18
23
  inject_into_file(
19
24
  "config/application.rb",
@@ -25,7 +30,7 @@ module Suspenders
25
30
  def configure_environment(rails_env, config)
26
31
  inject_into_file(
27
32
  "config/environments/#{rails_env}.rb",
28
- "\n\n #{config}",
33
+ "\n #{config}",
29
34
  before: "\nend"
30
35
  )
31
36
  end
@@ -37,6 +37,24 @@ module Suspenders
37
37
  end
38
38
  end
39
39
 
40
+ def set_heroku_honeybadger_env
41
+ %w(staging production).each do |environment|
42
+ run_toolbelt_command(
43
+ "config:add HONEYBADGER_ENV=#{environment}",
44
+ environment,
45
+ )
46
+ end
47
+ end
48
+
49
+ def set_heroku_backup_schedule
50
+ %w(staging production).each do |environment|
51
+ run_toolbelt_command(
52
+ "pg:backups:schedule DATABASE_URL --at '10:00 UTC'",
53
+ environment,
54
+ )
55
+ end
56
+ end
57
+
40
58
  def create_review_apps_setup_script
41
59
  app_builder.template(
42
60
  "bin_setup_review_app.erb",
@@ -5,15 +5,19 @@ module Suspenders
5
5
  include Suspenders::Actions
6
6
  extend Forwardable
7
7
 
8
- def_delegators :heroku_adapter,
9
- :create_heroku_application_manifest_file,
10
- :create_heroku_pipeline,
11
- :create_production_heroku_app,
12
- :create_staging_heroku_app,
13
- :create_review_apps_setup_script,
14
- :set_heroku_rails_secrets,
15
- :set_heroku_remotes,
16
- :set_heroku_application_host
8
+ def_delegators(
9
+ :heroku_adapter,
10
+ :create_heroku_application_manifest_file,
11
+ :create_heroku_pipeline,
12
+ :create_production_heroku_app,
13
+ :create_review_apps_setup_script,
14
+ :create_staging_heroku_app,
15
+ :set_heroku_application_host,
16
+ :set_heroku_backup_schedule,
17
+ :set_heroku_honeybadger_env,
18
+ :set_heroku_rails_secrets,
19
+ :set_heroku_remotes,
20
+ )
17
21
 
18
22
  def readme
19
23
  template 'README.md.erb', 'README.md'
@@ -43,14 +47,6 @@ module Suspenders
43
47
  'raise_delivery_errors = false', 'raise_delivery_errors = true'
44
48
  end
45
49
 
46
- def remove_turbolinks
47
- replace_in_file(
48
- "app/assets/javascripts/application.js",
49
- "//= require turbolinks",
50
- ""
51
- )
52
- end
53
-
54
50
  def set_test_delivery_method
55
51
  inject_into_file(
56
52
  "config/environments/development.rb",
@@ -157,11 +153,7 @@ module Suspenders
157
153
  config.middleware.use Rack::CanonicalHost, ENV.fetch("APPLICATION_HOST")
158
154
  RUBY
159
155
 
160
- inject_into_file(
161
- "config/environments/production.rb",
162
- config,
163
- after: "Rails.application.configure do",
164
- )
156
+ configure_environment "production", config
165
157
  end
166
158
 
167
159
  def enable_rack_deflater
@@ -226,7 +218,7 @@ config.public_file_server.headers = {
226
218
  end
227
219
 
228
220
  def create_database
229
- bundle_command 'exec rake db:create db:migrate'
221
+ bundle_command "exec rails db:create db:migrate"
230
222
  end
231
223
 
232
224
  def replace_gemfile(path)
@@ -310,8 +302,14 @@ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
310
302
 
311
303
  def configure_action_mailer
312
304
  action_mailer_host "development", %{"localhost:3000"}
305
+ action_mailer_asset_host "development", %{"localhost:3000"}
313
306
  action_mailer_host "test", %{"www.example.com"}
307
+ action_mailer_asset_host "test", %{"www.example.com"}
314
308
  action_mailer_host "production", %{ENV.fetch("APPLICATION_HOST")}
309
+ action_mailer_asset_host(
310
+ "production",
311
+ %{ENV.fetch("ASSET_HOST", ENV.fetch("APPLICATION_HOST"))},
312
+ )
315
313
  end
316
314
 
317
315
  def configure_active_job
@@ -351,10 +349,6 @@ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
351
349
  directory("dotfiles", ".")
352
350
  end
353
351
 
354
- def init_git
355
- run 'git init'
356
- end
357
-
358
352
  def create_heroku_apps(flags)
359
353
  create_staging_heroku_app(flags)
360
354
  create_production_heroku_app(flags)
@@ -370,8 +364,8 @@ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
370
364
  If you have previously run the `./bin/setup` script,
371
365
  you can deploy to staging and production with:
372
366
 
373
- $ ./bin/deploy staging
374
- $ ./bin/deploy production
367
+ % ./bin/deploy staging
368
+ % ./bin/deploy production
375
369
  MARKDOWN
376
370
 
377
371
  append_file "README.md", instructions
@@ -401,7 +395,7 @@ you can deploy to staging and production with:
401
395
 
402
396
  def setup_bundler_audit
403
397
  copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake"
404
- append_file "Rakefile", %{\ntask default: "bundler:audit"\n}
398
+ append_file "Rakefile", %{\ntask default: "bundle:audit"\n}
405
399
  end
406
400
 
407
401
  def setup_spring
@@ -29,6 +29,12 @@ module Suspenders
29
29
  class_option :skip_test, type: :boolean, default: true,
30
30
  desc: "Skip Test Unit"
31
31
 
32
+ class_option :skip_system_test,
33
+ type: :boolean, default: true, desc: "Skip system test files"
34
+
35
+ class_option :skip_turbolinks,
36
+ type: :boolean, default: true, desc: "Skip turbolinks gem"
37
+
32
38
  def finish_template
33
39
  invoke :suspenders_customization
34
40
  super
@@ -47,7 +53,6 @@ module Suspenders
47
53
  invoke :remove_config_comment_lines
48
54
  invoke :remove_routes_comment_lines
49
55
  invoke :setup_dotfiles
50
- invoke :setup_git
51
56
  invoke :setup_database
52
57
  invoke :create_local_heroku_setup
53
58
  invoke :create_heroku_apps
@@ -56,6 +61,7 @@ module Suspenders
56
61
  invoke :setup_bundler_audit
57
62
  invoke :setup_spring
58
63
  invoke :generate_default
64
+ invoke :setup_default_directories
59
65
  invoke :outro
60
66
  end
61
67
 
@@ -80,7 +86,6 @@ module Suspenders
80
86
  say 'Setting up the development environment'
81
87
  build :raise_on_missing_assets_in_test
82
88
  build :raise_on_delivery_errors
83
- build :remove_turbolinks
84
89
  build :set_test_delivery_method
85
90
  build :add_bullet_gem_configuration
86
91
  build :raise_on_unpermitted_parameters
@@ -142,14 +147,6 @@ module Suspenders
142
147
  build :setup_rack_mini_profiler
143
148
  end
144
149
 
145
- def setup_git
146
- if !options[:skip_git]
147
- say "Initializing git"
148
- invoke :setup_default_directories
149
- invoke :init_git
150
- end
151
- end
152
-
153
150
  def create_local_heroku_setup
154
151
  say "Creating local Heroku setup"
155
152
  build :create_review_apps_setup_script
@@ -164,6 +161,8 @@ module Suspenders
164
161
  build :set_heroku_remotes
165
162
  build :set_heroku_rails_secrets
166
163
  build :set_heroku_application_host
164
+ build :set_heroku_honeybadger_env
165
+ build :set_heroku_backup_schedule
167
166
  build :create_heroku_pipeline
168
167
  build :configure_automatic_deployment
169
168
  end
@@ -199,10 +198,6 @@ module Suspenders
199
198
  build :setup_spring
200
199
  end
201
200
 
202
- def init_git
203
- build :init_git
204
- end
205
-
206
201
  def copy_miscellaneous_files
207
202
  say 'Copying miscellaneous support files'
208
203
  build :copy_miscellaneous_files
@@ -223,6 +218,8 @@ module Suspenders
223
218
 
224
219
  def generate_default
225
220
  run("spring stop")
221
+ generate("suspenders:initialize_active_job")
222
+ generate("suspenders:enforce_ssl")
226
223
  generate("suspenders:static")
227
224
  generate("suspenders:stylesheet_base")
228
225
  end
@@ -0,0 +1,12 @@
1
+ require "rails/generators"
2
+ require_relative "../actions"
3
+
4
+ module Suspenders
5
+ class EnforceSslGenerator < Rails::Generators::Base
6
+ include Suspenders::Actions
7
+
8
+ def enforce_ssl
9
+ configure_environment "production", "config.force_ssl = true"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ require "rails/generators"
2
+
3
+ module Suspenders
4
+ class InitializeActiveJobGenerator < Rails::Generators::Base
5
+ source_root(
6
+ File.expand_path(
7
+ File.join("..", "..", "..", "templates"),
8
+ File.dirname(__FILE__),
9
+ ),
10
+ )
11
+
12
+ def initialize_active_job
13
+ copy_file(
14
+ "active_job.rb",
15
+ "config/initializers/active_job.rb",
16
+ )
17
+ end
18
+ end
19
+ end
@@ -7,8 +7,8 @@ module Suspenders
7
7
  File.dirname(__FILE__))
8
8
 
9
9
  def add_stylesheet_gems
10
- gem "bourbon", "~> 5.0.0.beta.7"
11
- gem "neat", "~> 2.0.0.beta.1"
10
+ gem "bourbon", "~> 5.0.0.beta.8"
11
+ gem "neat", "~> 2.1"
12
12
  gem "refills", group: [:development, :test]
13
13
  Bundler.with_clean_env { run "bundle install" }
14
14
  end
@@ -33,5 +33,9 @@ module Suspenders
33
33
  def install_bitters
34
34
  run "bitters install --path app/assets/stylesheets"
35
35
  end
36
+
37
+ def install_normalize_css
38
+ run "bin/yarn add normalize.css"
39
+ end
36
40
  end
37
41
  end
@@ -1,8 +1,8 @@
1
1
  module Suspenders
2
- RAILS_VERSION = "~> 5.0.0".freeze
2
+ RAILS_VERSION = "~> 5.1.3".freeze
3
3
  RUBY_VERSION = IO.
4
4
  read("#{File.dirname(__FILE__)}/../../.ruby-version").
5
5
  strip.
6
6
  freeze
7
- VERSION = "1.44.0".freeze
7
+ VERSION = "1.45.0".freeze
8
8
  end
@@ -30,6 +30,16 @@ module Suspenders
30
30
  )
31
31
  end
32
32
 
33
+ it "sets the heroku backup schedule" do
34
+ app_builder = double(app_name: app_name)
35
+ allow(app_builder).to receive(:run)
36
+
37
+ Heroku.new(app_builder).set_heroku_backup_schedule
38
+
39
+ expect(app_builder).to have_backup_schedule("staging")
40
+ expect(app_builder).to have_backup_schedule("production")
41
+ end
42
+
33
43
  it "sets the application host" do
34
44
  app_builder = double(app_name: app_name)
35
45
  allow(app_builder).to receive(:run)
@@ -49,6 +59,11 @@ module Suspenders
49
59
  SuspendersTestHelpers::APP_NAME
50
60
  end
51
61
 
62
+ def have_backup_schedule(remote_name)
63
+ have_received(:run).
64
+ with(/pg:backups:schedule DATABASE_URL --at '10:00 UTC' --remote #{remote_name}/)
65
+ end
66
+
52
67
  def have_configured_var(remote_name, var)
53
68
  have_received(:run).with(/config:add #{var}=.+ --remote #{remote_name}/)
54
69
  end
@@ -18,14 +18,10 @@ RSpec.describe "Heroku" do
18
18
  "production",
19
19
  "SECRET_KEY_BASE",
20
20
  )
21
- expect(FakeHeroku).to have_configured_vars(
22
- "staging",
23
- "APPLICATION_HOST",
24
- )
25
- expect(FakeHeroku).to have_configured_vars(
26
- "production",
27
- "APPLICATION_HOST",
28
- )
21
+ %w(staging production).each do |env|
22
+ expect(FakeHeroku).to have_configured_vars(env, "APPLICATION_HOST")
23
+ expect(FakeHeroku).to have_configured_vars(env, "HONEYBADGER_ENV")
24
+ end
29
25
  expect(FakeHeroku).to have_setup_pipeline_for(app_name)
30
26
 
31
27
  bin_setup_path = "#{project_path}/bin/setup"
@@ -29,6 +29,14 @@ RSpec.describe "Suspend a new project with default configuration" do
29
29
  end
30
30
  end
31
31
 
32
+ it "includes the bundle:audit task" do
33
+ Dir.chdir(project_path) do
34
+ Bundler.with_clean_env do
35
+ expect(`rails -T`).to include("rails bundle:audit")
36
+ end
37
+ end
38
+ end
39
+
32
40
  it "creates .ruby-version from Suspenders .ruby-version" do
33
41
  ruby_version_file = IO.read("#{project_path}/.ruby-version")
34
42
 
@@ -92,6 +100,11 @@ RSpec.describe "Suspend a new project with default configuration" do
92
100
  expect(env).to include "RACK_MINI_PROFILER=0"
93
101
  end
94
102
 
103
+ it "initializes ActiveJob to avoid memory bloat" do
104
+ expect(File).
105
+ to exist("#{project_path}/config/initializers/active_job.rb")
106
+ end
107
+
95
108
  it "creates a rack-mini-profiler initializer" do
96
109
  expect(File).
97
110
  to exist("#{project_path}/config/initializers/rack_mini_profiler.rb")
@@ -101,7 +114,7 @@ RSpec.describe "Suspend a new project with default configuration" do
101
114
  expect(analytics_partial).
102
115
  to include(%{<% if ENV["SEGMENT_KEY"] %>})
103
116
  expect(analytics_partial).
104
- to include(%{window.analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
117
+ to include(%{analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
105
118
  end
106
119
 
107
120
  it "raises on unpermitted parameters in all environments" do
@@ -124,6 +137,12 @@ RSpec.describe "Suspend a new project with default configuration" do
124
137
  )
125
138
  end
126
139
 
140
+ it "configures production environment to enforce SSL" do
141
+ expect(production_config).to match(
142
+ /^ +config.force_ssl = true/,
143
+ )
144
+ end
145
+
127
146
  it "raises on missing translations in development and test" do
128
147
  [development_config, test_config].each do |environment_file|
129
148
  expect(environment_file).to match(
@@ -147,6 +166,13 @@ RSpec.describe "Suspend a new project with default configuration" do
147
166
  to match(/^ +config.action_mailer.delivery_method = :file$/)
148
167
  end
149
168
 
169
+ it "sets action mailer default host and asset host" do
170
+ config_key = 'config\.action_mailer\.asset_host'
171
+ config_value =
172
+ '{ host: ENV\.fetch\("ASSET_HOST", ENV\.fetch\("APPLICATION_HOST"\)\) }'
173
+ expect(production_config).to match(/#{config_key} = #{config_value}/)
174
+ end
175
+
150
176
  it "uses APPLICATION_HOST, not HOST in the production config" do
151
177
  expect(production_config).to match(/"APPLICATION_HOST"/)
152
178
  expect(production_config).not_to match(/"HOST"/)
@@ -221,7 +247,8 @@ RSpec.describe "Suspend a new project with default configuration" do
221
247
 
222
248
  expect(bin_setup).to include("PARENT_APP_NAME=#{app_name.dasherize}-staging")
223
249
  expect(bin_setup).to include("APP_NAME=#{app_name.dasherize}-staging-pr-$1")
224
- expect(bin_setup).to include("heroku run rake db:migrate --exit-code --app $APP_NAME")
250
+ expect(bin_setup).
251
+ to include("heroku run rails db:migrate --exit-code --app $APP_NAME")
225
252
  expect(bin_setup).to include("heroku ps:scale worker=1 --app $APP_NAME")
226
253
  expect(bin_setup).to include("heroku restart --app $APP_NAME")
227
254
 
@@ -232,7 +259,7 @@ RSpec.describe "Suspend a new project with default configuration" do
232
259
  bin_deploy_path = "#{project_path}/bin/deploy"
233
260
  bin_deploy = IO.read(bin_deploy_path)
234
261
 
235
- expect(bin_deploy).to include("heroku run rake db:migrate --exit-code")
262
+ expect(bin_deploy).to include("heroku run rails db:migrate --exit-code")
236
263
  expect(File.stat(bin_deploy_path)).to be_executable
237
264
  end
238
265
 
@@ -264,7 +291,9 @@ RSpec.describe "Suspend a new project with default configuration" do
264
291
  expect(read_project_file(flashes_path)).to match(/\$flashes/m)
265
292
 
266
293
  app_css = read_project_file(%w(app assets stylesheets application.scss))
267
- expect(app_css).to match(/normalize-rails.*bourbon.*neat.*base.*refills/m)
294
+ expect(app_css).to match(
295
+ /normalize\.css\/normalize\.css.*bourbon.*neat.*base.*refills/m,
296
+ )
268
297
  end
269
298
 
270
299
  it "doesn't use turbolinks" do
@@ -272,6 +301,11 @@ RSpec.describe "Suspend a new project with default configuration" do
272
301
  expect(app_js).not_to match(/turbolinks/)
273
302
  end
274
303
 
304
+ it "configures Timecop safe mode" do
305
+ spec_helper = read_project_file(%w(spec spec_helper.rb))
306
+ expect(spec_helper).to match(/Timecop.safe_mode = true/)
307
+ end
308
+
275
309
  def development_config
276
310
  @_development_config ||=
277
311
  read_project_file %w(config environments development.rb)
@@ -17,6 +17,12 @@ module SuspendersTestHelpers
17
17
  `
18
18
  #{suspenders_bin} #{APP_NAME} #{arguments}
19
19
  `
20
+ Dir.chdir(APP_NAME) do
21
+ with_env("HOME", tmp_path) do
22
+ `git add .`
23
+ `git commit -m 'Initial commit'`
24
+ end
25
+ end
20
26
  end
21
27
  end
22
28
  end
@@ -45,7 +51,7 @@ module SuspendersTestHelpers
45
51
  if File.exist?(project_path)
46
52
  Dir.chdir(project_path) do
47
53
  Bundler.with_clean_env do
48
- `rake db:drop`
54
+ `rails db:drop`
49
55
  end
50
56
  end
51
57
  end
@@ -80,4 +86,14 @@ module SuspendersTestHelpers
80
86
  def root_path
81
87
  File.expand_path('../../../', __FILE__)
82
88
  end
89
+
90
+ def with_env(name, new_value)
91
+ prior = ENV[name]
92
+ ENV[name] = new_value.to_s
93
+
94
+ yield
95
+
96
+ ensure
97
+ ENV[name] = prior
98
+ end
83
99
  end
@@ -27,7 +27,7 @@ rush to build something amazing; don't use it if you like missing deadlines.
27
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28
28
  s.version = Suspenders::VERSION
29
29
 
30
- s.add_dependency 'bitters', '~> 1.5'
30
+ s.add_dependency 'bitters', '~> 1.7'
31
31
  s.add_dependency 'bundler', '~> 1.3'
32
32
  s.add_dependency 'rails', Suspenders::RAILS_VERSION
33
33
 
@@ -1,5 +1,10 @@
1
1
  source "https://rubygems.org"
2
2
 
3
+ git_source(:github) do |repo_name|
4
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
5
+ "https://github.com/#{repo_name}.git"
6
+ end
7
+
3
8
  ruby "<%= Suspenders::RUBY_VERSION %>"
4
9
 
5
10
  gem "autoprefixer-rails"
@@ -7,7 +12,6 @@ gem "delayed_job_active_record"
7
12
  gem "flutie"
8
13
  gem "honeybadger"
9
14
  gem "jquery-rails"
10
- gem "normalize-rails", "~> 3.0.0"
11
15
  gem "pg"
12
16
  gem "puma"
13
17
  gem "rack-canonical-host"
@@ -20,9 +24,13 @@ gem "sprockets", ">= 3.0.0"
20
24
  gem "suspenders"
21
25
  gem "title"
22
26
  gem "uglifier"
27
+ <% if options[:webpack] %>
28
+ gem "webpacker"
29
+ <% end %>
23
30
 
24
31
  group :development do
25
32
  gem "listen"
33
+ gem "rack-mini-profiler", require: false
26
34
  gem "spring"
27
35
  gem "spring-commands-rspec"
28
36
  gem "web-console"
@@ -36,11 +44,7 @@ group :development, :test do
36
44
  gem "factory_girl_rails"
37
45
  gem "pry-byebug"
38
46
  gem "pry-rails"
39
- gem "rspec-rails", "~> 3.5"
40
- end
41
-
42
- group :development, :staging do
43
- gem "rack-mini-profiler", require: false
47
+ gem "rspec-rails", "~> 3.6"
44
48
  end
45
49
 
46
50
  group :test do
@@ -54,6 +58,6 @@ group :test do
54
58
  gem "webmock"
55
59
  end
56
60
 
57
- group :staging, :production do
61
+ group :production do
58
62
  gem "rack-timeout"
59
63
  end
@@ -1,2 +1,2 @@
1
1
  web: bundle exec puma -p $PORT -C ./config/puma.rb
2
- worker: bundle exec rake jobs:work
2
+ worker: bundle exec rails jobs:work
@@ -1,7 +1,8 @@
1
1
  <% if ENV["SEGMENT_KEY"] %>
2
2
  <script type="text/javascript">
3
- window.analytics=window.analytics||[],window.analytics.methods=["identify","group","track","page","pageview","alias","ready","on","once","off","trackLink","trackForm","trackClick","trackSubmit"],window.analytics.factory=function(t){return function(){var a=Array.prototype.slice.call(arguments);return a.unshift(t),window.analytics.push(a),window.analytics}};for(var i=0;i<window.analytics.methods.length;i++){var key=window.analytics.methods[i];window.analytics[key]=window.analytics.factory(key)}window.analytics.load=function(t){if(!document.getElementById("analytics-js")){var a=document.createElement("script");a.type="text/javascript",a.id="analytics-js",a.async=!0,a.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(a,n)}},window.analytics.SNIPPET_VERSION="2.0.9",
4
- window.analytics.load("<%= ENV["SEGMENT_KEY"] %>");
5
- window.analytics.page();
3
+ !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0";
4
+ analytics.load("<%= ENV["SEGMENT_KEY"] %>");
5
+ analytics.page();
6
+ }}();
6
7
  </script>
7
8
  <% end %>
@@ -0,0 +1,13 @@
1
+ require "active_job/logging"
2
+
3
+ ActiveSupport::Notifications.unsubscribe("enqueue.active_job")
4
+
5
+ module ActiveJob
6
+ module Logging
7
+ class EnqueueLogSubscriber < LogSubscriber
8
+ define_method :enqueue, instance_method(:enqueue)
9
+ end
10
+ end
11
+ end
12
+
13
+ ActiveJob::Logging::EnqueueLogSubscriber.attach_to(:active_job)
@@ -1,6 +1,6 @@
1
1
  @charset "utf-8";
2
2
 
3
- @import "normalize-rails";
3
+ @import "normalize.css/normalize.css";
4
4
 
5
5
  @import "bourbon";
6
6
  @import "neat";
@@ -8,5 +8,5 @@ branch="$(git symbolic-ref HEAD --short)"
8
8
  target="${1:-staging}"
9
9
 
10
10
  git push "$target" "$branch:master"
11
- heroku run rake db:migrate --exit-code --remote "$target"
11
+ heroku run rails db:migrate --exit-code --remote "$target"
12
12
  heroku restart --remote "$target"
@@ -11,10 +11,14 @@ gem install bundler --conservative
11
11
  bundle check || bundle install
12
12
 
13
13
  # Set up database and add any development seed data
14
- bin/rake dev:prime
14
+ bin/rails dev:prime
15
15
 
16
- # Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv
17
- mkdir -p .git/safe
16
+ if [ ! -d .git/safe ] && echo $PATH | grep .git/safe > /dev/null; then
17
+ echo "-----------------------------------------------------------------------"
18
+ echo
19
+ echo "-> When you trust this repo, remember to run: mkdir -p .git/safe"
20
+ echo
21
+ fi
18
22
 
19
23
  # Only if this isn't CI
20
24
  # if [ -z "$CI" ]; then
@@ -11,9 +11,12 @@ fi
11
11
 
12
12
  PARENT_APP_NAME=<%= app_name.dasherize %>-staging
13
13
  APP_NAME=<%= app_name.dasherize %>-staging-pr-$1
14
- URL=`heroku pg:backups public-url -a $PARENT_APP_NAME`
14
+
15
+ heroku pg:backups:capture --app $PARENT_APP_NAME
16
+
17
+ URL=`heroku pg:backups public-url --app $PARENT_APP_NAME`
15
18
 
16
19
  heroku pg:backups restore $URL DATABASE_URL --confirm $APP_NAME --app $APP_NAME
17
- heroku run rake db:migrate --exit-code --app $APP_NAME
20
+ heroku run rails db:migrate --exit-code --app $APP_NAME
18
21
  heroku ps:scale worker=1 --app $APP_NAME
19
22
  heroku restart --app $APP_NAME
@@ -1,12 +1,4 @@
1
1
  if Rails.env.development? || Rails.env.test?
2
- require "bundler/audit/cli"
3
-
4
- namespace :bundler do
5
- desc "Updates the ruby-advisory-db and runs audit"
6
- task :audit do
7
- %w(update check).each do |command|
8
- Bundler::Audit::CLI.start [command]
9
- end
10
- end
11
- end
2
+ require "bundler/audit/task"
3
+ Bundler::Audit::Task.new
12
4
  end
@@ -17,5 +17,3 @@ production: &deploy
17
17
  pool: <%%= [Integer(ENV.fetch("MAX_THREADS", 5)), Integer(ENV.fetch("DB_POOL", 5))].max %>
18
18
  timeout: 5000
19
19
  url: <%%= ENV.fetch("DATABASE_URL", "") %>
20
-
21
- staging: *deploy
@@ -1,14 +1,8 @@
1
- default: &default
1
+ shared:
2
2
  secret_key_base: <%%= ENV["SECRET_KEY_BASE"] %>
3
3
 
4
4
  development:
5
- <<: *default
6
5
 
7
6
  test:
8
- <<: *default
9
-
10
- staging:
11
- <<: *default
12
7
 
13
8
  production:
14
- <<: *default
@@ -10,6 +10,7 @@ if ENV.fetch("COVERAGE", false)
10
10
  end
11
11
 
12
12
  require "webmock/rspec"
13
+ require "timecop"
13
14
 
14
15
  # http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
15
16
  RSpec.configure do |config|
@@ -27,3 +28,6 @@ RSpec.configure do |config|
27
28
  end
28
29
 
29
30
  WebMock.disable_net_connect!(allow_localhost: true)
31
+
32
+ # Only allow Timecop with block syntax
33
+ Timecop.safe_mode = true
@@ -2,12 +2,17 @@
2
2
  *.DS_Store
3
3
  *.swo
4
4
  *.swp
5
+ .byebug_history
5
6
  /.bundle
6
7
  /.env.local
7
8
  /coverage/*
8
9
  /db/*.sqlite3
10
+ /db/*.sqlite3-journal
9
11
  /log/*
10
- /public/system
12
+ /node_modules
11
13
  /public/assets
14
+ /public/packs
15
+ /public/system
12
16
  /tags
13
17
  /tmp/*
18
+ /yarn-error.log
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: suspenders
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.44.0
4
+ version: 1.45.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoughtbot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-25 00:00:00.000000000 Z
11
+ date: 2017-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bitters
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.5'
19
+ version: '1.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.5'
26
+ version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 5.0.0
47
+ version: 5.1.3
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 5.0.0
54
+ version: 5.1.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +98,8 @@ files:
98
98
  - lib/suspenders/adapters/heroku.rb
99
99
  - lib/suspenders/app_builder.rb
100
100
  - lib/suspenders/generators/app_generator.rb
101
+ - lib/suspenders/generators/enforce_ssl_generator.rb
102
+ - lib/suspenders/generators/initialize_active_job_generator.rb
101
103
  - lib/suspenders/generators/static_generator.rb
102
104
  - lib/suspenders/generators/stylesheet_base_generator.rb
103
105
  - lib/suspenders/version.rb
@@ -121,6 +123,7 @@ files:
121
123
  - templates/_flashes.html.erb
122
124
  - templates/_javascript.html.erb
123
125
  - templates/action_mailer.rb
126
+ - templates/active_job.rb
124
127
  - templates/app.json.erb
125
128
  - templates/application.scss
126
129
  - templates/bin_deploy
@@ -165,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
168
  requirements:
166
169
  - - ">="
167
170
  - !ruby/object:Gem::Version
168
- version: 2.4.0
171
+ version: 2.4.1
169
172
  required_rubygems_version: !ruby/object:Gem::Requirement
170
173
  requirements:
171
174
  - - ">="
@@ -173,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
176
  version: '0'
174
177
  requirements: []
175
178
  rubyforge_project:
176
- rubygems_version: 2.6.8
179
+ rubygems_version: 2.6.13
177
180
  signing_key:
178
181
  specification_version: 4
179
182
  summary: Generate a Rails app using thoughtbot's best practices.