suspenders 1.55.1 → 1.56.1

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