suspenders 1.44.0 → 1.45.0

Sign up to get free protection for your applications and to get access to all the features.
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.