pmdtester 1.0.0.pre.beta2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ci/build.sh +67 -0
- data/.ci/files/env.gpg +1 -0
- data/.ci/inc/install-openjdk.inc +26 -0
- data/.ci/manual-integration-tests.sh +20 -0
- data/.github/workflows/build.yml +39 -0
- data/.github/workflows/manual-integration-tests.yml +32 -0
- data/.gitignore +9 -0
- data/.hoerc +1 -0
- data/.rubocop.yml +21 -2
- data/.rubocop_todo.yml +7 -8
- data/.ruby-version +1 -0
- data/Gemfile +1 -13
- data/History.md +108 -0
- data/Manifest.txt +60 -0
- data/README.rdoc +130 -7
- data/Rakefile +31 -17
- data/bin/pmdtester +1 -1
- data/config/all-java.xml +1 -1
- data/config/design.xml +1 -1
- data/config/projectlist_1_0_0.xsd +2 -1
- data/config/projectlist_1_1_0.xsd +31 -0
- data/lib/pmdtester.rb +48 -0
- data/lib/pmdtester/builders/liquid_renderer.rb +73 -0
- data/lib/pmdtester/builders/pmd_report_builder.rb +133 -64
- data/lib/pmdtester/builders/project_builder.rb +100 -0
- data/lib/pmdtester/builders/project_hasher.rb +126 -0
- data/lib/pmdtester/builders/rule_set_builder.rb +95 -51
- data/lib/pmdtester/builders/simple_progress_logger.rb +27 -0
- data/lib/pmdtester/builders/summary_report_builder.rb +62 -120
- data/lib/pmdtester/cmd.rb +15 -1
- data/lib/pmdtester/collection_by_file.rb +55 -0
- data/lib/pmdtester/parsers/options.rb +33 -10
- data/lib/pmdtester/parsers/pmd_report_document.rb +79 -29
- data/lib/pmdtester/parsers/projects_parser.rb +2 -6
- data/lib/pmdtester/pmd_branch_detail.rb +36 -13
- data/lib/pmdtester/pmd_configerror.rb +62 -0
- data/lib/pmdtester/pmd_error.rb +34 -34
- data/lib/pmdtester/pmd_report_detail.rb +10 -13
- data/lib/pmdtester/pmd_tester_utils.rb +57 -0
- data/lib/pmdtester/pmd_violation.rb +66 -26
- data/lib/pmdtester/project.rb +28 -25
- data/lib/pmdtester/report_diff.rb +194 -70
- data/lib/pmdtester/resource_locator.rb +4 -0
- data/lib/pmdtester/runner.rb +82 -57
- data/pmdtester.gemspec +64 -0
- data/resources/_includes/diff_pill_row.html +6 -0
- data/resources/css/bootstrap.min.css +7 -0
- data/resources/css/datatables.min.css +36 -0
- data/resources/css/pmd-tester.css +131 -0
- data/resources/js/bootstrap.min.js +7 -0
- data/resources/js/code-snippets.js +66 -0
- data/resources/js/datatables.min.js +726 -0
- data/resources/js/jquery-3.2.1.slim.min.js +4 -0
- data/resources/js/jquery.min.js +2 -0
- data/resources/js/popper.min.js +5 -0
- data/resources/js/project-report.js +136 -0
- data/resources/project_diff_report.html +205 -0
- data/resources/project_index.html +102 -0
- metadata +117 -44
- data/.travis.yml +0 -22
- data/lib/pmdtester/builders/diff_builder.rb +0 -35
- data/lib/pmdtester/builders/diff_report_builder.rb +0 -226
- data/lib/pmdtester/builders/html_report_builder.rb +0 -34
- data/lib/pmdtester/pmdtester.rb +0 -17
- data/resources/css/maven-base.css +0 -155
- data/resources/css/maven-theme.css +0 -171
data/lib/pmdtester/project.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative './pmd_branch_detail'
|
|
4
|
-
|
|
5
3
|
module PmdTester
|
|
6
4
|
# This class represents all the information about the project
|
|
7
5
|
class Project
|
|
6
|
+
include PmdTesterUtils
|
|
7
|
+
|
|
8
8
|
REPOSITORIES_PATH = 'target/repositories'
|
|
9
9
|
|
|
10
10
|
attr_reader :name
|
|
@@ -15,15 +15,17 @@ module PmdTester
|
|
|
15
15
|
attr_reader :exclude_pattern
|
|
16
16
|
attr_accessor :report_diff
|
|
17
17
|
# key: pmd branch name as String => value: local path of pmd report
|
|
18
|
+
attr_reader :build_command
|
|
19
|
+
attr_reader :auxclasspath_command
|
|
20
|
+
# stores the auxclasspath calculated after cloning/preparing the project
|
|
21
|
+
attr_accessor :auxclasspath
|
|
18
22
|
|
|
19
23
|
def initialize(project)
|
|
20
24
|
@name = project.at_xpath('name').text
|
|
21
25
|
@type = project.at_xpath('type').text
|
|
22
26
|
@connection = project.at_xpath('connection').text
|
|
23
27
|
|
|
24
|
-
@tag = 'master'
|
|
25
|
-
tag_element = project.at_xpath('tag')
|
|
26
|
-
@tag = tag_element.text unless tag_element.nil?
|
|
28
|
+
@tag = project.at_xpath('tag')&.text || 'master'
|
|
27
29
|
|
|
28
30
|
webview_url_element = project.at_xpath('webview-url')
|
|
29
31
|
@webview_url = default_webview_url
|
|
@@ -34,6 +36,9 @@ module PmdTester
|
|
|
34
36
|
@exclude_pattern.push(ep.text)
|
|
35
37
|
end
|
|
36
38
|
|
|
39
|
+
@build_command = project.at_xpath('build-command')&.text
|
|
40
|
+
@auxclasspath_command = project.at_xpath('auxclasspath-command')&.text
|
|
41
|
+
|
|
37
42
|
@report_diff = nil
|
|
38
43
|
end
|
|
39
44
|
|
|
@@ -60,6 +65,10 @@ module PmdTester
|
|
|
60
65
|
file_path.gsub(%r{/#{local_source_path}}, @name)
|
|
61
66
|
end
|
|
62
67
|
|
|
68
|
+
def get_local_path(file_path)
|
|
69
|
+
file_path.sub(%r{/#{local_source_path}/}, '')
|
|
70
|
+
end
|
|
71
|
+
|
|
63
72
|
def get_pmd_report_path(branch_name)
|
|
64
73
|
if branch_name.nil?
|
|
65
74
|
nil
|
|
@@ -76,6 +85,14 @@ module PmdTester
|
|
|
76
85
|
end
|
|
77
86
|
end
|
|
78
87
|
|
|
88
|
+
def get_config_path(branch_name)
|
|
89
|
+
if branch_name.nil?
|
|
90
|
+
nil
|
|
91
|
+
else
|
|
92
|
+
"#{get_project_target_dir(branch_name)}/config.xml"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
79
96
|
def get_project_target_dir(branch_name)
|
|
80
97
|
branch_filename = PmdBranchDetail.branch_filename(branch_name)
|
|
81
98
|
dir = "target/reports/#{branch_filename}/#{@name}"
|
|
@@ -87,26 +104,12 @@ module PmdTester
|
|
|
87
104
|
"#{REPOSITORIES_PATH}/#{@name}"
|
|
88
105
|
end
|
|
89
106
|
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def diff_report_index_path
|
|
97
|
-
"#{target_diff_report_path}/index.html"
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def diff_report_index_ref_path
|
|
101
|
-
"./#{name}/index.html"
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def diffs_exist?
|
|
105
|
-
@report_diff.diffs_exist?
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def introduce_new_errors?
|
|
109
|
-
@report_diff.introduce_new_errors?
|
|
107
|
+
def compute_report_diff(base_branch, patch_branch, filter_set)
|
|
108
|
+
self.report_diff = build_report_diff(get_pmd_report_path(base_branch),
|
|
109
|
+
get_pmd_report_path(patch_branch),
|
|
110
|
+
get_report_info_path(base_branch),
|
|
111
|
+
get_report_info_path(patch_branch),
|
|
112
|
+
filter_set)
|
|
110
113
|
end
|
|
111
114
|
end
|
|
112
115
|
end
|
|
@@ -1,111 +1,235 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PmdTester
|
|
4
|
+
# A bunch of counters to summarize differences
|
|
5
|
+
class RunningDiffCounters
|
|
6
|
+
attr_accessor :changed, :new, :removed, :patch_total, :base_total
|
|
7
|
+
|
|
8
|
+
def initialize(base_total)
|
|
9
|
+
@base_total = base_total
|
|
10
|
+
@patch_total = 0
|
|
11
|
+
|
|
12
|
+
@new = @removed = @changed = 0
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def changed_total
|
|
16
|
+
new + removed + changed
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def merge!(other)
|
|
20
|
+
self.changed += other.changed
|
|
21
|
+
self.new += other.new
|
|
22
|
+
self.removed += other.removed
|
|
23
|
+
self.base_total += other.base_total
|
|
24
|
+
self.patch_total += other.patch_total
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_h
|
|
28
|
+
{
|
|
29
|
+
changed: changed,
|
|
30
|
+
new: new,
|
|
31
|
+
removed: removed,
|
|
32
|
+
base_total: base_total,
|
|
33
|
+
patch_total: patch_total
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_s
|
|
38
|
+
"RunningDiffCounters[#{to_h}]"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Simple info about a rule, collected by the report xml parser
|
|
43
|
+
class RuleInfo
|
|
44
|
+
attr_reader :name, :info_url
|
|
45
|
+
|
|
46
|
+
def initialize(name, info_url)
|
|
47
|
+
@name = name
|
|
48
|
+
@info_url = info_url
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# A full report, created by the report XML parser,
|
|
53
|
+
# can be diffed with another report into a ReportDiff
|
|
54
|
+
class Report
|
|
55
|
+
attr_reader :violations_by_file,
|
|
56
|
+
:errors_by_file,
|
|
57
|
+
:configerrors_by_rule,
|
|
58
|
+
:exec_time,
|
|
59
|
+
:timestamp,
|
|
60
|
+
:infos_by_rule
|
|
61
|
+
|
|
62
|
+
def initialize(report_document: nil,
|
|
63
|
+
exec_time: 0,
|
|
64
|
+
timestamp: '0')
|
|
65
|
+
initialize_empty
|
|
66
|
+
initialize_with_report_document report_document unless report_document.nil?
|
|
67
|
+
@exec_time = exec_time
|
|
68
|
+
@timestamp = timestamp
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.empty
|
|
72
|
+
new
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def initialize_with_report_document(report_document)
|
|
78
|
+
@violations_by_file = report_document.violations
|
|
79
|
+
@errors_by_file = report_document.errors
|
|
80
|
+
@configerrors_by_rule = report_document.configerrors
|
|
81
|
+
@infos_by_rule = report_document.infos_by_rules
|
|
82
|
+
|
|
83
|
+
PmdTester.logger.debug("Loaded #{@violations_by_file.total_size} violations " \
|
|
84
|
+
"in #{@violations_by_file.num_files} files")
|
|
85
|
+
PmdTester.logger.debug("Loaded #{@errors_by_file.total_size} errors " \
|
|
86
|
+
"in #{@errors_by_file.num_files} files")
|
|
87
|
+
PmdTester.logger.debug("Loaded #{@configerrors_by_rule.size} config errors")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def initialize_empty
|
|
91
|
+
@violations_by_file = CollectionByFile.new
|
|
92
|
+
@errors_by_file = CollectionByFile.new
|
|
93
|
+
@configerrors_by_rule = {}
|
|
94
|
+
@infos_by_rule = {}
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
4
98
|
# This class represents all the diff report information,
|
|
5
99
|
# including the summary information of the original pmd reports,
|
|
6
100
|
# as well as the specific information of the diff report.
|
|
7
101
|
class ReportDiff
|
|
8
|
-
|
|
9
|
-
attr_accessor :patch_violations_size
|
|
10
|
-
attr_accessor :violation_diffs_size
|
|
11
|
-
|
|
12
|
-
attr_accessor :base_errors_size
|
|
13
|
-
attr_accessor :patch_errors_size
|
|
14
|
-
attr_accessor :error_diffs_size
|
|
102
|
+
include PmdTester
|
|
15
103
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
104
|
+
attr_reader :error_counts
|
|
105
|
+
attr_reader :violation_counts
|
|
106
|
+
attr_reader :configerror_counts
|
|
19
107
|
|
|
20
|
-
attr_accessor :
|
|
21
|
-
attr_accessor :
|
|
108
|
+
attr_accessor :violation_diffs_by_file
|
|
109
|
+
attr_accessor :error_diffs_by_file
|
|
110
|
+
attr_accessor :configerror_diffs_by_rule
|
|
22
111
|
|
|
23
|
-
attr_accessor :
|
|
24
|
-
attr_accessor :
|
|
112
|
+
attr_accessor :rule_infos_union
|
|
113
|
+
attr_accessor :base_report
|
|
114
|
+
attr_accessor :patch_report
|
|
25
115
|
|
|
26
|
-
def initialize
|
|
27
|
-
@
|
|
28
|
-
@
|
|
29
|
-
@
|
|
116
|
+
def initialize(base_report:, patch_report:)
|
|
117
|
+
@violation_counts = RunningDiffCounters.new(base_report.violations_by_file.total_size)
|
|
118
|
+
@error_counts = RunningDiffCounters.new(base_report.errors_by_file.total_size)
|
|
119
|
+
@configerror_counts = RunningDiffCounters.new(base_report.configerrors_by_rule.values.flatten.length)
|
|
30
120
|
|
|
31
|
-
@
|
|
32
|
-
@
|
|
33
|
-
@
|
|
121
|
+
@violation_diffs_by_file = {}
|
|
122
|
+
@error_diffs_by_file = {}
|
|
123
|
+
@configerror_diffs_by_rule = {}
|
|
34
124
|
|
|
35
|
-
@
|
|
36
|
-
@
|
|
37
|
-
@
|
|
125
|
+
@rule_infos_union = base_report.infos_by_rule.dup
|
|
126
|
+
@base_report = base_report
|
|
127
|
+
@patch_report = patch_report
|
|
38
128
|
|
|
39
|
-
@
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@violation_diffs = {}
|
|
43
|
-
@error_diffs = {}
|
|
129
|
+
@violation_diffs_by_rule = {}
|
|
130
|
+
diff_with(patch_report)
|
|
44
131
|
end
|
|
45
132
|
|
|
46
|
-
def
|
|
47
|
-
|
|
133
|
+
def rule_summaries
|
|
134
|
+
@violation_diffs_by_rule.map do |(rule, counters)|
|
|
135
|
+
{
|
|
136
|
+
'name' => rule,
|
|
137
|
+
'info_url' => @rule_infos_union[rule].info_url,
|
|
138
|
+
**counters.to_h.transform_keys(&:to_s)
|
|
139
|
+
}
|
|
140
|
+
end
|
|
48
141
|
end
|
|
49
142
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@
|
|
55
|
-
@
|
|
56
|
-
|
|
143
|
+
private
|
|
144
|
+
|
|
145
|
+
def diff_with(patch_report)
|
|
146
|
+
@violation_counts.patch_total = patch_report.violations_by_file.total_size
|
|
147
|
+
@error_counts.patch_total = patch_report.errors_by_file.total_size
|
|
148
|
+
@configerror_counts.patch_total = patch_report.configerrors_by_rule.values.flatten.length
|
|
149
|
+
|
|
150
|
+
@violation_diffs_by_file = build_diffs(@violation_counts, &:violations_by_file)
|
|
151
|
+
count(@violation_diffs_by_file) { |v| getvdiff(v.rule_name) } # record the diffs in the rule counter
|
|
152
|
+
|
|
153
|
+
@error_diffs_by_file = build_diffs(@error_counts, &:errors_by_file)
|
|
154
|
+
@configerror_diffs_by_rule = build_diffs(@configerror_counts, &:configerrors_by_rule)
|
|
57
155
|
|
|
58
|
-
|
|
59
|
-
@
|
|
60
|
-
|
|
61
|
-
error_diffs = build_diffs(base_errors.errors, patch_errors.errors)
|
|
62
|
-
@error_diffs = error_diffs
|
|
63
|
-
@error_diffs_size = get_diffs_size(error_diffs)
|
|
156
|
+
count_by_rule(@base_report.violations_by_file, base: true)
|
|
157
|
+
count_by_rule(@patch_report.violations_by_file, base: false)
|
|
158
|
+
self
|
|
64
159
|
end
|
|
65
160
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
base_details.load(base_info) unless base_info.nil?
|
|
69
|
-
patch_details = PmdReportDetail.new
|
|
70
|
-
patch_details.load(patch_info) unless patch_info.nil?
|
|
161
|
+
def record_rule_info(violation)
|
|
162
|
+
return if @rule_infos_union.key?(violation.rule_name)
|
|
71
163
|
|
|
72
|
-
@
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
164
|
+
@rule_infos_union[violation.rule_name] = RuleInfo.new(violation.rule_name, violation.info_url)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def getvdiff(rule_name)
|
|
168
|
+
@violation_diffs_by_rule.fetch(rule_name) do |_|
|
|
169
|
+
@violation_diffs_by_rule[rule_name] = RunningDiffCounters.new(0)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
77
172
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
173
|
+
def count_by_rule(violations_h, base:)
|
|
174
|
+
violations_h.each_value do |v|
|
|
175
|
+
record_rule_info(v)
|
|
176
|
+
rule_diff = getvdiff(v.rule_name)
|
|
177
|
+
if base
|
|
178
|
+
rule_diff.base_total += 1
|
|
179
|
+
else
|
|
180
|
+
rule_diff.patch_total += 1
|
|
181
|
+
end
|
|
182
|
+
end
|
|
81
183
|
end
|
|
82
184
|
|
|
83
|
-
def build_diffs(
|
|
84
|
-
|
|
185
|
+
def build_diffs(counters, &getter)
|
|
186
|
+
base_hash = getter.yield(@base_report)
|
|
187
|
+
patch_hash = getter.yield(@patch_report)
|
|
188
|
+
# Keys are filenames
|
|
189
|
+
# Values are lists of violations/errors
|
|
190
|
+
diffs = base_hash.to_h.merge(patch_hash.to_h) do |_key, base_value, patch_value|
|
|
191
|
+
# make the difference of values
|
|
85
192
|
(base_value | patch_value) - (base_value & patch_value)
|
|
86
193
|
end
|
|
87
194
|
|
|
88
195
|
diffs.delete_if do |_key, value|
|
|
89
196
|
value.empty?
|
|
90
197
|
end
|
|
198
|
+
|
|
199
|
+
merge_changed_items(diffs)
|
|
200
|
+
count(diffs) { |_| counters }
|
|
201
|
+
diffs
|
|
91
202
|
end
|
|
92
203
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
204
|
+
# @param diff_h a hash { filename => list[violation]}, containing those that changed
|
|
205
|
+
# in case of config errors it's a hash { rulename => list[configerror] }
|
|
206
|
+
def merge_changed_items(diff_h)
|
|
207
|
+
diff_h.each do |fname, different|
|
|
208
|
+
different.sort_by!(&:sort_key)
|
|
209
|
+
diff_h[fname] = different.delete_if do |v|
|
|
210
|
+
v.branch == BASE &&
|
|
211
|
+
# try_merge will set v2.changed = true if it succeeds
|
|
212
|
+
different.any? { |v2| v2.try_merge?(v) }
|
|
213
|
+
end
|
|
97
214
|
end
|
|
98
|
-
size
|
|
99
215
|
end
|
|
100
216
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
217
|
+
def count(item_h)
|
|
218
|
+
item_h = { '' => item_h } if item_h.is_a?(Array)
|
|
219
|
+
|
|
220
|
+
item_h.each do |_k, items|
|
|
221
|
+
items.each do |item|
|
|
222
|
+
counter = yield item
|
|
223
|
+
|
|
224
|
+
if item.changed?
|
|
225
|
+
counter.changed += 1
|
|
226
|
+
elsif item.branch.eql?(BASE)
|
|
227
|
+
counter.removed += 1
|
|
228
|
+
else
|
|
229
|
+
counter.new += 1
|
|
230
|
+
end
|
|
105
231
|
end
|
|
106
232
|
end
|
|
107
|
-
|
|
108
|
-
false
|
|
109
233
|
end
|
|
110
234
|
end
|
|
111
235
|
end
|
data/lib/pmdtester/runner.rb
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative './builders/diff_builder.rb'
|
|
4
|
-
require_relative './builders/diff_report_builder.rb'
|
|
5
|
-
require_relative './builders/rule_set_builder'
|
|
6
|
-
require_relative './builders/summary_report_builder.rb'
|
|
7
|
-
require_relative './builders/pmd_report_builder.rb'
|
|
8
|
-
require_relative './parsers/options'
|
|
9
|
-
require_relative './parsers/projects_parser'
|
|
10
|
-
require_relative './pmdtester'
|
|
11
|
-
require_relative './pmd_branch_detail'
|
|
12
|
-
|
|
13
3
|
module PmdTester
|
|
14
4
|
# The Runner is a class responsible of organizing all PmdTester modules
|
|
15
5
|
# and running the PmdTester
|
|
16
6
|
class Runner
|
|
17
|
-
include
|
|
7
|
+
include PmdTesterUtils
|
|
8
|
+
|
|
18
9
|
def initialize(argv)
|
|
19
10
|
@options = Options.new(argv)
|
|
20
11
|
end
|
|
21
12
|
|
|
22
13
|
def run
|
|
14
|
+
clean unless @options.keep_reports
|
|
15
|
+
|
|
23
16
|
case @options.mode
|
|
24
17
|
when Options::LOCAL
|
|
25
18
|
run_local_mode
|
|
@@ -28,54 +21,74 @@ module PmdTester
|
|
|
28
21
|
when Options::SINGLE
|
|
29
22
|
run_single_mode
|
|
30
23
|
end
|
|
24
|
+
|
|
25
|
+
summarize_diffs
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def clean
|
|
29
|
+
clean_target = 'target/reports'
|
|
30
|
+
FileUtils.remove_dir(clean_target) if Dir.exist?(clean_target)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def run_local_mode
|
|
34
34
|
logger.info "Mode: #{@options.mode}"
|
|
35
|
-
RuleSetBuilder.new(@options).build if @options.auto_config_flag
|
|
36
|
-
|
|
37
35
|
get_projects(@options.project_list) unless @options.nil?
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
build_html_reports
|
|
36
|
+
rule_sets = RuleSetBuilder.new(@options).build if @options.auto_config_flag
|
|
37
|
+
return if rule_sets&.empty?
|
|
38
|
+
|
|
39
|
+
base_branch_details = create_pmd_report(config: @options.base_config, branch: @options.base_branch)
|
|
40
|
+
patch_branch_details = create_pmd_report(config: @options.patch_config, branch: @options.patch_branch)
|
|
41
|
+
|
|
42
|
+
build_html_reports(@projects, base_branch_details, patch_branch_details)
|
|
46
43
|
end
|
|
47
44
|
|
|
48
45
|
def run_online_mode
|
|
49
46
|
logger.info "Mode: #{@options.mode}"
|
|
50
47
|
|
|
51
|
-
baseline_path = download_baseline(@options.base_branch)
|
|
48
|
+
baseline_path = download_baseline(@options.baseline_download_url_prefix, @options.base_branch)
|
|
49
|
+
|
|
50
|
+
project_list = determine_project_list_for_online_mode(baseline_path)
|
|
51
|
+
get_projects(project_list)
|
|
52
52
|
|
|
53
53
|
if @options.auto_config_flag
|
|
54
|
-
RuleSetBuilder.new(@options).build
|
|
55
|
-
|
|
54
|
+
return if RuleSetBuilder.new(@options).build.empty?
|
|
55
|
+
elsif @options.patch_config == Options::DEFAULT_CONFIG_PATH
|
|
56
56
|
# patch branch build pmd reports with same configuration as base branch
|
|
57
|
+
# if not specified otherwise. This allows to use a different config (e.g. less rules)
|
|
58
|
+
# than used for creating the baseline. Use with care, though
|
|
57
59
|
@options.patch_config = "#{baseline_path}/config.xml"
|
|
60
|
+
else
|
|
61
|
+
logger.info "Using config #{@options.patch_config} which might differ from baseline"
|
|
58
62
|
end
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
project_list = "#{baseline_path}/project-list.xml"
|
|
62
|
-
get_projects(project_list)
|
|
64
|
+
patch_branch_details = create_pmd_report(config: @options.patch_config, branch: @options.patch_branch)
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
base_branch_details = PmdBranchDetail.load(@options.base_branch, logger)
|
|
67
|
+
build_html_reports(@projects, base_branch_details, patch_branch_details, @options.filter_set)
|
|
68
|
+
end
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
def determine_project_list_for_online_mode(baseline_path)
|
|
71
|
+
# patch branch build pmd report with same list of projects as base branch
|
|
72
|
+
# if not specified otherwise. This allows to use a different project list
|
|
73
|
+
# than used for creating the baseline. Use with care, though
|
|
74
|
+
if @options.project_list == Options::DEFAULT_LIST_PATH
|
|
75
|
+
project_list = "#{baseline_path}/project-list.xml"
|
|
76
|
+
else
|
|
77
|
+
logger.info "Using project list #{@options.project_list} which might differ from baseline"
|
|
78
|
+
project_list = @options.project_list
|
|
79
|
+
end
|
|
80
|
+
project_list
|
|
69
81
|
end
|
|
70
82
|
|
|
71
|
-
def download_baseline(branch_name)
|
|
83
|
+
def download_baseline(url_prefix, branch_name)
|
|
72
84
|
branch_filename = PmdBranchDetail.branch_filename(branch_name)
|
|
73
85
|
zip_filename = "#{branch_filename}-baseline.zip"
|
|
74
86
|
target_path = 'target/reports'
|
|
75
87
|
FileUtils.mkdir_p(target_path) unless File.directory?(target_path)
|
|
76
88
|
|
|
77
|
-
url = get_baseline_url(zip_filename)
|
|
78
|
-
|
|
89
|
+
url = get_baseline_url(url_prefix, zip_filename)
|
|
90
|
+
logger.info "Downloading baseline for branch #{branch_name} from #{url}"
|
|
91
|
+
wget_cmd = "wget --timestamping #{url}"
|
|
79
92
|
unzip_cmd = "unzip -qo #{zip_filename}"
|
|
80
93
|
|
|
81
94
|
Dir.chdir(target_path) do
|
|
@@ -86,45 +99,57 @@ module PmdTester
|
|
|
86
99
|
"#{target_path}/#{branch_filename}"
|
|
87
100
|
end
|
|
88
101
|
|
|
89
|
-
def get_baseline_url(zip_filename)
|
|
90
|
-
"
|
|
102
|
+
def get_baseline_url(url_prefix, zip_filename)
|
|
103
|
+
"#{url_prefix}#{zip_filename}"
|
|
91
104
|
end
|
|
92
105
|
|
|
93
106
|
def run_single_mode
|
|
94
107
|
logger.info "Mode: #{@options.mode}"
|
|
95
108
|
|
|
96
109
|
get_projects(@options.project_list) unless @options.nil?
|
|
97
|
-
|
|
98
|
-
.new(@options.patch_config, @projects,
|
|
99
|
-
@options.local_git_repo, @options.patch_branch)
|
|
100
|
-
.build
|
|
110
|
+
patch_branch_details = create_pmd_report(config: @options.patch_config, branch: @options.patch_branch)
|
|
101
111
|
# copy list of projects file to the patch baseline
|
|
102
|
-
FileUtils.cp(@options.project_list,
|
|
112
|
+
FileUtils.cp(@options.project_list, patch_branch_details.target_branch_project_list_path)
|
|
103
113
|
|
|
104
|
-
|
|
114
|
+
# for creating a baseline, no html report is needed
|
|
115
|
+
return if @options.html_flag
|
|
116
|
+
|
|
117
|
+
# in single mode, we don't have a base branch, only a patch branch...
|
|
118
|
+
empty_base_branch_details = PmdBranchDetail.load('single-mode', logger)
|
|
119
|
+
build_html_reports(@projects, empty_base_branch_details, patch_branch_details)
|
|
105
120
|
end
|
|
106
121
|
|
|
107
|
-
def
|
|
108
|
-
|
|
109
|
-
SummaryReportBuilder.new.build(@projects, @options.base_branch, @options.patch_branch)
|
|
122
|
+
def get_projects(file_path)
|
|
123
|
+
@projects = ProjectsParser.new.parse(file_path)
|
|
110
124
|
end
|
|
111
125
|
|
|
112
|
-
def
|
|
126
|
+
def summarize_diffs
|
|
127
|
+
error_total = RunningDiffCounters.new(0)
|
|
128
|
+
violations_total = RunningDiffCounters.new(0)
|
|
129
|
+
configerrors_total = RunningDiffCounters.new(0)
|
|
130
|
+
|
|
113
131
|
@projects.each do |project|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
132
|
+
diff = project.report_diff
|
|
133
|
+
|
|
134
|
+
# in case we are in single mode, there might be no diffs (only the patch branch is available)
|
|
135
|
+
next if diff.nil?
|
|
136
|
+
|
|
137
|
+
error_total.merge!(diff.error_counts)
|
|
138
|
+
violations_total.merge!(diff.violation_counts)
|
|
139
|
+
configerrors_total.merge!(diff.configerror_counts)
|
|
122
140
|
end
|
|
123
|
-
|
|
141
|
+
|
|
142
|
+
{
|
|
143
|
+
errors: error_total.to_h,
|
|
144
|
+
violations: violations_total.to_h,
|
|
145
|
+
configerrors: configerrors_total.to_h
|
|
146
|
+
}
|
|
124
147
|
end
|
|
125
148
|
|
|
126
|
-
|
|
127
|
-
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def create_pmd_report(config:, branch:)
|
|
152
|
+
PmdReportBuilder.new(@projects, @options, config, branch).build
|
|
128
153
|
end
|
|
129
154
|
end
|
|
130
155
|
end
|