Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suspenders 3.0.0 #1135

Merged
merged 71 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
0ff6cc0
Suspenders 3.0.0
stevepolitodesign Oct 14, 2023
6bd58f2
Introduce test helpers
stevepolitodesign Oct 19, 2023
84e0c95
Introduce `mocha`
stevepolitodesign Oct 27, 2023
5a6b6e4
Introduce `suspenders:accessibility` generator (#1137)
stevepolitodesign Nov 3, 2023
5ff19c5
Introduce `./bin/rails` to fix broken test runner (#1139)
stevepolitodesign Nov 9, 2023
47bef29
Introduce `suspenders:inline_svg` generator (#1140)
crackofdusk Nov 13, 2023
dbb1f98
./bin/rails -> bin/rails (#1141)
Nov 13, 2023
04ea752
Use "ruby" as the PLATFORM for Gemfile.lock (#1142)
Nov 14, 2023
4f20aa8
Introduce `suspenders:factories` generator (#1136)
stevepolitodesign Nov 17, 2023
6f1ec09
Remove implementation detail from `NEWS`
stevepolitodesign Nov 17, 2023
74603ad
Introduce `suspenders:advisories` generator (#1138)
stevepolitodesign Nov 28, 2023
1a03e95
Introduce `suspenders:styles` generator (#1145)
stevepolitodesign Nov 28, 2023
6bed72e
Modify `suspenders:styles` (#1146)
stevepolitodesign Nov 28, 2023
cb5dff8
Introduce suspenders:jobs generator (#1147)
laicuRoot Dec 6, 2023
81e0e68
Fix stylelint violations (#1150)
stevepolitodesign Dec 11, 2023
fe5fc93
Introduce 'suspenders:lint` generator (#1148)
stevepolitodesign Dec 11, 2023
551d60b
Introduce `suspenders:rake` generator (#1144)
stevepolitodesign Dec 12, 2023
8628dcb
Fix stylelint violations when using Tailwind (#1153)
stevepolitodesign Dec 12, 2023
51dcd4b
Introduce `suspenders:views` generator (#1154)
stevepolitodesign Jan 10, 2024
b065ae9
Introduce `suspenders:setup` generator (#1157)
stevepolitodesign Feb 16, 2024
c16e593
Clean up `suspenders:setup` (#1159)
stevepolitodesign Feb 16, 2024
63fa9cd
Introduce `suspenders:tasks` generator (#1160)
stevepolitodesign Feb 20, 2024
647bb4c
Introduce `suspenders:db:migrate` task (#1161)
stevepolitodesign Feb 20, 2024
fc8793d
Introduce `suspenders:email` generator (#1162)
stevepolitodesign Feb 28, 2024
9f624b1
Update front-end linting dependencies (#1163)
stevepolitodesign Mar 1, 2024
3b3712d
Disable Turbo's InstantClick (#1164)
stevepolitodesign Mar 8, 2024
0da07ad
Introduce `suspenders:testing` generator (#1156)
stevepolitodesign Mar 8, 2024
f3f4480
Setup Generator: Remove call to `test:prepare` (#1166)
stevepolitodesign Mar 21, 2024
39efb28
Lint Generator: Remove generated test/spec files (#1167)
stevepolitodesign Mar 21, 2024
8b8ecb9
Testing Generator: Improvements (#1168)
stevepolitodesign Mar 21, 2024
7866a7b
Styles Generator: Drop support for Tailwind (#1169)
stevepolitodesign Mar 22, 2024
87d1f5a
Lint Generator: Introduce `.prettierignore` (#1170)
stevepolitodesign Mar 22, 2024
52e99e9
Introduce `suspenders:prerequisites` generator (#1171)
stevepolitodesign Mar 22, 2024
5f90074
Introduce `suspenders:ci` generator (#1172)
stevepolitodesign Mar 23, 2024
eb6b1c1
CI Generator: Fix indentation and linting violations. (#1173)
stevepolitodesign Mar 23, 2024
ec2e811
Fix linting violations (#1175)
stevepolitodesign Mar 25, 2024
c7d3550
Fix additional linting violations (#1176)
stevepolitodesign Mar 25, 2024
97f1883
Fix missing linting violation (#1177)
stevepolitodesign Mar 25, 2024
e7926f1
Lint Generator: No longer fix violations after invocation (#1174)
stevepolitodesign Mar 25, 2024
a40d457
CI: Breakout jobs and support Ruby 3.3.0 (#1178)
stevepolitodesign Mar 26, 2024
f76fb25
Lint Generator: Handling missing `package.json` (#1179)
stevepolitodesign Mar 26, 2024
f6c6f45
Introduce `suspenders:cleanup:organize_gemfile` task (#1181)
stevepolitodesign Apr 2, 2024
667b7ae
Introduce `suspenders:production:environment` generator (#1151)
crackofdusk Apr 5, 2024
5a733e0
Introduce `suspenders:test:environment` generator (#1182)
stevepolitodesign Apr 5, 2024
7d666ca
Introduce `suspenders:development:environment` generator (#1149)
crackofdusk Apr 5, 2024
56b316c
Clean Up: Use `Environments` namespace (#1184)
stevepolitodesign Apr 5, 2024
1c9134f
Test Cleanup: Improve test setup (#1183)
stevepolitodesign Apr 5, 2024
8edaa4b
AccessibilityGenerator: Update gem declaration (#1185)
stevepolitodesign Apr 8, 2024
473e483
Rakefile: Conditionally require local dependencies (#1186)
stevepolitodesign Apr 9, 2024
08be1dd
Dynamically generate README (#1187)
stevepolitodesign Apr 13, 2024
c694b2a
Test Cleanup: Refactor tests to use helper (#1188)
stevepolitodesign Apr 13, 2024
e8eb46a
Introduce `suspenders:install:web` generator and application template…
stevepolitodesign Apr 14, 2024
5b133e7
Styles Generator: Install `postcss-url` (#1191)
stevepolitodesign Apr 19, 2024
f62c516
Lint Generator: Account for breaking changes in ESLint (#1192)
stevepolitodesign Apr 19, 2024
7952880
Test Cleanup: Update bundle assertions (#1193)
stevepolitodesign Apr 19, 2024
5433da2
Test Cleanup: Remove generator description tests (#1194)
stevepolitodesign Apr 19, 2024
ea9553c
Generated README: Titleize app name (#1195)
stevepolitodesign Apr 22, 2024
2c8616a
Jobs Generator: Remove obsolete configuration (#1197)
stevepolitodesign Apr 24, 2024
fc1c08e
Generators: Update descriptions (#1198)
stevepolitodesign Apr 26, 2024
a3e5a77
Documentation: Update README and CONTRIBUTING (#1199)
stevepolitodesign Apr 26, 2024
f9a702a
Install Generator: Generate `CONTRIBUTING.md` (#1196)
stevepolitodesign Apr 26, 2024
a175e7a
README: Update installation script
stevepolitodesign May 2, 2024
a38f247
NEWS: Document introduction of application template
stevepolitodesign May 2, 2024
4def0ae
LICENSE: Remove year and duplicate file
stevepolitodesign May 2, 2024
7bf6e82
Prerequisites: Use system version of Node (#1201)
stevepolitodesign May 7, 2024
69e5fd7
Prerequisites: Raise if Node version unsupported (#1202)
stevepolitodesign May 8, 2024
47199bf
Documentation: List requirements
stevepolitodesign May 8, 2024
1b1795a
Account for TOCTOU bug
stevepolitodesign May 9, 2024
aceb0e2
Depend on Ruby 3.3.1
stevepolitodesign May 9, 2024
088c1b9
Test: Suppress Node warnings
stevepolitodesign May 9, 2024
721f387
Template: Point gem to `main`
stevepolitodesign May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Introduce 'suspenders:lint` generator (#1148)
Closes #1107
Closes #1143

Creates a holistic linting solution that covers JavaScript, CSS, Ruby
and ERB.

Introduces [scripts][] that leverage [@thoughtbot/eslint-config][],
[@thoughtbot/stylelint-config][] and [prettier][].

Also introduces `.prettierrc` based off of our [Guides][].

We need to pin `stylelint` and `@thoughtbot/stlyelint-config` to
specific versions to account for this [open issue][]. Unfortunately,
running `yarn run lint:stylelint` results in deprecation warnings, which
will need to be addressed separately.

[scripts]: https://docs.npmjs.com/cli/v6/using-npm/scripts
[@thoughtbot/eslint-config]: https://github.com/thoughtbot/eslint-config
[@thoughtbot/stylelint-config]: https://github.com/thoughtbot/stylelint-config
[prettier]: https://prettier.io
[Guides]: https://github.com/thoughtbot/guides/blob/main/javascript/README.md#formatting
[open issue]: thoughtbot/stylelint-config#46

Introduces `rake standard` which also runs `erblint` to lint ERB files
via [better_html][], [erb_lint][] and [erblint-github][].

[better_html]: https://github.com/Shopify/better-html
[erb_lint]: https://github.com/Shopify/erb-lint
[erblint-github]: https://github.com/github/erblint-github

A future commit will ensure these linting rules are run during CI. In an
effort to support that future commit, we ensure to run `yarn run
fix:prettier` and `bundle exec standard:fix_unsafely` once the generator
is complete. Otherwise, CI would fail because of linting violations.

We call `standard:fix_unsafely` since `standard:fix` returns an error
status code on new Rails applications. Running `standard:fix_unsafely`
fixes this issue and returns a success status code.

It should be noted that we deliberately permit this generator to be
invoked on API only applications, because those applications can still
contain views, like ones used for mailers. However, a future commit could
explore removing the JavaScript linters.

Also improves the developer experience by introducing `with_test_suite`
helper, allowing the caller to run the generator in an application using
minitest or RSpec.
  • Loading branch information
stevepolitodesign committed Dec 11, 2023
commit fe5fc93bfa582b0368e92ecbc4cb034661dea54a
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Unreleased
* Introduce `suspenders:advisories` generator
* Introduce `suspenders:styles` generator
* Introduce `suspenders:jobs` generator
* Introduce `suspenders:lint` generator

20230113.0 (January, 13, 2023)

Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ improvement for the viewer.

[inline_svg]: https://github.com/jamesmartin/inline_svg

### Lint

Creates a holistic linting solution that covers JavaScript, CSS, Ruby and ERB.

Introduces NPM commands that leverage [@thoughtbot/eslint-config][],
[@thoughtbot/stylelint-config][] and [prettier][].

Also introduces `.prettierrc` based off of our [Guides][].

Introduces `rake standard` which also runs `erblint` to lint ERB files
via [better_html][], [erb_lint][] and [erblint-github][].

[@thoughtbot/eslint-config]: https://github.com/thoughtbot/eslint-config
[@thoughtbot/stylelint-config]: https://github.com/thoughtbot/stylelint-config
[prettier]: https://prettier.io
[Guides]: https://github.com/thoughtbot/guides/blob/main/javascript/README.md#formatting
[better_html]: https://github.com/Shopify/better-html
[erb_lint]: https://github.com/Shopify/erb-lint
[erblint-github]: https://github.com/github/erblint-github

### Styles

Configures applications to use [PostCSS][] or [Tailwind][] via
Expand Down
77 changes: 77 additions & 0 deletions lib/generators/suspenders/lint_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
module Suspenders
module Generators
class LintGenerator < Rails::Generators::Base
include Suspenders::Generators::Helpers

source_root File.expand_path("../../templates/lint", __FILE__)
desc "Creates a holistic linting solution that covers JavaScript, CSS, Ruby and ERB."

def install_dependencies
run "yarn add stylelint@^15.10.1 eslint @thoughtbot/[email protected] @thoughtbot/eslint-config npm-run-all prettier --dev"
end

def install_gems
gem_group :development, :test do
gem "better_html", require: false
gem "erb_lint", require: false
gem "erblint-github", require: false
gem "standard"
end
Bundler.with_unbundled_env { run "bundle install" }
end

def configure_stylelint
copy_file "stylelintrc.json", ".stylelintrc.json"
end

def configure_eslint
copy_file "eslintrc.json", ".eslintrc.json"
end

def configure_prettier
copy_file "prettierrc", ".prettierrc"
end

def configure_erb_lint
copy_file "erb-lint.yml", ".erb-lint.yml"
copy_file "config_better_html.yml", "config/better_html.yml"
copy_file "config_initializers_better_html.rb", "config/initializers/better_html.rb"
copy_file "erblint.rake", "lib/tasks/erblint.rake"
template "rubocop.yml.tt", ".rubocop.yml"

if default_test_suite?
copy_file "better_html_test.rb", "test/views/better_html_test.rb"
elsif rspec_test_suite?
copy_file "better_html_spec.rb", "spec/views/better_html_spec.rb"
end
end

def update_package_json
content = File.read package_json
json = JSON.parse content
json["scripts"] ||= {}

json["scripts"]["lint"] = "run-p lint:eslint lint:stylelint lint:prettier"
json["scripts"]["lint:eslint"] = "eslint --max-warnings=0 --no-error-on-unmatched-pattern 'app/javascript/**/*.js'"
json["scripts"]["lint:stylelint"] = "stylelint 'app/assets/stylesheets/**/*.css'"
json["scripts"]["lint:prettier"] = "prettier --check '**/*' --ignore-unknown"
json["scripts"]["fix:prettier"] = "prettier --write '**/*' --ignore-unknown"

File.write package_json, JSON.pretty_generate(json)
end

# This needs to be the last method definition to ensure everything is
# properly configured
def fix_violations
run "yarn run fix:prettier"
run "bundle exec rake standard:fix_unsafely"
end

private

def package_json
Rails.root.join("package.json")
end
end
end
end
17 changes: 17 additions & 0 deletions lib/generators/templates/lint/better_html_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require "spec_helper"

describe "ERB Implementation" do
def self.erb_lint
configuration = ActiveSupport::ConfigurationFile.parse(".erb-lint.yml")

ActiveSupport::OrderedOptions.new.merge!(configuration.deep_symbolize_keys!)
end

Rails.root.glob(erb_lint.glob).each do |template|
it "raises no html errors in #{template.relative_path_from(Rails.root)}" do
validator = BetterHtml::BetterErb::ErubiImplementation.new(template.read)

validator.validate!
end
end
end
17 changes: 17 additions & 0 deletions lib/generators/templates/lint/better_html_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require "test_helper"

class ErbImplementationTest < ActiveSupport::TestCase
def self.erb_lint
configuration = ActiveSupport::ConfigurationFile.parse(".erb-lint.yml")

ActiveSupport::OrderedOptions.new.merge!(configuration.deep_symbolize_keys!)
end

Rails.root.glob(erb_lint.glob).each do |template|
test "html errors in #{template.relative_path_from(Rails.root)}" do
validator = BetterHtml::BetterErb::ErubiImplementation.new(template.read)

validator.validate!
end
end
end
2 changes: 2 additions & 0 deletions lib/generators/templates/lint/config_better_html.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
allow_single_quoted_attributes: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Rails.configuration.to_prepare do
if Rails.env.test?
require "better_html"

BetterHtml.config = BetterHtml::Config.new(Rails.configuration.x.better_html)

BetterHtml.config.template_exclusion_filter = proc { |filename| !filename.start_with?(Rails.root.to_s) }
end
end
63 changes: 63 additions & 0 deletions lib/generators/templates/lint/erb-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
glob: "app/views/**/*.{html,turbo_stream}{+*,}.erb"

linters:
AllowedScriptType:
enabled: true
allowed_types:
- "module"
- "text/javascript"
ErbSafety:
enabled: true
better_html_config: "config/better_html.yml"
GitHub::Accessibility::AvoidBothDisabledAndAriaDisabledCounter:
enabled: true
GitHub::Accessibility::AvoidGenericLinkTextCounter:
enabled: true
GitHub::Accessibility::DisabledAttributeCounter:
enabled: true
GitHub::Accessibility::IframeHasTitleCounter:
enabled: true
GitHub::Accessibility::ImageHasAltCounter:
enabled: true
GitHub::Accessibility::LandmarkHasLabelCounter:
enabled: true
GitHub::Accessibility::LinkHasHrefCounter:
enabled: true
GitHub::Accessibility::NestedInteractiveElementsCounter:
enabled: true
GitHub::Accessibility::NoAriaLabelMisuseCounter:
enabled: true
GitHub::Accessibility::NoPositiveTabIndexCounter:
enabled: true
GitHub::Accessibility::NoRedundantImageAltCounter:
enabled: true
GitHub::Accessibility::NoTitleAttributeCounter:
enabled: true
GitHub::Accessibility::SvgHasAccessibleTextCounter:
enabled: true
Rubocop:
enabled: true
rubocop_config:
inherit_from:
- .rubocop.yml

Lint/EmptyBlock:
Enabled: false
Layout/InitialIndentation:
Enabled: false
Layout/TrailingEmptyLines:
Enabled: false
Layout/TrailingWhitespace:
Enabled: false
Layout/LeadingEmptyLines:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: false
Style/MultilineTernaryOperator:
Enabled: false
Lint/UselessAssignment:
Exclude:
- "app/views/**/*"

EnableDefaultLinters: true
47 changes: 47 additions & 0 deletions lib/generators/templates/lint/erblint.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module ERBLint
module RakeSupport
# Allow command line flags set in STANDARDOPTS (like MiniTest's TESTOPTS)
def self.argvify
if ENV["ERBLINTOPTS"]
ENV["ERBLINTOPTS"].split(/\s+/)
else
[]
end
end

# DELETE THIS FILE AFTER MERGE:
#
# * https://github.com/Shopify/better-html/pull/95
#
def self.backport!
BetterHtml::TestHelper::SafeErb::AllowedScriptType::VALID_JAVASCRIPT_TAG_TYPES.push("module")
end
end
end

desc "Lint templates with erb_lint"
task "erblint" do
require "erb_lint/cli"
require "erblint-github/linters"

ERBLint::RakeSupport.backport!

cli = ERBLint::CLI.new
success = cli.run(ERBLint::RakeSupport.argvify + ["--lint-all", "--format=compact"])
fail unless success
end

desc "Lint and automatically fix templates with erb_lint"
task "erblint:autocorrect" do
require "erb_lint/cli"
require "erblint-github/linters"

ERBLint::RakeSupport.backport!

cli = ERBLint::CLI.new
success = cli.run(ERBLint::RakeSupport.argvify + ["--lint-all", "--autocorrect"])
fail unless success
end

task "standard" => "erblint"
task "standard:fix" => "erblint:autocorrect"
7 changes: 7 additions & 0 deletions lib/generators/templates/lint/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": ["@thoughtbot/eslint-config/prettier"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
}
}
11 changes: 11 additions & 0 deletions lib/generators/templates/lint/prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"singleQuote": true,
"overrides": [
{
"files": ["**/*.css", "**/*.scss", "**/*.html"],
"options": {
"singleQuote": false
}
}
]
}
7 changes: 7 additions & 0 deletions lib/generators/templates/lint/rubocop.yml.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
AllCops:
TargetRubyVersion: <%= RUBY_VERSION %>

require: standard

inherit_gem:
standard: config/base.yml
3 changes: 3 additions & 0 deletions lib/generators/templates/lint/stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@thoughtbot/stylelint-config"
}
Loading