suspenders 20230113.0 → 20240516.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +83 -176
- data/Rakefile +13 -0
- data/lib/generators/suspenders/accessibility_generator.rb +24 -0
- data/lib/generators/suspenders/advisories_generator.rb +32 -0
- data/lib/generators/suspenders/ci_generator.rb +57 -0
- data/lib/generators/suspenders/email_generator.rb +56 -0
- data/lib/generators/suspenders/environments/development_generator.rb +50 -0
- data/lib/generators/suspenders/environments/production_generator.rb +27 -0
- data/lib/generators/suspenders/environments/test_generator.rb +39 -0
- data/lib/generators/suspenders/factories_generator.rb +64 -0
- data/lib/generators/suspenders/inline_svg_generator.rb +24 -0
- data/lib/generators/suspenders/install/web_generator.rb +71 -0
- data/lib/generators/suspenders/jobs_generator.rb +34 -0
- data/lib/generators/suspenders/lint_generator.rb +94 -0
- data/lib/generators/suspenders/prerequisites_generator.rb +19 -0
- data/lib/generators/suspenders/rake_generator.rb +25 -0
- data/lib/generators/suspenders/setup_generator.rb +14 -0
- data/lib/generators/suspenders/styles_generator.rb +84 -0
- data/lib/generators/suspenders/tasks_generator.rb +20 -0
- data/lib/generators/suspenders/testing_generator.rb +113 -0
- data/lib/generators/suspenders/views_generator.rb +38 -0
- data/lib/generators/templates/ci/ci.yml.tt +148 -0
- data/lib/generators/templates/ci/dependabot.yml +7 -0
- data/lib/generators/templates/email/email_interceptor.rb +11 -0
- data/lib/generators/templates/factories/factories_spec.rb +7 -0
- data/lib/generators/templates/factories/factories_test.rb +9 -0
- data/lib/generators/templates/install/web/CONTRIBUTING.md +94 -0
- data/lib/generators/templates/lint/config_better_html.yml +2 -0
- data/lib/generators/templates/lint/config_initializers_better_html.rb +9 -0
- data/lib/generators/templates/lint/erb-lint.yml +63 -0
- data/lib/generators/templates/lint/erblint.rake +47 -0
- data/lib/generators/templates/lint/eslintrc.json +7 -0
- data/lib/generators/templates/lint/package.json +4 -0
- data/lib/generators/templates/lint/prettierignore +1 -0
- data/lib/generators/templates/lint/prettierrc +11 -0
- data/lib/generators/templates/lint/rubocop.yml.tt +7 -0
- data/lib/generators/templates/prerequisites/node-version.tt +1 -0
- data/lib/generators/templates/setup/bin_setup.rb +39 -0
- data/lib/generators/templates/styles/postcss.config.js +11 -0
- data/lib/generators/templates/testing/driver.rb +5 -0
- data/lib/generators/templates/views/flashes.html.erb +7 -0
- data/lib/install/web.rb +54 -0
- data/lib/suspenders/cleanup/generate_readme.rb +165 -0
- data/lib/suspenders/cleanup/organize_gemfile.rb +134 -0
- data/lib/suspenders/engine.rb +5 -0
- data/lib/suspenders/generators.rb +126 -0
- data/lib/suspenders/railtie.rb +4 -0
- data/lib/suspenders/version.rb +4 -6
- data/lib/suspenders.rb +9 -33
- data/lib/tasks/suspenders.rake +37 -0
- metadata +82 -173
- data/.ruby-version +0 -1
- data/CONTRIBUTING.md +0 -59
- data/GOALS.md +0 -65
- data/LICENSE +0 -21
- data/NEWS.md +0 -738
- data/RELEASING.md +0 -18
- data/bin/suspenders +0 -50
- data/docs/heroku_deploy.md +0 -19
- data/docs/rails_7.md +0 -5
- data/lib/suspenders/actions/strip_comments_action.rb +0 -254
- data/lib/suspenders/actions.rb +0 -106
- data/lib/suspenders/adapters/heroku.rb +0 -136
- data/lib/suspenders/app_builder.rb +0 -267
- data/lib/suspenders/exit_on_failure.rb +0 -19
- data/lib/suspenders/generators/accessibility_generator.rb +0 -12
- data/lib/suspenders/generators/advisories_generator.rb +0 -15
- data/lib/suspenders/generators/analytics_generator.rb +0 -24
- data/lib/suspenders/generators/app_generator.rb +0 -215
- data/lib/suspenders/generators/base.rb +0 -60
- data/lib/suspenders/generators/ci_generator.rb +0 -32
- data/lib/suspenders/generators/db_optimizations_generator.rb +0 -18
- data/lib/suspenders/generators/factories_generator.rb +0 -22
- data/lib/suspenders/generators/forms_generator.rb +0 -18
- data/lib/suspenders/generators/inline_svg_generator.rb +0 -14
- data/lib/suspenders/generators/jobs_generator.rb +0 -37
- data/lib/suspenders/generators/js_driver_generator.rb +0 -18
- data/lib/suspenders/generators/json_generator.rb +0 -14
- data/lib/suspenders/generators/lint_generator.rb +0 -14
- data/lib/suspenders/generators/production/compression_generator.rb +0 -14
- data/lib/suspenders/generators/production/deployment_generator.rb +0 -16
- data/lib/suspenders/generators/production/email_generator.rb +0 -34
- data/lib/suspenders/generators/production/force_tls_generator.rb +0 -11
- data/lib/suspenders/generators/production/manifest_generator.rb +0 -25
- data/lib/suspenders/generators/production/single_redirect.rb +0 -15
- data/lib/suspenders/generators/production/timeout_generator.rb +0 -22
- data/lib/suspenders/generators/profiler_generator.rb +0 -35
- data/lib/suspenders/generators/runner_generator.rb +0 -48
- data/lib/suspenders/generators/staging/pull_requests_generator.rb +0 -25
- data/lib/suspenders/generators/static_generator.rb +0 -14
- data/lib/suspenders/generators/stylelint_generator.rb +0 -71
- data/lib/suspenders/generators/stylesheet_base_generator.rb +0 -15
- data/lib/suspenders/generators/testing_generator.rb +0 -43
- data/lib/suspenders/generators/views_generator.rb +0 -25
- data/templates/Gemfile.erb +0 -49
- data/templates/Procfile +0 -2
- data/templates/README.md.erb +0 -28
- data/templates/_analytics.html.erb +0 -8
- data/templates/_css_overrides.html.erb +0 -7
- data/templates/_flashes.html.erb +0 -7
- data/templates/active_job.rb +0 -14
- data/templates/application.postcss.css +0 -1
- data/templates/bin_auto_migrate +0 -5
- data/templates/bin_deploy +0 -10
- data/templates/bin_setup +0 -28
- data/templates/bin_setup_review_app.erb +0 -21
- data/templates/bin_yarn +0 -18
- data/templates/bundler_audit.rake +0 -4
- data/templates/capybara_silence_puma.rb +0 -1
- data/templates/chromedriver.rb +0 -27
- data/templates/circle.yml.erb +0 -6
- data/templates/config_locales_en.yml.erb +0 -19
- data/templates/descriptions/advisories.md +0 -5
- data/templates/descriptions/analytics.md +0 -4
- data/templates/descriptions/ci.md +0 -4
- data/templates/descriptions/compression.md +0 -4
- data/templates/descriptions/db_optimizations.md +0 -2
- data/templates/descriptions/deployment.md +0 -5
- data/templates/descriptions/email.md +0 -9
- data/templates/descriptions/factories.md +0 -12
- data/templates/descriptions/force_tls.md +0 -1
- data/templates/descriptions/forms.md +0 -1
- data/templates/descriptions/inline_svg.md +0 -2
- data/templates/descriptions/jobs.md +0 -3
- data/templates/descriptions/js_driver.md +0 -4
- data/templates/descriptions/json.md +0 -1
- data/templates/descriptions/lint.md +0 -3
- data/templates/descriptions/manifest.md +0 -2
- data/templates/descriptions/profiler.md +0 -7
- data/templates/descriptions/pull_requests.md +0 -4
- data/templates/descriptions/runner.md +0 -10
- data/templates/descriptions/single_redirect.md +0 -1
- data/templates/descriptions/static.md +0 -5
- data/templates/descriptions/stylelint.md +0 -3
- data/templates/descriptions/stylesheet_base.md +0 -1
- data/templates/descriptions/testing.md +0 -9
- data/templates/descriptions/timeout.md +0 -4
- data/templates/descriptions/views.md +0 -8
- data/templates/email.rb +0 -3
- data/templates/errors.rb +0 -35
- data/templates/flashes_helper.rb +0 -5
- data/templates/hound.yml +0 -15
- data/templates/json_encoding.rb +0 -1
- data/templates/oj.rb +0 -3
- data/templates/partials/ci_simplecov.rb +0 -14
- data/templates/partials/db_optimizations_configuration.rb +0 -7
- data/templates/partials/deployment_readme.md +0 -8
- data/templates/partials/email_smtp.rb +0 -2
- data/templates/partials/profiler_readme.md +0 -8
- data/templates/partials/pull_requests_config.rb +0 -5
- data/templates/partials/runner_readme.md +0 -31
- data/templates/partials/runner_setup.rb +0 -2
- data/templates/postcss.config.js +0 -8
- data/templates/postgresql_database.yml.erb +0 -20
- data/templates/rack_mini_profiler.rb +0 -7
- data/templates/rails_helper.rb +0 -25
- data/templates/sample_env +0 -12
- data/templates/secrets.yml +0 -8
- data/templates/smtp.rb +0 -9
- data/templates/spec_helper.rb +0 -25
- data/templates/suspenders_gitignore +0 -18
- data/templates/suspenders_layout.html.erb.erb +0 -23
- /data/{templates → lib/generators/templates/factories}/factories.rb +0 -0
- /data/{templates → lib/generators/templates/factories}/factory_bot_rspec.rb +0 -0
- /data/{templates → lib/generators/templates/inline_svg}/inline_svg.rb +0 -0
- /data/{templates → lib/generators/templates/lint}/stylelintrc.json +0 -0
- /data/{templates → lib/generators/templates/tasks}/dev.rake +0 -0
- /data/{templates → lib/generators/templates/testing}/action_mailer.rb +0 -0
- /data/{templates → lib/generators/templates/testing}/i18n.rb +0 -0
- /data/{templates/shoulda_matchers_config_rspec.rb → lib/generators/templates/testing/shoulda_matchers.rb} +0 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class FactoriesGenerator < Rails::Generators::Base
|
4
|
+
include Suspenders::Generators::Helpers
|
5
|
+
|
6
|
+
source_root File.expand_path("../../templates/factories", __FILE__)
|
7
|
+
desc <<~MARKDOWN
|
8
|
+
Uses [FactoryBot][] as an alternative to [Fixtures][] to help you define
|
9
|
+
dummy and test data for your test suite. The `create`, `build`, and
|
10
|
+
`build_stubbed` class methods are directly available to all tests.
|
11
|
+
|
12
|
+
Place FactoryBot definitions in `spec/factories.rb`, at least until it
|
13
|
+
grows unwieldy. This helps reduce confusion around circular dependencies and
|
14
|
+
makes it easy to jump between definitions.
|
15
|
+
|
16
|
+
[FactoryBot]: https://github.com/thoughtbot/factory_bot
|
17
|
+
[Fixtures]: https://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures
|
18
|
+
MARKDOWN
|
19
|
+
|
20
|
+
def add_factory_bot
|
21
|
+
gem_group :development, :test do
|
22
|
+
gem "factory_bot_rails"
|
23
|
+
end
|
24
|
+
|
25
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_up_factory_bot
|
29
|
+
if default_test_helper_present?
|
30
|
+
insert_into_file Rails.root.join("test/test_helper.rb"), after: "class TestCase" do
|
31
|
+
"\n include FactoryBot::Syntax::Methods"
|
32
|
+
end
|
33
|
+
elsif rspec_test_helper_present?
|
34
|
+
copy_file "factory_bot_rspec.rb", "spec/support/factory_bot.rb"
|
35
|
+
insert_into_file Rails.root.join("spec/rails_helper.rb") do
|
36
|
+
%(Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file })
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def generate_empty_factories_file
|
42
|
+
if default_test_suite?
|
43
|
+
copy_file "factories.rb", "test/factories.rb"
|
44
|
+
elsif rspec_test_suite?
|
45
|
+
copy_file "factories.rb", "spec/factories.rb"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def remove_fixture_definitions
|
50
|
+
if default_test_helper_present?
|
51
|
+
comment_lines "test/test_helper.rb", /fixtures :all/
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_linting_test
|
56
|
+
if default_test_suite?
|
57
|
+
copy_file "factories_test.rb", "test/factory_bots/factories_test.rb"
|
58
|
+
elsif rspec_test_suite?
|
59
|
+
copy_file "factories_spec.rb", "spec/factory_bots/factories_spec.rb"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class InlineSvgGenerator < Rails::Generators::Base
|
4
|
+
include Suspenders::Generators::APIAppUnsupported
|
5
|
+
source_root File.expand_path("../../templates/inline_svg", __FILE__)
|
6
|
+
desc <<~MARKDOWN
|
7
|
+
Uses [inline_svg][] for embedding SVG documents into views.
|
8
|
+
|
9
|
+
Configuration can be found at `config/initializers/inline_svg.rb`
|
10
|
+
|
11
|
+
[inline_svg]: https://github.com/jamesmartin/inline_svg
|
12
|
+
MARKDOWN
|
13
|
+
|
14
|
+
def add_inline_svg_gem
|
15
|
+
gem "inline_svg"
|
16
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
17
|
+
end
|
18
|
+
|
19
|
+
def configure_inline_svg
|
20
|
+
copy_file "inline_svg.rb", "config/initializers/inline_svg.rb"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
module Install
|
4
|
+
class WebGenerator < Rails::Generators::Base
|
5
|
+
include Suspenders::Generators::APIAppUnsupported
|
6
|
+
include Suspenders::Generators::DatabaseUnsupported
|
7
|
+
include Suspenders::Generators::NodeNotInstalled
|
8
|
+
include Suspenders::Generators::NodeVersionUnsupported
|
9
|
+
|
10
|
+
source_root File.expand_path("../../../templates/install/web", __FILE__)
|
11
|
+
desc <<~MARKDOWN
|
12
|
+
Invokes all necessary generators for new Rails applications generated with Suspenders.
|
13
|
+
|
14
|
+
This generatator is intended to be invoked as part of an [application template][].
|
15
|
+
|
16
|
+
```
|
17
|
+
rails new suspenders_qa \
|
18
|
+
--skip-test \
|
19
|
+
-d=postgresql \
|
20
|
+
-m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
|
21
|
+
```
|
22
|
+
|
23
|
+
[application template]: https://guides.rubyonrails.org/rails_application_templates.html
|
24
|
+
MARKDOWN
|
25
|
+
|
26
|
+
def invoke_generators
|
27
|
+
# This needs to go first, since it configures `.node-version`
|
28
|
+
generate "suspenders:prerequisites"
|
29
|
+
|
30
|
+
generate "suspenders:accessibility"
|
31
|
+
generate "suspenders:advisories"
|
32
|
+
generate "suspenders:email"
|
33
|
+
generate "suspenders:factories"
|
34
|
+
generate "suspenders:inline_svg"
|
35
|
+
generate "suspenders:lint"
|
36
|
+
generate "suspenders:rake"
|
37
|
+
generate "suspenders:setup"
|
38
|
+
generate "suspenders:tasks"
|
39
|
+
generate "suspenders:testing"
|
40
|
+
generate "suspenders:views"
|
41
|
+
|
42
|
+
# suspenders:jobs needs to be invoked before suspenders:styles, since
|
43
|
+
# suspenders:styles generator creates Procfile.dev
|
44
|
+
generate "suspenders:styles"
|
45
|
+
generate "suspenders:jobs"
|
46
|
+
|
47
|
+
# Needs to run after other generators, since some touch the
|
48
|
+
# configuration files.
|
49
|
+
generate "suspenders:environments:test"
|
50
|
+
generate "suspenders:environments:development"
|
51
|
+
generate "suspenders:environments:production"
|
52
|
+
|
53
|
+
# Needs to be run last since it depends on lint, testing, and
|
54
|
+
# advisories
|
55
|
+
generate "suspenders:ci"
|
56
|
+
end
|
57
|
+
|
58
|
+
def cleanup
|
59
|
+
rake "suspenders:cleanup:organize_gemfile"
|
60
|
+
rake "suspenders:cleanup:generate_readme"
|
61
|
+
copy_file "CONTRIBUTING.md", "CONTRIBUTING.md"
|
62
|
+
end
|
63
|
+
|
64
|
+
def lint
|
65
|
+
run "yarn run fix:prettier"
|
66
|
+
run "bundle exec rake standard:fix_unsafely"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class JobsGenerator < Rails::Generators::Base
|
4
|
+
desc <<~MARKDOWN
|
5
|
+
Uses [Sidekiq][] for [background job][] processing.
|
6
|
+
|
7
|
+
Configures the `test` environment to use the [inline][] adapter.
|
8
|
+
|
9
|
+
[Sidekiq]: https://github.com/sidekiq/sidekiq
|
10
|
+
[background job]: https://guides.rubyonrails.org/active_job_basics.html
|
11
|
+
[inline]: https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html
|
12
|
+
MARKDOWN
|
13
|
+
|
14
|
+
def add_sidekiq_gem
|
15
|
+
gem "sidekiq"
|
16
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
17
|
+
end
|
18
|
+
|
19
|
+
def configure_active_job
|
20
|
+
environment "config.active_job.queue_adapter = :sidekiq"
|
21
|
+
environment "config.active_job.queue_adapter = :inline", env: "test"
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure_procfile
|
25
|
+
if Rails.root.join("Procfile.dev").exist?
|
26
|
+
append_to_file "Procfile.dev", "worker: bundle exec sidekiq"
|
27
|
+
else
|
28
|
+
say "Add default Procfile.dev"
|
29
|
+
create_file "Procfile.dev", "worker: bundle exec sidekiq"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class LintGenerator < Rails::Generators::Base
|
4
|
+
include Suspenders::Generators::Helpers
|
5
|
+
|
6
|
+
source_root File.expand_path("../../templates/lint", __FILE__)
|
7
|
+
desc <<~MARKDOWN
|
8
|
+
- Uses [@thoughtbot/eslint-config][] for JavaScript linting.
|
9
|
+
- Uses [@thoughtbot/stylelint-config][] for CSS linting.
|
10
|
+
- Uses [prettier][] for additional linting.
|
11
|
+
- Uses [better_html][], [erb_lint][], and [erblint-github][] for ERB linting.
|
12
|
+
- Uses [standard][] for Ruby linting.
|
13
|
+
|
14
|
+
**Available Commands**
|
15
|
+
|
16
|
+
- Run `yarn lint` to lint front-end code.
|
17
|
+
- Run `yarn fix:prettier` to automatically fix prettier violations.
|
18
|
+
- Run `bin/rails standard` to lint ERB and Ruby code.
|
19
|
+
- Run `bundle exec standardrb --fix` to fix standard violations.
|
20
|
+
|
21
|
+
[@thoughtbot/eslint-config]: https://github.com/thoughtbot/eslint-config
|
22
|
+
[@thoughtbot/stylelint-config]: https://github.com/thoughtbot/stylelint-config
|
23
|
+
[prettier]: https://prettier.io
|
24
|
+
[better_html]: https://github.com/Shopify/better-html
|
25
|
+
[erb_lint]: https://github.com/Shopify/erb-lint
|
26
|
+
[erblint-github]: https://github.com/github/erblint-github
|
27
|
+
[standard]: https://github.com/standardrb/standard
|
28
|
+
MARKDOWN
|
29
|
+
|
30
|
+
def check_package_json
|
31
|
+
unless File.exist? Rails.root.join("package.json")
|
32
|
+
copy_file "package.json", "package.json"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# TODO: Remove eslint version pin once the follownig is solved
|
37
|
+
# https://github.com/thoughtbot/eslint-config/issues/10
|
38
|
+
def install_dependencies
|
39
|
+
run "yarn add stylelint eslint@^8.9.0 @thoughtbot/stylelint-config @thoughtbot/eslint-config npm-run-all prettier --dev"
|
40
|
+
end
|
41
|
+
|
42
|
+
def install_gems
|
43
|
+
gem_group :development, :test do
|
44
|
+
gem "better_html", require: false
|
45
|
+
gem "erb_lint", require: false
|
46
|
+
gem "erblint-github", require: false
|
47
|
+
gem "standard"
|
48
|
+
end
|
49
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
50
|
+
end
|
51
|
+
|
52
|
+
def configure_stylelint
|
53
|
+
copy_file "stylelintrc.json", ".stylelintrc.json"
|
54
|
+
end
|
55
|
+
|
56
|
+
def configure_eslint
|
57
|
+
copy_file "eslintrc.json", ".eslintrc.json"
|
58
|
+
end
|
59
|
+
|
60
|
+
def configure_prettier
|
61
|
+
copy_file "prettierrc", ".prettierrc"
|
62
|
+
copy_file "prettierignore", ".prettierignore"
|
63
|
+
end
|
64
|
+
|
65
|
+
def configure_erb_lint
|
66
|
+
copy_file "erb-lint.yml", ".erb-lint.yml"
|
67
|
+
copy_file "config_better_html.yml", "config/better_html.yml"
|
68
|
+
copy_file "config_initializers_better_html.rb", "config/initializers/better_html.rb"
|
69
|
+
copy_file "erblint.rake", "lib/tasks/erblint.rake"
|
70
|
+
template "rubocop.yml.tt", ".rubocop.yml"
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_package_json
|
74
|
+
content = File.read package_json
|
75
|
+
json = JSON.parse content
|
76
|
+
json["scripts"] ||= {}
|
77
|
+
|
78
|
+
json["scripts"]["lint"] = "run-p lint:eslint lint:stylelint lint:prettier"
|
79
|
+
json["scripts"]["lint:eslint"] = "eslint --max-warnings=0 --no-error-on-unmatched-pattern 'app/javascript/**/*.js'"
|
80
|
+
json["scripts"]["lint:stylelint"] = "stylelint 'app/assets/stylesheets/**/*.css'"
|
81
|
+
json["scripts"]["lint:prettier"] = "prettier --check '**/*' --ignore-unknown"
|
82
|
+
json["scripts"]["fix:prettier"] = "prettier --write '**/*' --ignore-unknown"
|
83
|
+
|
84
|
+
File.write package_json, JSON.pretty_generate(json)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def package_json
|
90
|
+
Rails.root.join("package.json")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class PrerequisitesGenerator < Rails::Generators::Base
|
4
|
+
include Suspenders::Generators::Helpers
|
5
|
+
include Suspenders::Generators::NodeNotInstalled
|
6
|
+
include Suspenders::Generators::NodeVersionUnsupported
|
7
|
+
|
8
|
+
source_root File.expand_path("../../templates/prerequisites", __FILE__)
|
9
|
+
|
10
|
+
desc <<~MARKDOWN
|
11
|
+
Creates `.node-version` file set to the current LTS version.
|
12
|
+
MARKDOWN
|
13
|
+
|
14
|
+
def set_node_version
|
15
|
+
template "node-version", ".node-version"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class RakeGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates/rake", __FILE__)
|
5
|
+
desc <<~MARKDOWN
|
6
|
+
Adds default Raketask wich is a wrapper for `suspenders:rake`.
|
7
|
+
|
8
|
+
This will do the following:
|
9
|
+
|
10
|
+
- Run the test suite.
|
11
|
+
- Run a Ruby and ERB linter.
|
12
|
+
- Scan the Ruby codebase for any dependency vulnerabilities.
|
13
|
+
MARKDOWN
|
14
|
+
|
15
|
+
def configure_default_rake_task
|
16
|
+
append_to_file "Rakefile", <<~RUBY
|
17
|
+
|
18
|
+
if Rails.env.local?
|
19
|
+
task default: "suspenders:rake"
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class SetupGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates/setup", __FILE__)
|
5
|
+
desc <<~MARKDOWN
|
6
|
+
Run `bin/setup` to install dependencies and seed development data.
|
7
|
+
MARKDOWN
|
8
|
+
|
9
|
+
def replace_bin_setup
|
10
|
+
copy_file "bin_setup.rb", "bin/setup", force: true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class StylesGenerator < Rails::Generators::Base
|
4
|
+
include Suspenders::Generators::APIAppUnsupported
|
5
|
+
|
6
|
+
source_root File.expand_path("../../templates/styles", __FILE__)
|
7
|
+
desc <<~MARKDOWN
|
8
|
+
- Uses [PostCSS][] via [cssbundling-rails][].
|
9
|
+
- Uses [modern-normalize][] to normalize browsers' default style.
|
10
|
+
|
11
|
+
Configuration can be found at `postcss.config.js`.
|
12
|
+
|
13
|
+
Adds the following stylesheet structure.
|
14
|
+
|
15
|
+
```
|
16
|
+
app/assets/stylesheets/base.css
|
17
|
+
app/assets/stylesheets/components.css
|
18
|
+
app/assets/stylesheets/utilities.css
|
19
|
+
```
|
20
|
+
|
21
|
+
Adds `app/assets/static` so that [postcss-url][] has a directory to copy
|
22
|
+
assets to.
|
23
|
+
|
24
|
+
[PostCSS]: https://postcss.org
|
25
|
+
[cssbundling-rails]: https://github.com/rails/cssbundling-rails
|
26
|
+
[modern-normalize]: https://github.com/sindresorhus/modern-normalize
|
27
|
+
[postcss-url]: https://github.com/postcss/postcss-url
|
28
|
+
MARKDOWN
|
29
|
+
|
30
|
+
def add_cssbundling_rails_gem
|
31
|
+
gem "cssbundling-rails"
|
32
|
+
|
33
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
34
|
+
run "bin/rails css:install:postcss"
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_directory_structure
|
38
|
+
create_file "app/assets/stylesheets/base.css"
|
39
|
+
append_to_file "app/assets/stylesheets/base.css", "/* Base Styles */"
|
40
|
+
|
41
|
+
create_file "app/assets/stylesheets/components.css"
|
42
|
+
append_to_file "app/assets/stylesheets/components.css", "/* Component Styles */"
|
43
|
+
|
44
|
+
create_file "app/assets/stylesheets/utilities.css"
|
45
|
+
append_to_file "app/assets/stylesheets/utilities.css", "/* Utility Styles */"
|
46
|
+
end
|
47
|
+
|
48
|
+
def configure_application_stylesheet
|
49
|
+
run "yarn add modern-normalize"
|
50
|
+
|
51
|
+
append_to_file "app/assets/stylesheets/application.postcss.css" do
|
52
|
+
<<~TEXT
|
53
|
+
@import "modern-normalize";
|
54
|
+
@import "base.css";
|
55
|
+
@import "components.css";
|
56
|
+
@import "utilities.css";
|
57
|
+
TEXT
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def install_postcss_url
|
62
|
+
run "yarn add postcss-url"
|
63
|
+
end
|
64
|
+
|
65
|
+
def configures_postcss
|
66
|
+
begin
|
67
|
+
File.delete(postcss_config)
|
68
|
+
rescue Errno::ENOENT
|
69
|
+
end
|
70
|
+
|
71
|
+
empty_directory "app/assets/static"
|
72
|
+
create_file "app/assets/static/.gitkeep"
|
73
|
+
|
74
|
+
copy_file "postcss.config.js", "postcss.config.js"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def postcss_config
|
80
|
+
Rails.root.join("postcss.config.js")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class TasksGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates/tasks", __FILE__)
|
5
|
+
desc <<~MARKDOWN
|
6
|
+
Creates `lib/tasks/dev.rake` which contains the following tasks:
|
7
|
+
|
8
|
+
`bin/rails dev:prime` which loads sample data for local development.
|
9
|
+
MARKDOWN
|
10
|
+
|
11
|
+
def create_dev_rake
|
12
|
+
if Bundler.rubygems.find_name("factory_bot").any?
|
13
|
+
copy_file "dev.rake", "lib/tasks/dev.rake"
|
14
|
+
else
|
15
|
+
say "This generator requires Factory Bot"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class TestingGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates/testing", __FILE__)
|
5
|
+
desc <<~MARKDOWN
|
6
|
+
Uses [RSpec][] and [RSpec Rails][] in favor of the [default test suite][].
|
7
|
+
|
8
|
+
The test suite can be run with `bin/rails spec`.
|
9
|
+
|
10
|
+
Configuration can be found in the following files:
|
11
|
+
|
12
|
+
```
|
13
|
+
spec/rails_helper.rb
|
14
|
+
spec/spec_helper.rb
|
15
|
+
spec/support/action_mailer.rb
|
16
|
+
spec/support/driver.rb
|
17
|
+
spec/support/i18n.rb
|
18
|
+
spec/support/should_matchers.rb
|
19
|
+
```
|
20
|
+
|
21
|
+
- Uses [action_dispatch-testing-integration-capybara][] to introduce Capybara assertions into Request specs.
|
22
|
+
- Uses [should-matchers][] for simple one-liner tests for common Rails functionality.
|
23
|
+
- Uses [webmock][] for stubbing and setting expectations on HTTP requests in Ruby.
|
24
|
+
|
25
|
+
[RSpec]: http://rspec.info
|
26
|
+
[RSpec Rails]: https://github.com/rspec/rspec-rails
|
27
|
+
[default test suite]: https://guides.rubyonrails.org/testing.html
|
28
|
+
[action_dispatch-testing-integration-capybara]: https://github.com/thoughtbot/action_dispatch-testing-integration-capybara
|
29
|
+
[should-matchers]: https://github.com/thoughtbot/shoulda-matchers
|
30
|
+
[webmock]: https://github.com/bblimke/webmock
|
31
|
+
MARKDOWN
|
32
|
+
|
33
|
+
def add_gems
|
34
|
+
gem_group :development, :test do
|
35
|
+
gem "rspec-rails", "~> 6.1.0"
|
36
|
+
end
|
37
|
+
|
38
|
+
gem_group :test do
|
39
|
+
gem "capybara"
|
40
|
+
gem "action_dispatch-testing-integration-capybara",
|
41
|
+
github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1",
|
42
|
+
require: "action_dispatch/testing/integration/capybara/rspec"
|
43
|
+
gem "selenium-webdriver"
|
44
|
+
gem "shoulda-matchers", "~> 6.0"
|
45
|
+
gem "webmock"
|
46
|
+
end
|
47
|
+
|
48
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_rspec_installation_script
|
52
|
+
rails_command "generate rspec:install"
|
53
|
+
end
|
54
|
+
|
55
|
+
def modify_rails_helper
|
56
|
+
insert_into_file "spec/rails_helper.rb",
|
57
|
+
"\s\sconfig.infer_base_class_for_anonymous_controllers = false\n",
|
58
|
+
after: "RSpec.configure do |config|\n"
|
59
|
+
|
60
|
+
uncomment_lines "spec/rails_helper.rb", /Rails\.root\.glob/
|
61
|
+
end
|
62
|
+
|
63
|
+
def modify_spec_helper
|
64
|
+
persistence_file_path = "\s\sconfig.example_status_persistence_file_path = \"tmp/rspec_examples.txt\"\n"
|
65
|
+
order = "\s\sconfig.order = :random\n\n"
|
66
|
+
webmock_config = <<~RUBY
|
67
|
+
|
68
|
+
WebMock.disable_net_connect!(
|
69
|
+
allow_localhost: true,
|
70
|
+
allow: [
|
71
|
+
/(chromedriver|storage).googleapis.com/,
|
72
|
+
"googlechromelabs.github.io"
|
73
|
+
]
|
74
|
+
)
|
75
|
+
RUBY
|
76
|
+
|
77
|
+
insert_into_file "spec/spec_helper.rb",
|
78
|
+
persistence_file_path + order,
|
79
|
+
after: "RSpec.configure do |config|\n"
|
80
|
+
|
81
|
+
insert_into_file "spec/spec_helper.rb", "require \"webmock/rspec\"\n\n", before: "RSpec.configure do |config|"
|
82
|
+
insert_into_file "spec/spec_helper.rb", webmock_config
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_system_spec_dir
|
86
|
+
empty_directory "spec/system"
|
87
|
+
create_file "spec/system/.gitkeep"
|
88
|
+
end
|
89
|
+
|
90
|
+
def configure_chromedriver
|
91
|
+
copy_file "driver.rb", "spec/support/driver.rb"
|
92
|
+
end
|
93
|
+
|
94
|
+
def configure_i18n_helper
|
95
|
+
copy_file "i18n.rb", "spec/support/i18n.rb"
|
96
|
+
end
|
97
|
+
|
98
|
+
def configure_shoulda_matchers
|
99
|
+
copy_file "shoulda_matchers.rb", "spec/support/shoulda_matchers.rb"
|
100
|
+
end
|
101
|
+
|
102
|
+
def configure_action_mailer_helpers
|
103
|
+
# https://guides.rubyonrails.org/testing.html#the-basic-test-case
|
104
|
+
#
|
105
|
+
# The ActionMailer::Base.deliveries array is only reset automatically in
|
106
|
+
# ActionMailer::TestCase and ActionDispatch::IntegrationTest tests. If
|
107
|
+
# you want to have a clean slate outside these test cases, you can reset
|
108
|
+
# it manually with: ActionMailer::Base.deliveries.clear
|
109
|
+
copy_file "action_mailer.rb", "spec/support/action_mailer.rb"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Suspenders
|
2
|
+
module Generators
|
3
|
+
class ViewsGenerator < Rails::Generators::Base
|
4
|
+
include Suspenders::Generators::APIAppUnsupported
|
5
|
+
|
6
|
+
source_root File.expand_path("../../templates/views", __FILE__)
|
7
|
+
desc <<~MARKDOWN
|
8
|
+
- A [partial][] for [flash messages][] is located in `app/views/application/_flashes.html.erb`.
|
9
|
+
- Sets [lang][] attribute on `<html>` element to `en` via `I18n.local`.
|
10
|
+
- Dynamically sets `<title>` via the [title][] gem.
|
11
|
+
- Disables Turbo's [Prefetch][] in an effort to reduce unnecessary network requests.
|
12
|
+
|
13
|
+
[partial]: https://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
|
14
|
+
[flash messages]: https://guides.rubyonrails.org/action_controller_overview.html#the-flash
|
15
|
+
[lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang
|
16
|
+
[title]: https://github.com/calebhearth/title
|
17
|
+
[Prefetch]: https://turbo.hotwired.dev/handbook/drive#prefetching-links-on-hover
|
18
|
+
MARKDOWN
|
19
|
+
|
20
|
+
def install_gems
|
21
|
+
gem "title"
|
22
|
+
|
23
|
+
Bundler.with_unbundled_env { run "bundle install" }
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_views
|
27
|
+
copy_file "flashes.html.erb", "app/views/application/_flashes.html.erb"
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_application_layout
|
31
|
+
insert_into_file "app/views/layouts/application.html.erb", " <%= render \"flashes\" -%>\n", after: "<body>\n"
|
32
|
+
gsub_file "app/views/layouts/application.html.erb", /<html>/, "<html lang=\"<%= I18n.locale %>\">"
|
33
|
+
gsub_file "app/views/layouts/application.html.erb", /<title>.*<\/title>/, "<title><%= title %></title>"
|
34
|
+
insert_into_file "app/views/layouts/application.html.erb", " <meta name=\"turbo-prefetch\" content=\"false\">\n", after: "</title>"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|