suspenders 1.50.0 → 1.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +2 -3
- data/NEWS.md +9 -0
- data/README.md +2 -0
- data/lib/suspenders.rb +3 -0
- data/lib/suspenders/adapters/heroku.rb +0 -4
- data/lib/suspenders/app_builder.rb +0 -19
- data/lib/suspenders/generators/analytics_generator.rb +2 -7
- data/lib/suspenders/generators/app_generator.rb +2 -7
- data/lib/suspenders/generators/base.rb +20 -0
- data/lib/suspenders/generators/ci_generator.rb +2 -6
- data/lib/suspenders/generators/db_optimizations_generator.rb +2 -2
- data/lib/suspenders/generators/factories_generator.rb +2 -7
- data/lib/suspenders/generators/forms_generator.rb +2 -2
- data/lib/suspenders/generators/jobs_generator.rb +2 -12
- data/lib/suspenders/generators/js_driver_generator.rb +2 -7
- data/lib/suspenders/generators/json_generator.rb +2 -2
- data/lib/suspenders/generators/lint_generator.rb +2 -7
- data/lib/suspenders/generators/production/deployment_generator.rb +27 -0
- data/lib/suspenders/generators/production/email_generator.rb +2 -10
- data/lib/suspenders/generators/production/force_tls_generator.rb +2 -5
- data/lib/suspenders/generators/production/manifest_generator.rb +24 -0
- data/lib/suspenders/generators/production/timeout_generator.rb +2 -2
- data/lib/suspenders/generators/staging/pull_requests_generator.rb +2 -16
- data/lib/suspenders/generators/static_generator.rb +2 -2
- data/lib/suspenders/generators/stylelint_generator.rb +70 -0
- data/lib/suspenders/generators/stylesheet_base_generator.rb +4 -8
- data/lib/suspenders/generators/testing_generator.rb +2 -7
- data/lib/suspenders/generators/views_generator.rb +2 -7
- data/lib/suspenders/version.rb +1 -1
- data/spec/features/heroku_spec.rb +1 -1
- data/spec/features/json_spec.rb +1 -1
- data/spec/features/new_project_spec.rb +9 -5
- data/spec/features/production/deployment_spec.rb +22 -0
- data/spec/features/production/email_spec.rb +1 -1
- data/spec/features/production/manifest_spec.rb +35 -0
- data/spec/features/staging/pull_requests_spec.rb +1 -1
- data/spec/features/stylelint_spec.rb +60 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/be_executable_matcher.rb +7 -0
- data/spec/support/generators.rb +5 -0
- data/spec/support/project_files.rb +13 -0
- data/templates/Gemfile.erb +3 -1
- data/templates/hound.yml +3 -1
- data/templates/stylelintrc.json +3 -0
- metadata +40 -7
- data/templates/app.json.erb +0 -27
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e1d2489344013411f6af7910de4365d8216d3da045e184d399b7f72824194b2
|
|
4
|
+
data.tar.gz: 14b71a11bfed6786699ad314eeefe413b7c9d18da5b4330b44cdb88ff1985be2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 80ed93205b0fe4c881c4fef3848526a479a062d3c4decde4b52e152bcba74155c57d9625b487d62c77318c3044943dfd4cbee82650869a8295f389cdef0855e4
|
|
7
|
+
data.tar.gz: 12cb587caae5b9ac79b4b0e2f4f647331e93af7e27918031e1271edb9104433da07c2b4452ebab46c9cf07de2ff618eea031c36be459c0eb0db480709d71879f
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.6.3
|
data/.travis.yml
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
-
rvm: 2.
|
|
2
|
+
rvm: 2.6.3
|
|
3
3
|
cache: bundler
|
|
4
4
|
sudo: false
|
|
5
5
|
before_install:
|
|
6
|
-
- "echo '--colour' > ~/.rspec"
|
|
7
6
|
- git config --global user.name 'Travis CI'
|
|
8
7
|
- git config --global user.email 'travis-ci@example.com'
|
|
9
|
-
- gem install bundler
|
|
10
8
|
- gem update --system
|
|
9
|
+
- gem install bundler -v '< 2'
|
|
11
10
|
install: bundle install
|
|
12
11
|
notifications:
|
|
13
12
|
email: false
|
data/NEWS.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
1.51.0 (April 26, 2019)
|
|
2
|
+
|
|
3
|
+
* Changed: from sass-rails to sassc-rails.
|
|
4
|
+
* Upgraded: Ruby 2.6.3.
|
|
5
|
+
* Fixed: Avoid installing autoprefixer-rails in api mode
|
|
6
|
+
* New generator: `suspenders:stylelint` for setting up stylelint.
|
|
7
|
+
* New generator: `suspenders:production:manifest` for app.json.
|
|
8
|
+
* New generator: `suspenders:production:deployment` for bin/deploy script.
|
|
9
|
+
|
|
1
10
|
1.50.0 (December 28, 2018)
|
|
2
11
|
|
|
3
12
|
* Removed: jquery-rails.
|
data/README.md
CHANGED
|
@@ -101,6 +101,7 @@ Suspenders also comes with:
|
|
|
101
101
|
environments
|
|
102
102
|
* Configuration for [CircleCI][circle] Continuous Integration (tests)
|
|
103
103
|
* Configuration for [Hound][hound] Continuous Integration (style)
|
|
104
|
+
* Configuration for [stylelint][stylelint]
|
|
104
105
|
* The analytics adapter [Segment][segment] (and therefore config for Google
|
|
105
106
|
Analytics, Intercom, Facebook Ads, Twitter Ads, etc.)
|
|
106
107
|
|
|
@@ -111,6 +112,7 @@ Suspenders also comes with:
|
|
|
111
112
|
[i18n]: https://github.com/thoughtbot/suspenders/pull/304
|
|
112
113
|
[circle]: https://circleci.com/docs
|
|
113
114
|
[hound]: https://houndci.com
|
|
115
|
+
[stylelint]: https://stylelint.io/
|
|
114
116
|
[segment]: https://segment.com
|
|
115
117
|
|
|
116
118
|
## Heroku
|
data/lib/suspenders.rb
CHANGED
|
@@ -2,6 +2,7 @@ require "suspenders/version"
|
|
|
2
2
|
require "suspenders/generators/app_generator"
|
|
3
3
|
require "suspenders/generators/static_generator"
|
|
4
4
|
require "suspenders/generators/stylesheet_base_generator"
|
|
5
|
+
require "suspenders/generators/stylelint_generator"
|
|
5
6
|
require "suspenders/generators/forms_generator"
|
|
6
7
|
require "suspenders/generators/ci_generator"
|
|
7
8
|
require "suspenders/generators/db_optimizations_generator"
|
|
@@ -16,6 +17,8 @@ require "suspenders/generators/testing_generator"
|
|
|
16
17
|
require "suspenders/generators/production/force_tls_generator"
|
|
17
18
|
require "suspenders/generators/production/email_generator"
|
|
18
19
|
require "suspenders/generators/production/timeout_generator"
|
|
20
|
+
require "suspenders/generators/production/deployment_generator"
|
|
21
|
+
require "suspenders/generators/production/manifest_generator"
|
|
19
22
|
require "suspenders/generators/staging/pull_requests_generator"
|
|
20
23
|
require "suspenders/actions"
|
|
21
24
|
require "suspenders/adapters/heroku"
|
|
@@ -55,10 +55,6 @@ module Suspenders
|
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
def create_heroku_application_manifest_file
|
|
59
|
-
app_builder.template "app.json.erb", "app.json"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
58
|
def create_heroku_pipeline
|
|
63
59
|
pipelines_plugin = `heroku help | grep pipelines`
|
|
64
60
|
if pipelines_plugin.empty?
|
|
@@ -7,7 +7,6 @@ module Suspenders
|
|
|
7
7
|
|
|
8
8
|
def_delegators(
|
|
9
9
|
:heroku_adapter,
|
|
10
|
-
:create_heroku_application_manifest_file,
|
|
11
10
|
:create_heroku_pipeline,
|
|
12
11
|
:create_production_heroku_app,
|
|
13
12
|
:create_staging_heroku_app,
|
|
@@ -217,24 +216,6 @@ config.public_file_server.headers = {
|
|
|
217
216
|
create_production_heroku_app(flags)
|
|
218
217
|
end
|
|
219
218
|
|
|
220
|
-
def create_deploy_script
|
|
221
|
-
copy_file "bin_deploy", "bin/deploy"
|
|
222
|
-
|
|
223
|
-
instructions = <<-MARKDOWN
|
|
224
|
-
|
|
225
|
-
## Deploying
|
|
226
|
-
|
|
227
|
-
If you have previously run the `./bin/setup` script,
|
|
228
|
-
you can deploy to staging and production with:
|
|
229
|
-
|
|
230
|
-
% ./bin/deploy staging
|
|
231
|
-
% ./bin/deploy production
|
|
232
|
-
MARKDOWN
|
|
233
|
-
|
|
234
|
-
append_file "README.md", instructions
|
|
235
|
-
run "chmod a+x bin/deploy"
|
|
236
|
-
end
|
|
237
|
-
|
|
238
219
|
def configure_automatic_deployment
|
|
239
220
|
deploy_command = <<-YML.strip_heredoc
|
|
240
221
|
deployment:
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class AnalyticsGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__),
|
|
8
|
-
)
|
|
9
|
-
|
|
4
|
+
class AnalyticsGenerator < Generators::Base
|
|
10
5
|
def install_partial
|
|
11
6
|
copy_file "_analytics.html.erb",
|
|
12
7
|
"app/views/application/_analytics.html.erb"
|
|
@@ -55,7 +55,6 @@ module Suspenders
|
|
|
55
55
|
invoke :setup_spring
|
|
56
56
|
invoke :generate_default
|
|
57
57
|
invoke :setup_default_directories
|
|
58
|
-
invoke :create_local_heroku_setup
|
|
59
58
|
invoke :create_heroku_apps
|
|
60
59
|
invoke :generate_deployment_default
|
|
61
60
|
invoke :remove_config_comment_lines
|
|
@@ -113,12 +112,6 @@ module Suspenders
|
|
|
113
112
|
build :setup_rack_mini_profiler
|
|
114
113
|
end
|
|
115
114
|
|
|
116
|
-
def create_local_heroku_setup
|
|
117
|
-
say "Creating local Heroku setup"
|
|
118
|
-
build :create_deploy_script
|
|
119
|
-
build :create_heroku_application_manifest_file
|
|
120
|
-
end
|
|
121
|
-
|
|
122
115
|
def create_heroku_apps
|
|
123
116
|
if options[:heroku]
|
|
124
117
|
say "Creating Heroku apps"
|
|
@@ -200,6 +193,8 @@ module Suspenders
|
|
|
200
193
|
generate("suspenders:production:force_tls")
|
|
201
194
|
generate("suspenders:production:email")
|
|
202
195
|
generate("suspenders:production:timeout")
|
|
196
|
+
generate("suspenders:production:deployment")
|
|
197
|
+
generate("suspenders:production:manifest")
|
|
203
198
|
end
|
|
204
199
|
|
|
205
200
|
def outro
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
require_relative "../actions"
|
|
3
|
+
|
|
4
|
+
module Suspenders
|
|
5
|
+
module Generators
|
|
6
|
+
class Base < Rails::Generators::Base
|
|
7
|
+
include Suspenders::Actions
|
|
8
|
+
|
|
9
|
+
def self.default_source_root
|
|
10
|
+
File.expand_path(File.join("..", "..", "..", "templates"), __dir__)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def app_name
|
|
16
|
+
Rails.app_class.parent_name.demodulize.underscore.dasherize
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class CiGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__))
|
|
8
|
-
|
|
4
|
+
class CiGenerator < Generators::Base
|
|
9
5
|
def simplecov_test_integration
|
|
10
6
|
inject_into_file "spec/spec_helper.rb", before: 'SimpleCov.start "rails"' do
|
|
11
7
|
<<-RUBY
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class DbOptimizationsGenerator <
|
|
4
|
+
class DbOptimizationsGenerator < Generators::Base
|
|
5
5
|
def add_bullet
|
|
6
6
|
gem "bullet", group: %i(development test)
|
|
7
7
|
Bundler.with_clean_env { run "bundle install" }
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class FactoriesGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__),
|
|
8
|
-
)
|
|
9
|
-
|
|
4
|
+
class FactoriesGenerator < Generators::Base
|
|
10
5
|
def add_factory_bot
|
|
11
6
|
gem "factory_bot_rails", group: %i(development test)
|
|
12
7
|
Bundler.with_clean_env { run "bundle install" }
|
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
require_relative "../actions"
|
|
1
|
+
require_relative "base"
|
|
3
2
|
|
|
4
3
|
module Suspenders
|
|
5
|
-
class JobsGenerator <
|
|
6
|
-
include Suspenders::Actions
|
|
7
|
-
|
|
8
|
-
source_root(
|
|
9
|
-
File.expand_path(
|
|
10
|
-
File.join("..", "..", "..", "templates"),
|
|
11
|
-
File.dirname(__FILE__),
|
|
12
|
-
),
|
|
13
|
-
)
|
|
14
|
-
|
|
4
|
+
class JobsGenerator < Generators::Base
|
|
15
5
|
def add_jobs_gem
|
|
16
6
|
gem "delayed_job_active_record"
|
|
17
7
|
Bundler.with_clean_env { run "bundle install" }
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class JsDriverGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__),
|
|
8
|
-
)
|
|
9
|
-
|
|
4
|
+
class JsDriverGenerator < Generators::Base
|
|
10
5
|
def add_gems
|
|
11
6
|
gem "capybara-selenium", group: :test
|
|
12
7
|
gem "chromedriver-helper", group: :test
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class LintGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__),
|
|
8
|
-
)
|
|
9
|
-
|
|
4
|
+
class LintGenerator < Generators::Base
|
|
10
5
|
def set_up_hound
|
|
11
6
|
copy_file "hound.yml", ".hound.yml"
|
|
12
7
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative "../base"
|
|
2
|
+
|
|
3
|
+
module Suspenders
|
|
4
|
+
module Production
|
|
5
|
+
class DeploymentGenerator < Generators::Base
|
|
6
|
+
def copy_script
|
|
7
|
+
copy_file "bin_deploy", "bin/deploy"
|
|
8
|
+
chmod "bin/deploy", 0o755
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def inform_user
|
|
12
|
+
instructions = <<~MARKDOWN
|
|
13
|
+
|
|
14
|
+
## Deploying
|
|
15
|
+
|
|
16
|
+
If you have previously run the `./bin/setup` script,
|
|
17
|
+
you can deploy to staging and production with:
|
|
18
|
+
|
|
19
|
+
% ./bin/deploy staging
|
|
20
|
+
% ./bin/deploy production
|
|
21
|
+
MARKDOWN
|
|
22
|
+
|
|
23
|
+
append_file "README.md", instructions
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
require_relative "../../actions"
|
|
1
|
+
require_relative "../base"
|
|
3
2
|
|
|
4
3
|
module Suspenders
|
|
5
4
|
module Production
|
|
6
|
-
class EmailGenerator <
|
|
7
|
-
include Suspenders::Actions
|
|
8
|
-
|
|
9
|
-
source_root File.expand_path(
|
|
10
|
-
File.join("..", "..", "..", "..", "templates"),
|
|
11
|
-
File.dirname(__FILE__),
|
|
12
|
-
)
|
|
13
|
-
|
|
5
|
+
class EmailGenerator < Generators::Base
|
|
14
6
|
def smtp_configuration
|
|
15
7
|
copy_file "smtp.rb", "config/smtp.rb"
|
|
16
8
|
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
require_relative "../../actions"
|
|
1
|
+
require_relative "../base"
|
|
3
2
|
|
|
4
3
|
module Suspenders
|
|
5
4
|
module Production
|
|
6
|
-
class ForceTlsGenerator <
|
|
7
|
-
include Suspenders::Actions
|
|
8
|
-
|
|
5
|
+
class ForceTlsGenerator < Generators::Base
|
|
9
6
|
def config_enforce_ssl
|
|
10
7
|
configure_environment "production", "config.force_ssl = true"
|
|
11
8
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative "../base"
|
|
2
|
+
|
|
3
|
+
module Suspenders
|
|
4
|
+
module Production
|
|
5
|
+
class ManifestGenerator < Generators::Base
|
|
6
|
+
def render_manifest
|
|
7
|
+
expand_json(
|
|
8
|
+
"app.json",
|
|
9
|
+
name: app_name.dasherize,
|
|
10
|
+
scripts: {},
|
|
11
|
+
env: {
|
|
12
|
+
APPLICATION_HOST: { required: true },
|
|
13
|
+
EMAIL_RECIPIENTS: { required: true },
|
|
14
|
+
HEROKU_APP_NAME: { required: true },
|
|
15
|
+
HEROKU_PARENT_APP_NAME: { required: true },
|
|
16
|
+
RACK_ENV: { required: true },
|
|
17
|
+
SECRET_KEY_BASE: { generator: "secret" },
|
|
18
|
+
},
|
|
19
|
+
addons: ["heroku-postgresql"],
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
require_relative "../../actions"
|
|
1
|
+
require_relative "../base"
|
|
3
2
|
|
|
4
3
|
module Suspenders
|
|
5
4
|
module Staging
|
|
6
|
-
class PullRequestsGenerator <
|
|
7
|
-
include Suspenders::Actions
|
|
8
|
-
|
|
9
|
-
source_root File.expand_path(
|
|
10
|
-
File.join("..", "..", "..", "..", "templates"),
|
|
11
|
-
File.dirname(__FILE__),
|
|
12
|
-
)
|
|
13
|
-
|
|
5
|
+
class PullRequestsGenerator < Generators::Base
|
|
14
6
|
def configure_heroku_staging_pr_pipeline_host
|
|
15
7
|
config = <<-RUBY
|
|
16
8
|
|
|
@@ -36,12 +28,6 @@ module Suspenders
|
|
|
36
28
|
|
|
37
29
|
run "chmod a+x bin/setup_review_app"
|
|
38
30
|
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def app_name
|
|
43
|
-
Rails.application.class.parent_name.demodulize.underscore.dasherize
|
|
44
|
-
end
|
|
45
31
|
end
|
|
46
32
|
end
|
|
47
33
|
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require_relative "base"
|
|
2
|
+
|
|
3
|
+
module Suspenders
|
|
4
|
+
class StylelintGenerator < Generators::Base
|
|
5
|
+
def setup_hound
|
|
6
|
+
action InvokeGenerator.new(self, "suspenders:lint")
|
|
7
|
+
action ToggleComments.new(self, ".hound.yml", /stylelintrc/)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def install_stylelint
|
|
11
|
+
dependencies = ["stylelint", "@thoughtbot/stylelint-config"]
|
|
12
|
+
action YarnInstall.new(self, dependencies, "--dev")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def copy_stylelint_config
|
|
16
|
+
copy_file "stylelintrc.json", ".stylelintrc.json"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class InvokeGenerator
|
|
20
|
+
def initialize(base, generator)
|
|
21
|
+
@base = base
|
|
22
|
+
@generator = generator
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def invoke!
|
|
26
|
+
@base.invoke @generator
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def revoke!; end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class ToggleComments
|
|
33
|
+
def initialize(base, filename, pattern)
|
|
34
|
+
@base = base
|
|
35
|
+
@filename = filename
|
|
36
|
+
@pattern = pattern
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def invoke!
|
|
40
|
+
@base.uncomment_lines(@filename, @pattern)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def revoke!
|
|
44
|
+
@base.behavior = :invoke
|
|
45
|
+
@base.comment_lines(@filename, @pattern)
|
|
46
|
+
ensure
|
|
47
|
+
@base.behavior = :revoke
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class YarnInstall
|
|
52
|
+
def initialize(base, dependencies, flags)
|
|
53
|
+
@base = base
|
|
54
|
+
@dependencies = dependencies.join(" ")
|
|
55
|
+
@flags = flags
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def invoke!
|
|
59
|
+
@base.run "bin/yarn add #{@dependencies} #{@flags}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def revoke!
|
|
63
|
+
@base.behavior = :invoke
|
|
64
|
+
@base.run "bin/yarn remove #{@dependencies}"
|
|
65
|
+
ensure
|
|
66
|
+
@base.behavior = :revoke
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class StylesheetBaseGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__))
|
|
8
|
-
|
|
4
|
+
class StylesheetBaseGenerator < Generators::Base
|
|
9
5
|
def add_stylesheet_gems
|
|
10
|
-
gem "bourbon", "
|
|
11
|
-
gem "neat", "
|
|
6
|
+
gem "bourbon", ">= 5.0.1"
|
|
7
|
+
gem "neat", ">= 3.0.1"
|
|
12
8
|
Bundler.with_clean_env { run "bundle install" }
|
|
13
9
|
end
|
|
14
10
|
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class TestingGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__),
|
|
8
|
-
)
|
|
9
|
-
|
|
4
|
+
class TestingGenerator < Generators::Base
|
|
10
5
|
def add_testing_gems
|
|
11
6
|
gem "spring-commands-rspec", group: :development
|
|
12
7
|
gem "rspec-rails", "~> 3.6", group: %i(development test)
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "base"
|
|
2
2
|
|
|
3
3
|
module Suspenders
|
|
4
|
-
class ViewsGenerator <
|
|
5
|
-
source_root File.expand_path(
|
|
6
|
-
File.join("..", "..", "..", "templates"),
|
|
7
|
-
File.dirname(__FILE__),
|
|
8
|
-
)
|
|
9
|
-
|
|
4
|
+
class ViewsGenerator < Generators::Base
|
|
10
5
|
def create_partials_directory
|
|
11
6
|
empty_directory "app/views/application"
|
|
12
7
|
end
|
data/lib/suspenders/version.rb
CHANGED
|
@@ -30,7 +30,7 @@ RSpec.describe "Heroku" do
|
|
|
30
30
|
expect(bin_setup).to match(/^if heroku join --app #{app_name}-production/)
|
|
31
31
|
expect(bin_setup).to match(/^if heroku join --app #{app_name}-staging/)
|
|
32
32
|
expect(bin_setup).to match(/^git config heroku.remote staging/)
|
|
33
|
-
expect(
|
|
33
|
+
expect("bin/setup").to be_executable
|
|
34
34
|
|
|
35
35
|
readme = IO.read("#{project_path}/README.md")
|
|
36
36
|
|
data/spec/features/json_spec.rb
CHANGED
|
@@ -65,9 +65,7 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "makes bin/setup executable" do
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
expect(File.stat(bin_setup_path)).to be_executable
|
|
68
|
+
expect("bin/setup").to be_executable
|
|
71
69
|
end
|
|
72
70
|
|
|
73
71
|
it "adds support file for action mailer" do
|
|
@@ -263,7 +261,7 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
|
263
261
|
expect(bin_setup).to include("heroku ps:scale worker=1 --app $APP_NAME")
|
|
264
262
|
expect(bin_setup).to include("heroku restart --app $APP_NAME")
|
|
265
263
|
|
|
266
|
-
expect(
|
|
264
|
+
expect("bin/setup_review_app").to be_executable
|
|
267
265
|
end
|
|
268
266
|
|
|
269
267
|
it "creates deploy script" do
|
|
@@ -271,7 +269,7 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
|
271
269
|
bin_deploy = IO.read(bin_deploy_path)
|
|
272
270
|
|
|
273
271
|
expect(bin_deploy).to include("heroku run rails db:migrate --exit-code")
|
|
274
|
-
expect(
|
|
272
|
+
expect("bin/deploy").to be_executable
|
|
275
273
|
end
|
|
276
274
|
|
|
277
275
|
it "creates heroku application manifest file with application name in it" do
|
|
@@ -289,6 +287,12 @@ RSpec.describe "Suspend a new project with default configuration" do
|
|
|
289
287
|
expect(gemfile).to match(/high_voltage/)
|
|
290
288
|
end
|
|
291
289
|
|
|
290
|
+
it "adds sassc-rails" do
|
|
291
|
+
gemfile = read_project_file("Gemfile")
|
|
292
|
+
|
|
293
|
+
expect(gemfile).to match(/sassc-rails/)
|
|
294
|
+
end
|
|
295
|
+
|
|
292
296
|
it "adds and configures bourbon and neat" do
|
|
293
297
|
gemfile = read_project_file("Gemfile")
|
|
294
298
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe "suspenders:production:deployment", type: :generator do
|
|
4
|
+
it "generates the configuration for a production deployment" do
|
|
5
|
+
rm "bin/deploy"
|
|
6
|
+
|
|
7
|
+
with_app { generate("suspenders:production:deployment") }
|
|
8
|
+
|
|
9
|
+
expect("bin/deploy").to exist_as_a_file
|
|
10
|
+
expect("bin/deploy").to be_executable
|
|
11
|
+
expect("README.md").to match_contents(%r{bin/deploy})
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "destroys the configuration for a production deployment" do
|
|
15
|
+
touch "bin/deploy"
|
|
16
|
+
|
|
17
|
+
with_app { destroy("suspenders:production:deployment") }
|
|
18
|
+
|
|
19
|
+
expect("bin/deploy").not_to exist_as_a_file
|
|
20
|
+
expect("README.md").not_to match_contents(%r{bin/deploy})
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
RSpec.describe "suspenders:production:email" do
|
|
3
|
+
RSpec.describe "suspenders:production:email", type: :generator do
|
|
4
4
|
it "generates the configuration for a production email deployment" do
|
|
5
5
|
with_app { generate("suspenders:production:email") }
|
|
6
6
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe "suspenders:production:manifest", type: :generator do
|
|
4
|
+
it "generates the manifest for a production build" do
|
|
5
|
+
with_app { generate("suspenders:production:manifest") }
|
|
6
|
+
|
|
7
|
+
expect("app.json").to contain_json(
|
|
8
|
+
name: SuspendersTestHelpers::APP_NAME.dasherize,
|
|
9
|
+
env: {
|
|
10
|
+
APPLICATION_HOST: { required: true },
|
|
11
|
+
EMAIL_RECIPIENTS: { required: true },
|
|
12
|
+
HEROKU_APP_NAME: { required: true },
|
|
13
|
+
HEROKU_PARENT_APP_NAME: { required: true },
|
|
14
|
+
RACK_ENV: { required: true },
|
|
15
|
+
SECRET_KEY_BASE: { generator: "secret" },
|
|
16
|
+
},
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "destroys the manifest for a production build" do
|
|
21
|
+
with_app { destroy("suspenders:production:manifest") }
|
|
22
|
+
|
|
23
|
+
expect("app.json").not_to contain_json(
|
|
24
|
+
name: SuspendersTestHelpers::APP_NAME.dasherize,
|
|
25
|
+
env: {
|
|
26
|
+
APPLICATION_HOST: { required: true },
|
|
27
|
+
EMAIL_RECIPIENTS: { required: true },
|
|
28
|
+
HEROKU_APP_NAME: { required: true },
|
|
29
|
+
HEROKU_PARENT_APP_NAME: { required: true },
|
|
30
|
+
RACK_ENV: { required: true },
|
|
31
|
+
SECRET_KEY_BASE: { generator: "secret" },
|
|
32
|
+
},
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
RSpec.describe "suspenders:staging:pull_requests" do
|
|
3
|
+
RSpec.describe "suspenders:staging:pull_requests", type: :generators do
|
|
4
4
|
it "generates the configuration for Heroku pipeline review apps" do
|
|
5
5
|
with_app { generate("suspenders:staging:pull_requests") }
|
|
6
6
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe "suspenders:stylelint", type: :generator do
|
|
4
|
+
context "generate" do
|
|
5
|
+
it "creates .stylelintrc.json" do
|
|
6
|
+
with_app { generate("suspenders:stylelint") }
|
|
7
|
+
|
|
8
|
+
expect(".stylelintrc.json").
|
|
9
|
+
to match_contents(%r{"extends": "@thoughtbot/stylelint-config"})
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "adds stylelint and @thoughtbot/stylelint-config to the package.json" do
|
|
13
|
+
with_app { generate("suspenders:stylelint") }
|
|
14
|
+
|
|
15
|
+
expect("package.json").to match_contents(/devDependencies/)
|
|
16
|
+
expect("package.json").to match_contents(/stylelint/)
|
|
17
|
+
expect("package.json").to match_contents(%r{@thoughtbot/stylelint-config})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "uncomments the hound config_file option" do
|
|
21
|
+
with_app { generate("suspenders:stylelint") }
|
|
22
|
+
|
|
23
|
+
expect(".hound.yml").to(
|
|
24
|
+
match_contents(/^ config_file: \.stylelintrc\.json/),
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "destroy" do
|
|
30
|
+
it "removes .stylelintrc.json" do
|
|
31
|
+
with_app do
|
|
32
|
+
generate("suspenders:stylelint")
|
|
33
|
+
destroy("suspenders:stylelint")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
expect(".stylelintrc.json").not_to exist_as_a_file
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "removes stylelint and @thoughtbot/stylelint-config from package.json" do
|
|
40
|
+
with_app do
|
|
41
|
+
generate("suspenders:stylelint")
|
|
42
|
+
destroy("suspenders:stylelint")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
expect("package.json").not_to match_contents(/stylelint/)
|
|
46
|
+
expect("package.json").
|
|
47
|
+
not_to match_contents(%r{@thoughtbot/stylelint-config})
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "comments in the hound config_file option" do
|
|
51
|
+
with_app do
|
|
52
|
+
generate("suspenders:stylelint")
|
|
53
|
+
destroy("suspenders:stylelint")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
expect(".hound.yml").
|
|
57
|
+
to match_contents(/^ # config_file: \.stylelintrc\.json/)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ProjectFiles
|
|
2
|
+
def touch(filename)
|
|
3
|
+
path = File.join(project_path, filename)
|
|
4
|
+
dirname = File.dirname(path)
|
|
5
|
+
FileUtils.mkdir_p(dirname)
|
|
6
|
+
FileUtils.touch(path)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def rm(filename)
|
|
10
|
+
path = File.join(project_path, filename)
|
|
11
|
+
FileUtils.rm_rf(path)
|
|
12
|
+
end
|
|
13
|
+
end
|
data/templates/Gemfile.erb
CHANGED
|
@@ -7,14 +7,16 @@ end
|
|
|
7
7
|
|
|
8
8
|
ruby "<%= Suspenders::RUBY_VERSION %>"
|
|
9
9
|
|
|
10
|
+
<% unless options[:api] %>
|
|
10
11
|
gem "autoprefixer-rails"
|
|
12
|
+
<% end %>
|
|
11
13
|
gem "honeybadger"
|
|
12
14
|
gem "pg"
|
|
13
15
|
gem "puma"
|
|
14
16
|
gem "rack-canonical-host"
|
|
15
17
|
gem "rails", "<%= Suspenders::RAILS_VERSION %>"
|
|
16
18
|
gem "recipient_interceptor"
|
|
17
|
-
gem "
|
|
19
|
+
gem "sassc-rails"
|
|
18
20
|
gem "skylight"
|
|
19
21
|
gem "sprockets", ">= 3.0.0"
|
|
20
22
|
gem "title"
|
data/templates/hound.yml
CHANGED
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.
|
|
4
|
+
version: 1.51.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoughtbot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2019-04-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bitters
|
|
@@ -85,6 +85,7 @@ files:
|
|
|
85
85
|
- lib/suspenders/app_builder.rb
|
|
86
86
|
- lib/suspenders/generators/analytics_generator.rb
|
|
87
87
|
- lib/suspenders/generators/app_generator.rb
|
|
88
|
+
- lib/suspenders/generators/base.rb
|
|
88
89
|
- lib/suspenders/generators/ci_generator.rb
|
|
89
90
|
- lib/suspenders/generators/db_optimizations_generator.rb
|
|
90
91
|
- lib/suspenders/generators/factories_generator.rb
|
|
@@ -93,11 +94,14 @@ files:
|
|
|
93
94
|
- lib/suspenders/generators/js_driver_generator.rb
|
|
94
95
|
- lib/suspenders/generators/json_generator.rb
|
|
95
96
|
- lib/suspenders/generators/lint_generator.rb
|
|
97
|
+
- lib/suspenders/generators/production/deployment_generator.rb
|
|
96
98
|
- lib/suspenders/generators/production/email_generator.rb
|
|
97
99
|
- lib/suspenders/generators/production/force_tls_generator.rb
|
|
100
|
+
- lib/suspenders/generators/production/manifest_generator.rb
|
|
98
101
|
- lib/suspenders/generators/production/timeout_generator.rb
|
|
99
102
|
- lib/suspenders/generators/staging/pull_requests_generator.rb
|
|
100
103
|
- lib/suspenders/generators/static_generator.rb
|
|
104
|
+
- lib/suspenders/generators/stylelint_generator.rb
|
|
101
105
|
- lib/suspenders/generators/stylesheet_base_generator.rb
|
|
102
106
|
- lib/suspenders/generators/testing_generator.rb
|
|
103
107
|
- lib/suspenders/generators/views_generator.rb
|
|
@@ -111,14 +115,20 @@ files:
|
|
|
111
115
|
- spec/features/heroku_spec.rb
|
|
112
116
|
- spec/features/json_spec.rb
|
|
113
117
|
- spec/features/new_project_spec.rb
|
|
118
|
+
- spec/features/production/deployment_spec.rb
|
|
114
119
|
- spec/features/production/email_spec.rb
|
|
120
|
+
- spec/features/production/manifest_spec.rb
|
|
115
121
|
- spec/features/staging/pull_requests_spec.rb
|
|
122
|
+
- spec/features/stylelint_spec.rb
|
|
116
123
|
- spec/spec_helper.rb
|
|
124
|
+
- spec/support/be_executable_matcher.rb
|
|
117
125
|
- spec/support/contain_json_matcher.rb
|
|
118
126
|
- spec/support/exist_as_a_file_matcher.rb
|
|
119
127
|
- spec/support/fake_github.rb
|
|
120
128
|
- spec/support/fake_heroku.rb
|
|
129
|
+
- spec/support/generators.rb
|
|
121
130
|
- spec/support/match_contents_matcher.rb
|
|
131
|
+
- spec/support/project_files.rb
|
|
122
132
|
- spec/support/suspenders.rb
|
|
123
133
|
- suspenders.gemspec
|
|
124
134
|
- templates/Gemfile.erb
|
|
@@ -130,7 +140,6 @@ files:
|
|
|
130
140
|
- templates/_javascript.html.erb
|
|
131
141
|
- templates/action_mailer.rb
|
|
132
142
|
- templates/active_job.rb
|
|
133
|
-
- templates/app.json.erb
|
|
134
143
|
- templates/application.scss
|
|
135
144
|
- templates/bin_deploy
|
|
136
145
|
- templates/bin_setup
|
|
@@ -159,6 +168,7 @@ files:
|
|
|
159
168
|
- templates/shoulda_matchers_config_rspec.rb
|
|
160
169
|
- templates/smtp.rb
|
|
161
170
|
- templates/spec_helper.rb
|
|
171
|
+
- templates/stylelintrc.json
|
|
162
172
|
- templates/suspenders_gitignore
|
|
163
173
|
- templates/suspenders_layout.html.erb.erb
|
|
164
174
|
homepage: http://github.com/thoughtbot/suspenders
|
|
@@ -174,16 +184,39 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
174
184
|
requirements:
|
|
175
185
|
- - ">="
|
|
176
186
|
- !ruby/object:Gem::Version
|
|
177
|
-
version: 2.
|
|
187
|
+
version: 2.6.3
|
|
178
188
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
189
|
requirements:
|
|
180
190
|
- - ">="
|
|
181
191
|
- !ruby/object:Gem::Version
|
|
182
192
|
version: 2.7.4
|
|
183
193
|
requirements: []
|
|
184
|
-
|
|
185
|
-
rubygems_version: 2.7.6
|
|
194
|
+
rubygems_version: 3.0.3
|
|
186
195
|
signing_key:
|
|
187
196
|
specification_version: 4
|
|
188
197
|
summary: Generate a Rails app using thoughtbot's best practices.
|
|
189
|
-
test_files:
|
|
198
|
+
test_files:
|
|
199
|
+
- spec/adapters/heroku_spec.rb
|
|
200
|
+
- spec/fakes/bin/heroku
|
|
201
|
+
- spec/fakes/bin/hub
|
|
202
|
+
- spec/features/api_spec.rb
|
|
203
|
+
- spec/features/cli_help_spec.rb
|
|
204
|
+
- spec/features/github_spec.rb
|
|
205
|
+
- spec/features/heroku_spec.rb
|
|
206
|
+
- spec/features/json_spec.rb
|
|
207
|
+
- spec/features/new_project_spec.rb
|
|
208
|
+
- spec/features/production/deployment_spec.rb
|
|
209
|
+
- spec/features/production/email_spec.rb
|
|
210
|
+
- spec/features/production/manifest_spec.rb
|
|
211
|
+
- spec/features/staging/pull_requests_spec.rb
|
|
212
|
+
- spec/features/stylelint_spec.rb
|
|
213
|
+
- spec/spec_helper.rb
|
|
214
|
+
- spec/support/be_executable_matcher.rb
|
|
215
|
+
- spec/support/contain_json_matcher.rb
|
|
216
|
+
- spec/support/exist_as_a_file_matcher.rb
|
|
217
|
+
- spec/support/fake_github.rb
|
|
218
|
+
- spec/support/fake_heroku.rb
|
|
219
|
+
- spec/support/generators.rb
|
|
220
|
+
- spec/support/match_contents_matcher.rb
|
|
221
|
+
- spec/support/project_files.rb
|
|
222
|
+
- spec/support/suspenders.rb
|
data/templates/app.json.erb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name":"<%= app_name.dasherize %>",
|
|
3
|
-
"scripts":{},
|
|
4
|
-
"env":{
|
|
5
|
-
"APPLICATION_HOST":{
|
|
6
|
-
"required":true
|
|
7
|
-
},
|
|
8
|
-
"EMAIL_RECIPIENTS":{
|
|
9
|
-
"required":true
|
|
10
|
-
},
|
|
11
|
-
"HEROKU_APP_NAME": {
|
|
12
|
-
"required":true
|
|
13
|
-
},
|
|
14
|
-
"HEROKU_PARENT_APP_NAME": {
|
|
15
|
-
"required":true
|
|
16
|
-
},
|
|
17
|
-
"RACK_ENV":{
|
|
18
|
-
"required":true
|
|
19
|
-
},
|
|
20
|
-
"SECRET_KEY_BASE":{
|
|
21
|
-
"generator":"secret"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"addons":[
|
|
25
|
-
"heroku-postgresql"
|
|
26
|
-
]
|
|
27
|
-
}
|