Skip to content

Commit

Permalink
Merge branch 'main' into francisfuzz/docs-hardcodedstring
Browse files Browse the repository at this point in the history
  • Loading branch information
francisfuzz authored Mar 27, 2024
2 parents 8b3893b + 2b034d3 commit 6edd106
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: [2.7, '3.0', 3.1, 3.2, head]
ruby: [2.7, '3.0', 3.1, 3.2, 3.3, head]
gemfile: [rubocop-next, rubocop-old]
runs-on: ubuntu-latest
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
Expand Down
36 changes: 19 additions & 17 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
erb_lint (0.4.0)
erb_lint (0.5.0)
activesupport
better_html (>= 2.0.1)
parser (>= 2.7.1.4)
Expand All @@ -12,19 +12,19 @@ PATH
GEM
remote: https://rubygems.org/
specs:
actionview (7.0.4.3)
activesupport (= 7.0.4.3)
actionview (7.0.7.2)
activesupport (= 7.0.7.2)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activesupport (7.0.4.3)
activesupport (7.0.7.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
ast (2.4.2)
better_html (2.0.1)
better_html (2.0.2)
actionview (>= 6.0)
activesupport (>= 6.0)
ast (~> 2.0)
Expand All @@ -37,25 +37,27 @@ GEM
diff-lcs (1.5.0)
erubi (1.12.0)
fakefs (1.5.1)
i18n (1.12.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
loofah (2.19.1)
loofah (2.21.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mini_portile2 (2.8.1)
minitest (5.18.0)
nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
nokogiri (>= 1.12.0)
mini_portile2 (2.8.5)
minitest (5.19.0)
nokogiri (1.15.6)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
parallel (1.22.1)
parser (3.1.2.1)
ast (~> 2.4.1)
racc (1.6.2)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
racc (1.7.3)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.5.0)
Expand Down
89 changes: 61 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ linters:
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](#Linters) are enabled by default.
`EnableDefaultLinters`: enables or disables default linters. [Default linters](#linters) are enabled by default.

## Disable rule at offense-level
You can disable a rule by placing a disable comment in the following format:
Expand Down Expand Up @@ -102,28 +102,28 @@ linters:

## Linters

| Available Linters | Default | Description |
|-------------------------------------------------------|:-------:|-------------------------------------------------------------------------------------------------------------------------------------------|
| [AllowedScriptType](#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](#CommentSyntax) | Yes | detects bad ERB comment syntax |
| ExtraNewline | Yes | |
| [FinalNewline](#FinalNewline) | Yes | warns about missing newline at the end of a ERB template |
| [NoJavascriptTagHelper](#NoJavascriptTagHelper) | Yes | prevents the usage of Rails' `javascript_tag` |
| ParserErrors | Yes | |
| PartialInstanceVariable | No | detects instance variables in partials |
| [RequireInputAutocomplete](#RequireInputAutocomplete) | Yes | warns about missing autocomplete attributes in input tags |
| [RightTrim](#RightTrim) | Yes | enforces trimming at the right of an ERB tag |
| [SelfClosingTag](#SelfClosingTag) | Yes | enforces self closing tag styles for void elements |
| [SpaceAroundErbTag](#SpaceAroundErbTag) | Yes | enforces a single space after `<%` and before `%>` |
| SpaceIndentation | Yes | |
| SpaceInHtmlTag | Yes | |
| TrailingWhitespace | Yes | |
| [DeprecatedClasses](#DeprecatedClasses) | No | warns about deprecated css classes |
| [ErbSafety](#ErbSafety) | No | detects unsafe interpolation of ruby data into various javascript contexts and enforce usage of safe helpers like `.to_json`. |
| [Rubocop](#Rubocop) | No | runs RuboCop rules on ruby statements found in ERB templates |
| [RequireScriptNonce](#RequireScriptNonce) | No | warns about missing [Content Security Policy nonces](https://guides.rubyonrails.org/security.html#content-security-policy) in script tags |
| [HardCodedString](#HardCodedString) | No | warns if there is a visible hardcoded string in the DOM (does not check for a hardcoded string nested inside a JavaScript tag) |
| Available Linters | Default | Description |
| ------------------------------------------------ |:--------:|-------------|
| [AllowedScriptType](#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](#commentsyntax) | Yes | detects bad ERB comment syntax |
| ExtraNewline | Yes | |
| [FinalNewline](#finalnewline) | Yes | warns about missing newline at the end of a ERB template |
| [NoJavascriptTagHelper](#nojavascripttaghelper) | Yes | prevents the usage of Rails' `javascript_tag` |
| ParserErrors | Yes | |
| PartialInstanceVariable | No | detects instance variables in partials |
| [RequireInputAutocomplete](#requireinputautocomplete) | Yes | warns about missing autocomplete attributes in input tags |
| [RightTrim](#righttrim) | Yes | enforces trimming at the right of an ERB tag |
| [SelfClosingTag](#selfclosingtag) | Yes | enforces self closing tag styles for void elements |
| [SpaceAroundErbTag](#spacearounderbtag) | Yes | enforces a single space after `<%` and before `%>`|
| SpaceIndentation | Yes | |
| SpaceInHtmlTag | Yes | |
| TrailingWhitespace | Yes | |
| [DeprecatedClasses](#deprecatedclasses) | No | warns about deprecated css classes |
| [ErbSafety](#erbsafety) | No | detects unsafe interpolation of ruby data into various javascript contexts and enforce usage of safe helpers like `.to_json`. |
| [Rubocop](#rubocop) | No | runs RuboCop rules on ruby statements found in ERB templates |
| [RequireScriptNonce](#requirescriptnonce) | No | warns about missing [Content Security Policy nonces](https://guides.rubyonrails.org/security.html#content-security-policy) in script tags |
| [HardCodedString](#HardCodedString) | No | warns if there is a visible hardcoded string in the DOM (does not check for a hardcoded string nested inside a JavaScript tag) |

### DeprecatedClasses

Expand Down Expand Up @@ -581,16 +581,13 @@ module ERBLint
end
self.config_schema = ConfigSchema

def offenses(processed_source)
errors = []
def run(processed_source)
unless processed_source.file_content.include?('this file is fine')
errors << Offense.new(
self,
add_offense(
processed_source.to_source_range(0 ... processed_source.file_content.size),
"This file isn't fine. #{@config.custom_message}"
)
end
errors
end
end
end
Expand Down Expand Up @@ -688,6 +685,42 @@ erblint --format junit
</testsuite>
```
### GitLab
Used by [GitLab Code
Quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool).
```json
[
{
"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:
Expand Down
2 changes: 1 addition & 1 deletion dev.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: erb-lint

up:
- ruby: 2.5.3
- ruby: '3.2.2'
- bundler

commands:
Expand Down
55 changes: 55 additions & 0 deletions lib/erb_lint/reporters/gitlab_reporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

require "json"

module ERBLint
module Reporters
class GitlabReporter < Reporter
def preview; end

def show
puts formatted_data
end

private

def formatted_data
formatted_files.to_json
end

def formatted_files
processed_files.flat_map do |filename, offenses|
formatted_offenses(filename, offenses)
end
end

def formatted_offenses(filename, offenses)
offenses.map do |offense|
format_offense(filename, offense)
end
end

def format_offense(filename, offense)
{
description: offense.message,
check_name: offense.simple_name,
fingerprint: generate_fingerprint(filename, offense),
severity: offense.severity,
location: {
path: filename,
lines: {
begin: offense.line_number,
end: offense.last_line,
},
},
}
end

def generate_fingerprint(filename, offense)
Digest::MD5.hexdigest(
"#{offense.simple_name}@#{filename}:#{offense.line_number}:#{offense.last_line}"
)
end
end
end
end
2 changes: 1 addition & 1 deletion lib/erb_lint/runner_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def linters_config
def config_hash_for_linter(klass_name)
config_hash = linters_config[klass_name] || {}
config_hash["exclude"] ||= []
config_hash["exclude"].concat(global_exclude) if config_hash["exclude"].is_a?(Array)
config_hash["exclude"].concat(global_exclude).uniq! if config_hash["exclude"].is_a?(Array)
config_hash
end

Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module ERBLint
VERSION = "0.4.0"
VERSION = "0.5.0"
end
3 changes: 2 additions & 1 deletion spec/erb_lint/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def run(processed_source)
it "shows format instructions" do
expect { subject }.to(
output(Regexp.new("Report offenses in the given format: " \
"\\(compact, json, junit, multiline\\) " \
"\\(compact, gitlab, json, junit, multiline\\) " \
"\\(default: multiline\\)")).to_stdout
)
end
Expand Down Expand Up @@ -504,6 +504,7 @@ def run(processed_source)
expect { subject }.to(output(Regexp.new(Regexp.escape(<<~EOF.strip))).to_stderr)
nonexistentformat: is not a valid format. Available formats:
- compact
- gitlab
- json
- junit
- multiline
Expand Down
81 changes: 81 additions & 0 deletions spec/erb_lint/reporters/gitlab_reporter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

require "spec_helper"

describe ERBLint::Reporters::GitlabReporter do
describe ".show" do
subject { described_class.new(stats, false).show }

let(:stats) do
ERBLint::Stats.new(
found: 2,
processed_files: {
"app/views/subscriptions/_loader.html.erb" => offenses,
},
corrected: 1
)
end

let(:offenses) do
[
instance_double(
ERBLint::Offense,
message: "Extra space detected where there should be no space.",
line_number: 1,
column: 7,
simple_name: "SpaceInHtmlTag",
severity: "info",
last_line: 1,
last_column: 9,
length: 2,
),
instance_double(
ERBLint::Offense,
message: "Remove newline before `%>` to match start of tag.",
line_number: 52,
column: 10,
simple_name: "ClosingErbTagIndent",
severity: "warning",
last_line: 54,
last_column: 10,
length: 10,
),
]
end

let(:expected_hash) do
[
{
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 `%>` 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,
},
},
},
]
end

it "displays formatted offenses output" do
expect { subject }.to(output(expected_hash.to_json + "\n").to_stdout)
end
end
end
Loading

0 comments on commit 6edd106

Please sign in to comment.