In our Ruby guide we recommend using Standard. The gem describes itself as a Ruby style guide, linter, and formatter. It helps avoid the never-ending debates around code style by making decisions for us (I’m looking at you single vs double quotes!). It’s easy to use, consistent, avoids configuration and helps us write better styled and more consistent Ruby code.
As developers, we often write HTML when working with Ruby. It can be useful to
.erb templates to ensure consistency and catch errors. The
erb-lint gem from Shopify is a tool to lint our views. The linters enabled by
default are outlined in the documentation.
We can run both tools as part of CI. Here’s how to do that in GitHub Actions.
# .github/workflows/lint.yml name: Lint on: push jobs: lint: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true - name: Run Standard run: bundle exec standardrb - name: Run erb-lint run: bundle exec erblint --lint-all
Erb-lint can also run Rubocop to lint the Ruby code inside our views. The documentation demonstrates how to setup Rubocop linting with some basic configuration. But what about if we want to use Standard to lint the Ruby code in our views instead?
Running Standard with erb-lint
Standard documentation demonstrates how it can be used via Rubocop. We can add this to our erb-lint config and use Standard via Rubocop to lint the Ruby code in our views.
At the time of writing, there is a minor open issue with Rubocop that means all cops aren’t disabled by default. But we can override that setting manually, for now.
# .erb-lint.yml --- EnableDefaultLinters: true linters: Rubocop: enabled: true rubocop_config: require: standard inherit_gem: standard: config/base.yml AllCops: DisabledByDefault: true
One caveat of how erb-lint uses Rubocop is that the tool considers all Ruby code in isolation (i.e as though it were an individual Ruby file). This means we need to disable some of the Standard config in order to obtain sensible results.
To do this, we can inherit from another config file in addition to the Standard
gem. We disable 3 rules that make little or no sense when linting inline Ruby
code in an
Layout/TrailingEmptyLines: we don’t need trailing new lines when the Ruby code is inline.
Layout/InitialIndentation: the initial indentation might not be the start of the line when we write Ruby code in our views.
Lint/UselessAssignment: erb-lint cannot distinguish between useless and useful assignment, because it doesn’t retain any context. It can’t know whether or not a variable is subsequently used.
# .erb-lint.yml --- EnableDefaultLinters: true linters: Rubocop: enabled: true rubocop_config: require: standard inherit_gem: standard: config/base.yml + inherit_from: .erb-lint_rubocop.yml AllCops: DisabledByDefault: true
# .erb-lint_rubocop.yml Layout/TrailingEmptyLines: Enabled: false Layout/InitialIndentation: Enabled: false Lint/UselessAssignment: Enabled: false
Now we can lint our views including the Ruby code they contain using Standard - helping us to write better styled and more consistent code in our views!