Skip to content

Commit 0e8f328

Browse files
committed
Merge pull request #92 from adangel:include-full-pmd-report
Include full pmd report #92
2 parents d10e25c + 6616934 commit 0e8f328

26 files changed

+894
-51
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
## Fixed Issues
88

9+
* [#71](https://github.com/pmd/pmd-regression-tester/issues/71): Include full PMD report
910
* [#89](https://github.com/pmd/pmd-regression-tester/pull/89): Make it possible to select a subpath of cloned directory
1011
* [#91](https://github.com/pmd/pmd-regression-tester/pull/91): Filter baseline based on patch config
1112

Manifest.txt

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

lib/pmdtester/builders/liquid_renderer.rb

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,74 @@ def write_project_index(project, root)
5757
write_file("#{root}/index.html", render_liquid('project_diff_report.html', liquid_env))
5858
# generate array of violations in json
5959
write_file("#{root}/project_data.js", dump_violations_json(project))
60+
# copy original pmd reports
61+
copy_file("#{root}/base_pmd_report.xml", project.report_diff.base_report.file)
62+
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))
6070
end
6171

62-
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+
6381
h = {
6482
'source_link_base' => project.webview_url,
6583
'source_link_template' => link_template(project),
66-
**violations_to_hash(project)
84+
**violations_to_hash(project, violations_by_file, branch == 'diff')
6785
}
6886

69-
project_data = JSON.fast_generate(h)
87+
project_data = JSON.fast_generate(h, indent: ' ', object_nl: "\n", array_nl: "\n")
7088
"let project = #{project_data}"
7189
end
90+
91+
private
92+
93+
def copy_file(target_file, source_file)
94+
if File.exist? source_file
95+
FileUtils.cp(source_file, target_file)
96+
logger&.info "Written #{target_file}"
97+
else
98+
logger&.warn "File #{source_file} not found"
99+
end
100+
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
72129
end
73130
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/builders/summary_report_builder.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def to_liquid(details, config_name)
8080
'sha' => details.branch_last_sha,
8181
'message' => details.branch_last_message
8282
},
83+
'timestamp' => details.timestamp,
8384
'execution_time' => PmdReportDetail.convert_seconds(details.execution_time),
8485
'jdk_info' => details.jdk_version,
8586
'locale' => details.language,

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/pmd_branch_detail.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class PmdBranchDetail
1010
attr_accessor :branch_last_sha
1111
attr_accessor :branch_last_message
1212
attr_accessor :branch_name
13+
# Start of the regression report
14+
attr_accessor :timestamp
1315
# The branch's execution time on all standard projects
1416
attr_accessor :execution_time
1517
attr_accessor :jdk_version
@@ -26,6 +28,7 @@ def initialize(branch_name)
2628
@branch_name = branch_name
2729
branch_filename = PmdBranchDetail.branch_filename(branch_name)
2830
@base_branch_dir = "target/reports/#{branch_filename}" unless @branch_name.nil?
31+
@timestamp = Time.now
2932
@execution_time = 0
3033
# the result of command 'java -version' is going to stderr
3134
@jdk_version = Cmd.stderr_of('java -version')
@@ -42,11 +45,13 @@ def self.load(branch_name, logger)
4245
details.branch_last_sha = hash['branch_last_sha']
4346
details.branch_last_message = hash['branch_last_message']
4447
details.branch_name = hash['branch_name']
48+
details.timestamp = hash['timestamp']
4549
details.execution_time = hash['execution_time']
4650
details.jdk_version = hash['jdk_version']
4751
details.language = hash['language']
4852
details.pull_request = hash['pull_request']
4953
else
54+
details.timestamp = Time.now
5055
details.jdk_version = ''
5156
details.language = ''
5257
logger&.warn "#{details.path_to_save_file} doesn't exist!"
@@ -58,6 +63,7 @@ def save
5863
hash = { branch_last_sha: @branch_last_sha,
5964
branch_last_message: @branch_last_message,
6065
branch_name: @branch_name,
66+
timestamp: @timestamp,
6167
execution_time: @execution_time,
6268
jdk_version: @jdk_version,
6369
language: @language,

lib/pmdtester/pmd_tester_utils.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def parse_pmd_report(report_file, branch, report_details, filter_set = nil)
2929
parser.parse_file(report_file) if File.exist?(report_file)
3030
Report.new(
3131
report_document: doc,
32+
file: report_file,
3233

3334
timestamp: report_details.timestamp,
3435
exec_time: report_details.execution_time

lib/pmdtester/report_diff.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,45 @@ class Report
5757
:configerrors_by_rule,
5858
:exec_time,
5959
:timestamp,
60-
:infos_by_rule
60+
:file
6161

6262
def initialize(report_document: nil,
63+
file: '',
6364
exec_time: 0,
6465
timestamp: '0')
6566
initialize_empty
6667
initialize_with_report_document report_document unless report_document.nil?
6768
@exec_time = exec_time
6869
@timestamp = timestamp
70+
@file = file
6971
end
7072

7173
def self.empty
7274
new
7375
end
7476

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+
7593
private
7694

7795
def initialize_with_report_document(report_document)
7896
@violations_by_file = report_document.violations
7997
@errors_by_file = report_document.errors
8098
@configerrors_by_rule = report_document.configerrors
81-
@infos_by_rule = report_document.infos_by_rules
8299

83100
PmdTester.logger.debug("Loaded #{@violations_by_file.total_size} violations " \
84101
"in #{@violations_by_file.num_files} files")
@@ -91,7 +108,6 @@ def initialize_empty
91108
@violations_by_file = CollectionByFile.new
92109
@errors_by_file = CollectionByFile.new
93110
@configerrors_by_rule = {}
94-
@infos_by_rule = {}
95111
end
96112
end
97113

@@ -122,7 +138,7 @@ def initialize(base_report:, patch_report:)
122138
@error_diffs_by_file = {}
123139
@configerror_diffs_by_rule = {}
124140

125-
@rule_infos_union = base_report.infos_by_rule.dup
141+
@rule_infos_union = {}
126142
@base_report = base_report
127143
@patch_report = patch_report
128144

0 commit comments

Comments
 (0)