Skip to content

Commit 6616934

Browse files
committed
Render full PMD report as html
Fixes #71
1 parent 6a30bc7 commit 6616934

16 files changed

+804
-57
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ Metrics/ClassLength:
2727
Metrics/BlockLength:
2828
Exclude:
2929
- 'lib/pmdtester/parsers/options.rb'
30+
31+
Metrics/ModuleLength:
32+
CountAsOne: ['array', 'hash']

History.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
## Fixed Issues
66

7+
* [#71](https://github.com/pmd/pmd-regression-tester/issues/71): Include full PMD report
8+
79
## External Contributions
810

911
# 1.1.2 / 2021-04-20

Manifest.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ resources/js/popper.min.js
5757
resources/js/project-report.js
5858
resources/project_diff_report.html
5959
resources/project_index.html
60+
resources/project_pmd_report.html

lib/pmdtester/builders/liquid_renderer.rb

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,31 @@ def write_project_index(project, root)
6060
# copy original pmd reports
6161
copy_file("#{root}/base_pmd_report.xml", project.report_diff.base_report.file)
6262
copy_file("#{root}/patch_pmd_report.xml", project.report_diff.patch_report.file)
63+
# render full pmd reports
64+
write_file("#{root}/base_pmd_report.html",
65+
render_liquid('project_pmd_report.html', pmd_report_liquid_env(project, BASE)))
66+
write_file("#{root}/base_data.js", dump_violations_json(project, BASE))
67+
write_file("#{root}/patch_pmd_report.html",
68+
render_liquid('project_pmd_report.html', pmd_report_liquid_env(project, PATCH)))
69+
write_file("#{root}/patch_data.js", dump_violations_json(project, PATCH))
6370
end
6471

65-
def dump_violations_json(project)
72+
def dump_violations_json(project, branch = 'diff')
73+
violations_by_file = if branch == BASE
74+
project.report_diff.base_report.violations_by_file.to_h
75+
elsif branch == PATCH
76+
project.report_diff.patch_report.violations_by_file.to_h
77+
else
78+
project.report_diff.violation_diffs_by_file
79+
end
80+
6681
h = {
6782
'source_link_base' => project.webview_url,
6883
'source_link_template' => link_template(project),
69-
**violations_to_hash(project)
84+
**violations_to_hash(project, violations_by_file, branch == 'diff')
7085
}
7186

72-
project_data = JSON.fast_generate(h)
87+
project_data = JSON.fast_generate(h, indent: ' ', object_nl: "\n", array_nl: "\n")
7388
"let project = #{project_data}"
7489
end
7590

@@ -83,5 +98,33 @@ def copy_file(target_file, source_file)
8398
logger&.warn "File #{source_file} not found"
8499
end
85100
end
101+
102+
def pmd_report_liquid_env(project, branch)
103+
report = if branch == BASE
104+
project.report_diff.base_report
105+
else
106+
project.report_diff.patch_report
107+
end
108+
{
109+
'project_name' => project.name,
110+
'branch' => branch,
111+
'report' => report_to_h(project, report)
112+
}
113+
end
114+
115+
def report_to_h(project, report)
116+
{
117+
'violation_counts' => report.violations_by_file.total_size,
118+
'error_counts' => report.errors_by_file.total_size,
119+
'configerror_counts' => report.configerrors_by_rule.values.flatten.length,
120+
121+
'execution_time' => PmdReportDetail.convert_seconds(report.exec_time),
122+
'timestamp' => report.timestamp,
123+
124+
'rules' => report.rule_summaries,
125+
'errors' => report.errors_by_file.all_values.map { |e| error_to_hash(e, project) },
126+
'configerrors' => report.configerrors_by_rule.values.flatten.map { |e| configerror_to_hash(e) }
127+
}
128+
end
86129
end
87130
end

lib/pmdtester/builders/project_hasher.rb

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,14 @@ def report_diff_to_h(rdiff)
2525
}
2626
end
2727

28-
def errors_to_h(project)
29-
errors = project.report_diff.error_diffs_by_file.values.flatten
30-
errors.map { |e| error_to_hash(e, project) }
31-
end
32-
33-
def configerrors_to_h(project)
34-
configerrors = project.report_diff.configerror_diffs_by_rule.values.flatten
35-
configerrors.map { |e| configerror_to_hash(e) }
36-
end
37-
38-
def violations_to_hash(project)
28+
def violations_to_hash(project, violations_by_file, is_diff)
3929
filename_index = []
4030
all_vs = []
41-
project.report_diff.violation_diffs_by_file.each do |file, vs|
31+
violations_by_file.each do |file, vs|
4232
file_ref = filename_index.size
4333
filename_index.push(project.get_local_path(file))
4434
vs.each do |v|
45-
all_vs.push(make_violation_hash(file_ref, v))
35+
all_vs.push(make_violation_hash(file_ref, v, is_diff))
4636
end
4737
end
4838

@@ -52,36 +42,19 @@ def violations_to_hash(project)
5242
}
5343
end
5444

55-
def link_template(project)
56-
l_str = project.type == 'git' ? 'L' : 'l'
57-
"#{project.webview_url}/{file}##{l_str}{line}"
58-
end
59-
60-
def violation_type(violation)
61-
if violation.changed?
62-
'~'
63-
elsif violation.branch == 'patch'
64-
'+'
65-
else
66-
'-'
67-
end
45+
def errors_to_h(project)
46+
errors = project.report_diff.error_diffs_by_file.values.flatten
47+
errors.map { |e| error_to_hash(e, project) }
6848
end
6949

70-
def make_violation_hash(file_ref, violation)
71-
h = {
72-
't' => violation_type(violation),
73-
'l' => violation.line,
74-
'f' => file_ref,
75-
'r' => violation.rule_name,
76-
'm' => violation.changed? ? diff_fragments(violation) : violation.message
77-
}
78-
h['ol'] = violation.old_line if violation.changed? && violation.line != violation.old_line
79-
h
50+
def configerrors_to_h(project)
51+
configerrors = project.report_diff.configerror_diffs_by_rule.values.flatten
52+
configerrors.map { |e| configerror_to_hash(e) }
8053
end
8154

82-
def diff_fragments(violation)
83-
diff = Differ.diff_by_word(violation.message, violation.old_message)
84-
diff.format_as(:html)
55+
def link_template(project)
56+
l_str = project.type == 'git' ? 'L' : 'l'
57+
"#{project.webview_url}/{file}##{l_str}{line}"
8558
end
8659

8760
def error_to_hash(error, project)
@@ -122,5 +95,34 @@ def change_type(item)
12295
'added'
12396
end
12497
end
98+
99+
private
100+
101+
def violation_type(violation)
102+
if violation.changed?
103+
'~'
104+
elsif violation.branch == PATCH
105+
'+'
106+
else
107+
'-'
108+
end
109+
end
110+
111+
def make_violation_hash(file_ref, violation, is_diff = TRUE)
112+
h = {
113+
't' => is_diff ? violation_type(violation) : '+',
114+
'l' => violation.line,
115+
'f' => file_ref,
116+
'r' => violation.rule_name,
117+
'm' => is_diff && violation.changed? ? diff_fragments(violation) : violation.message
118+
}
119+
h['ol'] = violation.old_line if is_diff && violation.changed? && violation.line != violation.old_line
120+
h
121+
end
122+
123+
def diff_fragments(violation)
124+
diff = Differ.diff_by_word(violation.message, violation.old_message)
125+
diff.format_as(:html)
126+
end
125127
end
126128
end

lib/pmdtester/parsers/pmd_report_document.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ class PmdReportDocument < Nokogiri::XML::SAX::Document
88
attr_reader :violations
99
attr_reader :errors
1010
attr_reader :configerrors
11-
attr_reader :infos_by_rules
1211

1312
def initialize(branch_name, working_dir, filter_set = nil)
1413
@violations = CollectionByFile.new
1514
@errors = CollectionByFile.new
1615
@configerrors = Hash.new { |hash, key| hash[key] = [] }
1716

18-
@infos_by_rules = {}
1917
@current_violations = []
2018
@current_violation = nil
2119
@current_error = nil

lib/pmdtester/report_diff.rb

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class Report
5757
:configerrors_by_rule,
5858
:exec_time,
5959
:timestamp,
60-
:infos_by_rule,
6160
:file
6261

6362
def initialize(report_document: nil,
@@ -75,13 +74,28 @@ def self.empty
7574
new
7675
end
7776

77+
def rule_summaries
78+
summary = {}
79+
@violations_by_file.each_value do |violation|
80+
unless summary.key?(violation.rule_name)
81+
summary[violation.rule_name] = {
82+
'name' => violation.rule_name,
83+
'info_url' => violation.info_url,
84+
'count' => 0
85+
}
86+
end
87+
summary[violation.rule_name]['count'] += 1
88+
end
89+
90+
summary.values
91+
end
92+
7893
private
7994

8095
def initialize_with_report_document(report_document)
8196
@violations_by_file = report_document.violations
8297
@errors_by_file = report_document.errors
8398
@configerrors_by_rule = report_document.configerrors
84-
@infos_by_rule = report_document.infos_by_rules
8599

86100
PmdTester.logger.debug("Loaded #{@violations_by_file.total_size} violations " \
87101
"in #{@violations_by_file.num_files} files")
@@ -94,7 +108,6 @@ def initialize_empty
94108
@violations_by_file = CollectionByFile.new
95109
@errors_by_file = CollectionByFile.new
96110
@configerrors_by_rule = {}
97-
@infos_by_rule = {}
98111
end
99112
end
100113

@@ -125,7 +138,7 @@ def initialize(base_report:, patch_report:)
125138
@error_diffs_by_file = {}
126139
@configerror_diffs_by_rule = {}
127140

128-
@rule_infos_union = base_report.infos_by_rule.dup
141+
@rule_infos_union = {}
129142
@base_report = base_report
130143
@patch_report = patch_report
131144

pmdtester.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ Gem::Specification.new do |s|
1111
s.metadata = { "bug_tracker_uri" => "https://github.com/pmd/pmd-regression-tester/issues", "homepage_uri" => "https://pmd.github.io", "source_code_uri" => "https://github.com/pmd/pmd-regression-tester" } if s.respond_to? :metadata=
1212
s.require_paths = ["lib".freeze]
1313
s.authors = ["Andreas Dangel".freeze, "Binguo Bao".freeze, "Cl\u00E9ment Fournier".freeze]
14-
s.date = "2021-06-17"
14+
s.date = "2021-06-18"
1515
s.description = "A regression testing tool ensure that new problems and unexpected behaviors will not be introduced to PMD project after fixing an issue , and new rules can work as expected.".freeze
1616
s.email = ["andreas.dangel@pmd-code.org".freeze, "djydewang@gmail.com".freeze, "clement.fournier76@gmail.com".freeze]
1717
s.executables = ["pmdtester".freeze]
1818
s.extra_rdoc_files = ["History.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze]
19-
s.files = [".ci/build.sh".freeze, ".ci/inc/fetch_ci_scripts.bash".freeze, ".ci/manual-integration-tests.sh".freeze, ".github/workflows/build.yml".freeze, ".github/workflows/manual-integration-tests.yml".freeze, ".gitignore".freeze, ".hoerc".freeze, ".rubocop.yml".freeze, ".rubocop_todo.yml".freeze, ".ruby-version".freeze, "Gemfile".freeze, "History.md".freeze, "LICENSE".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "Rakefile".freeze, "bin/pmdtester".freeze, "config/all-java.xml".freeze, "config/design.xml".freeze, "config/project-list.xml".freeze, "config/projectlist_1_0_0.xsd".freeze, "config/projectlist_1_1_0.xsd".freeze, "lib/pmdtester.rb".freeze, "lib/pmdtester/builders/liquid_renderer.rb".freeze, "lib/pmdtester/builders/pmd_report_builder.rb".freeze, "lib/pmdtester/builders/project_builder.rb".freeze, "lib/pmdtester/builders/project_hasher.rb".freeze, "lib/pmdtester/builders/rule_set_builder.rb".freeze, "lib/pmdtester/builders/simple_progress_logger.rb".freeze, "lib/pmdtester/builders/summary_report_builder.rb".freeze, "lib/pmdtester/cmd.rb".freeze, "lib/pmdtester/collection_by_file.rb".freeze, "lib/pmdtester/parsers/options.rb".freeze, "lib/pmdtester/parsers/pmd_report_document.rb".freeze, "lib/pmdtester/parsers/projects_parser.rb".freeze, "lib/pmdtester/pmd_branch_detail.rb".freeze, "lib/pmdtester/pmd_configerror.rb".freeze, "lib/pmdtester/pmd_error.rb".freeze, "lib/pmdtester/pmd_report_detail.rb".freeze, "lib/pmdtester/pmd_tester_utils.rb".freeze, "lib/pmdtester/pmd_violation.rb".freeze, "lib/pmdtester/project.rb".freeze, "lib/pmdtester/report_diff.rb".freeze, "lib/pmdtester/resource_locator.rb".freeze, "lib/pmdtester/runner.rb".freeze, "pmdtester.gemspec".freeze, "resources/_includes/diff_pill_row.html".freeze, "resources/css/bootstrap.min.css".freeze, "resources/css/datatables.min.css".freeze, "resources/css/pmd-tester.css".freeze, "resources/js/bootstrap.min.js".freeze, "resources/js/code-snippets.js".freeze, "resources/js/datatables.min.js".freeze, "resources/js/jquery-3.2.1.slim.min.js".freeze, "resources/js/jquery.min.js".freeze, "resources/js/popper.min.js".freeze, "resources/js/project-report.js".freeze, "resources/project_diff_report.html".freeze, "resources/project_index.html".freeze]
19+
s.files = [".ci/build.sh".freeze, ".ci/inc/fetch_ci_scripts.bash".freeze, ".ci/manual-integration-tests.sh".freeze, ".github/workflows/build.yml".freeze, ".github/workflows/manual-integration-tests.yml".freeze, ".gitignore".freeze, ".hoerc".freeze, ".rubocop.yml".freeze, ".rubocop_todo.yml".freeze, ".ruby-version".freeze, "Gemfile".freeze, "History.md".freeze, "LICENSE".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "Rakefile".freeze, "bin/pmdtester".freeze, "config/all-java.xml".freeze, "config/design.xml".freeze, "config/project-list.xml".freeze, "config/projectlist_1_0_0.xsd".freeze, "config/projectlist_1_1_0.xsd".freeze, "lib/pmdtester.rb".freeze, "lib/pmdtester/builders/liquid_renderer.rb".freeze, "lib/pmdtester/builders/pmd_report_builder.rb".freeze, "lib/pmdtester/builders/project_builder.rb".freeze, "lib/pmdtester/builders/project_hasher.rb".freeze, "lib/pmdtester/builders/rule_set_builder.rb".freeze, "lib/pmdtester/builders/simple_progress_logger.rb".freeze, "lib/pmdtester/builders/summary_report_builder.rb".freeze, "lib/pmdtester/cmd.rb".freeze, "lib/pmdtester/collection_by_file.rb".freeze, "lib/pmdtester/parsers/options.rb".freeze, "lib/pmdtester/parsers/pmd_report_document.rb".freeze, "lib/pmdtester/parsers/projects_parser.rb".freeze, "lib/pmdtester/pmd_branch_detail.rb".freeze, "lib/pmdtester/pmd_configerror.rb".freeze, "lib/pmdtester/pmd_error.rb".freeze, "lib/pmdtester/pmd_report_detail.rb".freeze, "lib/pmdtester/pmd_tester_utils.rb".freeze, "lib/pmdtester/pmd_violation.rb".freeze, "lib/pmdtester/project.rb".freeze, "lib/pmdtester/report_diff.rb".freeze, "lib/pmdtester/resource_locator.rb".freeze, "lib/pmdtester/runner.rb".freeze, "pmdtester.gemspec".freeze, "resources/_includes/diff_pill_row.html".freeze, "resources/css/bootstrap.min.css".freeze, "resources/css/datatables.min.css".freeze, "resources/css/pmd-tester.css".freeze, "resources/js/bootstrap.min.js".freeze, "resources/js/code-snippets.js".freeze, "resources/js/datatables.min.js".freeze, "resources/js/jquery-3.2.1.slim.min.js".freeze, "resources/js/jquery.min.js".freeze, "resources/js/popper.min.js".freeze, "resources/js/project-report.js".freeze, "resources/project_diff_report.html".freeze, "resources/project_index.html".freeze, "resources/project_pmd_report.html".freeze]
2020
s.homepage = "https://pmd.github.io".freeze
2121
s.licenses = ["BSD-2-Clause".freeze]
2222
s.rdoc_options = ["--main".freeze, "README.rdoc".freeze]

resources/js/project-report.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ $(document).ready(function () {
5757
viewTotal: true,
5858
cascadePanes: true,
5959
columns: [0, 1, 3],
60-
order: ['Rule', 'Location (click row to expand)', 'Type']
60+
order: ['Rule', 'Location (click row to expand)', 'Type'],
61+
threshold: 1 // always show filters in search pane (default: 0.6)
6162
},
6263
// scrollCollapse: true,
6364
// paging: false,

resources/project_diff_report.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ <h2>Summary</h2>
7373
</tr>
7474
<tr>
7575
<td class="item">Full Report</td>
76-
<td class="base"><a href="base_pmd_report.xml">Base pmd_report.xml</a></td>
77-
<td class="patch"><a href="patch_pmd_report.xml">Patch pmd_report.xml</a></td>
76+
<td class="base"><a href="base_pmd_report.html">Base PMD Report</a></td>
77+
<td class="patch"><a href="patch_pmd_report.html">Patch PMD Report</a></td>
7878
<td class="diff"></td>
7979
</tr>
8080
</tbody>

0 commit comments

Comments
 (0)