suspenders 1.49.0 → 1.54.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +6 -4
  4. data/CONTRIBUTING.md +15 -15
  5. data/GOALS.md +65 -0
  6. data/NEWS.md +60 -0
  7. data/README.md +8 -7
  8. data/docs/heroku_deploy.md +19 -0
  9. data/lib/suspenders.rb +12 -0
  10. data/lib/suspenders/actions.rb +2 -2
  11. data/lib/suspenders/adapters/heroku.rb +14 -14
  12. data/lib/suspenders/app_builder.rb +3 -97
  13. data/lib/suspenders/generators/advisories_generator.rb +19 -0
  14. data/lib/suspenders/generators/analytics_generator.rb +2 -7
  15. data/lib/suspenders/generators/app_generator.rb +18 -44
  16. data/lib/suspenders/generators/base.rb +59 -0
  17. data/lib/suspenders/generators/ci_generator.rb +20 -14
  18. data/lib/suspenders/generators/db_optimizations_generator.rb +5 -17
  19. data/lib/suspenders/generators/factories_generator.rb +2 -7
  20. data/lib/suspenders/generators/forms_generator.rb +2 -2
  21. data/lib/suspenders/generators/inline_svg_generator.rb +14 -0
  22. data/lib/suspenders/generators/jobs_generator.rb +2 -12
  23. data/lib/suspenders/generators/js_driver_generator.rb +8 -10
  24. data/lib/suspenders/generators/json_generator.rb +10 -0
  25. data/lib/suspenders/generators/lint_generator.rb +2 -7
  26. data/lib/suspenders/generators/preloader_generator.rb +122 -0
  27. data/lib/suspenders/generators/production/compression_generator.rb +14 -0
  28. data/lib/suspenders/generators/production/deployment_generator.rb +16 -0
  29. data/lib/suspenders/generators/production/email_generator.rb +7 -18
  30. data/lib/suspenders/generators/production/force_tls_generator.rb +2 -5
  31. data/lib/suspenders/generators/production/manifest_generator.rb +25 -0
  32. data/lib/suspenders/generators/production/single_redirect.rb +15 -0
  33. data/lib/suspenders/generators/production/timeout_generator.rb +3 -2
  34. data/lib/suspenders/generators/profiler_generator.rb +35 -0
  35. data/lib/suspenders/generators/runner_generator.rb +48 -0
  36. data/lib/suspenders/generators/staging/pull_requests_generator.rb +25 -0
  37. data/lib/suspenders/generators/static_generator.rb +6 -2
  38. data/lib/suspenders/generators/stylelint_generator.rb +70 -0
  39. data/lib/suspenders/generators/stylesheet_base_generator.rb +7 -12
  40. data/lib/suspenders/generators/testing_generator.rb +5 -21
  41. data/lib/suspenders/generators/views_generator.rb +2 -7
  42. data/lib/suspenders/version.rb +2 -2
  43. data/spec/adapters/heroku_spec.rb +28 -2
  44. data/spec/expand_json_spec.rb +89 -0
  45. data/spec/features/advisories_spec.rb +24 -0
  46. data/spec/features/ci_spec.rb +31 -0
  47. data/spec/features/db_optimizations_spec.rb +19 -0
  48. data/spec/features/heroku_spec.rb +7 -14
  49. data/spec/features/inline_svg_spec.rb +10 -0
  50. data/spec/features/json_spec.rb +15 -0
  51. data/spec/features/new_project_spec.rb +18 -35
  52. data/spec/features/preloader_spec.rb +25 -0
  53. data/spec/features/production/compression_spec.rb +23 -0
  54. data/spec/features/production/deployment_spec.rb +22 -0
  55. data/spec/features/production/email_spec.rb +1 -1
  56. data/spec/features/production/manifest_spec.rb +37 -0
  57. data/spec/features/production/single_redirect_spec.rb +25 -0
  58. data/spec/features/profiler_spec.rb +20 -0
  59. data/spec/features/runner_spec.rb +30 -0
  60. data/spec/features/staging/pull_requests_spec.rb +22 -0
  61. data/spec/features/static_spec.rb +17 -0
  62. data/spec/features/stylelint_spec.rb +60 -0
  63. data/spec/spec_helper.rb +1 -0
  64. data/spec/support/be_executable_matcher.rb +7 -0
  65. data/spec/support/contain_json_matcher.rb +16 -10
  66. data/spec/support/generators.rb +5 -0
  67. data/spec/support/project_files.rb +25 -0
  68. data/spec/support/rails_template.rb +1 -0
  69. data/spec/support/suspenders.rb +16 -13
  70. data/suspenders.gemspec +1 -1
  71. data/templates/Gemfile.erb +6 -12
  72. data/templates/_javascript.html.erb +1 -8
  73. data/templates/application.scss +0 -1
  74. data/templates/bin_auto_migrate +5 -0
  75. data/templates/bin_deploy +0 -2
  76. data/templates/bin_setup +2 -2
  77. data/templates/bin_setup_review_app.erb +0 -1
  78. data/templates/capybara_silence_puma.rb +1 -0
  79. data/templates/chromedriver.rb +14 -4
  80. data/templates/descriptions/advisories.md +5 -0
  81. data/templates/descriptions/analytics.md +4 -0
  82. data/templates/descriptions/ci.md +4 -0
  83. data/templates/descriptions/compression.md +4 -0
  84. data/templates/descriptions/db_optimizations.md +2 -0
  85. data/templates/descriptions/deployment.md +5 -0
  86. data/templates/descriptions/email.md +9 -0
  87. data/templates/descriptions/factories.md +12 -0
  88. data/templates/descriptions/force_tls.md +1 -0
  89. data/templates/descriptions/forms.md +1 -0
  90. data/templates/descriptions/inline_svg.md +2 -0
  91. data/templates/descriptions/jobs.md +3 -0
  92. data/templates/descriptions/js_driver.md +4 -0
  93. data/templates/descriptions/json.md +1 -0
  94. data/templates/descriptions/lint.md +3 -0
  95. data/templates/descriptions/manifest.md +2 -0
  96. data/templates/descriptions/preloader.md +3 -0
  97. data/templates/descriptions/profiler.md +7 -0
  98. data/templates/descriptions/pull_requests.md +4 -0
  99. data/templates/descriptions/runner.md +10 -0
  100. data/templates/descriptions/single_redirect.md +1 -0
  101. data/templates/descriptions/static.md +5 -0
  102. data/templates/descriptions/stylelint.md +3 -0
  103. data/templates/descriptions/stylesheet_base.md +4 -0
  104. data/templates/descriptions/testing.md +9 -0
  105. data/templates/descriptions/timeout.md +4 -0
  106. data/templates/descriptions/views.md +8 -0
  107. data/templates/factory_bot_rspec.rb +2 -0
  108. data/templates/hound.yml +3 -1
  109. data/templates/inline_svg.rb +3 -0
  110. data/templates/partials/ci_simplecov.rb +16 -0
  111. data/templates/partials/db_optimizations_configuration.rb +7 -0
  112. data/templates/partials/deployment_readme.md +8 -0
  113. data/templates/partials/email_smtp.rb +3 -0
  114. data/templates/partials/profiler_readme.md +8 -0
  115. data/templates/partials/pull_requests_config.rb +5 -0
  116. data/templates/partials/runner_readme.md +31 -0
  117. data/templates/partials/runner_setup.rb +3 -0
  118. data/templates/rack_mini_profiler.rb +2 -0
  119. data/templates/rails_helper.rb +7 -4
  120. data/templates/{dotfiles/.env → sample_env} +0 -2
  121. data/templates/spec_helper.rb +4 -7
  122. data/templates/spring.rb +6 -0
  123. data/templates/stylelintrc.json +3 -0
  124. data/templates/suspenders_gitignore +1 -1
  125. metadata +106 -16
  126. data/templates/app.json.erb +0 -27
  127. data/templates/browserslist +0 -3
  128. data/templates/dotfiles/.ctags +0 -2
  129. data/templates/puma.rb +0 -28
@@ -1,10 +1,3 @@
1
- <%= javascript_include_tag :application %>
1
+ <%= javascript_pack_tag :application %>
2
2
 
3
3
  <%= yield :javascript %>
4
-
5
- <% if Rails.env.test? %>
6
- <%= javascript_tag do %>
7
- $.fx.off = true;
8
- $.ajaxSetup({ async: false });
9
- <% end %>
10
- <% end %>
@@ -3,6 +3,5 @@
3
3
  @import "normalize.css/normalize";
4
4
 
5
5
  @import "bourbon";
6
- @import "neat";
7
6
 
8
7
  @import "base/base";
@@ -0,0 +1,5 @@
1
+ set -e
2
+
3
+ if [ -n "$AUTO_MIGRATE_DB" ]; then
4
+ bundle exec rake db:migrate
5
+ fi
@@ -8,5 +8,3 @@ branch="$(git symbolic-ref HEAD --short)"
8
8
  target="${1:-staging}"
9
9
 
10
10
  git push "$target" "$branch:master"
11
- heroku run rails db:migrate --exit-code --remote "$target"
12
- heroku restart --remote "$target"
@@ -24,5 +24,5 @@ if [ ! -d .git/safe ] && echo $PATH | grep .git/safe > /dev/null; then
24
24
  fi
25
25
 
26
26
  # Only if this isn't CI
27
- # if [ -z "$CI" ]; then
28
- # fi
27
+ if [ -z "$CI" ]; then
28
+ fi
@@ -17,6 +17,5 @@ heroku pg:backups:capture --app $PARENT_APP_NAME
17
17
  URL=`heroku pg:backups public-url --app $PARENT_APP_NAME`
18
18
 
19
19
  heroku pg:backups restore $URL DATABASE_URL --confirm $APP_NAME --app $APP_NAME
20
- heroku run rails db:migrate --exit-code --app $APP_NAME
21
20
  heroku ps:scale worker=1 --app $APP_NAME
22
21
  heroku restart --app $APP_NAME
@@ -0,0 +1 @@
1
+ Capybara.server = :puma, { Silent: true }
@@ -5,13 +5,23 @@ Capybara.register_driver :chrome do |app|
5
5
  end
6
6
 
7
7
  Capybara.register_driver :headless_chrome do |app|
8
- capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
9
- chromeOptions: { args: %w(headless disable-gpu) },
10
- )
8
+ options = ::Selenium::WebDriver::Chrome::Options.new
9
+ options.headless!
10
+ options.add_argument "--window-size=1680,1050"
11
11
 
12
12
  Capybara::Selenium::Driver.new app,
13
13
  browser: :chrome,
14
- desired_capabilities: capabilities
14
+ options: options
15
15
  end
16
16
 
17
17
  Capybara.javascript_driver = :headless_chrome
18
+
19
+ RSpec.configure do |config|
20
+ config.before(:each, type: :system) do
21
+ driven_by :rack_test
22
+ end
23
+
24
+ config.before(:each, type: :system, js: true) do
25
+ driven_by Capybara.javascript_driver
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ Show security advisories during development.
2
+
3
+ Uses the `bundler-audit` gem and rake task to update the local security
4
+ database and show any relevant issues with the app's dependencies. This happens
5
+ on every test run and interaction with `bin/rake` and `bin/rails`.
@@ -0,0 +1,4 @@
1
+ Work with a user analytics service.
2
+
3
+ Add the JavaScript for connecting to Segment to a partial and, if possible,
4
+ include that partial on every page.
@@ -0,0 +1,4 @@
1
+ Prepare the app for running tests on a continuous integration service.
2
+
3
+ Sets up a CircleCI configuration using `bin/setup` to initialize the app and
4
+ `rake` to run the tests. Use SimpleCov for code coverage metrics on CI.
@@ -0,0 +1,4 @@
1
+ Compress HTTP requests at the Rails layer.
2
+
3
+ This uses `Rack::Deflater`, and is done at the app layer instead of at the Web
4
+ server layer.
@@ -0,0 +1,2 @@
1
+ Get database performance insights as you develop. This installs and configures
2
+ Bullet.
@@ -0,0 +1,5 @@
1
+ Script and document the deployment.
2
+
3
+ This adds a `bin/deploy` script, to be called like `deploy staging` or
4
+ `deploy production`, along with updates to the README.md describing how to use
5
+ it.
@@ -0,0 +1,9 @@
1
+ Configure the app for email.
2
+
3
+ Set the app up with SMTP in production. This expects the following environment
4
+ variables to be set:
5
+
6
+ - `SMTP_ADDRESS`
7
+ - `SMTP_DOMAIN`
8
+ - `SMTP_PASSWORD`
9
+ - `SMTP_USERNAME`
@@ -0,0 +1,12 @@
1
+ Build test data with clarity and ease.
2
+
3
+ This uses FactoryBot to help you define dummy and test data for your test
4
+ suite. The `create`, `build`, and `build_stubbed` class methods are directly
5
+ available to all tests.
6
+
7
+ We recommend putting FactoryBot definitions in one `spec/factories.rb` file, at
8
+ least until it grows unwieldy. This helps reduce confusion around circular
9
+ dependencies and makes it easy to jump between definitions.
10
+
11
+ Outside of the tests, the `dev:prime` rake task can be used to insert initial
12
+ development data into the database. You can use FactoryBot here, too.
@@ -0,0 +1 @@
1
+ Redirect users to the HTTPS URL on the production Web site.
@@ -0,0 +1 @@
1
+ Make forms easier to make with form helpers. This mostly involves SimpleForm.
@@ -0,0 +1,2 @@
1
+ Render SVG images inline, as a potential performance improvement for the
2
+ viewer.
@@ -0,0 +1,3 @@
1
+ Set up our favorite job runner.
2
+
3
+ Currently we like DelayedJob. Run all tests inline by default.
@@ -0,0 +1,4 @@
1
+ Set up the test suite for running JavaScript tests.
2
+
3
+ This uses the latest and greatest JavaScript test runner -- currently,
4
+ chromedriver. It comes with a headless mode and a headful/debugging mode.
@@ -0,0 +1 @@
1
+ Use the fastest JSON parser available.
@@ -0,0 +1,3 @@
1
+ Prepare the app for style linting.
2
+
3
+ This sets up your app to use Hound with a default Hound configuration.
@@ -0,0 +1,2 @@
1
+ Write the AppManifest (`app.json`) document with all the environment variables
2
+ we require.
@@ -0,0 +1,3 @@
1
+ Speed up your Rails development flow with a preloader.
2
+
3
+ This installs Spring, including the Spring binstubs.
@@ -0,0 +1,7 @@
1
+ Show runtime profiling for your Rails app as you develop it.
2
+
3
+ This uses the `rack-mini-profiler` gem to show a speed badge on every page.
4
+ This is controlled by the `RACK_MINI_PROFILER` environment variable which
5
+ defaults to `0` in the `.sample.env`. Set it to `1` to enable profiling.
6
+
7
+ Updates your README.md to explain this environment variable.
@@ -0,0 +1,4 @@
1
+ Create a staging environment for each pull request.
2
+
3
+ This glues Heroku review apps to GitHub pull requests, populating the database
4
+ from the generic staging environment on a low-scale review app.
@@ -0,0 +1,10 @@
1
+ Set up the app to run locally with ease.
2
+
3
+ Use Puma and the Rails jobs runner to run the app. This can be done via either
4
+ `heroku local` or any Foreman-compatible project runner (e.g. `foreman start`).
5
+
6
+ Configure your app using `.env`. Installs a basic `.sample.env` that is meant
7
+ to be checked into git and used as a template for your `.env`. The `bin/setup`
8
+ script is modified to safely copy `.sample.env` to `.env` for you.
9
+
10
+ Document all of this in the README.
@@ -0,0 +1 @@
1
+ Canonicalize the URL by configuring the `Rack::CanonicalHost` middleware.
@@ -0,0 +1,5 @@
1
+ Easily add static pages to your dynamic Rails app.
2
+
3
+ Files placed in the `app/views/pages` directory are rendered using the standard
4
+ Rails view renderer and accessible at `/pages/:view_name`, via the
5
+ `high_voltage` gem.
@@ -0,0 +1,3 @@
1
+ Enable stylesheet linting.
2
+
3
+ This configures the stylelint tool to work locally and integrated with Hound.
@@ -0,0 +1,4 @@
1
+ Set up the basic tools needed for the thoughtbot design system.
2
+
3
+ This integrates the Bourbon library of Scss mixins with Normalize.css as a
4
+ reset, then re-styles it by bringing Bitters into your project.
@@ -0,0 +1,9 @@
1
+ Set up the project for an in-depth test-driven development workflow.
2
+
3
+ - Maintain the test DB schema.
4
+ - Clear mail deliveries between tests.
5
+ - Import i18n helpers for use in tests.
6
+ - Prepare for system tests in `spec/system`.
7
+ - Integrate Formulaic for easier form testing.
8
+ - RSpec infers the file type based on the directory name.
9
+ - Install and configure RSpec and shoulda-matchers, with Spring integration.
@@ -0,0 +1,4 @@
1
+ Kill Rack requests that last too long.
2
+
3
+ This adds the `rack-timeout` gem and configures it to kill the connection after
4
+ 10 seconds.
@@ -0,0 +1,8 @@
1
+ View templates for flash, JavaScript, and CSS.
2
+
3
+ - Disable CSS animations in tests.
4
+ - Run JavaScript when the page has loaded.
5
+ - Use the `title` gem for controlling the page title via i18n.
6
+ - Insert one-off JavaScript into a `:javascript` content block.
7
+ - Creates the directory for storing generic, application-level partials.
8
+ - Render user-facing partials (alert, error, notice, success) on all pages.
@@ -1,3 +1,5 @@
1
+ FactoryBot.use_parent_strategy = true
2
+
1
3
  RSpec.configure do |config|
2
4
  config.include FactoryBot::Syntax::Methods
3
5
  end
@@ -10,5 +10,7 @@ ruby:
10
10
  # config_file: .ruby-style.yml
11
11
  enabled: true
12
12
  scss:
13
- # config_file: .scss-style.yml
13
+ enabled: false
14
+ stylelint:
15
+ # config_file: .stylelintrc.json
14
16
  enabled: true
@@ -0,0 +1,3 @@
1
+ InlineSvg.configure do |config|
2
+ config.raise_on_file_not_found = true
3
+ end
@@ -0,0 +1,16 @@
1
+ if ENV.fetch("COVERAGE", false)
2
+ require "simplecov"
3
+
4
+ if ENV["CIRCLE_ARTIFACTS"]
5
+ dir = File.join(ENV["CIRCLE_ARTIFACTS"], "coverage")
6
+ SimpleCov.coverage_dir(dir)
7
+ end
8
+
9
+
10
+ SimpleCov.start "rails"
11
+
12
+ if defined?(Spring) && ENV["DISABLE_SPRING"].to_i == 1
13
+ Rails.application.eager_load!
14
+ end
15
+ end
16
+
@@ -0,0 +1,7 @@
1
+
2
+
3
+ config.after_initialize do
4
+ Bullet.enable = true
5
+ Bullet.bullet_logger = true
6
+ Bullet.rails_logger = true
7
+ end
@@ -0,0 +1,8 @@
1
+
2
+ ## Deploying
3
+
4
+ If you have previously run the `./bin/setup` script,
5
+ you can deploy to staging and production with:
6
+
7
+ % ./bin/deploy staging
8
+ % ./bin/deploy production
@@ -0,0 +1,3 @@
1
+
2
+ config.action_mailer.delivery_method = :smtp
3
+ config.action_mailer.smtp_settings = SMTP_SETTINGS
@@ -0,0 +1,8 @@
1
+
2
+ ## Profiler
3
+
4
+ The [rack-mini-profiler] gem can be enabled by setting
5
+ `RACK_MINI_PROFILER=1` in the environment. This will display a speed
6
+ badge on every page.
7
+
8
+ [rack-mini-profiler]: https://github.com/MiniProfiler/rack-mini-profiler
@@ -0,0 +1,5 @@
1
+ if ENV.fetch("HEROKU_APP_NAME", "").include?("staging-pr-")
2
+ ENV["APPLICATION_HOST"] = ENV["HEROKU_APP_NAME"] + ".herokuapp.com"
3
+ ENV["ASSET_HOST"] = ENV["HEROKU_APP_NAME"] + ".herokuapp.com"
4
+ end
5
+
@@ -0,0 +1,31 @@
1
+ ## Configuration
2
+
3
+ Environment variables during local development are handled by the node-foreman
4
+ project runner. To provide environment variables, create a `.env` file at the
5
+ root of the project. In that file provide the environment variables listed in
6
+ `.sample.env`. The `bin/setup` script does this for you, but be careful about
7
+ overwriting your existing `.env` file.
8
+
9
+ `app.json` also contains a list of environment variables that are required for
10
+ the application. The `.sample.env` file provides either non-secret vars that
11
+ can be copied directly into your own `.env` file or instructions on where to
12
+ obtain secret values.
13
+
14
+ During development add any new environment variables needed by the application
15
+ to both `.sample.env` and `app.json`, providing either **public** default
16
+ values or brief instructions on where secret values may be found.
17
+
18
+ Do not commit the `.env` file to the git repo.
19
+
20
+ ## Running the Application
21
+
22
+ Use the `heroku local` runner to run the app locally as it would run on Heroku.
23
+ This uses the node-forman runner, which reads from the `Procfile` file.
24
+
25
+ ```sh
26
+ heroku local
27
+ ```
28
+
29
+ Once the server is started the application is reachable at
30
+ `http://localhost:3000`.
31
+
@@ -0,0 +1,3 @@
1
+ puts "\n== Copying sample env =="
2
+ system! 'cp -i .sample.env .env'
3
+
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  if ENV["RACK_MINI_PROFILER"].to_i > 0
2
4
  require "rack-mini-profiler"
3
5
 
@@ -1,19 +1,22 @@
1
1
  ENV["RACK_ENV"] = "test"
2
2
 
3
3
  require File.expand_path("../../config/environment", __FILE__)
4
- abort("DATABASE_URL environment variable is set") if ENV["DATABASE_URL"]
4
+
5
+ if Rails.env.production?
6
+ abort("The Rails environment is running in production mode!")
7
+ end
5
8
 
6
9
  require "rspec/rails"
7
10
 
8
11
  Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file }
9
12
 
10
- module Features
11
- # Extend this module in spec/support/features/*.rb
13
+ module SystemTestHelper
14
+ # Extend this module in spec/support/system/*.rb
12
15
  include Formulaic::Dsl
13
16
  end
14
17
 
15
18
  RSpec.configure do |config|
16
- config.include Features, type: :feature
19
+ config.include SystemTestHelper, type: :system
17
20
  config.infer_base_class_for_anonymous_controllers = false
18
21
  config.infer_spec_type_from_file_location!
19
22
  config.use_transactional_fixtures = true
@@ -3,9 +3,7 @@ ASSET_HOST=localhost:3000
3
3
  APPLICATION_HOST=localhost:3000
4
4
  PORT=3000
5
5
  RACK_ENV=development
6
- RACK_MINI_PROFILER=0
7
6
  SECRET_KEY_BASE=development_secret
8
- EXECJS_RUNTIME=Node
9
7
  SMTP_ADDRESS=smtp.example.com
10
8
  SMTP_DOMAIN=example.com
11
9
  SMTP_PASSWORD=password
@@ -1,9 +1,3 @@
1
- if ENV.fetch("COVERAGE", false)
2
- require "simplecov"
3
-
4
- SimpleCov.start "rails"
5
- end
6
-
7
1
  require "webmock/rspec"
8
2
  require "timecop"
9
3
 
@@ -22,7 +16,10 @@ RSpec.configure do |config|
22
16
  config.order = :random
23
17
  end
24
18
 
25
- WebMock.disable_net_connect!(allow_localhost: true)
19
+ WebMock.disable_net_connect!(
20
+ allow_localhost: true,
21
+ allow: "chromedriver.storage.googleapis.com",
22
+ )
26
23
 
27
24
  # Only allow Timecop with block syntax
28
25
  Timecop.safe_mode = true
@@ -0,0 +1,6 @@
1
+ Spring.watch(
2
+ ".ruby-version",
3
+ ".rbenv-vars",
4
+ "tmp/restart.txt",
5
+ "tmp/caching-dev.txt",
6
+ )