diff --git a/README.md b/README.md index 980589ce..1936ce7b 100644 --- a/README.md +++ b/README.md @@ -643,6 +643,42 @@ erblint --format junit ``` +### 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: diff --git a/lib/erb_lint/reporters/gitlab_reporter.rb b/lib/erb_lint/reporters/gitlab_reporter.rb new file mode 100644 index 00000000..b9001bcb --- /dev/null +++ b/lib/erb_lint/reporters/gitlab_reporter.rb @@ -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 diff --git a/spec/erb_lint/cli_spec.rb b/spec/erb_lint/cli_spec.rb index 4a3726cc..9663a4a7 100644 --- a/spec/erb_lint/cli_spec.rb +++ b/spec/erb_lint/cli_spec.rb @@ -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 @@ -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 diff --git a/spec/erb_lint/reporters/gitlab_reporter_spec.rb b/spec/erb_lint/reporters/gitlab_reporter_spec.rb new file mode 100644 index 00000000..04f0091b --- /dev/null +++ b/spec/erb_lint/reporters/gitlab_reporter_spec.rb @@ -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