Giter Site home page Giter Site logo

erb-lint's Introduction

ERB Lint Build Status

erb-lint is a tool to help lint your ERB or HTML files using the included linters or by writing your own.

Requirements

  • Ruby 2.3.0+
  • This is due to use of the safe navigation operator (&.)
  • This is also due to the use of the tilde-heredoc <<~ syntax in some tests.

Installation

gem install erb_lint

...or add the following to your Gemfile and run bundle install:

gem 'erb_lint', require: false

Configuration

Create a .erb-lint.yml file in your project, with the following structure:

---
EnableDefaultLinters: true
linters:
  ErbSafety:
    enabled: true
    better_html_config: .better-html.yml
  Rubocop:
    enabled: true
    rubocop_config:
      inherit_from:
        - .rubocop.yml

See below for linter-specific configuration options.

Usage

This gem provides a command-line interface which can be run like so:

  1. Run erblint [options] if the gem is installed standalone.
  2. Run bundle exec erblint [options] if the gem is installed as a Gemfile dependency for your app.

For example, erblint --lint-all --enable-all-linters will run all available linters on all ERB files in the current directory or its descendants (**/*.html{+*,}.erb).

If you want to change the glob & exclude that is used, you can configure it by adding it to your config file as follows:

---
glob: "**/*.{html,text,js}{+*,}.erb"
exclude:
  - '**/vendor/**/*'
  - '**/node_modules/**/*'
linters:
  ErbSafety:
    enabled: true
    better_html_config: .better-html.yml
  Rubocop:
    enabled: true
    rubocop_config:
      inherit_from:
        - .rubocop.yml

Make sure to add **/ to exclude patterns; it matches the target files' absolute paths.

Enable or disable default linters

EnableDefaultLinters: enables or disables default linters. Default linters are enabled by default.

Disable rule at offense-level

You can disable a rule by placing a disable comment in the following format:

Comment on offending lines

<hr /> <%# erblint:disable SelfClosingTag %>

To raise an error when there is a useless disable comment, enable NoUnusedDisable.

To disable inline comments and report all offenses, set --disable-inline-configs option.

Exclude

You can specify the exclude patterns both of global and lint-local.

---
exclude:
  - '**/global-lib/**/*'
linters:
  ErbSafety:
    exclude:
      - '**/local-lib/**/*'

Linters

Available Linters Default Description
AllowedScriptType Yes prevents the addition of <script> tags that have type attributes that are not in a white-list of allowed values
ClosingErbTagIndent Yes
CommentSyntax Yes detects bad ERB comment syntax
ExtraNewline Yes
FinalNewline Yes warns about missing newline at the end of a ERB template
NoJavascriptTagHelper Yes prevents the usage of Rails' javascript_tag
ParserErrors Yes
PartialInstanceVariable No detects instance variables in partials
RequireInputAutocomplete Yes warns about missing autocomplete attributes in input tags
RightTrim Yes enforces trimming at the right of an ERB tag
SelfClosingTag Yes enforces self closing tag styles for void elements
SpaceAroundErbTag Yes enforces a single space after <% and before %>
SpaceIndentation Yes
SpaceInHtmlTag Yes
TrailingWhitespace Yes
DeprecatedClasses No warns about deprecated css classes
ErbSafety No detects unsafe interpolation of ruby data into various javascript contexts and enforce usage of safe helpers like .to_json.
Rubocop No runs RuboCop rules on ruby statements found in ERB templates
RequireScriptNonce No warns about missing Content Security Policy nonces in script tags

DeprecatedClasses

DeprecatedClasses will find all classes used on HTML elements and report any classes that violate the rule set that you provide.

A rule_set is specified as a list, each with a set of deprecated classes and a corresponding suggestion to use as an alternative.

Example configuration:

---
linters:
  DeprecatedClasses:
    enabled: true
    exclude:
      - 'app/views/shared/deprecated/**'
    addendum: "See UX wiki for help."
    rule_set:
      - deprecated: ['badge[-_\w]*']
        suggestion: "Use the ui_badge() component instead."

You can specify an addendum to be added to the end of each violation. The error message format is: "Deprecated class ... #{suggestion}" or "Deprecated class ... #{suggestion} #{addendum}" if an addendum is present.

Linter-Specific Option Description
rule_set A list of rules, each with a deprecated and suggestion option.
deprecated A list of regular expressions which specify the classes deprecated by this rule.
suggestion A string to be included in the rule's error message. Make this informative and specific to the rule that it is contained in.
addendum A string to be included at the end of every error message of the rule set. (Optional)

FinalNewline

Files must have a final newline. This results in better diffs when adding lines to the file, since SCM systems such as git won't think that you touched the last line.

You can customize whether or not a final newline exists with the present option.

Example configuration:

---
linters:
  FinalNewline:
    enabled: true
Linter-Specific Option Description
present Whether a final newline should be present (default true)

ErbSafety

Runs the checks provided by better-html's erb safety test helper.

When using ERB interpolations in javascript contexts, this linter enforces the usage of safe helpers such as .to_json. See better-html's readme for more information.

Any ERB statement that does not call a safe helper is deemed unsafe and a violation is shown.

For example:

Not allowed ❌
<a onclick="alert(<%= some_data %>)">

Allowed ✅
<a onclick="alert(<%= some_data.to_json %>)">
Not allowed ❌
<script>var myData = <%= some_data %>;</script>

Allowed ✅
<script>var myData = <%= some_data.to_json %>;</script>

Example configuration:

---
linters:
  ErbSafety:
    enabled: true
    better_html_config: .better-html.yml
Linter-Specific Option Description
better_html_config Name of the configuration file to use for better-html. Optional. Valid options and their defaults are described in better-html's readme.

Rubocop

Runs RuboCop on all ruby statements found in ERB templates. The RuboCop configuration that erb-lint uses can inherit from the configuration that the rest of your application uses. erb-lint can be configured independently however, as it will often be necessary to disable specific RuboCop rules that do not apply to ERB files.

Note: Each ruby statement (between ERB tags <% ... %>) is parsed and analyzed independently of each other. Any rule that requires a broader context can trigger false positives (e.g. Lint/UselessAssignment will complaint for an assignment even if used in a subsequent ERB tag).

Example configuration:

---
linters:
  Rubocop:
    enabled: true
    rubocop_config:
      inherit_from:
        - .rubocop.yml
      Layout/InitialIndentation:
        Enabled: false
      Layout/LineLength:
        Enabled: false
      Layout/TrailingEmptyLines:
        Enabled: false
      Layout/TrailingWhitespace:
        Enabled: false
      Naming/FileName:
        Enabled: false
      Style/FrozenStringLiteralComment:
        Enabled: false
      Lint/UselessAssignment:
        Enabled: false
      Rails/OutputSafety:
        Enabled: false

The cops disabled in the example configuration above provide a good starting point.

Linter-Specific Option Description
rubocop_config A valid rubocop configuration hash. Mandatory when this cop is enabled. See rubocop's manual entry on Configuration
only Only run cops listed in this array instead of all cops.
config_file_path A path to a valid rubocop configuration file. When this is provided, rubocop_config will be ignored.

RequireInputAutocomplete

This linter prevents the usage of certain types of HTML <input> without an autocomplete argument: color, date, datetime-local, email, month, number, password, range, search, tel, text, time, url, or week. The HTML autocomplete helps users to complete filling in forms by using data stored in the browser. This is particularly useful for people with motor disabilities or cognitive impairment who may have difficulties filling out forms online.

Bad ❌
<input type="email" ...>
Good ✅
<input type="email" autocomplete="nope" ...>
<input type="email" autocomplete="email" ...>

RightTrim

Trimming at the right of an ERB tag can be done with either =%> or -%>, this linter enforces one of these two styles.

Example configuration:

---
linters:
  RightTrim:
    enabled: true
    enforced_style: '-'
Linter-Specific Option Description
enforced_style Which style to enforce, can be either - or =. Optional. Defaults to -.

SpaceAroundErbTag

Enforce a single space after <% and before %> in the ERB source. This linter ignores opening ERB tags (<%) that are followed by a newline, and closing ERB tags (%>) that are preceded by a newline.

Bad ❌
<%foo%>
<%=foo-%>

Good ✅
<% foo %>

<%
  foo
%>

Example configuration:

---
linters:
  SpaceAroundErbTag:
    enabled: true

NoJavascriptTagHelper

This linter prevents the usage of Rails' javascript_tag helper in ERB templates.

The html parser used in this gem knows not to look for html tags within certain other tags like script, style, and others. The html parser does this to avoid confusing javascript expressions like if (1<a || b>1) for a malformed html tag. Using the javascript_tag in a ERB template prevents the parser from recognizing the change of parsing context and may fail or produce erroneous output as a result.

Bad ❌
<%= javascript_tag(content, defer: true) %>
Good ✅
<script defer="true"><%== content %></script>

Bad ❌
<%= javascript_tag do %>
  alert(1)
<% end %>
Good ✅
<script>
  alert(1)
</script>

The autocorrection rule adds //<![CDATA[ and //]]> markers to the existing script, as this is the default behavior for javascript_tag. This can be disabled by changing the correction_style linter option from cdata to plain.

Example configuration:

---
linters:
  NoJavascriptTagHelper:
    enabled: true
    correction_style: 'plain'
Linter-Specific Option Description
correction_style When configured with cdata, adds CDATA markers. When configured with plain, don't add makers. Defaults to cdata.

RequireScriptNonce

This linter prevents the usage of HTML <script>, Rails javascript_tag, javascript_include_tag and javascript_pack_tag without a nonce argument. The purpose of such a check is to ensure that when content securty policy is implemented in an application, there is a means of discovering tags that need to be updated with a nonce argument to enable script execution at application runtime.

Bad ❌
<script>
    alert(1)
</script>
Good ✅
<script nonce="<%= request.content_security_policy_nonce %>" >
    alert(1)
</script>
Bad ❌
<%= javascript_tag do -%>
  alert(1)
<% end -%>
Good ✅
<%= javascript_tag nonce: true do -%>
  alert(1)
<% end -%>
Bad ❌
<%= javascript_include_tag "script" %>
Good ✅
<%= javascript_include_tag "script", nonce: true %>
Bad ❌
<%= javascript_pack_tag "script" %>
Good ✅
<%= javascript_pack_tag "script", nonce: true %>

SelfClosingTag

This linter enforces self closing tag styles for void elements.

The void elements are area, base, br, col, embed, hr, img, input, keygen, link, menuitem, meta, param, source, track, and wbr.

If enforced_style is set to always (XHTML style):

Bad ❌
<link rel="stylesheet" type="text/css" href="styles.css">
Good ✅
<img src="someimage.png" alt="Some Image" />

If enforced_style is set to never (HTML5 style):

Bad ❌
<hr />
Good ✅
<meta charset="UTF-8">

Example configuration:

---
linters:
  SelfClosingTag:
    enabled: true
    enforced_style: 'always'
Linter-Specific Option Description
enforced_style If we should always or never expect self closing tags for void elements. Defaults to never.

AllowedScriptType

This linter prevent the addition of <script> tags that have type attributes that are not in a white-list of allowed values.

It is common practice for web developers to use <script> tags with non-executable type attributes, such as application/json or text/html to pass arbitrary data into an html page. Despite not being executable, these tags are subject to the same parsing quirks as executable script tags, and it is therefore more difficult to prevent security issues from creeping in. Consider for instance an application where it is possible to inject the string </script><script> unescaped into a text/html tag, the application would be vulnerable to XSS.

This pattern can easily be replaced by <div> tags with data attributes that can just as easily be read from javascript, and have the added benefit of being safer. When content_tag(:div) or tag.div() is used to pass arbitrary user data into the html document, it becomes much harder to inadvertently introduce a security issue.

It may also be desirable to avoid typos in type attributes.

Bad ❌
<script type="text/javacsrïpt"></script>
Good ✅
<script type="text/javascript"></script>

By default, this linter allows the type attribute to be omitted, as the behavior in browsers is to consider <script> to be the same as <script type="text/javascript">. When the linter is configured with allow_blank: false, instances of <script> tags without a type will be auto-corrected to <script type="text/javascript">.

It may also be desirable to disallow <script> tags from appearing anywhere in your application. For instance, Rails applications can benefit from serving static javascript code from the asset pipeline, as well as other security benefits. The disallow_inline_scripts: true config option may be used for that purpose.

Example configuration:

---
linters:
  AllowedScriptType:
    enabled: true
    allowed_types:
      - 'application/json'
      - 'text/javascript'
      - 'text/html'
    allow_blank: false
    disallow_inline_scripts: false
Linter-Specific Option Description
allowed_types An array of allowed types. Defaults to ["text/javascript"].
allow_blank True or false, depending on whether or not the type attribute may be omitted entirely from a <script> tag. Defaults to true.
disallow_inline_scripts Do not allow inline <script> tags anywhere in ERB templates. Defaults to false.

CommentSyntax

This linter enforces the use of the correct ERB comment syntax, since Ruby comments (<% # comment %> with a space) are not technically valid ERB comments.

Bad ❌
<% # This is a Ruby comment %>
Good ✅
<%# This is an ERB comment %>

Bad ❌
<% # This is a Ruby comment; it can fail to parse. %>
Good ✅
<%# This is an ERB comment; it is parsed correctly. %>

Good ✅
<%
  # This is a multi-line ERB comment.
%>

Custom Linters

erb-lint allows you to create custom linters specific to your project. It will load linters from the .erb-linters directory in the root of your repository. See the linters directory for examples of how to write linters.

# .erb-linters/custom_linter.rb

module ERBLint
  module Linters
    class CustomLinter < Linter
      include LinterRegistry

      class ConfigSchema < LinterConfig
        property :custom_message, accepts: String
      end
      self.config_schema = ConfigSchema

      def run(processed_source)
        unless processed_source.file_content.include?('this file is fine')
          add_offense(
            processed_source.to_source_range(0 ... processed_source.file_content.size),
            "This file isn't fine. #{@config.custom_message}"
          )
        end
      end
    end
  end
end

By default, this linter would be disabled. You can enable it by adding an entry to .erb-lint.yml:

---
linters:
  CustomLinter:
    enabled: true
    custom_message: We suggest you change this file.

Test your linter by running erblint's command-line interface:

bundle exec erblint --enable-linters custom_linter --lint-all

Running this on a random project might yield this output:

Linting 15 files with 1 linters...

This file isn't fine. We suggest you change this file.
In file: app/views/layouts/application.html.erb:1

Errors were found in ERB files

To write a linter that can autocorrect offenses it detects, simply add an autocorrect method that returns a callable. The callable is called with an instance of RuboCop::Cop::Corrector as argument, and therefore erb-lint correctors work exactly as RuboCop correctors do.

def autocorrect(_processed_source, offense)
  lambda do |corrector|
    corrector.insert_after(offense.source_range, "this file is fine")
  end
end

Output formats

You can change the output format of ERB Lint by specifying formatters with the -f/--format option.

Multiline (default)

$ erblint
Linting 8 files with 12 linters...

Remove multiple trailing newline at the end of the file.
In file: app/views/users/show.html.erb:95

Remove newline before `%>` to match start of tag.
In file: app/views/subscriptions/index.html.erb:38

2 error(s) were found in ERB files

Compact

erblint --format compact
Linting 8 files with 12 linters...
app/views/users/show.html.erb:95:0: Remove multiple trailing newline at the end of the file.
app/views/users/_graph.html.erb:27:37: Extra space detected where there should be no space
2 error(s) were found in ERB files

JUnit

erblint --format junit
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="erblint" tests="2" failures="2">
  <properties>
    <property name="erb_lint_version" value="%{erb_lint_version}"/>
    <property name="ruby_engine" value="%{ruby_engine}"/>
    <property name="ruby_version" value="%{ruby_version}"/>
    <property name="ruby_patchlevel" value="%{ruby_patchlevel}"/>
    <property name="ruby_platform" value="%{ruby_platform}"/>
  </properties>
  <testcase name="app/views/subscriptions/_loader.html.erb" file="app/views/subscriptions/_loader.html.erb" lineno="1">
    <failure message="SpaceInHtmlTag: Extra space detected where there should be no space." type="SpaceInHtmlTag">
      <![CDATA[SpaceInHtmlTag: Extra space detected where there should be no space. at app/views/subscriptions/_loader.html.erb:1:7]]>
    </failure>
  </testcase>
  <testcase name="app/views/application/index.html.erb" file="app/views/subscriptions/_menu.html.erb"/>
</testsuite>

GitLab

Used by GitLab Code Quality.

[
   {
      "description":"Extra space detected where there should be no space.",
      "check_name":"SpaceInHtmlTag",
      "fingerprint":"5a259c7cafa2c9ca229dfd7d21536698",
      "severity":"info",
      "location":{
         "path":"app/views/subscriptions/_loader.html.erb",
         "lines":{
            "begin":1,
            "end":1
         }
      }
   },
   {
      "description":"Remove newline before `%\u003e` to match start of tag.",
      "check_name":"ClosingErbTagIndent",
      "fingerprint":"60b4ed2120c7abeebebb43fba4a19559",
      "severity":"warning",
      "location":{
         "path":"app/views/subscriptions/_loader.html.erb",
         "lines":{
            "begin":52,
            "end":54
         }
      }
   }
]

Caching

The cache is currently opt-in - to turn it on, use the --cache option:

erblint --cache ./app
Cache mode is on
Linting 413 files with 15 linters...
File names pruned from the cache will be logged

No errors were found in ERB files

Cached lint results are stored in the .erb-lint-cache directory by default, though a custom directory can be provided via the --cache-dir option. Cache filenames are computed with a hash of information about the file and erb-lint settings. These files store instance attributes of the CachedOffense object, which only contain the Offense attributes necessary to restore the results of running erb-lint for output. The cache also automatically prunes outdated files each time it's run.

You can also use the --clear-cache option to delete the cache file directory.

License

This project is released under the MIT license.

erb-lint's People

Contributors

adrianna-chang-shopify avatar almostwhitehat avatar andersonkrs avatar dependabot[bot] avatar edouard-chin avatar einstein- avatar etiennebarrie avatar exterm avatar george-ma avatar issyl0 avatar jen-taylor-shopify avatar jeremyhansonfinger avatar jhottenstein avatar justinthec avatar khiga8 avatar lastgabs avatar leighhalliday avatar mangoov avatar manuelpuyol avatar marcandre avatar michelle-gong avatar mikoto2000 avatar mvz avatar petergoldstein avatar pftg avatar rafaelfranca avatar samuelbeshara avatar thegedge avatar wildmaples avatar zachfeldman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erb-lint's Issues

Stop using Colorize gem

I am not a fan of the dependency on the Colorize gem, since it monkey-patches String:

» ruby -e 'puts String.colors'
-e:1:in `<main>': undefined method `colors' for String:Class (NoMethodError)
» ruby -r colorize -e 'puts String.colors'
black
light_black
red
[…]

Would you be open to a pull request switching to use e.g. Rainbow instead?

Linter suggestion - detect instance variable in partials

It is well known that instance variables inside partials are considered a bad practice, however I could not find any linter for it.

I have created a custom linter to solve this issue.

Would you be accepting a PR to add it to erb-lint?

Upgrade rubocop runtime dependency

In current version 0.0.35 rubocop is required as a runtime dependency with s.add_dependency('rubocop', '~> 0.79'), so any project using this gem won't be able to upgrade to rubocop v1.X.X.

Is it possible to make this dependency more flexible?

Rules breaking the code in .erb files

I think this gem assumes that every block of Ruby in a .erb file is a different Ruby file.
In my case, I've explicitly disabled some rules, to make this gem not break my code.

       Layout/InitialIndentation:
        Enabled: false # This rule removes the "<%" e "<%="  from the code, if enabled.
      Layout/TrailingEmptyLines:
        Enabled: false
      Layout/TrailingWhitespace:
        Enabled: false  # This rule removes the "<%" e "<%="  from the code, if enabled.
      Layout/LeadingEmptyLines:
        Enabled: false

I suggest 3 options for this:

  • These rules should be placed in the readme for ease of acess, telling the users to disable them
  • These rules should be disabled by the erb lint gem
  • The erb lint gem souldn't treat every block of Ruby code as a different Ruby file.

Auto correct broken in rubocop 0.82, NoMethodError: undefined method `begin_pos' for s(:str, "..."):RuboCop::AST::StrNode

Exception occured when processing: app/views/statistics/_find_question_form.html.erb
If this file cannot be processed by erb-lint, you can exclude it in your configuration file.
cause: #<NoMethodError: undefined method `begin_pos' for s(:str, "questions_for_form"):RuboCop::AST::StrNode
Did you mean?  begin_type?>
/Users/fonsan/.rvm/gems/ruby-2.6.6@dok/gems/rubocop-0.82.0/lib/rubocop/cop/cop.rb:38:in `rescue in call'
/Users/fonsan/.rvm/gems/ruby-2.6.6@dok/gems/rubocop-0.82.0/lib/rubocop/cop/cop.rb:35:in `call'
/Users/fonsan/.rvm/gems/ruby-2.6.6@dok/gems/erb_lint-0.0.32/lib/erb_lint/linters/rubocop.rb:48:in `block in autocorrect'
/Users/fonsan/.rvm/gems/ruby-2.6.6@dok/gems/rubocop-0.82.0/lib/rubocop/cop/corrector.rb:63:in `block (2 levels) in rewrite'
/Users/fonsan/.rvm/gems/ruby-2.6.6@dok/gems/parser-2.7.1.1/lib/parser/source/tree_rewriter.rb:256:in `transaction'
/Users/fonsan/.rvm/gems/ruby-2.6.6@dok/gems/rubocop-0.82.0/lib/rubocop/cop/corrector.rb:62:in `block in rewrite'

I have tracked it down to this change which allows for other things than source ranges to pass through. Not sure if I will have to the time to fix it but leaving this here for the googles

rubocop/rubocop#7863

Issues with ERB + AlpineJS

I have an erb file that is failing the lint verification. Here's the snippet:

<button @click="open = true"
  data-action="click->modal#open"
  class="text-white bg-indigo-500 hover:bg-indigo-700 inline-flex py-3 px-5 rounded-lg items-center focus:shadow-outline shadow">
  <span class="flex items-start flex-col leading-none">
    <span class="text-sm mb-1">Are you a marketer?</span>
    <span class="title-font font-medium">Start an ethical ad campaign</span>
  </span>
</button>

The lint fails with the @click attribute. Is there a way to ensure these are not causing the lint failure?

Linter suggestion - detect referencing of constants

I had suggested this for rubocop-rails a while ago in rubocop/rubocop-rails#32 :

This implies a tight coupling between different layers of the application. Also, it seems wrong for the view to access the model layer directly, rather than having data passed via the controller.

It's been closed there because RuboCop isn't going to support rendering engines, but I'm wondering if it would be considered as a potential addition to erb-lint ?

Do not fail on `info` offenses

Rubocop's default behavior is to report but not return a non-zero value on cops with severity info.

I would like to take advantage of this to progressively activate cops (first activate them with severity info so offenses will be reported on linters but won't cause pipeline to fail) which works as intended on rubocop but not on erblint.

Is there any way to make erblint behave exactly as rubocop in this case? (ie return a non-zero value only when offenses not marked as info fail)

v0.0.26 requires Ruby 2.3+ - please update gemspec

Your Readme says that the gem works with Ruby 2.2+, but it does not: a fair amount of the code uses the &. syntax introduced in Ruby 2.3. (Your gemspec doesn't declare a required_ruby_version at all.)

Yes, work is underway to update our production deployments so we can get our codebases onto a supported version of Ruby, but it's still annoying to have to dig to find out which version of the gem might actually be compatible with Ruby 2.2.

ParserErrors linter fails on AlpineJS attributes

Stemming somewhat from #177, I have an issue with some ERB files I have that use AlpineJS directives. For example, this snippet:

<nav x-data="{ open: false }" @keydown.window.escape="open = false" class="bg-white border-b"></nav>

gives the error:

1:30: expected whitespace, '>', attribute name or value (at @)

when running bundle exec erblint --enable-linters parser_errors --lint-all -f compact

It doesn't appear that the default parser doesn't accept configuration for what characters to allow for attribute names.

Rubocop Rails/Present problem?

When I run erblint, I get only 1 warning for Rails/Present instead of 2. I don't know if this is a problem with erblint or rubocop. Am I doing something wrong?

Steps to reproduce

$ erblint --version
0.0.26
$ rubocop --version
0.59.2

Erb file name foo.html.erb

<% unless @foo.blank? %>
  <h1>Hello</h1>
<% end %>

<span class="<%= 'foo' unless @foo.blank? %>"></span>

erblint config

---
linters:
  Rubocop:
    enabled: true
    rubocop_config:
      Rails:
        Enabled: true
      Rails/Present:
        Enabled: true
      Layout/InitialIndentation:
        Enabled: false
      Layout/TrailingBlankLines:
        Enabled: false
      Style/FrozenStringLiteralComment:
        Enabled: false
 ↳ $ erblint foo.html.erb
Linting 1 files with 13 linters...

Rails/Present: Use `if @foo.present?` instead of `unless @foo.blank?`.
In file: foo.html.erb:5

1 error(s) were found in ERB files

As you can see, erblint found only the unless .blank? in line 5 and not the one in line 1. How come? 🤔

Linter loops over file 7 times?

Hi there.

I was reviewing the source for this gem and found something I was curious about.

https://github.com/Shopify/erb-lint/blob/b0d8579277e756ed26aaccf13581f75d9a5e0b9e/lib/erb_lint/cli.rb#L103-L120

Why does the linter loop over autocorrectable files 7 times? Is 7 an arbitrary number?

I saw that it was added in bd096a1 for #36.

On the face of it, it looks like we'd just be wasting CPU cycles by performing the same operation an arbitrary number of times.

Any clues as to why this was the approach that was taken would be greatly appreciated. Thanks!

SelfClosingTag linter suggestions

https://github.com/Shopify/erb-lint/blob/9e356ad6f56bbe32338dbbe2bed6000528d3a17c/lib/erb_lint/linters/self_closing_tag.rb#L10-L11

For example the br and link element are void elements which only have a start tag.

Void elements only have a start tag; end tags must not be specified for void elements.

Implicitely it says that they are not self closing as it goes on for foreign elements:

Foreign elements must either have a start tag and an end tag, or a start tag that is marked as self-closing, in which case they must not have an end tag.

As for other elements such as the command one, these maybe should go into their own linter, suggesting not to use obsolete elements?

This is of course assuming most people use HTML5 and not XHTML(5). WDYT?

Loading linters from a gem

Hello all!

I wanted to extract some of my custom linters into a gem, but it doesn't seem possible in the current configuration (since erblint only loads them from .erblint).
Is there a known workaround to load linters from different places?

Using RightTrim and SpaceAroundErbTag with RightTrim.enforced_style set to '='

Hi.
I've recently added this gem to my project, and liking it a lot. However I'm used to the =%> closing tag style in favour of -%> and I seem to be having an issue with it.

I try to use the RightTrim linter with the enforced_style set to = but it seems to erroneously trigger the SpaceAroundErbTag linter, whereas this doesn't happen with -.

Steps

run:
rails new erb-lint-test
cd erb-lint-test/

Add gem 'erb_lint' to Gemfile
Run bundle

Create a .erb-lint.yml:

---
linters:
  ErbSafety:
    enabled: false
  RightTrim:
    enabled: true
    enforced_style: '='
  Rubocop:
    enabled: false

Change a closing tag, such as the one from the stylesheet_link_tag in app/views/layouts/application.html.erb:8.
from

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>

to

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' =%>

Actual

When running bundle exec erblint app/views/layouts/application.html.erb now it outputs:

$ bundle exec erblint app/views/layouts/application.html.erb
Linting 1 files with 12 linters...

Use 1 space before `%>` instead of 0 space.
In file: app/views/layouts/application.html.erb:8

1 error(s) were found in ERB files

Expected

whereas changing the closing tag from =%> to -%> and the enforced_style value from = to - the output is as expected:

$ bundle exec erblint app/views/layouts/application.html.erb
Linting 1 files with 12 linters...

No errors were found in ERB files

Extra

version

Using erb_lint version 0.0.30

autocorrect

Running with --autocorrect results in:

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index cac6434..ea16009 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -5,7 +5,7 @@
     <%= csrf_meta_tags %>
     <%= csp_meta_tag %>
 
-    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
+    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = %>
     <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
   </head>

I'd expect the correction to set it to =%> (note: no space between = and %)

Am I doing something wrong, or is this a bug?
Thanks!

Gemfile.lock should not be under source control

It is the CI's job to insure that difference version of the dependencies are ok.

This does not imply the Gemfile.lock should be under source control.

The reasons why it should not be committed for gems still stand. Please follow established community guidelines.

From #41

"That approach is actually not ideal since any developers should have all tests passed as soon as they clone the repo. This might not be the case because all developers could have multiple different dependencies version"

If tests are not passing for a developer because he happens to have a combination of dependencies that don't work, then this is an issue that needs to be fixed (by either having the right specifications in the gemspec or by fixing the gem)! Moreover it may be an indication that the CI is not testing enough different combinations of the dependencies. Committing the Gemfile.lock to avoid a bad gemspec specification is the wrong approach to fix this problem.

FWIW, I just cloned this repo and I get:

$ bundle --version
Traceback (most recent call last):
	4: from /Users/work/.rvm/gems/ruby-2.7.1/bin/ruby_executable_hooks:24:in `<main>'
	3: from /Users/work/.rvm/gems/ruby-2.7.1/bin/ruby_executable_hooks:24:in `eval'
	2: from /Users/work/.rvm/rubies/ruby-2.7.1/bin/bundle:23:in `<main>'
	1: from /Users/work/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/rubygems.rb:294:in `activate_bin_path'
/Users/work/.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/rubygems.rb:275:in `find_spec_for_exe': Could not find 'bundler' (1.17.3) required by your /Users/work/erb-lint/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:1.17.3`

Annoying I'd have to install a particularly old version of bundler to install run the specs.

Trying out any updated version of a dependency (even a dev one) will make my repo dirty.

I recommend going the other direction, i.e. git-ignoring Gemfile.lock and Gemfile.local, and that Gemfile loads Gemfile.local if present. This enables developers to test with any dependency versions they want to locally (including local repos) without having to make their repo dirty. Features/Bugs that happen to depend on a particular dependency version will be caught by the CI, as they should.

Loading Custom Linters is broken

It appears the loading custom linters from CLI doesn't work correctly. Following the README instructions is met with:

$ bundle exec erblint --enable-linters custom_linter --lint-all
custom_linter: not a valid linter name (rubocop, rubocop_text, parser_errors, space_around_erb_tag, space_in_html_tag, extra_newline, right_trim, erb_safety, trailing_whitespace, closing_erb_tag_indent, space_indentation, hard_coded_string, no_javascript_tag_helper, allowed_script_type, self_closing_tag, final_newline, deprecated_classes)

Taking a dive into this, it appears that options are loaded and validated before the custom linters are loaded.

https://github.com/Shopify/erb-lint/blob/90702271d5811cc9a677c69e2ae4f332ca53d248/lib/erb_lint/cli.rb#L35-L37

Here the args are validated against known_linter_names:

https://github.com/Shopify/erb-lint/blob/90702271d5811cc9a677c69e2ae4f332ca53d248/lib/erb_lint/cli.rb#L269-L277

known_linter_names expects that all the linters have already been loaded:

https://github.com/Shopify/erb-lint/blob/90702271d5811cc9a677c69e2ae4f332ca53d248/lib/erb_lint/cli.rb#L213-L217

But in the LinterRegistry we can see that custom linters are only explicitly loaded when load_custom_linters is called:

https://github.com/Shopify/erb-lint/blob/90702271d5811cc9a677c69e2ae4f332ca53d248/lib/erb_lint/linter_registry.rb#L20-L23

load_custom_linters is only called when the Runner is initialised, but that happens some 30 lines after the options have been validated:

https://github.com/Shopify/erb-lint/blob/90702271d5811cc9a677c69e2ae4f332ca53d248/lib/erb_lint/cli.rb#L58

Changing the known_linter_names to be the following appears to fix the issue:

def known_linter_names
  @known_linter_names ||= begin
    ERBLint::LinterRegistry.load_custom_linters
    ERBLint::LinterRegistry.linters
      .map(&:simple_name)
      .map(&:underscore)
  end
end

(Note that Custom Linters still don't work at this point as the README is out of date #123)

Error with rubocop 0.85

Running erblint with rubocop 0.85 fails:

Exception occured when processing: app/views/issues/show.html.erb
If this file cannot be processed by erb-lint, you can exclude it in your configuration file.
undefined method `reject' for #<RuboCop::Cop::Registry:0x000055f48b351dc8>
/usr/local/share/gems/ruby/2.7.0/gems/rubocop-0.85.0/lib/rubocop/cop/team.rb:147:in `roundup_relevant_cops'
/usr/local/share/gems/ruby/2.7.0/gems/rubocop-0.85.0/lib/rubocop/cop/team.rb:116:in `offenses'
/usr/local/share/gems/ruby/2.7.0/gems/rubocop-0.85.0/lib/rubocop/cop/team.rb:67:in `inspect_file'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/linters/rubocop.rb:71:in `inspect_content'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/linters/rubocop.rb:34:in `block in run'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:26:in `<<'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:26:in `block (2 levels) in descendants'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:14:in `traverse'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:20:in `block in traverse_all'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:19:in `each'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:19:in `traverse_all'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:15:in `traverse'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:20:in `block in traverse_all'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:19:in `each'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:19:in `traverse_all'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:15:in `traverse'
/usr/local/share/gems/ruby/2.7.0/gems/better_html-1.0.15/lib/better_html/ast/iterator.rb:27:in `block in descendants'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/linters/rubocop.rb:33:in `each'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/linters/rubocop.rb:33:in `each'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/linters/rubocop.rb:33:in `run'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/runner.rb:25:in `block in run'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/runner.rb:24:in `each'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/runner.rb:24:in `run'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/cli.rb:113:in `block in run_with_corrections'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/cli.rb:111:in `times'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/cli.rb:111:in `run_with_corrections'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/cli.rb:63:in `block in run'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/cli.rb:60:in `each'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/lib/erb_lint/cli.rb:60:in `run'
/usr/local/share/gems/ruby/2.7.0/gems/erb_lint-0.0.33/exe/erblint:9:in `<top (required)>'
/usr/local/share/gems/ruby/2.7.0/bin/erblint:23:in `load'
/usr/local/share/gems/ruby/2.7.0/bin/erblint:23:in `<top (required)>'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/cli/exec.rb:74:in `load'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/cli/exec.rb:28:in `run'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/cli.rb:463:in `exec'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/cli.rb:27:in `dispatch'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/cli.rb:18:in `start'
/usr/local/share/gems/gems/bundler-1.17.2/exe/bundle:30:in `block in <top (required)>'
/usr/local/share/gems/gems/bundler-1.17.2/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'
/usr/local/share/gems/gems/bundler-1.17.2/exe/bundle:22:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'

Pass folder to options

Can be useful to pass a folder as option (not only file name).
Now running the command bundle exec erblint app/views/admin/ the result is

Exception occured when processing: app/views/admin
Is a directory @ io_fread ...

My expectation was that erblint appends the path to "**/.html{+,}.erb" as here https://github.com/Shopify/erb-lint/blob/master/lib/erb_lint/cli.rb#L14

It works as expected with bundle exec erblint "app/views/admin/**/*.html{+*,}.erb"

How to disable BetterHTML?

I added ERB Lint to the gemfile to be able to run it on demand and in CI, but now I'm getting exceptions thrown from my views that are coming from BetterHTML. How do I disable this?

Feature Request: Caching

We have a large codebase of 1,277 erb files. Running 12 linters on all of those files, it takes over 3 minutes. This is a bottleneck to our build system. Ideally, we could run these in parallel or with caching (so only changed files are inspected). This problem will only get worse as we enable more linters and add more erb files to our codebase.

Rubocop has a cache option explained here: https://github.com/rubocop-hq/rubocop/blob/master/manual/caching.md

We would love if such a feature existed for erblint. Thank you!

autocorrect Removes Portions of Code & Results in SyntaxError

bug.erb:

      <%= public_form_for resource, as: resource_name, url: confirm_path, html: { class: 'form-vertical' } do |f| %>
              <%= f.hidden_field :confirmation_token %>
      <% end %>

.erb-lint.yml:

---
linters:
  FinalNewline:
    enabled: true
  SpaceIndentation:
    enabled: true
  Rubocop:
    enabled: true
    rubocop_config:
      Layout/TrailingBlankLines:
        Enabled: true
      Style/FrozenStringLiteralComment:
        Enabled: false
/tmp >erblint --autocorrect bug.erb
warning: parser/current is loading parser/ruby25, which recognizes
warning: 2.5.6-compliant syntax, but you are running 2.5.2.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
Linting 1 files with 12 autocorrectable linters...

26 error(s) corrected in ERB files

Result:

/tmp >cat bug.erb
      <%=lic_form_for resource, as: resource_name, url: confirm_path, html: { class: 'form-vertical' }


 do |f| %>
              <%= .hidden_field :confirmation_token %>
      <% end %>

rubocop error with erblint command: `<class:RedundantConditional>': undefined method `join' for #<Set: {...}>

I'm unable to run erblint command (both with bundle exec and without), it shows the following error:

ruby-2.5.5/gems/rubocop-0.84.0/lib/rubocop/cop/style/redundant_conditional.rb:57:in class:RedundantConditional': undefined method join' for #<Set: {:==, :===, :!=, :<=, :>=, :>, :<}> (NoMethodError)

My setup is:

  • ruby 2.5.5
  • rails 6.0.1
  • erb_lint (0.0.37)
    activesupport
    better_html (~> 1.0.7)
    html_tokenizer
    parser (>= 2.7.1.4)
    rainbow
    rubocop
    smart_properties
  • rubocop 0.84.0
  • rubocop-ast 1.4.0
  • rubocop-performance 1.5.0

Editor integration

Summary

erb-lint is a great tool to keep your ERB consistent and avoid known security issues, such as rendering raw inputs.

However, the linting process is usually late in the development process, typically being run during CI, which can slow down developers since they may only get notified of errors after opening a PR and getting the build to fail.

Proposal

Make erb-lint easy to integrate with editors (Vim, Emacs, VSCode...) so developers can have real-time feedback of the ERB they are editing.

Problems

The current output that erb-lint provides does not contain all the necessary information to decorate editors with the exact location of linting errors. Right now, it's only possible to get the line where the error occurs instead of the whole block (line + columns).

Solution

Adding a generic formatter that exposes more data about the error, such as a JSON formatter, similar to rubocop's formatter.

Exposing structured information about the errors in the file would allow better decorations for editors, like underlining the exact location of offenses.

Related

#173
#219
#224

Ability to run under rspec/test-unit

Is it possible to run erb-lint against all templates during a test run? Something like what's provided by better-html:

# RAILS_ROOT/spec/views/erb_safety_spec.rb

require 'better_html/test_helper/safe_erb_tester'
require 'rails_helper'

ERB_GLOB = Rails.root.join('app/views/**/{*.htm,*.html,*.htm.erb,*.html.erb,*.html+*.erb}')

RSpec.describe 'safe_erb' do # rubocop:disable RSpec/DescribeClass
  include BetterHtml::TestHelper::SafeErbTester

  Dir[ERB_GLOB].each do |filename|
    pathname = Pathname.new(filename).relative_path_from(Rails.root)
    it "validates #{pathname}" do
      data = File.read(filename)
      BetterHtml::BetterErb::ErubiImplementation.new(data).validate!
      assert_erb_safety(data)
    end
  end
end

Update Github's description for this repo

Please replace the repository's description:

Linting gem purposed for use on Policial.io

  1. that site doesn't seem to exist
  2. which site this was created for has nothing to do with why anyone would want to look at this repo/gem
  3. I'm guessing this was copied when Shopify forked the gem, but even justinthec's original repo has a more meaningful description now

Ignore strings in mustache templates

If the HardCodedString linter is enabled, mustache variables get flagged:

<template>
  <p>{{first_name}}</p>
</template>

I don't know what the best solution would be. Maybe ignore anything with {{ }}? I like using erb-lint a lot and could find some time to address this.

Update gemspec homepage to help us find the current repo

When I search for this gem on rubygems.org, the only link there takes me to the original repo that hasn't been updated in a couple years - if I hadn't been paying attention to the version history, I would assume that the gem was abandoned and not even try to install it.

Some people may not think to look under that repo's forks to discover that this is the current repo for the gem's development.

Errors on unrecognized cops

When running rubocop-rspec and rubocop-rails I see this error when running erb-lint:

RuboCop::ValidationError: unrecognized cop RSpec/AnyInstance found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/ContextWording found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/DescribeClass found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/ExampleLength found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/ExpectInHook found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/FilePath found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/InstanceVariable found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/IteratedExpectation found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/MessageChain found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/MessageSpies found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/NamedSubject found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/NestedGroups found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/PredicateMatcher found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/ScatteredLet found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/SubjectStub found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop RSpec/VerifiedDoubles found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/ActiveRecordAliases found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/ApplicationJob found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/Blank found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/EnvironmentComparison found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/FilePath found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/HasManyOrHasOneDependent found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/HelperInstanceVariable found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/LexicallyScopedActionFilter found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/OutputSafety found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/Present found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/RakeEnvironment found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/SkipsModelValidations found in .erblint-rubocop20200429-12840-848tz0, unrecognized cop Rails/TimeZone found in .erblint-rubocop20200429-12840-848tz0

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/rubocop-0.82.0/lib/rubocop/config_validator.rb:99:in `alert_about_unrecognized_cops'

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/rubocop-0.82.0/lib/rubocop/config_validator.rb:40:in `validate'

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/rubocop-0.82.0/lib/rubocop/config.rb:44:in `check'

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/rubocop-0.82.0/lib/rubocop/config.rb:37:in `create'

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/rubocop-0.82.0/lib/rubocop/config_loader.rb:54:in `load_file'

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/erb_lint-0.0.32/lib/erb_lint/linters/rubocop.rb:132:in `block in config_from_hash'

/home/travis/build/sul-dlss/argo/vendor/bundle/ruby/2.6.0/gems/erb_lint-0.0.32/lib/erb_lint/linters/rubocop.rb:95:in `block in tempfile_from'

However, I can fix it if I add the following to my .rubocop_todo.yml (this is already present in my .rubocop.yml)

require:
  - rubocop-rspec
  - rubocop-rails

Remove filtering of linters when using --autocorrect

I'd like to have a single command that will both run all of the enabled linters configured in my .erb-lint.yml and autocorrect the linters that support autocorrect.

Currently it seems like using the --autocorrect flag filters down the linters to only run linters that are autocorrectable and non-correctable linters do not run.

I tried some workarounds, for example, running --autocorrect --enable-all-linters will run all the linters, but won't respect the linters I've disabled in my .erb-lint.yml file.

Ideally, I would like the --autocorrect flag to only trigger autocorrection, and otherwise respect the configuration I have within my .erb-lint.yml for enabled/disabled cops.

False positive for Lint/UselessAssignment

I'm getting

Lint/UselessAssignment: Useless assignment to variable - `rows`.
In file: app/views/spree/admin/vanity_urls/_form_row.html.erb:18

Lint/UselessAssignment: Useless assignment to variable - `autogrow`.
In file: app/views/spree/admin/vanity_urls/_form_row.html.erb:19

for this code (extracted from a larger file):

<td>
  <%= f.label :message %>
  <br />
  <% rows = record.message.to_s.count("\n") + 1 %>
  <% autogrow = 'this.setAttribute("rows", this.value.match(/$|\n/g).length)' %>
  <%= f.text_area :message, disabled: record.persisted?, rows: rows, onkeyup: autogrow %>
</td>

Policy on adding linters

  1. Are the maintainers aware of any repositories of custom linters, beyond those included in the project?
  2. If some new linter were to be written, would the maintainers be interested in a PR for including them in the mainline project, or including references to it in the documentation (for the benefit of users unable to find them)?

These are 'soft' questions, so by all means close this issue if they are not well-suited here. My particular use case is that I'd like to find or make a linter that checks indentation in html.erb files, and as far as I can tell none exists. If one exists already, it would be helpful if you would link to it. If I instead go on to write one, then other users might benefit from having it be linked by your project.

All the best,
Dan

Problem with erb statements within <script>-Tag

When linting something like this

<script>
  <% do something %>
  Some output
</script>

I keep getting

erb statement not allowed here; did you mean '<%=' ?

Why would <% ... %> not be allowed within a <script>-Tag?

Possibility to turn erb-lint into rubocop extension?

See this. There's a few extensions, mostly focusing on Ruby code.

I didn't dig into the code of erb-lint deep enough to be able to tell if this project has to stay separate from rubocop or if it could be written as an extension? As an extension, it could theoretically also be adopted by rubocop-hq, much like rubocop-rspec was.

WDYT?

JSON output must disable HTML escaping

The README shows this example as "good":

var myData = <%= some_data.to_json %>;

However, this would escape the &quot; marks and break the syntax, and it looks like this should be used with <%== or <%= raw.

Is there a way to validate this, or enforce one of these preferred styles?

Rubocop linter not compatible with Ruby < 2.4

Error trace

Exception occured when processing: app/views/books/index.html.erb
undefined method `match?' for ".rubocop.yml":String
Did you mean?  match
/.rvm/gems/ruby-2.3.3/gems/erb_lint-0.0.28/lib/erb_lint/linters/rubocop.rb:150:in `block in base_configs'

Config file

---
linters:
  ErbSafety:
    enabled: true
  Rubocop:
    enabled: true
    rubocop_config:
      inherit_from:
        - .rubocop.yml
      Layout/InitialIndentation:
        Enabled: false
      Layout/TrailingBlankLines:
        Enabled: false

Possible cause

String#match? and Regexp#match? are available from Ruby 2.4 and later only, the min required Ruby version to run the gem is 2.3.0+.

Possible solution

Implement a custom definition of Regexp#match? for old Rubies (as Rails and others does) and swap the match expression from "some_string".match?(/pattern/) to /pattern/.match?("some_string")

class Regexp #:nodoc:
  def multiline?
    options & MULTILINE == MULTILINE
  end

  def match?(string, pos = 0)
    !!match(string, pos)
  end unless //.respond_to?(:match?)
end

Related

rails/rails#32970

or simply using

string =~ regexp

Gemspec and rubocop.yml still reference ruby 2.3

that is not supported in ruby 2.3

I see. The reason why I'm asking is because the .gemspec file still mentions 2.3, so does .rubocop.yml and the README.

https://github.com/Shopify/erb-lint/blob/f0d65d75d0d93e7cc1632421e55159847e0f60a3/erb_lint.gemspec#L21
https://github.com/Shopify/erb-lint/blob/f0d65d75d0d93e7cc1632421e55159847e0f60a3/.rubocop.yml#L5
https://github.com/Shopify/erb-lint/blob/f0d65d75d0d93e7cc1632421e55159847e0f60a3/README.md#requirements

Support of Ruby 2.3 has ended

I realize that, however that sometimes doesn't directly correlate with what gems generally support, though. :)

Originally posted by @aried3r in #131 (comment)

Installation fails on Big Sur

I'm trying to install this gem on macOS Big Sur 11.2.3 but its html_tokenizer dependency is failing:

Building native extensions. This could take a while...
ERROR:  Error installing html_tokenizer:
	ERROR: Failed to build gem native extension.

    current directory: /Users/user/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/html_tokenizer-0.0.7/ext/html_tokenizer_ext
/Users/user/.rbenv/versions/3.0.1/bin/ruby -I /Users/user/.rbenv/versions/3.0.1/lib/ruby/3.0.0 -r ./siteconf20210517-79502-ixgkui.rb extconf.rb
creating Makefile

current directory: /Users/user/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/html_tokenizer-0.0.7/ext/html_tokenizer_ext
make DESTDIR\= clean

current directory: /Users/user/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/html_tokenizer-0.0.7/ext/html_tokenizer_ext
make DESTDIR\=
compiling html_tokenizer.c
compiling parser.c
parser.c:459:45: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
      INT2NUM(ref.line_number), INT2NUM(ref.column_number));
                                ~~~~~~~ ~~~~^~~~~~~~~~~~~
parser.c:459:19: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
      INT2NUM(ref.line_number), INT2NUM(ref.column_number));
      ~~~~~~~ ~~~~^~~~~~~~~~~
parser.c:458:51: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
      INT2NUM(ref.mb_start), INT2NUM(ref.mb_start + mb_strlen),
                             ~~~~~~~ ~~~~~~~~~~~~~^~~~~~~~~~~
parser.c:458:19: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
      INT2NUM(ref.mb_start), INT2NUM(ref.mb_start + mb_strlen),
      ~~~~~~~ ~~~~^~~~~~~~
parser.c:498:9: warning: unused variable 'old' [-Wunused-variable]
  void *old = parser->doc.data;
        ^
parser.c:721:26: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' [-Wshorten-64-to-32]
  return INT2NUM(parser->errors_count);
         ~~~~~~~ ~~~~~~~~^~~~~~~~~~~~
parser.c:792:3: warning: incompatible function pointer types passing 'VALUE (VALUE, VALUE)' (aka 'unsigned long (unsigned long, unsigned long)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)') [-Wincompatible-function-pointer-types]
  rb_define_method(cParser, "errors", parser_errors_method, 0);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/user/.rbenv/versions/3.0.1/include/ruby-3.0.0/ruby/internal/anyargs.h:287:135: note: expanded from macro 'rb_define_method'
#define rb_define_method(klass, mid, func, arity)           RBIMPL_ANYARGS_DISPATCH_rb_define_method((arity), (func))((klass), (mid), (func), (arity))
                                                                                                                                      ^~~~~~
/Users/user/.rbenv/versions/3.0.1/include/ruby-3.0.0/ruby/internal/anyargs.h:276:1: note: passing argument to parameter here
RBIMPL_ANYARGS_DECL(rb_define_method, VALUE, const char *)
^
/Users/user/.rbenv/versions/3.0.1/include/ruby-3.0.0/ruby/internal/anyargs.h:254:72: note: expanded from macro 'RBIMPL_ANYARGS_DECL'
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _00(__VA_ARGS__, VALUE(*)(VALUE), int); \
                                                                       ^
7 warnings generated.
compiling tokenizer.c
tokenizer.c:138:106: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
  rb_yield_values(3, token_type_to_symbol(type), INT2NUM(tk->scan.mb_cursor), INT2NUM(tk->scan.mb_cursor + mb_length));
                                                                              ~~~~~~~ ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
tokenizer.c:138:67: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
  rb_yield_values(3, token_type_to_symbol(type), INT2NUM(tk->scan.mb_cursor), INT2NUM(tk->scan.mb_cursor + mb_length));
                                                 ~~~~~~~ ~~~~~~~~~^~~~~~~~~
tokenizer.c:667:15: warning: unused variable 'old' [-Wunused-variable]
  const char *old = tk->scan.string;
              ^
3 warnings generated.
linking shared-object html_tokenizer_ext.bundle

current directory: /Users/user/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/html_tokenizer-0.0.7/ext/html_tokenizer_ext
make DESTDIR\= install
make: /usr/local/bin/gmkdir: No such file or directory
make: *** [.sitearchdir.time] Error 1

make install failed, exit code 2

Gem files will remain installed in /Users/user/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/html_tokenizer-0.0.7 for inspection.
Results logged to /Users/user/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/extensions/x86_64-darwin-20/3.0.0/html_tokenizer-0.0.7/gem_make.out

erb_lint can't resolve configs from gems

Our project is attempting to migrate to use "gem" based Rubocop configs to try and smooth out the bumps when external dependencies change.

At the moment, our rubocop.yml file has the following lines:

inherit_from:
  - http://shopify.github.io/ruby-style-guide/rubocop.yml

This is problematic as we get into scenarios where that file will update but our version of Rubocop doesn't support the new lint rules and ERB Lint doesn't support those rules either.

To solve we're attempting to migrate to the "gem" approach as described in https://shopify.github.io/ruby-style-guide/:

inherit_from:
  rubocop-shopify: rubocop.yml

This results in a crash when running erb_lint:

$ bundle exec erblint --lint-all
Linting 943 files with 14 linters...

TypeError: no implicit conversion of Array into String
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/file_loader.rb:25:in `expand_path'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/file_loader.rb:25:in `read_content'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/file_loader.rb:14:in `yaml'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:182:in `block in base_configs'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:178:in `map'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:178:in `base_configs'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:168:in `resolve_inheritance'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:160:in `config_from_hash'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:182:in `block in base_configs'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:178:in `map'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:178:in `base_configs'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:168:in `resolve_inheritance'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:160:in `config_from_hash'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/linters/rubocop.rb:27:in `initialize'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/runner.rb:16:in `new'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/runner.rb:16:in `block in initialize'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/runner.rb:15:in `map'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/runner.rb:15:in `initialize'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/cli.rb:58:in `new'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/cli.rb:58:in `run'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/exe/erblint:9:in `<top (required)>'
/Users/brendanabbott/.gem/ruby/2.6.6/bin/erblint:23:in `load'
/Users/brendanabbott/.gem/ruby/2.6.6/bin/erblint:23:in `<top (required)>'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/cli/exec.rb:74:in `load'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/cli/exec.rb:74:in `kernel_load'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/cli/exec.rb:28:in `run'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/cli.rb:463:in `exec'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/cli.rb:27:in `dispatch'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/cli.rb:18:in `start'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/exe/bundle:30:in `block in <top (required)>'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'
/Users/brendanabbott/.gem/ruby/2.6.6/gems/bundler-1.17.3/exe/bundle:22:in `<top (required)>'
/Users/brendanabbott/.gem/ruby/2.6.6/bin/bundle:23:in `load'
/Users/brendanabbott/.gem/ruby/2.6.6/bin/bundle:23:in `<main>'

With a pry session, I was able to see that erb_lint is choking on:

From: /Users/brendanabbott/.gem/ruby/2.6.6/gems/erb_lint-0.0.35/lib/erb_lint/file_loader.rb:28 ERBLint::FileLoader#read_content:

    24: def read_content(filename)
    25:   require 'pry'
    26:   binding.pry
    27: 
 => 28:   path = File.expand_path(filename, base_path)
    29:   File.read(path)
    30: end

[1] pry(#<ERBLint::FileLoader>)> filename
=> ["rubocop-shopify", "rubocop.yml"]

Obsolete cop error

After gem install erb-lint I'm running into the following error when I tryerblint -all with the default .yml file given in the info page on github

RuboCop::ValidationError: The `Layout/AlignParameters` cop has been renamed to `Layout/ParameterAlignment`.
(obsolete configuration found in .erblint-rubocop20200214-17293-1otoi35, please update it)
The `Layout/TrailingBlankLines` cop has been renamed to `Layout/TrailingEmptyLines`.
(obsolete configuration found in .erblint-rubocop20200214-17293-1otoi35, please update it)
The `Lint/HandleExceptions` cop has been renamed to `Lint/SuppressedException`.
(obsolete configuration found in .erblint-rubocop20200214-17293-1otoi35, please update it)
The `Naming/UncommunicativeBlockParamName` cop has been renamed to `Naming/BlockParameterName`.
(obsolete configuration found in .erblint-rubocop20200214-17293-1otoi35, please update it)
The `Naming/UncommunicativeMethodParamName` cop has been renamed to `Naming/MethodParameterName`.
(obsolete configuration found in .erblint-rubocop20200214-17293-1otoi35, please update it)

Mass error reporting for single file

When rubocop is enabled, erb lint outputs one error per line of text in the file where any issues are found, repeating the same issues for each one.

Copy of output with rubocop enabled:

Running: ERB Lint
warning: parser/current is loading parser/ruby26, which recognizes
warning: 2.6.6-compliant syntax, but you are running 2.6.5.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
Linting 1 files with 14 linters...

Layout/InitialIndentation: Indentation of first line in file detected.
In file: app/views/layouts/application.html.erb:12

Layout/TrailingEmptyLines: Final newline missing.
In file: app/views/layouts/application.html.erb:12

Layout/InitialIndentation: Indentation of first line in file detected.
In file: app/views/layouts/application.html.erb:16

Layout/TrailingEmptyLines: Final newline missing.
In file: app/views/layouts/application.html.erb:16

Layout/InitialIndentation: Indentation of first line in file detected.
In file: app/views/layouts/application.html.erb:17

Layout/TrailingEmptyLines: Final newline missing.
In file: app/views/layouts/application.html.erb:17

...

Layout/InitialIndentation: Indentation of first line in file detected.
In file: app/views/layouts/application.html.erb:39

Layout/TrailingEmptyLines: Final newline missing.
In file: app/views/layouts/application.html.erb:39

30 error(s) were found in ERB files

With rubocop disabled in the erb-lint:

Running: ERB Lint
warning: parser/current is loading parser/ruby26, which recognizes
warning: 2.6.6-compliant syntax, but you are running 2.6.5.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
Linting 1 files with 13 linters...

No errors were found in ERB files
End: ERB Lint

copy of erb-lint.yml

---
EnableDefaultLinters: true
linters:
    ErbSafety:
        enabled: true
    Rubocop:
        enabled: false
        rubocop_config:
            inherit_from:
                - .rubocop.yml

My assumption is that for some reason it is treating any line of ruby interpolation as a whole file for rubocop and therefore reporting it that way?

'exclude' option not working?

Hey!

I just found this project thanks to an issue in rubocop. Thanks, it looks awesome and I already found some layout issues thanks to it! :)

I was playing around when I found that using the CLI does not respect the exclude options of linters. I didn't find anything in the code that would suggest that this option would override the local linter config.

$ erblint --lint-all
Linting 2 files with 13 linters...

String not translated: ErbLintExclude
In file: app/views/layouts/application.html.erb:4

String not translated: /* Email styles need to be inline */
In file: app/views/layouts/mailer.html.erb:6

2 error(s) were found in ERB files
# .erb-lint.yml

---
linters:
  HardCodedString:
    enabled: true
    exclude:
      - 'app/views/**/*'

I also tried 'app/views/**' which I think is the wrong globbing syntax anyway.

Reproduction in this repo: https://github.com/aried3r/erb-lint-exclude

SpaceInHtmlTag customisation

When the SpaceInHtmlTag rule is enabled, the following code is flagged:

<img
  alt='...'
  className='...'
/>

I realise that I could just disable this rule but then the following code is accepted:

<img     alt='...'              className='...' />

Which is undesirable.

Is it possible to customise the SpaceInHtmlTag rule such that scenario 1 is accepted but scenario 2 is not? Or do we have to make a choice on what we want to accept?

Exceptions occur during processing with RuboCop 0.72

undefined method `[]' for nil:NilClass
gems/erb_lint-0.0.28/lib/erb_lint/linters/rubocop.rb:111:in `cop_classes'
gems/erb_lint-0.0.28/lib/erb_lint/linters/rubocop.rb:120:in `build_team'
gems/erb_lint-0.0.28/lib/erb_lint/linters/rubocop.rb:70:in `inspect_content'
gems/erb_lint-0.0.28/lib/erb_lint/linters/rubocop.rb:34:in `block in run'

RuboCop 0.72 removes Rails cops from the core library. The error occurs when executing this line because @rubocop_config['Rails'] will be nil.

elsif @rubocop_config['Rails']['Enabled']

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.