suspenders 20230113.0 → 20240516.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +83 -176
  3. data/Rakefile +13 -0
  4. data/lib/generators/suspenders/accessibility_generator.rb +24 -0
  5. data/lib/generators/suspenders/advisories_generator.rb +32 -0
  6. data/lib/generators/suspenders/ci_generator.rb +57 -0
  7. data/lib/generators/suspenders/email_generator.rb +56 -0
  8. data/lib/generators/suspenders/environments/development_generator.rb +50 -0
  9. data/lib/generators/suspenders/environments/production_generator.rb +27 -0
  10. data/lib/generators/suspenders/environments/test_generator.rb +39 -0
  11. data/lib/generators/suspenders/factories_generator.rb +64 -0
  12. data/lib/generators/suspenders/inline_svg_generator.rb +24 -0
  13. data/lib/generators/suspenders/install/web_generator.rb +71 -0
  14. data/lib/generators/suspenders/jobs_generator.rb +34 -0
  15. data/lib/generators/suspenders/lint_generator.rb +94 -0
  16. data/lib/generators/suspenders/prerequisites_generator.rb +19 -0
  17. data/lib/generators/suspenders/rake_generator.rb +25 -0
  18. data/lib/generators/suspenders/setup_generator.rb +14 -0
  19. data/lib/generators/suspenders/styles_generator.rb +84 -0
  20. data/lib/generators/suspenders/tasks_generator.rb +20 -0
  21. data/lib/generators/suspenders/testing_generator.rb +113 -0
  22. data/lib/generators/suspenders/views_generator.rb +38 -0
  23. data/lib/generators/templates/ci/ci.yml.tt +148 -0
  24. data/lib/generators/templates/ci/dependabot.yml +7 -0
  25. data/lib/generators/templates/email/email_interceptor.rb +11 -0
  26. data/lib/generators/templates/factories/factories_spec.rb +7 -0
  27. data/lib/generators/templates/factories/factories_test.rb +9 -0
  28. data/lib/generators/templates/install/web/CONTRIBUTING.md +94 -0
  29. data/lib/generators/templates/lint/config_better_html.yml +2 -0
  30. data/lib/generators/templates/lint/config_initializers_better_html.rb +9 -0
  31. data/lib/generators/templates/lint/erb-lint.yml +63 -0
  32. data/lib/generators/templates/lint/erblint.rake +47 -0
  33. data/lib/generators/templates/lint/eslintrc.json +7 -0
  34. data/lib/generators/templates/lint/package.json +4 -0
  35. data/lib/generators/templates/lint/prettierignore +1 -0
  36. data/lib/generators/templates/lint/prettierrc +11 -0
  37. data/lib/generators/templates/lint/rubocop.yml.tt +7 -0
  38. data/lib/generators/templates/prerequisites/node-version.tt +1 -0
  39. data/lib/generators/templates/setup/bin_setup.rb +39 -0
  40. data/lib/generators/templates/styles/postcss.config.js +11 -0
  41. data/lib/generators/templates/testing/driver.rb +5 -0
  42. data/lib/generators/templates/views/flashes.html.erb +7 -0
  43. data/lib/install/web.rb +54 -0
  44. data/lib/suspenders/cleanup/generate_readme.rb +165 -0
  45. data/lib/suspenders/cleanup/organize_gemfile.rb +134 -0
  46. data/lib/suspenders/engine.rb +5 -0
  47. data/lib/suspenders/generators.rb +126 -0
  48. data/lib/suspenders/railtie.rb +4 -0
  49. data/lib/suspenders/version.rb +4 -6
  50. data/lib/suspenders.rb +9 -33
  51. data/lib/tasks/suspenders.rake +37 -0
  52. metadata +82 -173
  53. data/.ruby-version +0 -1
  54. data/CONTRIBUTING.md +0 -59
  55. data/GOALS.md +0 -65
  56. data/LICENSE +0 -21
  57. data/NEWS.md +0 -738
  58. data/RELEASING.md +0 -18
  59. data/bin/suspenders +0 -50
  60. data/docs/heroku_deploy.md +0 -19
  61. data/docs/rails_7.md +0 -5
  62. data/lib/suspenders/actions/strip_comments_action.rb +0 -254
  63. data/lib/suspenders/actions.rb +0 -106
  64. data/lib/suspenders/adapters/heroku.rb +0 -136
  65. data/lib/suspenders/app_builder.rb +0 -267
  66. data/lib/suspenders/exit_on_failure.rb +0 -19
  67. data/lib/suspenders/generators/accessibility_generator.rb +0 -12
  68. data/lib/suspenders/generators/advisories_generator.rb +0 -15
  69. data/lib/suspenders/generators/analytics_generator.rb +0 -24
  70. data/lib/suspenders/generators/app_generator.rb +0 -215
  71. data/lib/suspenders/generators/base.rb +0 -60
  72. data/lib/suspenders/generators/ci_generator.rb +0 -32
  73. data/lib/suspenders/generators/db_optimizations_generator.rb +0 -18
  74. data/lib/suspenders/generators/factories_generator.rb +0 -22
  75. data/lib/suspenders/generators/forms_generator.rb +0 -18
  76. data/lib/suspenders/generators/inline_svg_generator.rb +0 -14
  77. data/lib/suspenders/generators/jobs_generator.rb +0 -37
  78. data/lib/suspenders/generators/js_driver_generator.rb +0 -18
  79. data/lib/suspenders/generators/json_generator.rb +0 -14
  80. data/lib/suspenders/generators/lint_generator.rb +0 -14
  81. data/lib/suspenders/generators/production/compression_generator.rb +0 -14
  82. data/lib/suspenders/generators/production/deployment_generator.rb +0 -16
  83. data/lib/suspenders/generators/production/email_generator.rb +0 -34
  84. data/lib/suspenders/generators/production/force_tls_generator.rb +0 -11
  85. data/lib/suspenders/generators/production/manifest_generator.rb +0 -25
  86. data/lib/suspenders/generators/production/single_redirect.rb +0 -15
  87. data/lib/suspenders/generators/production/timeout_generator.rb +0 -22
  88. data/lib/suspenders/generators/profiler_generator.rb +0 -35
  89. data/lib/suspenders/generators/runner_generator.rb +0 -48
  90. data/lib/suspenders/generators/staging/pull_requests_generator.rb +0 -25
  91. data/lib/suspenders/generators/static_generator.rb +0 -14
  92. data/lib/suspenders/generators/stylelint_generator.rb +0 -71
  93. data/lib/suspenders/generators/stylesheet_base_generator.rb +0 -15
  94. data/lib/suspenders/generators/testing_generator.rb +0 -43
  95. data/lib/suspenders/generators/views_generator.rb +0 -25
  96. data/templates/Gemfile.erb +0 -49
  97. data/templates/Procfile +0 -2
  98. data/templates/README.md.erb +0 -28
  99. data/templates/_analytics.html.erb +0 -8
  100. data/templates/_css_overrides.html.erb +0 -7
  101. data/templates/_flashes.html.erb +0 -7
  102. data/templates/active_job.rb +0 -14
  103. data/templates/application.postcss.css +0 -1
  104. data/templates/bin_auto_migrate +0 -5
  105. data/templates/bin_deploy +0 -10
  106. data/templates/bin_setup +0 -28
  107. data/templates/bin_setup_review_app.erb +0 -21
  108. data/templates/bin_yarn +0 -18
  109. data/templates/bundler_audit.rake +0 -4
  110. data/templates/capybara_silence_puma.rb +0 -1
  111. data/templates/chromedriver.rb +0 -27
  112. data/templates/circle.yml.erb +0 -6
  113. data/templates/config_locales_en.yml.erb +0 -19
  114. data/templates/descriptions/advisories.md +0 -5
  115. data/templates/descriptions/analytics.md +0 -4
  116. data/templates/descriptions/ci.md +0 -4
  117. data/templates/descriptions/compression.md +0 -4
  118. data/templates/descriptions/db_optimizations.md +0 -2
  119. data/templates/descriptions/deployment.md +0 -5
  120. data/templates/descriptions/email.md +0 -9
  121. data/templates/descriptions/factories.md +0 -12
  122. data/templates/descriptions/force_tls.md +0 -1
  123. data/templates/descriptions/forms.md +0 -1
  124. data/templates/descriptions/inline_svg.md +0 -2
  125. data/templates/descriptions/jobs.md +0 -3
  126. data/templates/descriptions/js_driver.md +0 -4
  127. data/templates/descriptions/json.md +0 -1
  128. data/templates/descriptions/lint.md +0 -3
  129. data/templates/descriptions/manifest.md +0 -2
  130. data/templates/descriptions/profiler.md +0 -7
  131. data/templates/descriptions/pull_requests.md +0 -4
  132. data/templates/descriptions/runner.md +0 -10
  133. data/templates/descriptions/single_redirect.md +0 -1
  134. data/templates/descriptions/static.md +0 -5
  135. data/templates/descriptions/stylelint.md +0 -3
  136. data/templates/descriptions/stylesheet_base.md +0 -1
  137. data/templates/descriptions/testing.md +0 -9
  138. data/templates/descriptions/timeout.md +0 -4
  139. data/templates/descriptions/views.md +0 -8
  140. data/templates/email.rb +0 -3
  141. data/templates/errors.rb +0 -35
  142. data/templates/flashes_helper.rb +0 -5
  143. data/templates/hound.yml +0 -15
  144. data/templates/json_encoding.rb +0 -1
  145. data/templates/oj.rb +0 -3
  146. data/templates/partials/ci_simplecov.rb +0 -14
  147. data/templates/partials/db_optimizations_configuration.rb +0 -7
  148. data/templates/partials/deployment_readme.md +0 -8
  149. data/templates/partials/email_smtp.rb +0 -2
  150. data/templates/partials/profiler_readme.md +0 -8
  151. data/templates/partials/pull_requests_config.rb +0 -5
  152. data/templates/partials/runner_readme.md +0 -31
  153. data/templates/partials/runner_setup.rb +0 -2
  154. data/templates/postcss.config.js +0 -8
  155. data/templates/postgresql_database.yml.erb +0 -20
  156. data/templates/rack_mini_profiler.rb +0 -7
  157. data/templates/rails_helper.rb +0 -25
  158. data/templates/sample_env +0 -12
  159. data/templates/secrets.yml +0 -8
  160. data/templates/smtp.rb +0 -9
  161. data/templates/spec_helper.rb +0 -25
  162. data/templates/suspenders_gitignore +0 -18
  163. data/templates/suspenders_layout.html.erb.erb +0 -23
  164. /data/{templates → lib/generators/templates/factories}/factories.rb +0 -0
  165. /data/{templates → lib/generators/templates/factories}/factory_bot_rspec.rb +0 -0
  166. /data/{templates → lib/generators/templates/inline_svg}/inline_svg.rb +0 -0
  167. /data/{templates → lib/generators/templates/lint}/stylelintrc.json +0 -0
  168. /data/{templates → lib/generators/templates/tasks}/dev.rake +0 -0
  169. /data/{templates → lib/generators/templates/testing}/action_mailer.rb +0 -0
  170. /data/{templates → lib/generators/templates/testing}/i18n.rb +0 -0
  171. /data/{templates/shoulda_matchers_config_rspec.rb → lib/generators/templates/testing/shoulda_matchers.rb} +0 -0
@@ -0,0 +1,148 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ <%- if scan_ruby? -%>
10
+ scan_ruby:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v4
16
+
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: .ruby-version
21
+ bundler-cache: true
22
+
23
+ - name: Scan for security vulnerabilities in Ruby dependencies
24
+ run: |
25
+ bin/rails bundle:audit:update
26
+ bin/rails bundle:audit
27
+ <% end -%>
28
+
29
+ <%- if scan_js? -%>
30
+ scan_js:
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - name: Checkout code
35
+ uses: actions/checkout@v4
36
+
37
+ - name: Set up Ruby
38
+ uses: ruby/setup-ruby@v1
39
+ with:
40
+ ruby-version: .ruby-version
41
+ bundler-cache: true
42
+
43
+ - name: Setup Node
44
+ uses: actions/setup-node@v4
45
+ with:
46
+ node-version-file: .node-version
47
+
48
+ - name: Install modules
49
+ run: yarn install
50
+
51
+ - name: Scan for security vulnerabilities in JavaScript dependencies
52
+ run: |
53
+ bin/importmap audit
54
+ yarn audit
55
+ <% end -%>
56
+
57
+ <%- if lint? -%>
58
+ lint:
59
+ runs-on: ubuntu-latest
60
+ steps:
61
+ - name: Checkout code
62
+ uses: actions/checkout@v4
63
+
64
+ - name: Set up Ruby
65
+ uses: ruby/setup-ruby@v1
66
+ with:
67
+ ruby-version: .ruby-version
68
+ bundler-cache: true
69
+
70
+ - name: Setup Node
71
+ uses: actions/setup-node@v4
72
+ with:
73
+ node-version-file: .node-version
74
+
75
+ - name: Install modules
76
+ run: yarn install
77
+
78
+ - name: Lint Ruby code for consistent style
79
+ run: bin/rails standard
80
+
81
+ - name: Lint front-end code for consistent style
82
+ run: yarn lint
83
+ <% end -%>
84
+
85
+ test:
86
+ runs-on: ubuntu-latest
87
+
88
+ services:
89
+ postgres:
90
+ image: postgres
91
+ env:
92
+ POSTGRES_USER: postgres
93
+ POSTGRES_PASSWORD: postgres
94
+ ports:
95
+ - 5432:5432
96
+ options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
97
+
98
+ # redis:
99
+ # image: redis
100
+ # ports:
101
+ # - 6379:6379
102
+ # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
103
+
104
+ steps:
105
+ - name: Install packages
106
+ run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable curl libjemalloc2 libvips postgresql-client libpq-dev
107
+
108
+ - name: Checkout code
109
+ uses: actions/checkout@v4
110
+
111
+ - name: Set up Ruby
112
+ uses: ruby/setup-ruby@v1
113
+ with:
114
+ ruby-version: .ruby-version
115
+ bundler-cache: true
116
+
117
+ <%- if using_node? -%>
118
+ - name: Setup Node
119
+ uses: actions/setup-node@v4
120
+ with:
121
+ node-version-file: .node-version
122
+
123
+ - name: Install modules
124
+ run: yarn install
125
+ <%- end -%>
126
+
127
+ - name: Run tests
128
+ env:
129
+ RAILS_ENV: test
130
+ DATABASE_URL: postgres://postgres:postgres@localhost:5432
131
+ # REDIS_URL: redis://localhost:6379/0
132
+ <%- if using_rspec? -%>
133
+ run: bin/rails db:setup spec
134
+ <%- else -%>
135
+ run: bin/rails db:setup test test:system
136
+ <%- end -%>
137
+
138
+ - name: Keep screenshots from failed system tests
139
+ uses: actions/upload-artifact@v4
140
+ if: failure()
141
+ with:
142
+ name: screenshots
143
+ <%- if using_rspec? -%>
144
+ path: ${{ github.workspace }}/tmp/capybara
145
+ <%- else -%>
146
+ path: ${{ github.workspace }}/tmp/screenshots
147
+ <%- end -%>
148
+ if-no-files-found: ignore
@@ -0,0 +1,7 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: '/'
5
+ schedule:
6
+ interval: daily
7
+ open-pull-requests-limit: 10
@@ -0,0 +1,11 @@
1
+ class EmailInterceptor
2
+ include ActiveSupport::Configurable
3
+
4
+ config_accessor :interceptor_addresses, default: []
5
+
6
+ def self.delivering_email(message)
7
+ to = interceptor_addresses
8
+
9
+ message.to = to if to.any?
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require "rails_helper"
2
+
3
+ RSpec.describe "Factories" do
4
+ it "has valid factoties" do
5
+ FactoryBot.lint traits: true
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require "test_helper"
2
+
3
+ class FactoryBotsTest < ActiveSupport::TestCase
4
+ class FactoryLintingTest < FactoryBotsTest
5
+ test "linting of factories" do
6
+ FactoryBot.lint traits: true
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,94 @@
1
+ # Contributing
2
+
3
+ ## Accessibility Tooling
4
+
5
+ Building accessible applications is a complex, multi-faceted, and mission critical endeavor. While tooling cannot guarantee an accessible experience, it can help raise the bar for the baseline experience in important ways.
6
+
7
+ In addition to the W3C's [WAI Overview][], [WAI Authoring Practices Guide][], and [WAI-ARIA Specification][], along with MDN's [Accessibility Documentation][], the [thoughtbot handbook][] includes some high-level technical guidance.
8
+
9
+ [WAI Overview]: https://www.w3.org/WAI/standards-guidelines/aria/
10
+ [WAI Authoring Practices Guide]: https://www.w3.org/WAI/ARIA/apg/
11
+ [WAI-ARIA Specification]: https://www.w3.org/TR/wai-aria/
12
+ [Accessibility Documentation]: https://developer.mozilla.org/en-US/docs/Web/Accessibility
13
+ [thoughtbot guides]: https://github.com/thoughtbot/guides/blob/main/accessibility/README.md#development
14
+
15
+ ### Capybara and the System Test Suite
16
+
17
+ [Capybara][] is responsible for driving the application's [System Test][] suite through Real Life browser sessions.
18
+
19
+ Capybara drives the page and makes assertions about its state and content through utilities called [Selectors][]. They're a layer of abstraction that's a blend of HTML tag names and ARIA role semantics. For example, Capybara uses the `:link` selector whether it needs to locate and click on an `<a>` element through a call to [click_link][] or make an assertion about the presence and content of an `<a>` element through a call to [assert_link][].
20
+
21
+ Out of the box, Capybara provides a wide range of [built-in selectors][] that cover the majority of a System Test harness' needs. In addition to the out of the box selectors, this project also depends on the [capybara_accessible_selectors][] gem to expand Capybara's set of selectors.
22
+
23
+ If you find yourself in a situation where you're reaching for CSS selectors or other means of resolving nodes, you might benefit from a built-in selector or one provided by `capybara_accessible_selectors`. Take this test block, for example:
24
+
25
+ ```ruby
26
+ # <fieldset class="some-css selector-chain">
27
+ # <legend>Some fields</legend>
28
+ #
29
+ # <button class="my-button">Click me</button>
30
+ #
31
+ # <label>
32
+ # Fill me in
33
+ # <input class=".my-text-field">
34
+ # </label>
35
+ # </fieldset>
36
+
37
+ # BEFORE
38
+ within ".some-css .selector-chain" do
39
+ find(".my-button").click
40
+ find(".my-text-field").set "Hello, world"
41
+ end
42
+
43
+ # AFTER
44
+ within :fieldset, "Some field" do
45
+ click_button "Click me"
46
+ fill_in "Fill me in", with: "Hello, world"
47
+ end
48
+ ```
49
+
50
+ The [Testing RSpec][] section of the `thoughtbot/guides` provides some general guidance for automated Acceptance Testing.
51
+
52
+ [Capybara]: https://rubydoc.info/github/teamcapybara/capybara/master/
53
+ [System Test]: https://guides.rubyonrails.org/testing.html#system-testing
54
+ [Selectors]: https://rubydoc.info/github/teamcapybara/capybara/master#selectors
55
+ [click_link]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions:click_link
56
+ [assert_link]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Minitest/Assertions:assert_link
57
+ [built-in selectors]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Selector#built-in-selectors
58
+ [capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors
59
+ [Testing RSpec]: https://github.com/thoughtbot/guides/blob/main/testing-rspec/README.md#acceptance-tests
60
+
61
+ ### `capybara_accessibility_audit` and `axe.js`
62
+
63
+ This project depends on the [capybara_accessibility_audit][] gem to enhance the application's System Test suite to audit the browser's DOM for statically detectable accessibility violations. Under the hood, `capybara_accessibility_audit` utilizes [axe.js][] for auditing.
64
+
65
+ The categories of violation that `capybara_accessibility_audit` can detect span a wide range from insufficient [color contrast][] to invalid or insufficient [landmark-based information hierarchy][landmark], to [unnamed form controls][] and beyond.
66
+
67
+ Out of the box, `capybara_accessibility_audit` will extend Capybara to conduct an accessibility audit after a variety of actions like `visit` and `click_link`. That project can [be configured to suit this application's needs][capybara_accessibility_audit-configuration].
68
+
69
+ If you can integrate `capybara_accessibility_audit` from the project's inception, you can start with (and maintain!) accessibility violation bankruptcy.
70
+
71
+ [capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit
72
+ [capybara_accessibility_audit-configuration]: https://github.com/thoughtbot/capybara_accessibility_audit?tab=readme-ov-file#frequently-asked-questions
73
+ [axe.js]: https://www.deque.com/axe/
74
+ [color contrast]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast
75
+ [landmark]: https://developer.mozilla.org/en-US/blog/aria-accessibility-html-landmark-roles/
76
+ [unnamed form controls]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Text_labels_and_names#form_elements_must_be_labeled
77
+
78
+ ### VoiceOver on macos
79
+
80
+ VoiceOver is a screen reader integrated directly into the macOS operating system. You can learn more from [Apple's Accessibility Support][].
81
+
82
+ VoiceOver and Safari are tightly integrated. If you're developing this
83
+ application on a Mac, you should familiarize yourself with how to navigate in
84
+ Safari using VoiceOver. You can learn more about how to use VoiceOver from the
85
+ [Get started with VoiceOver on Mac][]. You might also enjoy [Screen Reader
86
+ Basics: VoiceOver][] in the A11ycasts series of videos from the "Chrome for Developers" YouTube channel.
87
+
88
+ [![Watch Screen Reader Basics: VoiceOver](https://img.youtube.com/vi/5R-6WvAihms/maxresdefault.jpg)](https://www.youtube.com/watch?v=5R-6WvAihms)
89
+
90
+ After you've written a System Test or have completed a feature, it can be **extremely** valuable to navigate to that part of the application and try your best to recreate the experience based on keyboard navigation and screen reader announcements alone.
91
+
92
+ [Apple's Accessibility Support]: https://support.apple.com/accessibility
93
+ [Get started with VoiceOver on Mac]: https://support.apple.com/guide/voiceover/get-started-vo4be8816d70/10/mac/14.0
94
+ [Screen Reader Basics: VoiceOver]: https://www.youtube.com/watch?v=5R-6WvAihms
@@ -0,0 +1,2 @@
1
+ ---
2
+ allow_single_quoted_attributes: false
@@ -0,0 +1,9 @@
1
+ Rails.configuration.to_prepare do
2
+ if Rails.env.test?
3
+ require "better_html"
4
+
5
+ BetterHtml.config = BetterHtml::Config.new(Rails.configuration.x.better_html)
6
+
7
+ BetterHtml.config.template_exclusion_filter = proc { |filename| !filename.start_with?(Rails.root.to_s) }
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ ---
2
+ glob: "app/views/**/*.{html,turbo_stream}{+*,}.erb"
3
+
4
+ linters:
5
+ AllowedScriptType:
6
+ enabled: true
7
+ allowed_types:
8
+ - "module"
9
+ - "text/javascript"
10
+ ErbSafety:
11
+ enabled: true
12
+ better_html_config: "config/better_html.yml"
13
+ GitHub::Accessibility::AvoidBothDisabledAndAriaDisabledCounter:
14
+ enabled: true
15
+ GitHub::Accessibility::AvoidGenericLinkTextCounter:
16
+ enabled: true
17
+ GitHub::Accessibility::DisabledAttributeCounter:
18
+ enabled: true
19
+ GitHub::Accessibility::IframeHasTitleCounter:
20
+ enabled: true
21
+ GitHub::Accessibility::ImageHasAltCounter:
22
+ enabled: true
23
+ GitHub::Accessibility::LandmarkHasLabelCounter:
24
+ enabled: true
25
+ GitHub::Accessibility::LinkHasHrefCounter:
26
+ enabled: true
27
+ GitHub::Accessibility::NestedInteractiveElementsCounter:
28
+ enabled: true
29
+ GitHub::Accessibility::NoAriaLabelMisuseCounter:
30
+ enabled: true
31
+ GitHub::Accessibility::NoPositiveTabIndexCounter:
32
+ enabled: true
33
+ GitHub::Accessibility::NoRedundantImageAltCounter:
34
+ enabled: true
35
+ GitHub::Accessibility::NoTitleAttributeCounter:
36
+ enabled: true
37
+ GitHub::Accessibility::SvgHasAccessibleTextCounter:
38
+ enabled: true
39
+ Rubocop:
40
+ enabled: true
41
+ rubocop_config:
42
+ inherit_from:
43
+ - .rubocop.yml
44
+
45
+ Lint/EmptyBlock:
46
+ Enabled: false
47
+ Layout/InitialIndentation:
48
+ Enabled: false
49
+ Layout/TrailingEmptyLines:
50
+ Enabled: false
51
+ Layout/TrailingWhitespace:
52
+ Enabled: false
53
+ Layout/LeadingEmptyLines:
54
+ Enabled: false
55
+ Style/FrozenStringLiteralComment:
56
+ Enabled: false
57
+ Style/MultilineTernaryOperator:
58
+ Enabled: false
59
+ Lint/UselessAssignment:
60
+ Exclude:
61
+ - "app/views/**/*"
62
+
63
+ EnableDefaultLinters: true
@@ -0,0 +1,47 @@
1
+ module ERBLint
2
+ module RakeSupport
3
+ # Allow command line flags set in STANDARDOPTS (like MiniTest's TESTOPTS)
4
+ def self.argvify
5
+ if ENV["ERBLINTOPTS"]
6
+ ENV["ERBLINTOPTS"].split(/\s+/)
7
+ else
8
+ []
9
+ end
10
+ end
11
+
12
+ # DELETE THIS FILE AFTER MERGE:
13
+ #
14
+ # * https://github.com/Shopify/better-html/pull/95
15
+ #
16
+ def self.backport!
17
+ BetterHtml::TestHelper::SafeErb::AllowedScriptType::VALID_JAVASCRIPT_TAG_TYPES.push("module")
18
+ end
19
+ end
20
+ end
21
+
22
+ desc "Lint templates with erb_lint"
23
+ task "erblint" do
24
+ require "erb_lint/cli"
25
+ require "erblint-github/linters"
26
+
27
+ ERBLint::RakeSupport.backport!
28
+
29
+ cli = ERBLint::CLI.new
30
+ success = cli.run(ERBLint::RakeSupport.argvify + ["--lint-all", "--format=compact"])
31
+ fail unless success
32
+ end
33
+
34
+ desc "Lint and automatically fix templates with erb_lint"
35
+ task "erblint:autocorrect" do
36
+ require "erb_lint/cli"
37
+ require "erblint-github/linters"
38
+
39
+ ERBLint::RakeSupport.backport!
40
+
41
+ cli = ERBLint::CLI.new
42
+ success = cli.run(ERBLint::RakeSupport.argvify + ["--lint-all", "--autocorrect"])
43
+ fail unless success
44
+ end
45
+
46
+ task "standard" => "erblint"
47
+ task "standard:fix" => "erblint:autocorrect"
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": ["@thoughtbot/eslint-config/prettier"],
3
+ "parserOptions": {
4
+ "ecmaVersion": "latest",
5
+ "sourceType": "module"
6
+ }
7
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "app",
3
+ "private": "true"
4
+ }
@@ -0,0 +1 @@
1
+ vendor/bundle/**
@@ -0,0 +1,11 @@
1
+ {
2
+ "singleQuote": true,
3
+ "overrides": [
4
+ {
5
+ "files": ["**/*.css", "**/*.scss", "**/*.html"],
6
+ "options": {
7
+ "singleQuote": false
8
+ }
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,7 @@
1
+ AllCops:
2
+ TargetRubyVersion: <%= RUBY_VERSION %>
3
+
4
+ require: standard
5
+
6
+ inherit_gem:
7
+ standard: config/base.yml
@@ -0,0 +1 @@
1
+ <%= node_version %>
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ require "fileutils"
3
+ require "bundler"
4
+
5
+ # path to your application root.
6
+ APP_ROOT = File.expand_path("..", __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args, exception: true)
10
+ end
11
+
12
+ def using_node?
13
+ File.exist? "package.json"
14
+ end
15
+
16
+ FileUtils.chdir APP_ROOT do
17
+ puts "== Installing dependencies =="
18
+ system! "gem install bundler --conservative"
19
+ system("bundle check") || system!("bundle install")
20
+ system("yarn install --check-files") if using_node?
21
+
22
+ puts "\n== Preparing database and adding development seed data =="
23
+ if File.exist? "lib/tasks/dev.rake"
24
+ system! "bin/rails dev:prime"
25
+ else
26
+ system! "bin/rails db:prepare"
27
+ end
28
+
29
+ if Bundler.rubygems.find_name("sprockets")
30
+ puts "\n== Generating assets =="
31
+ system! "bin/rails assets:clobber assets:precompile"
32
+ end
33
+
34
+ puts "\n== Removing old logs and tempfiles =="
35
+ system! "bin/rails log:clear tmp:clear"
36
+
37
+ puts "\n== Restarting application server =="
38
+ system! "bin/rails restart"
39
+ end
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ plugins: [
3
+ require('postcss-import'),
4
+ require('postcss-nesting'),
5
+ require('autoprefixer'),
6
+ require('postcss-url')({
7
+ url: 'copy',
8
+ assetsPath: 'app/assets/static'
9
+ })
10
+ ],
11
+ }
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each, type: :system) do
3
+ driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ <% if flash.any? %>
2
+ <div class="flashes">
3
+ <% flash.each do |type, message| -%>
4
+ <div class="flash-<%= type %>"><%= message %></div>
5
+ <% end -%>
6
+ </div>
7
+ <% end %>
@@ -0,0 +1,54 @@
1
+ def node_version
2
+ ENV["NODE_VERSION"] || `node --version`[/\d+\.\d+\.\d+/]
3
+ end
4
+
5
+ def node_not_installed?
6
+ !node_version.present?
7
+ end
8
+
9
+ def node_version_unsupported?
10
+ node_version < "20.0.0"
11
+ end
12
+
13
+ def apply_template!
14
+ if node_not_installed? || node_version_unsupported?
15
+ message = <<~ERROR
16
+
17
+
18
+ === Node version unsupported ===
19
+
20
+ Suspenders requires Node >= 20.0.0
21
+ ERROR
22
+
23
+ fail Rails::Generators::Error, message
24
+ end
25
+ if options[:database] == "postgresql" && options[:skip_test]
26
+ after_bundle do
27
+ gem_group :development, :test do
28
+ gem "suspenders", github: "thoughtbot/suspenders"
29
+ end
30
+
31
+ run "bundle install"
32
+
33
+ generate "suspenders:install:web"
34
+ rails_command "db:prepare"
35
+
36
+ say "\nCongratulations! You just pulled our suspenders."
37
+ end
38
+ else
39
+ message = <<~ERROR
40
+
41
+
42
+ === Please use the correct options ===
43
+
44
+ rails new <app_name> \\
45
+ --skip-test \\
46
+ -d=postgresql \\
47
+ -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
48
+ ERROR
49
+
50
+ fail Rails::Generators::Error, message
51
+ end
52
+ end
53
+
54
+ apply_template!