suspenders 1.55.1 → 1.56.1

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CONTRIBUTING.md +1 -1
  4. data/NEWS.md +28 -1
  5. data/README.md +4 -11
  6. data/bin/suspenders +29 -2
  7. data/lib/suspenders/actions/strip_comments_action.rb +254 -0
  8. data/lib/suspenders/actions.rb +1 -1
  9. data/lib/suspenders/app_builder.rb +13 -11
  10. data/lib/suspenders/exit_on_failure.rb +19 -0
  11. data/lib/suspenders/generators/app_generator.rb +21 -14
  12. data/lib/suspenders/generators/base.rb +1 -0
  13. data/lib/suspenders/generators/json_generator.rb +4 -0
  14. data/lib/suspenders/generators/production/email_generator.rb +2 -2
  15. data/lib/suspenders/generators/testing_generator.rb +1 -2
  16. data/lib/suspenders/version.rb +1 -1
  17. data/lib/suspenders.rb +2 -1
  18. data/templates/descriptions/testing.md +1 -1
  19. data/templates/errors.rb +1 -0
  20. data/templates/oj.rb +3 -0
  21. data/templates/partials/email_smtp.rb +2 -2
  22. data/templates/partials/pull_requests_config.rb +5 -4
  23. data/templates/postgresql_database.yml.erb +1 -0
  24. metadata +53 -95
  25. data/.gitignore +0 -5
  26. data/.standard.yml +0 -2
  27. data/.travis.yml +0 -15
  28. data/Gemfile +0 -3
  29. data/Rakefile +0 -9
  30. data/USAGE +0 -13
  31. data/bin/rake +0 -16
  32. data/bin/rspec +0 -16
  33. data/bin/setup +0 -13
  34. data/lib/suspenders/generators/preloader_generator.rb +0 -122
  35. data/spec/adapters/heroku_spec.rb +0 -98
  36. data/spec/expand_json_spec.rb +0 -89
  37. data/spec/fakes/bin/heroku +0 -5
  38. data/spec/fakes/bin/hub +0 -5
  39. data/spec/features/advisories_spec.rb +0 -24
  40. data/spec/features/api_spec.rb +0 -18
  41. data/spec/features/ci_spec.rb +0 -31
  42. data/spec/features/cli_help_spec.rb +0 -36
  43. data/spec/features/db_optimizations_spec.rb +0 -19
  44. data/spec/features/github_spec.rb +0 -16
  45. data/spec/features/heroku_spec.rb +0 -64
  46. data/spec/features/inline_svg_spec.rb +0 -10
  47. data/spec/features/json_spec.rb +0 -15
  48. data/spec/features/lint_spec.rb +0 -26
  49. data/spec/features/new_project_spec.rb +0 -321
  50. data/spec/features/preloader_spec.rb +0 -25
  51. data/spec/features/production/compression_spec.rb +0 -23
  52. data/spec/features/production/deployment_spec.rb +0 -22
  53. data/spec/features/production/email_spec.rb +0 -47
  54. data/spec/features/production/manifest_spec.rb +0 -37
  55. data/spec/features/production/single_redirect_spec.rb +0 -25
  56. data/spec/features/profiler_spec.rb +0 -20
  57. data/spec/features/runner_spec.rb +0 -30
  58. data/spec/features/staging/pull_requests_spec.rb +0 -22
  59. data/spec/features/static_spec.rb +0 -17
  60. data/spec/features/stylelint_spec.rb +0 -60
  61. data/spec/spec_helper.rb +0 -21
  62. data/spec/support/be_executable_matcher.rb +0 -7
  63. data/spec/support/contain_json_matcher.rb +0 -30
  64. data/spec/support/exist_as_a_file_matcher.rb +0 -7
  65. data/spec/support/fake_github.rb +0 -21
  66. data/spec/support/fake_heroku.rb +0 -53
  67. data/spec/support/generators.rb +0 -5
  68. data/spec/support/match_contents_matcher.rb +0 -6
  69. data/spec/support/project_files.rb +0 -25
  70. data/spec/support/rails_template.rb +0 -1
  71. data/spec/support/suspenders.rb +0 -184
  72. data/suspenders.gemspec +0 -35
  73. data/templates/descriptions/preloader.md +0 -3
  74. data/templates/spring.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61b9cb4553f3ffae97642ec3aa15c218be90a047c89c3ba0373fad360dd942fc
4
- data.tar.gz: 962cf7626ca047b3a8e414ead6043476778717c5647dd0928efc5fd3b0b65ec6
3
+ metadata.gz: 683a61a7377c93edb0f396688cd578f338bcdc5de7ffb28276165e1bb81edcc4
4
+ data.tar.gz: c5a8d3b44cd4c8f9277b0f7d4c223b034b4ae93d050830c3f8755eef1766814e
5
5
  SHA512:
6
- metadata.gz: 8905a5aeafa593a8d81430529f5d7bbbe1a532d87da0c7039834aa84122113f817f1ff180c055929146a40c79b772254a5faf4625d4ec49c30bc48983d4c61a2
7
- data.tar.gz: 39a8250d0f32c5d09990f786625e3864400e8a41ad27fffe44d69bf2d6365c8fe765db2b99eb40d17ecf9ef86daca7a02d851b0ed9f69f6aa927558787ff3894
6
+ metadata.gz: 7646058fca03e48da09e9a3a26ec4ca21f9e07a51ff2394f548b231c1b50d78ea514c27589473039ed9cb86e9fddb6614ca00bad68dbe19800590f56e6124c46
7
+ data.tar.gz: 67cffd8fa9c7fe841ec6595545bb200b38f500baef0036b9bf29be8c7950b59fb27ed8f2094933fd9d8b00760981a516bd17f6d5e83765290d0ba74fac44c73f
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.6
1
+ 2.7.4
data/CONTRIBUTING.md CHANGED
@@ -48,7 +48,7 @@ All new contributions must be within the generator framework, as described in
48
48
 
49
49
  ## Versions
50
50
 
51
- To update the Ruby version, change `.ruby-version` and `.travis.yml`.
51
+ To update the Ruby version, change `.ruby-version`.
52
52
 
53
53
  If you see this error while running tests:
54
54
 
data/NEWS.md CHANGED
@@ -1,4 +1,31 @@
1
- Unreleased
1
+ 1.56.1 (July 17, 2022)
2
+
3
+ Fixes a critical error with the previous release
4
+
5
+ * Run database migrations as the last step of bin/suspenders
6
+ * Fix bundler error on bin/suspenders script
7
+
8
+ 1.56.0 (July 4, 2022)
9
+
10
+ Maintenance release
11
+
12
+ * Fixed: Make Suspenders fail if running with an unsupported Rails version
13
+ * Added: Update default configuration to use request specs
14
+ * Added: Add missing Errno::ECONNREFUSED to HTTP_ERRORS
15
+ * Fixed: Drop use of git in gemspec
16
+ * Fixed: Enforce bundler >= 2.1.0
17
+ * Fixed: Make suspenders abort when something goes wrong
18
+ * Fixed: Reliability and aesthetics of the config files comment stripper
19
+ * Fixed: ActionMailer asset host in the production configuration
20
+ * Added: Configure the oj gem (fast JSON parsing) when generating a new application
21
+ * Fixed: Improve error message of the match_contents matcher
22
+ * Fixed: Convert generator tests to unit tests thus speeding up the test suite
23
+ * Removed: Preloader generator / spring
24
+ * Added: Pull in DATABASE_URL env var explicitly in database.yml
25
+ * Removed: Travis CI configuration
26
+ * Upgraded: Ruby to version 2.7.4
27
+ * Added: A GitHub Action for CI
28
+ * Fixed: Run bin/suspenders in both CLI and tests against a fixed Rails version
2
29
 
3
30
  1.55.1 (September 11, 2020)
4
31
 
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # Suspenders [![Build Status](https://secure.travis-ci.org/thoughtbot/suspenders.svg?branch=master)](http://travis-ci.org/thoughtbot/suspenders) [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
1
+ # Suspenders
2
+
3
+ [![Build Status](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/thoughtbot/suspenders/actions)
4
+ [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
2
5
 
3
6
  Suspenders is the base Rails application used at
4
7
  [thoughtbot](https://thoughtbot.com/).
@@ -64,8 +67,6 @@ And development gems like:
64
67
  unused eager loading
65
68
  * [Bundler Audit](https://github.com/rubysec/bundler-audit) for scanning the
66
69
  Gemfile for insecure dependencies based on published CVEs
67
- * [Spring](https://github.com/rails/spring) for fast Rails actions via
68
- pre-loading
69
70
  * [Web Console](https://github.com/rails/web-console) for better debugging via
70
71
  in-browser IRB consoles.
71
72
 
@@ -162,14 +163,6 @@ This has the same effect as running:
162
163
 
163
164
  hub create organization/project
164
165
 
165
- ## Spring
166
-
167
- Suspenders uses [spring](https://github.com/rails/spring) by default.
168
- It makes Rails applications load faster, but it might introduce confusing issues
169
- around stale code not being refreshed.
170
- If you think your application is running old code, run `spring stop`.
171
- And if you'd rather not use spring, add `DISABLE_SPRING=1` to your login file.
172
-
173
166
  ## Dependencies
174
167
 
175
168
  Suspenders requires the latest version of Ruby.
data/bin/suspenders CHANGED
@@ -4,14 +4,41 @@ require 'pathname'
4
4
  source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
5
5
  $LOAD_PATH << source_path
6
6
 
7
- require 'suspenders'
7
+ activate_rails_version = ->(rails_version) do
8
+ rails_bin_path = Gem.activate_bin_path("railties", "rails", rails_version)
9
+ rails_path = File.expand_path("../..", rails_bin_path)
10
+ $LOAD_PATH.unshift(rails_path)
11
+ end
12
+
13
+ if str = ARGV.first
14
+ str = str.b[/\A_(.*)_\z/, 1]
15
+
16
+ if str && Gem::Version.correct?(str)
17
+ rails_version = str
18
+ ARGV.shift
19
+
20
+ begin
21
+ activate_rails_version.call(rails_version)
22
+ rescue Gem::GemNotFoundException
23
+ abort "Suspenders error: Unable to find Rails version #{rails_version}"
24
+ end
25
+ else
26
+ require "suspenders/version"
27
+
28
+ spec = Gem::Specification.find_by_name("rails", Suspenders::RAILS_VERSION)
29
+
30
+ activate_rails_version.call(spec.version.to_s)
31
+ end
32
+ end
33
+
34
+ require "suspenders"
8
35
 
9
36
  if ARGV.empty?
10
37
  puts "Please provide a path for the new application"
11
38
  puts
12
39
  puts "See --help for more info"
13
40
  exit 0
14
- elsif ['-v', '--version'].include? ARGV[0]
41
+ elsif ["-v", "--version"].include? ARGV[0]
15
42
  puts Suspenders::VERSION
16
43
  exit 0
17
44
  end
@@ -0,0 +1,254 @@
1
+ require "parser/current"
2
+
3
+ module Suspenders
4
+ module Actions
5
+ class StripCommentsAction
6
+ class << self
7
+ def call(source)
8
+ parser = Parser::CurrentRuby.new
9
+
10
+ source
11
+ .then { |s| strip_comments(s, parser) }
12
+ .then { |s| strip_trailing_whitespace(s) }
13
+ .then { |s| strip_dup_newlines(s) }
14
+ .then { |s| strip_leading_scope_newlines(s, parser) }
15
+ end
16
+
17
+ private
18
+
19
+ def strip_comments(source, parser)
20
+ StripComments.call(source, parser.reset)
21
+ end
22
+
23
+ def strip_trailing_whitespace(source)
24
+ source.gsub(/[[:blank:]]+$/, "")
25
+ end
26
+
27
+ def strip_dup_newlines(source)
28
+ source.gsub(/\n{2,}/, "\n\n")
29
+ end
30
+
31
+ def strip_leading_scope_newlines(source, parser)
32
+ StripLeadingScopeNewlines.call(source, parser.reset)
33
+ end
34
+ end
35
+
36
+ # Strips full-line and inline comments from a buffer but does
37
+ # not remove whitespaces or newlines after the fact. Example
38
+ # input:
39
+ #
40
+ # MyGem.application.configure do |config|
41
+ # # Full-line comment
42
+ # config.option1 = :value # Inline comment
43
+ # end
44
+ #
45
+ # The output is:
46
+ #
47
+ # MyGem.application.configure do |config|
48
+ #
49
+ # config.option1 = :value
50
+ # end
51
+ class StripComments
52
+ class << self
53
+ def call(source, parser)
54
+ buffer = Parser::Source::Buffer.new(nil, source: source)
55
+ rewriter = Parser::Source::TreeRewriter.new(buffer)
56
+
57
+ _, comments = parser.parse_with_comments(buffer)
58
+
59
+ comments.each do |comment|
60
+ strip_comment(comment, buffer, rewriter)
61
+ end
62
+
63
+ rewriter.process
64
+ end
65
+
66
+ private
67
+
68
+ def strip_comment(comment, buffer, rewriter)
69
+ expr = comment.location.expression
70
+
71
+ if full_line_comment?(expr)
72
+ expr = full_line_comment_expr(expr, buffer)
73
+ end
74
+
75
+ rewriter.remove(expr)
76
+ end
77
+
78
+ def full_line_comment_expr(expr, buffer)
79
+ pos = BackwardStringScanner.beginning_of_line_pos(expr, expr.begin_pos)
80
+
81
+ Parser::Source::Range.new(buffer, pos, expr.end_pos + 1)
82
+ end
83
+
84
+ def full_line_comment?(expr)
85
+ expr.source == expr.source_line.lstrip
86
+ end
87
+ end
88
+ end
89
+
90
+ # A tiny, non-stateful backward string scanner somewhat inspired
91
+ # by Ruby's StringScanner. Ruby's StringScanner is unable to
92
+ # seek backward on a string.
93
+ class BackwardStringScanner
94
+ def self.beginning_of_line_pos(expr, initial_pos)
95
+ skip_before(expr, initial_pos) { |char| char == "\n" }
96
+ end
97
+
98
+ def self.skip_before(expr, initial_pos, &block)
99
+ skip_until(expr, initial_pos, -1, &block)
100
+ end
101
+
102
+ def self.skip_until(expr, initial_pos, lookup_inc = 0)
103
+ pos = initial_pos
104
+
105
+ loop do
106
+ break if pos.zero?
107
+ char = expr.source_buffer.source[pos + lookup_inc]
108
+ break if yield(char)
109
+ pos -= 1
110
+ end
111
+
112
+ pos
113
+ end
114
+ end
115
+
116
+ # The intent of this class is purely aesthetic: remove leading
117
+ # newlines inside of code scopes like blocks and begin/end.
118
+ # Example input:
119
+ #
120
+ # module MyGem
121
+ #
122
+ # MyGem.application.configure do |config|
123
+ #
124
+ # config.option1 = true
125
+ #
126
+ # config.option2 = false
127
+ # end
128
+ # end
129
+ #
130
+ # The output is:
131
+ #
132
+ # module MyGem
133
+ # MyGem.application.configure do |config|
134
+ # config.option1 = true
135
+ #
136
+ # config.option2 = false
137
+ # end
138
+ # end
139
+ class StripLeadingScopeNewlines
140
+ def self.call(source, parser)
141
+ buffer = Parser::Source::Buffer.new(nil, source: source)
142
+ ast = parser.parse(buffer)
143
+
144
+ LeadingNewlineStripRewriter.new.rewrite(buffer, ast).lstrip
145
+ end
146
+
147
+ class LeadingNewlineStripRewriter < Parser::TreeRewriter
148
+ def on_module(node)
149
+ strip_newline_before(node.children[1])
150
+ strip_newline_after(node.children.last)
151
+
152
+ super
153
+ end
154
+
155
+ def on_class(node)
156
+ strip_newline_before(node.children[2])
157
+ strip_newline_after(node.children.last)
158
+
159
+ super
160
+ end
161
+
162
+ def on_begin(node)
163
+ handle_begin(node)
164
+
165
+ super
166
+ end
167
+
168
+ def on_kwbegin(node)
169
+ strip_newline_before(node.children[0])
170
+ strip_newline_after(node.children.last)
171
+
172
+ handle_begin(node)
173
+
174
+ super
175
+ end
176
+
177
+ def on_block(node)
178
+ strip_newline_before(node.children[2])
179
+ strip_newline_after(node.children.last)
180
+
181
+ super
182
+ end
183
+
184
+ private
185
+
186
+ def handle_begin(node)
187
+ strip_blank_lines_between_setter_calls(node.children)
188
+
189
+ node.children.each do |child_node|
190
+ send("on_#{child_node.type}", child_node)
191
+ end
192
+ end
193
+
194
+ def strip_blank_lines_between_setter_calls(children)
195
+ pairs = children.each_cons(2).to_a
196
+
197
+ pairs.each do |(node_before, node_after)|
198
+ if setter_call?(node_before) && setter_call?(node_after)
199
+ strip_newline_before(node_after)
200
+ end
201
+ end
202
+ end
203
+
204
+ def setter_call?(node)
205
+ node.children[1].to_s.end_with?("=")
206
+ end
207
+
208
+ def strip_newline_before(node)
209
+ return if node.nil?
210
+
211
+ expr = node.location.expression
212
+ end_pos = find_end_pos(expr, expr.begin_pos)
213
+ begin_pos = find_begin_pos(expr, end_pos)
214
+
215
+ strip_source_range(expr, begin_pos, end_pos)
216
+ end
217
+
218
+ def strip_newline_after(node)
219
+ return if node.nil?
220
+
221
+ expr = node.location.expression
222
+ source = expr.source_buffer.source
223
+
224
+ if source[expr.end_pos + 1] == "\n"
225
+ strip_source_range(expr, expr.end_pos, expr.end_pos + 1)
226
+ end
227
+ end
228
+
229
+ def find_end_pos(expr, begin_pos)
230
+ BackwardStringScanner.skip_until(expr, begin_pos) do |char|
231
+ char == "\n"
232
+ end
233
+ end
234
+
235
+ def find_begin_pos(expr, end_pos)
236
+ BackwardStringScanner.skip_before(expr, end_pos) do |char|
237
+ char != "\n" && char != " "
238
+ end
239
+ end
240
+
241
+ def strip_source_range(expr, begin_pos, end_pos)
242
+ remove(
243
+ Parser::Source::Range.new(
244
+ expr.source_buffer,
245
+ begin_pos,
246
+ end_pos
247
+ )
248
+ )
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
254
+ end
@@ -6,7 +6,7 @@ module Suspenders
6
6
  unless contents.gsub!(find, replace)
7
7
  raise "#{find.inspect} not found in #{relative_path}"
8
8
  end
9
- File.open(path, "w") { |file| file.write(contents) }
9
+ File.write(path, contents)
10
10
  end
11
11
 
12
12
  def action_mailer_host(rails_env, host)
@@ -81,7 +81,8 @@ module Suspenders
81
81
  config.generators do |generate|
82
82
  generate.helper false
83
83
  generate.javascripts false
84
- generate.request_specs false
84
+ generate.controller_specs false
85
+ generate.request_specs true
85
86
  generate.routing_specs false
86
87
  generate.stylesheets false
87
88
  generate.test_framework :rspec
@@ -134,6 +135,10 @@ module Suspenders
134
135
  bundle_command "exec rails db:create db:migrate"
135
136
  end
136
137
 
138
+ def run_database_migrations
139
+ bundle_command "exec rails db:migrate"
140
+ end
141
+
137
142
  def replace_gemfile(path)
138
143
  template "Gemfile.erb", "Gemfile", force: true do |content|
139
144
  if path
@@ -168,10 +173,12 @@ module Suspenders
168
173
  action_mailer_host "test", %("www.example.com")
169
174
  action_mailer_asset_host "test", %("http://www.example.com")
170
175
  action_mailer_host "production", %{ENV.fetch("APPLICATION_HOST")}
176
+ # rubocop:disable Lint/InterpolationCheck
171
177
  action_mailer_asset_host(
172
178
  "production",
173
- %{ENV.fetch("ASSET_HOST", ENV.fetch("APPLICATION_HOST"))}
179
+ %q{"https://#{ENV.fetch("ASSET_HOST", ENV.fetch("APPLICATION_HOST"))}"}
174
180
  )
181
+ # rubocop:enable Lint/InterpolationCheck
175
182
  end
176
183
 
177
184
  def create_heroku_apps(flags)
@@ -203,15 +210,10 @@ module Suspenders
203
210
  ]
204
211
 
205
212
  config_files.each do |config_file|
206
- path = File.join(destination_root, "config/#{config_file}")
207
-
208
- accepted_content = File.readlines(path).reject { |line|
209
- line =~ /^.*#.*$/ || line =~ /^$\n/
210
- }
213
+ path = Pathname(destination_root).join("config", config_file)
214
+ source = Actions::StripCommentsAction.call(path.read)
211
215
 
212
- File.open(path, "w") do |file|
213
- accepted_content.each { |line| file.puts line }
214
- end
216
+ path.write(source)
215
217
  end
216
218
  end
217
219
 
@@ -226,7 +228,7 @@ module Suspenders
226
228
  <<~EOS
227
229
  task(:default).clear
228
230
  task default: [:spec]
229
-
231
+
230
232
  if defined? RSpec
231
233
  task(:spec).clear
232
234
  RSpec::Core::RakeTask.new(:spec) do |t|
@@ -0,0 +1,19 @@
1
+ require "active_support/concern"
2
+ require "English"
3
+
4
+ module Suspenders
5
+ module ExitOnFailure
6
+ extend ActiveSupport::Concern
7
+
8
+ def bundle_command(*)
9
+ super
10
+ exit(false) if $CHILD_STATUS.exitstatus.nonzero?
11
+ end
12
+
13
+ module ClassMethods
14
+ def exit_on_failure?
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,31 +3,33 @@ require "rails/generators/rails/app/app_generator"
3
3
 
4
4
  module Suspenders
5
5
  class AppGenerator < Rails::Generators::AppGenerator
6
+ include ExitOnFailure
7
+
6
8
  hide!
7
9
 
8
10
  class_option :database, type: :string, aliases: "-d", default: "postgresql",
9
- desc: "Configure for selected database (options: #{DATABASES.join("/")})"
11
+ desc: "Configure for selected database (options: #{DATABASES.join("/")})"
10
12
 
11
13
  class_option :heroku, type: :boolean, aliases: "-H", default: false,
12
- desc: "Create staging and production Heroku apps"
14
+ desc: "Create staging and production Heroku apps"
13
15
 
14
16
  class_option :heroku_flags, type: :string, default: "",
15
- desc: "Set extra Heroku flags"
17
+ desc: "Set extra Heroku flags"
16
18
 
17
19
  class_option :github, type: :string, default: nil,
18
- desc: "Create Github repository and add remote origin pointed to repo"
20
+ desc: "Create Github repository and add remote origin pointed to repo"
19
21
 
20
22
  class_option :version, type: :boolean, aliases: "-v", group: :suspenders,
21
- desc: "Show Suspenders version number and quit"
23
+ desc: "Show Suspenders version number and quit"
22
24
 
23
25
  class_option :help, type: :boolean, aliases: "-h", group: :suspenders,
24
- desc: "Show this help message and quit"
26
+ desc: "Show this help message and quit"
25
27
 
26
28
  class_option :path, type: :string, default: nil,
27
- desc: "Path to the gem"
29
+ desc: "Path to the gem"
28
30
 
29
31
  class_option :skip_test, type: :boolean, default: true,
30
- desc: "Skip Test Unit"
32
+ desc: "Skip Test Unit"
31
33
 
32
34
  class_option :skip_system_test,
33
35
  type: :boolean, default: true, desc: "Skip system test files"
@@ -35,6 +37,9 @@ module Suspenders
35
37
  class_option :skip_turbolinks,
36
38
  type: :boolean, default: true, desc: "Skip turbolinks gem"
37
39
 
40
+ class_option :skip_spring, type: :boolean, default: true,
41
+ desc: class_options[:skip_spring].description
42
+
38
43
  def finish_template
39
44
  invoke :suspenders_customization
40
45
  super
@@ -54,6 +59,7 @@ module Suspenders
54
59
  invoke :generate_deployment_default
55
60
  invoke :remove_config_comment_lines
56
61
  invoke :remove_routes_comment_lines
62
+ invoke :run_database_migrations
57
63
  invoke :outro
58
64
  end
59
65
 
@@ -137,19 +143,21 @@ module Suspenders
137
143
  build :remove_routes_comment_lines
138
144
  end
139
145
 
146
+ def run_database_migrations
147
+ build :run_database_migrations
148
+ end
149
+
140
150
  def generate_default
141
- run("spring stop")
151
+ run("spring stop > /dev/null 2>&1 || true")
142
152
  generate("suspenders:runner")
143
153
  generate("suspenders:profiler")
144
154
  generate("suspenders:json")
145
155
  generate("suspenders:static")
146
- generate("suspenders:stylesheet_base")
156
+ generate("suspenders:stylesheet_base") unless options[:api]
147
157
  generate("suspenders:testing")
148
158
  generate("suspenders:ci")
149
159
  generate("suspenders:js_driver")
150
- unless options[:api]
151
- generate("suspenders:forms")
152
- end
160
+ generate("suspenders:forms") unless options[:api]
153
161
  generate("suspenders:db_optimizations")
154
162
  generate("suspenders:factories")
155
163
  generate("suspenders:lint")
@@ -157,7 +165,6 @@ module Suspenders
157
165
  generate("suspenders:analytics")
158
166
  generate("suspenders:inline_svg")
159
167
  generate("suspenders:advisories")
160
- generate("suspenders:preloader")
161
168
  end
162
169
 
163
170
  def generate_deployment_default
@@ -5,6 +5,7 @@ module Suspenders
5
5
  module Generators
6
6
  class Base < Rails::Generators::Base
7
7
  include Suspenders::Actions
8
+ include ExitOnFailure
8
9
 
9
10
  def self.default_source_root
10
11
  File.expand_path(File.join("..", "..", "..", "templates"), __dir__)
@@ -6,5 +6,9 @@ module Suspenders
6
6
  gem "oj"
7
7
  Bundler.with_unbundled_env { run "bundle install" }
8
8
  end
9
+
10
+ def configure_oj
11
+ copy_file "oj.rb", "config/initializers/oj.rb"
12
+ end
9
13
  end
10
14
  end
@@ -7,14 +7,14 @@ module Suspenders
7
7
  copy_file "smtp.rb", "config/smtp.rb"
8
8
 
9
9
  prepend_file "config/environments/production.rb",
10
- %{require Rails.root.join("config/smtp")\n}
10
+ %{require Rails.root.join("config/smtp")\n\n}
11
11
  end
12
12
 
13
13
  def use_smtp
14
14
  inject_template_into_file(
15
15
  "config/environments/production.rb",
16
16
  "partials/email_smtp.rb",
17
- after: "config.action_mailer.perform_caching = false"
17
+ after: "config.action_mailer.perform_caching = false\n"
18
18
  )
19
19
  end
20
20
 
@@ -3,8 +3,7 @@ require_relative "base"
3
3
  module Suspenders
4
4
  class TestingGenerator < Generators::Base
5
5
  def add_testing_gems
6
- gem "spring-commands-rspec", group: :development
7
- gem "rspec-rails", "~> 3.6", group: %i[development test]
6
+ gem "rspec-rails", "~> 5.1", group: %i[development test]
8
7
  gem "shoulda-matchers", group: :test
9
8
 
10
9
  Bundler.with_unbundled_env { run "bundle install" }
@@ -4,5 +4,5 @@ module Suspenders
4
4
  .read("#{File.dirname(__FILE__)}/../../.ruby-version")
5
5
  .strip
6
6
  .freeze
7
- VERSION = "1.55.1".freeze
7
+ VERSION = "1.56.1".freeze
8
8
  end
data/lib/suspenders.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "suspenders/version"
2
+ require "suspenders/exit_on_failure"
2
3
  require "suspenders/generators/advisories_generator"
3
4
  require "suspenders/generators/app_generator"
4
5
  require "suspenders/generators/static_generator"
@@ -16,7 +17,6 @@ require "suspenders/generators/js_driver_generator"
16
17
  require "suspenders/generators/json_generator"
17
18
  require "suspenders/generators/testing_generator"
18
19
  require "suspenders/generators/inline_svg_generator"
19
- require "suspenders/generators/preloader_generator"
20
20
  require "suspenders/generators/profiler_generator"
21
21
  require "suspenders/generators/runner_generator"
22
22
  require "suspenders/generators/production/force_tls_generator"
@@ -28,5 +28,6 @@ require "suspenders/generators/production/manifest_generator"
28
28
  require "suspenders/generators/production/single_redirect"
29
29
  require "suspenders/generators/staging/pull_requests_generator"
30
30
  require "suspenders/actions"
31
+ require "suspenders/actions/strip_comments_action"
31
32
  require "suspenders/adapters/heroku"
32
33
  require "suspenders/app_builder"
@@ -6,4 +6,4 @@ Set up the project for an in-depth test-driven development workflow.
6
6
  - Prepare for system tests in `spec/system`.
7
7
  - Integrate Formulaic for easier form testing.
8
8
  - RSpec infers the file type based on the directory name.
9
- - Install and configure RSpec and shoulda-matchers, with Spring integration.
9
+ - Install and configure RSpec and shoulda-matchers.
data/templates/errors.rb CHANGED
@@ -12,6 +12,7 @@ HTTP_ERRORS = [
12
12
  EOFError,
13
13
  Errno::ECONNRESET,
14
14
  Errno::EINVAL,
15
+ Errno::ECONNREFUSED,
15
16
  Net::HTTPBadResponse,
16
17
  Net::HTTPHeaderSyntaxError,
17
18
  Net::ProtocolError,
data/templates/oj.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "oj"
2
+
3
+ Oj.optimize_rails