pmdtester 1.3.0 → 1.5.0
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/.github/workflows/build.yml +3 -2
- data/.github/workflows/manual-integration-tests.yml +3 -2
- data/History.md +23 -0
- data/README.rdoc +6 -7
- data/Rakefile +11 -6
- data/lib/pmdtester/builders/liquid_renderer.rb +6 -0
- data/lib/pmdtester/builders/pmd_report_builder.rb +32 -15
- data/lib/pmdtester/builders/project_builder.rb +4 -4
- data/lib/pmdtester/builders/project_hasher.rb +3 -0
- data/lib/pmdtester/builders/rule_set_builder.rb +113 -76
- data/lib/pmdtester/cmd.rb +39 -11
- data/lib/pmdtester/parsers/pmd_report_document.rb +3 -4
- data/lib/pmdtester/pmd_report_detail.rb +16 -2
- data/lib/pmdtester/pmd_tester_utils.rb +2 -1
- data/lib/pmdtester/pmd_violation.rb +11 -1
- data/lib/pmdtester/project.rb +3 -0
- data/lib/pmdtester/report_diff.rb +7 -1
- data/lib/pmdtester/runner.rb +9 -5
- data/lib/pmdtester/semver.rb +6 -0
- data/lib/pmdtester.rb +1 -1
- data/pmdtester.gemspec +15 -15
- data/resources/project_diff_report.html +6 -0
- data/resources/project_pmd_report.html +4 -0
- metadata +20 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d00209411d45b04f8ebcfb34d4289b682a9c3d044998b1f82e15c1d08e184ed
|
4
|
+
data.tar.gz: d6d6a48c4a2c558b9058c91dc57e2043e304addc90b8e7cc7441f07c50dac624
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82c0d9bce215128d2fb56f44116c7c6f5394b8a34ff8b26918974a89e2c6e67b4d76c14b3a920b372e345ffbe33e114cdacfbcdd962f1c76f5fddc24595d8998
|
7
|
+
data.tar.gz: effbb41f97137a0b6a93bc200cd8ebb3b7323dabaeef1eca50bfee3dd97b00e0418987b28661328902b1f66942843acad32bc397f1dc04590cbc9d0a19d1c4b7
|
data/.github/workflows/build.yml
CHANGED
@@ -15,6 +15,7 @@ on:
|
|
15
15
|
|
16
16
|
jobs:
|
17
17
|
build:
|
18
|
+
timeout-minutes: 120
|
18
19
|
runs-on: ubuntu-latest
|
19
20
|
continue-on-error: false
|
20
21
|
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
|
@@ -27,9 +28,9 @@ jobs:
|
|
27
28
|
~/.cache
|
28
29
|
vendor/bundle
|
29
30
|
target/repositories
|
30
|
-
key:
|
31
|
+
key: v3-${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
|
31
32
|
restore-keys: |
|
32
|
-
|
33
|
+
v3-${{ runner.os }}-
|
33
34
|
- name: Set up Ruby 2.7
|
34
35
|
uses: ruby/setup-ruby@v1
|
35
36
|
with:
|
@@ -8,6 +8,7 @@ on:
|
|
8
8
|
|
9
9
|
jobs:
|
10
10
|
build:
|
11
|
+
timeout-minutes: 120
|
11
12
|
runs-on: ubuntu-latest
|
12
13
|
continue-on-error: false
|
13
14
|
steps:
|
@@ -19,9 +20,9 @@ jobs:
|
|
19
20
|
~/.cache
|
20
21
|
vendor/bundle
|
21
22
|
target/repositories
|
22
|
-
key:
|
23
|
+
key: v3-${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
|
23
24
|
restore-keys: |
|
24
|
-
|
25
|
+
v3-${{ runner.os }}-
|
25
26
|
- name: Set up Ruby 2.7
|
26
27
|
uses: ruby/setup-ruby@v1
|
27
28
|
with:
|
data/History.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
# 1.5.0 / 2022-05-06
|
2
|
+
|
3
|
+
## Enhancements
|
4
|
+
|
5
|
+
* [#108](https://github.com/pmd/pmd-regression-tester/issues/108): Disable progress bar for PMD 7
|
6
|
+
* [#109](https://github.com/pmd/pmd-regression-tester/issues/109): Make stdout/stderr and exit code available
|
7
|
+
|
8
|
+
## Fixed Issues
|
9
|
+
|
10
|
+
* [#107](https://github.com/pmd/pmd-regression-tester/issues/107): Deprecated command line options is used: `-auxclasspath`
|
11
|
+
|
12
|
+
# 1.4.1 / 2022-04-12
|
13
|
+
|
14
|
+
## Fixed Issues
|
15
|
+
|
16
|
+
* [#104](https://github.com/pmd/pmd-regression-tester/issues/104): Baseline filtering is not working anymore
|
17
|
+
|
18
|
+
# 1.4.0 / 2022-03-24
|
19
|
+
|
20
|
+
## Enhancements
|
21
|
+
|
22
|
+
* [#103](https://github.com/pmd/pmd-regression-tester/pull/103): Support other languages besides java
|
23
|
+
|
1
24
|
# 1.3.0 / 2021-12-17
|
2
25
|
|
3
26
|
## Enhancements
|
data/README.rdoc
CHANGED
@@ -105,23 +105,22 @@ The tool creates the following folders:
|
|
105
105
|
|
106
106
|
=== Runtime dependency
|
107
107
|
|
108
|
-
nokogiri
|
108
|
+
nokogiri ~> 1.13
|
109
109
|
slop ~> 4.6
|
110
110
|
differ ~> 0.1
|
111
|
-
rufus-scheduler ~> 3.
|
111
|
+
rufus-scheduler ~> 3.8
|
112
112
|
logger-colors ~> 1.0
|
113
|
-
liquid
|
113
|
+
liquid ~> 5.2
|
114
114
|
|
115
115
|
=== Development dependency
|
116
116
|
|
117
|
-
hoe ~> 3.22
|
118
117
|
hoe-bundler ~> 1.5
|
119
118
|
hoe-git ~> 1.6
|
120
119
|
minitest ~> 5.10
|
121
120
|
mocha ~> 1.5
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
rubocop ~> 0.93
|
122
|
+
test-unit ~> 3.5
|
123
|
+
rdoc ~> 6.4
|
125
124
|
|
126
125
|
== INSTALL:
|
127
126
|
|
data/Rakefile
CHANGED
@@ -19,18 +19,23 @@ hoe = Hoe.spec 'pmdtester' do
|
|
19
19
|
developer 'Clément Fournier', 'clement.fournier76@gmail.com'
|
20
20
|
|
21
21
|
self.clean_globs = %w[target/reports/**/* target/test/**/* target/dynamic-config.xml Gemfile.lock]
|
22
|
-
self.extra_deps += [
|
23
|
-
|
24
|
-
|
22
|
+
self.extra_deps += [
|
23
|
+
['nokogiri', '~> 1.13'],
|
24
|
+
['slop', '~> 4.6'],
|
25
|
+
['differ', '~> 0.1'],
|
26
|
+
['rufus-scheduler', '~> 3.8'],
|
27
|
+
['logger-colors', '~> 1.0'],
|
28
|
+
['liquid', '~> 5.2']
|
29
|
+
]
|
25
30
|
self.extra_dev_deps += [
|
26
31
|
['hoe-bundler', '~> 1.5'],
|
27
32
|
['hoe-git', '~> 1.6'],
|
28
33
|
['minitest', '~> 5.10'],
|
29
34
|
['mocha', '~> 1.5'],
|
30
35
|
# use the same version of rubocop as codacy
|
31
|
-
['rubocop', '~> 0.
|
32
|
-
['test-unit', '~> 3.
|
33
|
-
['rdoc',
|
36
|
+
['rubocop', '~> 0.93'],
|
37
|
+
['test-unit', '~> 3.5'],
|
38
|
+
['rdoc', '~> 6.4']
|
34
39
|
]
|
35
40
|
spec_extras[:required_ruby_version] = '>= 2.7'
|
36
41
|
|
@@ -60,6 +60,11 @@ module PmdTester
|
|
60
60
|
# copy original pmd reports
|
61
61
|
copy_file("#{root}/base_pmd_report.xml", project.report_diff.base_report.file)
|
62
62
|
copy_file("#{root}/patch_pmd_report.xml", project.report_diff.patch_report.file)
|
63
|
+
# copy stdout and stderr outputs
|
64
|
+
copy_file("#{root}/base_stdout.txt", "#{project.report_diff.base_report.report_folder}/stdout.txt")
|
65
|
+
copy_file("#{root}/base_stderr.txt", "#{project.report_diff.base_report.report_folder}/stderr.txt")
|
66
|
+
copy_file("#{root}/patch_stdout.txt", "#{project.report_diff.patch_report.report_folder}/stdout.txt")
|
67
|
+
copy_file("#{root}/patch_stderr.txt", "#{project.report_diff.patch_report.report_folder}/stderr.txt")
|
63
68
|
# render full pmd reports
|
64
69
|
write_file("#{root}/base_pmd_report.html",
|
65
70
|
render_liquid('project_pmd_report.html', pmd_report_liquid_env(project, BASE)))
|
@@ -120,6 +125,7 @@ module PmdTester
|
|
120
125
|
|
121
126
|
'execution_time' => PmdReportDetail.convert_seconds(report.exec_time),
|
122
127
|
'timestamp' => report.timestamp,
|
128
|
+
'exit_code' => report.exit_code,
|
123
129
|
|
124
130
|
'rules' => report.rule_summaries,
|
125
131
|
'errors' => report.errors_by_file.all_values.map { |e| error_to_hash(e, project) },
|
@@ -25,7 +25,7 @@ module PmdTester
|
|
25
25
|
def get_pmd_binary_file
|
26
26
|
logger.info "#{@pmd_branch_name}: Start packaging PMD"
|
27
27
|
Dir.chdir(@local_git_repo) do
|
28
|
-
build_branch_sha = Cmd.
|
28
|
+
build_branch_sha = Cmd.execute_successfully("git rev-parse #{@pmd_branch_name}^{commit}")
|
29
29
|
|
30
30
|
checkout_build_branch # needs a clean working tree, otherwise fails
|
31
31
|
|
@@ -70,49 +70,53 @@ module PmdTester
|
|
70
70
|
' -Dcheckstyle.skip=true' \
|
71
71
|
' -Dpmd.skip=true' \
|
72
72
|
' -T1C -B'
|
73
|
-
Cmd.
|
73
|
+
Cmd.execute_successfully(package_cmd)
|
74
74
|
end
|
75
75
|
|
76
76
|
logger.info "#{@pmd_branch_name}: Extracting the zip"
|
77
|
-
Cmd.
|
78
|
-
Cmd.
|
77
|
+
Cmd.execute_successfully("unzip -qo #{pmd_dist_target} -d pmd-dist/target/exploded")
|
78
|
+
Cmd.execute_successfully("mv pmd-dist/target/exploded/pmd-bin-#{@pmd_version} #{into_dir}")
|
79
79
|
end
|
80
80
|
|
81
81
|
def determine_pmd_version
|
82
82
|
version_cmd = "./mvnw -q -Dexec.executable=\"echo\" -Dexec.args='${project.version}' " \
|
83
83
|
'--non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec'
|
84
|
-
Cmd.
|
84
|
+
Cmd.execute_successfully(version_cmd)
|
85
85
|
end
|
86
86
|
|
87
87
|
def get_last_commit_sha
|
88
88
|
get_last_commit_sha_cmd = 'git rev-parse HEAD^{commit}'
|
89
|
-
Cmd.
|
89
|
+
Cmd.execute_successfully(get_last_commit_sha_cmd)
|
90
90
|
end
|
91
91
|
|
92
92
|
def get_last_commit_message
|
93
93
|
get_last_commit_message_cmd = 'git log -1 --pretty=%B'
|
94
|
-
Cmd.
|
94
|
+
Cmd.execute_successfully(get_last_commit_message_cmd)
|
95
95
|
end
|
96
96
|
|
97
97
|
def generate_pmd_report(project)
|
98
98
|
error_recovery_options = @error_recovery ? 'PMD_JAVA_OPTS="-Dpmd.error_recovery -ea" ' : ''
|
99
99
|
run_path = "#{saved_distro_path(@pmd_branch_details.branch_last_sha)}/bin/run.sh"
|
100
100
|
fail_on_violation = should_use_long_cli_options ? '--fail-on-violation false' : '-failOnViolation false'
|
101
|
+
auxclasspath_option = create_auxclasspath_option(project)
|
101
102
|
pmd_cmd = "#{error_recovery_options}" \
|
102
103
|
"#{run_path} pmd -d #{project.local_source_path} -f xml " \
|
103
104
|
"-R #{project.get_config_path(@pmd_branch_name)} " \
|
104
105
|
"-r #{project.get_pmd_report_path(@pmd_branch_name)} " \
|
105
106
|
"#{fail_on_violation} -t #{@threads} " \
|
106
|
-
"#{
|
107
|
+
"#{auxclasspath_option}" \
|
108
|
+
"#{pmd7? ? ' --no-progress' : ''}"
|
107
109
|
start_time = Time.now
|
110
|
+
exit_code = nil
|
108
111
|
if File.exist?(project.get_pmd_report_path(@pmd_branch_name))
|
109
112
|
logger.warn "#{@pmd_branch_name}: Skipping PMD run - report " \
|
110
113
|
"#{project.get_pmd_report_path(@pmd_branch_name)} already exists"
|
111
114
|
else
|
112
|
-
Cmd.execute(pmd_cmd)
|
115
|
+
status = Cmd.execute(pmd_cmd, project.get_project_target_dir(@pmd_branch_name))
|
116
|
+
exit_code = status.exitstatus
|
113
117
|
end
|
114
118
|
end_time = Time.now
|
115
|
-
[end_time - start_time, end_time]
|
119
|
+
[end_time - start_time, end_time, exit_code]
|
116
120
|
end
|
117
121
|
|
118
122
|
def generate_config_for(project)
|
@@ -139,12 +143,12 @@ module PmdTester
|
|
139
143
|
progress_logger = SimpleProgressLogger.new("generating #{project.name}'s PMD report")
|
140
144
|
progress_logger.start
|
141
145
|
generate_config_for(project)
|
142
|
-
execution_time, end_time = generate_pmd_report(project)
|
146
|
+
execution_time, end_time, exit_code = generate_pmd_report(project)
|
143
147
|
progress_logger.stop
|
144
148
|
sum_time += execution_time
|
145
149
|
|
146
|
-
|
147
|
-
|
150
|
+
PmdReportDetail.create(execution_time: execution_time, timestamp: end_time,
|
151
|
+
exit_code: exit_code, report_info_path: project.get_report_info_path(@pmd_branch_name))
|
148
152
|
logger.info "#{project.name}'s PMD report was generated successfully"
|
149
153
|
end
|
150
154
|
|
@@ -167,7 +171,7 @@ module PmdTester
|
|
167
171
|
def checkout_build_branch
|
168
172
|
logger.info "#{@pmd_branch_name}: Checking out the branch"
|
169
173
|
# note that this would fail if the tree is dirty
|
170
|
-
Cmd.
|
174
|
+
Cmd.execute_successfully("git checkout #{@pmd_branch_name}")
|
171
175
|
|
172
176
|
# determine the version
|
173
177
|
@pmd_version = determine_pmd_version
|
@@ -193,12 +197,25 @@ module PmdTester
|
|
193
197
|
end
|
194
198
|
|
195
199
|
def wd_has_dirty_git_changes
|
196
|
-
!Cmd.
|
200
|
+
!Cmd.execute_successfully('git status --porcelain').empty?
|
197
201
|
end
|
198
202
|
|
199
203
|
def should_use_long_cli_options
|
200
204
|
logger.debug "PMD Version: #{@pmd_version}"
|
201
205
|
Semver.compare(@pmd_version, '6.41.0') >= 0
|
202
206
|
end
|
207
|
+
|
208
|
+
def create_auxclasspath_option(project)
|
209
|
+
auxclasspath_option = ''
|
210
|
+
unless project.auxclasspath.empty?
|
211
|
+
auxclasspath_option = should_use_long_cli_options ? '--aux-classpath ' : '-auxclasspath '
|
212
|
+
auxclasspath_option += project.auxclasspath
|
213
|
+
end
|
214
|
+
auxclasspath_option
|
215
|
+
end
|
216
|
+
|
217
|
+
def pmd7?
|
218
|
+
Semver.compare(@pmd_version, '7.0.0-SNAPSHOT') >= 0
|
219
|
+
end
|
203
220
|
end
|
204
221
|
end
|
@@ -30,7 +30,7 @@ module PmdTester
|
|
30
30
|
# once but may be used with several tags.
|
31
31
|
clone_cmd = "git clone --no-single-branch --depth 1 #{project.connection} #{path}"
|
32
32
|
|
33
|
-
Cmd.
|
33
|
+
Cmd.execute_successfully(clone_cmd)
|
34
34
|
end
|
35
35
|
|
36
36
|
Dir.chdir(path) do
|
@@ -71,7 +71,7 @@ module PmdTester
|
|
71
71
|
if project.auxclasspath_command
|
72
72
|
logger.debug "Executing auxclasspath-command: #{project.auxclasspath_command}"
|
73
73
|
auxclasspath = run_as_script(Dir.getwd, project.auxclasspath_command)
|
74
|
-
project.auxclasspath =
|
74
|
+
project.auxclasspath = auxclasspath
|
75
75
|
else
|
76
76
|
project.auxclasspath = ''
|
77
77
|
end
|
@@ -87,7 +87,7 @@ module PmdTester
|
|
87
87
|
if command.start_with?('#!')
|
88
88
|
shell = command.lines[0].chomp[2..] # remove leading "#!"
|
89
89
|
end
|
90
|
-
stdout = Cmd.
|
90
|
+
stdout = Cmd.execute_successfully("#{shell} #{script.path}")
|
91
91
|
ensure
|
92
92
|
script.unlink
|
93
93
|
end
|
@@ -99,7 +99,7 @@ module PmdTester
|
|
99
99
|
|
100
100
|
reset_cmd = "git checkout #{tag}; git reset --hard #{tag}"
|
101
101
|
|
102
|
-
Cmd.
|
102
|
+
Cmd.execute_successfully(reset_cmd)
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -21,6 +21,9 @@ module PmdTester
|
|
21
21
|
'base_timestamp' => rdiff.base_report.timestamp,
|
22
22
|
'patch_timestamp' => rdiff.patch_report.timestamp,
|
23
23
|
|
24
|
+
'base_exit_code' => rdiff.base_report.exit_code,
|
25
|
+
'patch_exit_code' => rdiff.patch_report.exit_code,
|
26
|
+
|
24
27
|
'rule_diffs' => rdiff.rule_summaries
|
25
28
|
}
|
26
29
|
end
|
@@ -9,73 +9,70 @@ module PmdTester
|
|
9
9
|
# Attention: we only consider java rulesets now.
|
10
10
|
class RuleSetBuilder
|
11
11
|
include PmdTester
|
12
|
-
ALL_CATEGORIES = Set['bestpractices.xml', 'codestyle.xml', 'design.xml', 'documentation.xml',
|
13
|
-
'errorprone.xml', 'multithreading.xml', 'performance.xml',
|
14
|
-
'security.xml'].freeze
|
15
|
-
PATH_TO_PMD_JAVA_BASED_RULES =
|
16
|
-
'pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule'
|
17
|
-
PATH_TO_PMD_XPATH_BASED_RULES = 'pmd-java/src/main/resources/category/java'
|
18
|
-
PATH_TO_ALL_JAVA_RULES =
|
19
|
-
ResourceLocator.locate('config/all-java.xml')
|
20
12
|
PATH_TO_DYNAMIC_CONFIG = 'target/dynamic-config.xml'
|
21
|
-
|
13
|
+
NO_RULES_CHANGED_MESSAGE = 'No regression tested rules have been changed!'
|
22
14
|
|
23
15
|
def initialize(options)
|
24
16
|
@options = options
|
25
17
|
end
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
19
|
+
#
|
20
|
+
# Creates a dynamic ruleset based on the changed sources.
|
21
|
+
# Returns true, when rules are affected by the changed sources.
|
22
|
+
# Returns false, when no rules are affected and regression tester can be skipped.
|
23
|
+
#
|
24
|
+
def build?
|
25
|
+
languages = determine_languages
|
26
|
+
filenames = diff_filenames(languages)
|
27
|
+
run_required, rule_refs = get_rule_refs(filenames)
|
28
|
+
if run_required
|
29
|
+
output_filter_set(rule_refs)
|
30
|
+
build_config_file(rule_refs)
|
31
|
+
logger.debug "Dynamic configuration: #{[rule_refs]}"
|
32
|
+
else
|
33
|
+
logger.info NO_RULES_CHANGED_MESSAGE
|
34
|
+
end
|
35
|
+
run_required
|
34
36
|
end
|
35
37
|
|
36
38
|
def calculate_filter_set
|
37
|
-
output_filter_set(
|
39
|
+
output_filter_set([])
|
38
40
|
end
|
39
41
|
|
40
42
|
def output_filter_set(rule_refs)
|
41
|
-
if rule_refs
|
42
|
-
if @options.mode == Options::ONLINE
|
43
|
+
if rule_refs.empty?
|
44
|
+
if @options.mode == Options::ONLINE && @options.filter_with_patch_config
|
43
45
|
@options.filter_set = Set[]
|
44
46
|
doc = File.open(@options.patch_config) { |f| Nokogiri::XML(f) }
|
45
47
|
rules = doc.css('ruleset rule')
|
46
48
|
rules.each do |r|
|
47
49
|
ref = r.attributes['ref'].content
|
48
|
-
ref.delete_prefix!('category/
|
50
|
+
ref.delete_prefix!('category/')
|
49
51
|
@options.filter_set.add(ref)
|
50
52
|
end
|
51
53
|
|
52
|
-
logger.
|
54
|
+
logger.info "Using filter based on patch config #{@options.patch_config}: " \
|
53
55
|
"#{@options.filter_set}"
|
54
56
|
else
|
55
|
-
# if `rule_refs`
|
56
|
-
logger.
|
57
|
+
# if `rule_refs` is empty, then no filter can be used when comparing to the baseline
|
58
|
+
logger.info 'No filter when comparing patch to baseline'
|
57
59
|
@options.filter_set = nil
|
58
60
|
end
|
59
61
|
else
|
60
|
-
logger.
|
62
|
+
logger.info "Filter is now #{rule_refs}"
|
61
63
|
@options.filter_set = rule_refs
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
diff_cmd = "git diff --name-only #{base}..#{patch} -- pmd-core/src/main pmd-java/src/main"
|
72
|
-
filenames = Cmd.execute(diff_cmd)
|
73
|
-
end
|
74
|
-
filenames.split("\n")
|
75
|
-
end
|
76
|
-
|
67
|
+
#
|
68
|
+
# Determines the rules or category rulesets, that are potentially affected by the change.
|
69
|
+
# Returns an empty set, if all rules are affected and there is no
|
70
|
+
# filtering possible or if no rules are affected.
|
71
|
+
# Whether to run the regression test is returned as an additional boolean flag.
|
72
|
+
#
|
77
73
|
def get_rule_refs(filenames)
|
78
|
-
categories, rules = determine_categories_rules(filenames)
|
74
|
+
run_required, categories, rules = determine_categories_rules(filenames)
|
75
|
+
logger.debug "Regression test required: #{run_required}"
|
79
76
|
logger.debug "Categories: #{categories}"
|
80
77
|
logger.debug "Rules: #{rules}"
|
81
78
|
|
@@ -87,48 +84,11 @@ module PmdTester
|
|
87
84
|
refs = Set[]
|
88
85
|
refs.merge(categories)
|
89
86
|
refs.merge(rules)
|
90
|
-
refs
|
91
|
-
end
|
92
|
-
|
93
|
-
def determine_categories_rules(filenames)
|
94
|
-
categories = Set[]
|
95
|
-
rules = Set[]
|
96
|
-
filenames.each do |filename|
|
97
|
-
match_data = check_single_filename(filename)
|
98
|
-
|
99
|
-
unless match_data.nil?
|
100
|
-
if match_data.size == 2
|
101
|
-
categories.add("#{match_data[1]}.xml")
|
102
|
-
else
|
103
|
-
rules.add("#{match_data[1]}.xml/#{match_data[2]}")
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
next unless match_data.nil?
|
108
|
-
|
109
|
-
logger.debug "Change doesn't match specific rule/category - enable all rules"
|
110
|
-
categories = ALL_CATEGORIES
|
111
|
-
rules.clear
|
112
|
-
break
|
113
|
-
end
|
114
|
-
[categories, rules]
|
115
|
-
end
|
116
|
-
|
117
|
-
def check_single_filename(filename)
|
118
|
-
logger.debug "Checking #{filename}"
|
119
|
-
match_data = %r{#{PATH_TO_PMD_JAVA_BASED_RULES}/([^/]+)/([^/]+)Rule.java}.match(filename)
|
120
|
-
match_data = %r{#{PATH_TO_PMD_XPATH_BASED_RULES}/([^/]+).xml}.match(filename) if match_data.nil?
|
121
|
-
logger.debug "Matches: #{match_data.inspect}"
|
122
|
-
match_data
|
87
|
+
[run_required, refs]
|
123
88
|
end
|
124
89
|
|
125
90
|
def build_config_file(rule_refs)
|
126
91
|
if rule_refs.empty?
|
127
|
-
logger.info NO_JAVA_RULES_CHANGED_MESSAGE
|
128
|
-
return
|
129
|
-
end
|
130
|
-
|
131
|
-
if rule_refs == ALL_CATEGORIES
|
132
92
|
logger.debug 'All rules are used. Not generating a dynamic ruleset.'
|
133
93
|
logger.debug "Using the configured/default ruleset base_config=#{@options.base_config} "\
|
134
94
|
"patch_config=#{@options.patch_config}"
|
@@ -147,7 +107,7 @@ module PmdTester
|
|
147
107
|
'name' => 'Dynamic PmdTester Ruleset') do
|
148
108
|
xml.description 'The ruleset generated by PmdTester dynamically'
|
149
109
|
rule_refs.each do |entry|
|
150
|
-
xml.rule('ref' => "category
|
110
|
+
xml.rule('ref' => "category/#{entry}")
|
151
111
|
end
|
152
112
|
end
|
153
113
|
end
|
@@ -158,5 +118,82 @@ module PmdTester
|
|
158
118
|
@options.base_config = PATH_TO_DYNAMIC_CONFIG
|
159
119
|
@options.patch_config = PATH_TO_DYNAMIC_CONFIG
|
160
120
|
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def determine_categories_rules(filenames)
|
125
|
+
regression_test_required = false
|
126
|
+
categories = Set[]
|
127
|
+
rules = Set[]
|
128
|
+
filenames.each do |filename|
|
129
|
+
matched = check_single_filename(filename, categories, rules)
|
130
|
+
regression_test_required = true if matched
|
131
|
+
|
132
|
+
next if matched
|
133
|
+
|
134
|
+
logger.info "Change in file #{filename} doesn't match specific rule/category - enable all rules"
|
135
|
+
regression_test_required = true
|
136
|
+
categories.clear
|
137
|
+
rules.clear
|
138
|
+
break
|
139
|
+
end
|
140
|
+
[regression_test_required, categories, rules]
|
141
|
+
end
|
142
|
+
|
143
|
+
def check_single_filename(filename, categories, rules)
|
144
|
+
logger.debug "Checking #{filename}"
|
145
|
+
|
146
|
+
# matches Java-based rule implementations
|
147
|
+
match_data = %r{.+/src/main/java/.+/lang/([^/]+)/rule/([^/]+)/([^/]+)Rule.java}.match(filename)
|
148
|
+
unless match_data.nil?
|
149
|
+
logger.debug "Matches: #{match_data.inspect}"
|
150
|
+
rules.add("#{match_data[1]}/#{match_data[2]}.xml/#{match_data[3]}")
|
151
|
+
return true
|
152
|
+
end
|
153
|
+
|
154
|
+
# matches xpath rules
|
155
|
+
match_data = %r{.+/src/main/resources/category/([^/]+)/([^/]+).xml}.match(filename)
|
156
|
+
unless match_data.nil?
|
157
|
+
logger.debug "Matches: #{match_data.inspect}"
|
158
|
+
categories.add("#{match_data[1]}/#{match_data[2]}.xml")
|
159
|
+
return true
|
160
|
+
end
|
161
|
+
|
162
|
+
false
|
163
|
+
end
|
164
|
+
|
165
|
+
def diff_filenames(languages)
|
166
|
+
filenames = nil
|
167
|
+
Dir.chdir(@options.local_git_repo) do
|
168
|
+
base = @options.base_branch
|
169
|
+
patch = @options.patch_branch
|
170
|
+
|
171
|
+
filepath_filter = ''
|
172
|
+
unless languages.empty?
|
173
|
+
filepath_filter = '-- pmd-core/src/main'
|
174
|
+
languages.each { |l| filepath_filter = "#{filepath_filter} pmd-#{l}/src/main" }
|
175
|
+
end
|
176
|
+
|
177
|
+
# We only need to support git here, since PMD's repo is using git.
|
178
|
+
diff_cmd = "git diff --name-only #{base}..#{patch} #{filepath_filter}"
|
179
|
+
filenames = Cmd.execute_successfully(diff_cmd)
|
180
|
+
end
|
181
|
+
filenames.split("\n")
|
182
|
+
end
|
183
|
+
|
184
|
+
#
|
185
|
+
# Determines all languages, that are part of the regression test.
|
186
|
+
# This is based on the configured rules/rulesets.
|
187
|
+
#
|
188
|
+
def determine_languages
|
189
|
+
languages = Set[]
|
190
|
+
doc = File.open(@options.patch_config) { |f| Nokogiri::XML(f) }
|
191
|
+
rules = doc.css('ruleset rule')
|
192
|
+
rules.each do |r|
|
193
|
+
ref = r.attributes['ref'].content
|
194
|
+
languages.add(ref.split('/')[1])
|
195
|
+
end
|
196
|
+
languages
|
197
|
+
end
|
161
198
|
end
|
162
199
|
end
|
data/lib/pmdtester/cmd.rb
CHANGED
@@ -6,9 +6,35 @@ module PmdTester
|
|
6
6
|
# Containing the common method for executing shell command
|
7
7
|
class Cmd
|
8
8
|
extend PmdTester
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
#
|
11
|
+
# Executes the given command and returns the process status.
|
12
|
+
# stdout and stderr are written to the files "stdout.txt" and "stderr.txt"
|
13
|
+
# in path.
|
14
|
+
#
|
15
|
+
def self.execute(cmd, path)
|
16
|
+
stdout, stderr, status = internal_execute(cmd)
|
17
|
+
|
18
|
+
file = File.new("#{path}/stdout.txt", 'w')
|
19
|
+
file.puts stdout
|
20
|
+
file.close
|
21
|
+
|
22
|
+
file = File.new("#{path}/stderr.txt", 'w')
|
23
|
+
file.puts stderr
|
24
|
+
file.close
|
25
|
+
|
26
|
+
status
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.execute_successfully(cmd)
|
30
|
+
stdout, stderr, status = internal_execute(cmd)
|
31
|
+
|
32
|
+
unless status.success?
|
33
|
+
logger.error stdout
|
34
|
+
logger.error stderr
|
35
|
+
raise CmdException.new(cmd, stdout, stderr, status)
|
36
|
+
end
|
37
|
+
|
12
38
|
stdout
|
13
39
|
end
|
14
40
|
|
@@ -22,14 +48,12 @@ module PmdTester
|
|
22
48
|
|
23
49
|
stdout, stderr, status = Open3.capture3("#{cmd};")
|
24
50
|
|
25
|
-
logger.debug
|
26
|
-
|
27
|
-
|
28
|
-
logger.error stderr
|
29
|
-
raise CmdException.new(cmd, stderr)
|
30
|
-
end
|
51
|
+
logger.debug "status: #{status}"
|
52
|
+
logger.debug "stdout: #{stdout}"
|
53
|
+
logger.debug "stderr: #{stderr}"
|
31
54
|
|
32
55
|
stdout&.chomp!
|
56
|
+
stderr&.chomp!
|
33
57
|
|
34
58
|
[stdout, stderr, status]
|
35
59
|
end
|
@@ -40,15 +64,19 @@ module PmdTester
|
|
40
64
|
# The exception should be raised when the shell command failed.
|
41
65
|
class CmdException < StandardError
|
42
66
|
attr_reader :cmd
|
67
|
+
attr_reader :stdout
|
43
68
|
attr_reader :error
|
69
|
+
attr_reader :status
|
44
70
|
attr_reader :message
|
45
71
|
|
46
72
|
COMMON_MSG = 'An error occurred while executing the shell command'
|
47
73
|
|
48
|
-
def initialize(cmd, error)
|
74
|
+
def initialize(cmd, stdout, error, status)
|
49
75
|
@cmd = cmd
|
76
|
+
@stdout = stdout
|
50
77
|
@error = error
|
51
|
-
@
|
78
|
+
@status = status
|
79
|
+
@message = "#{COMMON_MSG} '#{cmd}' #{status}"
|
52
80
|
end
|
53
81
|
end
|
54
82
|
end
|
@@ -89,11 +89,10 @@ module PmdTester
|
|
89
89
|
def match_filter_set?(violation)
|
90
90
|
return true if @filter_set.nil?
|
91
91
|
|
92
|
-
|
93
|
-
return true if @filter_set.include?(
|
94
|
-
|
95
|
-
rule_ref = "#{ruleset_attr}/#{violation.rule_name}"
|
92
|
+
ruleset_filter = violation.language << '/' << violation.ruleset_name.delete(' ').downcase! << '.xml'
|
93
|
+
return true if @filter_set.include?(ruleset_filter)
|
96
94
|
|
95
|
+
rule_ref = "#{ruleset_filter}/#{violation.rule_name}"
|
97
96
|
@filter_set.include?(rule_ref)
|
98
97
|
end
|
99
98
|
|
@@ -8,15 +8,22 @@ module PmdTester
|
|
8
8
|
attr_accessor :execution_time
|
9
9
|
attr_accessor :timestamp
|
10
10
|
attr_accessor :working_dir
|
11
|
+
attr_accessor :exit_code
|
11
12
|
|
12
|
-
def initialize(execution_time: 0, timestamp: '', working_dir: Dir.getwd)
|
13
|
+
def initialize(execution_time: 0, timestamp: '', working_dir: Dir.getwd, exit_code: nil)
|
13
14
|
@execution_time = execution_time
|
14
15
|
@timestamp = timestamp
|
15
16
|
@working_dir = working_dir
|
17
|
+
@exit_code = exit_code.nil? ? '?' : exit_code.to_s
|
16
18
|
end
|
17
19
|
|
18
20
|
def save(report_info_path)
|
19
|
-
hash = {
|
21
|
+
hash = {
|
22
|
+
execution_time: @execution_time,
|
23
|
+
timestamp: @timestamp,
|
24
|
+
working_dir: @working_dir,
|
25
|
+
exit_code: @exit_code
|
26
|
+
}
|
20
27
|
file = File.new(report_info_path, 'w')
|
21
28
|
file.puts JSON.generate(hash)
|
22
29
|
file.close
|
@@ -36,6 +43,13 @@ module PmdTester
|
|
36
43
|
self.class.convert_seconds(@execution_time)
|
37
44
|
end
|
38
45
|
|
46
|
+
def self.create(execution_time: 0, timestamp: '', working_dir: Dir.getwd, exit_code: nil, report_info_path:)
|
47
|
+
detail = PmdReportDetail.new(execution_time: execution_time, timestamp: timestamp,
|
48
|
+
working_dir: working_dir, exit_code: exit_code)
|
49
|
+
detail.save(report_info_path)
|
50
|
+
detail
|
51
|
+
end
|
52
|
+
|
39
53
|
# convert seconds into HH::MM::SS
|
40
54
|
def self.convert_seconds(seconds)
|
41
55
|
Time.at(seconds.abs).utc.strftime('%H:%M:%S')
|
@@ -27,7 +27,7 @@ module PmdTester
|
|
27
27
|
# </xs:simpleContent>
|
28
28
|
# </xs:complexType>
|
29
29
|
|
30
|
-
attr_reader :fname, :info_url, :line, :old_line, :old_message, :rule_name, :ruleset_name
|
30
|
+
attr_reader :fname, :info_url, :line, :old_line, :old_message, :rule_name, :ruleset_name, :language
|
31
31
|
attr_accessor :message
|
32
32
|
|
33
33
|
# rubocop:disable Metrics/ParameterLists
|
@@ -43,6 +43,8 @@ module PmdTester
|
|
43
43
|
|
44
44
|
@ruleset_name = ruleset_name
|
45
45
|
|
46
|
+
@language = determine_language_from_info_url
|
47
|
+
|
46
48
|
@changed = false
|
47
49
|
@old_message = nil
|
48
50
|
@old_line = nil
|
@@ -102,5 +104,13 @@ module PmdTester
|
|
102
104
|
'changed' => changed?
|
103
105
|
}
|
104
106
|
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def determine_language_from_info_url
|
111
|
+
# @info_url is e.g. http://pmd.sourceforge.net/snapshot/pmd_rules_java_codestyle.html#fielddeclarationsshouldbeatstartofclass
|
112
|
+
m = @info_url.match(/pmd_rules_(\w+)_/)
|
113
|
+
m[1]
|
114
|
+
end
|
105
115
|
end
|
106
116
|
end
|
data/lib/pmdtester/project.rb
CHANGED
@@ -123,6 +123,9 @@ module PmdTester
|
|
123
123
|
get_report_info_path(base_branch),
|
124
124
|
get_report_info_path(patch_branch),
|
125
125
|
filter_set)
|
126
|
+
|
127
|
+
report_diff.base_report.report_folder = get_project_target_dir(base_branch)
|
128
|
+
report_diff.patch_report.report_folder = get_project_target_dir(patch_branch)
|
126
129
|
end
|
127
130
|
end
|
128
131
|
end
|
@@ -57,17 +57,22 @@ module PmdTester
|
|
57
57
|
:configerrors_by_rule,
|
58
58
|
:exec_time,
|
59
59
|
:timestamp,
|
60
|
+
:exit_code,
|
60
61
|
:file
|
61
62
|
|
63
|
+
attr_accessor :report_folder
|
64
|
+
|
62
65
|
def initialize(report_document: nil,
|
63
66
|
file: '',
|
64
67
|
exec_time: 0,
|
65
|
-
timestamp: '0'
|
68
|
+
timestamp: '0',
|
69
|
+
exit_code: '?')
|
66
70
|
initialize_empty
|
67
71
|
initialize_with_report_document report_document unless report_document.nil?
|
68
72
|
@exec_time = exec_time
|
69
73
|
@timestamp = timestamp
|
70
74
|
@file = file
|
75
|
+
@exit_code = exit_code
|
71
76
|
end
|
72
77
|
|
73
78
|
def self.empty
|
@@ -108,6 +113,7 @@ module PmdTester
|
|
108
113
|
@violations_by_file = CollectionByFile.new
|
109
114
|
@errors_by_file = CollectionByFile.new
|
110
115
|
@configerrors_by_rule = {}
|
116
|
+
@report_folder = ''
|
111
117
|
end
|
112
118
|
end
|
113
119
|
|
data/lib/pmdtester/runner.rb
CHANGED
@@ -33,8 +33,11 @@ module PmdTester
|
|
33
33
|
def run_local_mode
|
34
34
|
logger.info "Mode: #{@options.mode}"
|
35
35
|
get_projects(@options.project_list) unless @options.nil?
|
36
|
-
|
37
|
-
|
36
|
+
if @options.auto_config_flag
|
37
|
+
run_required = RuleSetBuilder.new(@options).build?
|
38
|
+
logger.debug "Run required: #{run_required}"
|
39
|
+
return unless run_required
|
40
|
+
end
|
38
41
|
|
39
42
|
base_branch_details = create_pmd_report(config: @options.base_config, branch: @options.base_branch)
|
40
43
|
patch_branch_details = create_pmd_report(config: @options.patch_config, branch: @options.patch_branch)
|
@@ -51,7 +54,8 @@ module PmdTester
|
|
51
54
|
get_projects(project_list)
|
52
55
|
|
53
56
|
if @options.auto_config_flag
|
54
|
-
|
57
|
+
logger.info 'Autogenerating a dynamic ruleset based on source changes'
|
58
|
+
return unless RuleSetBuilder.new(@options).build?
|
55
59
|
elsif @options.patch_config == Options::DEFAULT_CONFIG_PATH
|
56
60
|
# patch branch build pmd reports with same configuration as base branch
|
57
61
|
# if not specified otherwise. This allows to use a different config (e.g. less rules)
|
@@ -93,8 +97,8 @@ module PmdTester
|
|
93
97
|
unzip_cmd = "unzip -qo #{zip_filename}"
|
94
98
|
|
95
99
|
Dir.chdir(target_path) do
|
96
|
-
Cmd.
|
97
|
-
Cmd.
|
100
|
+
Cmd.execute_successfully(wget_cmd) unless File.exist?(zip_filename)
|
101
|
+
Cmd.execute_successfully(unzip_cmd)
|
98
102
|
end
|
99
103
|
|
100
104
|
"#{target_path}/#{branch_filename}"
|
data/lib/pmdtester/semver.rb
CHANGED
@@ -4,6 +4,12 @@ module PmdTester
|
|
4
4
|
# Utility to deal with semantic versions
|
5
5
|
class Semver
|
6
6
|
def self.compare(version_a, version_b)
|
7
|
+
result = internal_compare(version_a, version_b)
|
8
|
+
PmdTester.logger.debug " result: #{result}"
|
9
|
+
result
|
10
|
+
end
|
11
|
+
|
12
|
+
private_class_method def self.internal_compare(version_a, version_b)
|
7
13
|
PmdTester.logger.debug "Comparing #{version_a} <=> #{version_b}"
|
8
14
|
m = /(\d+)\.(\d+)\.(\d+)(.*)/.match(version_a)
|
9
15
|
a_major = m[1].to_i
|
data/lib/pmdtester.rb
CHANGED
@@ -33,7 +33,7 @@ require_relative 'pmdtester/parsers/projects_parser'
|
|
33
33
|
# and unexpected behaviors will not be introduced to PMD project
|
34
34
|
# after fixing an issue and new rules can work as expected.
|
35
35
|
module PmdTester
|
36
|
-
VERSION = '1.
|
36
|
+
VERSION = '1.5.0'
|
37
37
|
BASE = 'base'
|
38
38
|
PATCH = 'patch'
|
39
39
|
PR_NUM_ENV_VAR = 'PMD_CI_PULL_REQUEST_NUMBER' # see PmdBranchDetail
|
data/pmdtester.gemspec
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
# DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake hoe:spec`.
|
2
2
|
|
3
3
|
# -*- encoding: utf-8 -*-
|
4
|
-
# stub: pmdtester 1.
|
4
|
+
# stub: pmdtester 1.5.0 ruby lib
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "pmdtester".freeze
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
11
11
|
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=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andreas Dangel".freeze, "Binguo Bao".freeze, "Cl\u00E9ment Fournier".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2022-05-06"
|
15
15
|
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
|
16
16
|
s.email = ["andreas.dangel@pmd-code.org".freeze, "djydewang@gmail.com".freeze, "clement.fournier76@gmail.com".freeze]
|
17
17
|
s.executables = ["pmdtester".freeze]
|
@@ -29,34 +29,34 @@ Gem::Specification.new do |s|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if s.respond_to? :add_runtime_dependency then
|
32
|
-
s.add_runtime_dependency(%q<nokogiri>.freeze, ["
|
32
|
+
s.add_runtime_dependency(%q<nokogiri>.freeze, ["~> 1.13"])
|
33
33
|
s.add_runtime_dependency(%q<slop>.freeze, ["~> 4.6"])
|
34
34
|
s.add_runtime_dependency(%q<differ>.freeze, ["~> 0.1"])
|
35
|
-
s.add_runtime_dependency(%q<rufus-scheduler>.freeze, ["~> 3.
|
35
|
+
s.add_runtime_dependency(%q<rufus-scheduler>.freeze, ["~> 3.8"])
|
36
36
|
s.add_runtime_dependency(%q<logger-colors>.freeze, ["~> 1.0"])
|
37
|
-
s.add_runtime_dependency(%q<liquid>.freeze, ["
|
37
|
+
s.add_runtime_dependency(%q<liquid>.freeze, ["~> 5.2"])
|
38
38
|
s.add_development_dependency(%q<hoe-bundler>.freeze, ["~> 1.5"])
|
39
39
|
s.add_development_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
|
40
40
|
s.add_development_dependency(%q<minitest>.freeze, ["~> 5.10"])
|
41
41
|
s.add_development_dependency(%q<mocha>.freeze, ["~> 1.5"])
|
42
|
-
s.add_development_dependency(%q<rubocop>.freeze, ["~> 0.
|
43
|
-
s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.
|
44
|
-
s.add_development_dependency(%q<rdoc>.freeze, ["
|
42
|
+
s.add_development_dependency(%q<rubocop>.freeze, ["~> 0.93"])
|
43
|
+
s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.5"])
|
44
|
+
s.add_development_dependency(%q<rdoc>.freeze, ["~> 6.4"])
|
45
45
|
s.add_development_dependency(%q<hoe>.freeze, ["~> 3.23"])
|
46
46
|
else
|
47
|
-
s.add_dependency(%q<nokogiri>.freeze, ["
|
47
|
+
s.add_dependency(%q<nokogiri>.freeze, ["~> 1.13"])
|
48
48
|
s.add_dependency(%q<slop>.freeze, ["~> 4.6"])
|
49
49
|
s.add_dependency(%q<differ>.freeze, ["~> 0.1"])
|
50
|
-
s.add_dependency(%q<rufus-scheduler>.freeze, ["~> 3.
|
50
|
+
s.add_dependency(%q<rufus-scheduler>.freeze, ["~> 3.8"])
|
51
51
|
s.add_dependency(%q<logger-colors>.freeze, ["~> 1.0"])
|
52
|
-
s.add_dependency(%q<liquid>.freeze, ["
|
52
|
+
s.add_dependency(%q<liquid>.freeze, ["~> 5.2"])
|
53
53
|
s.add_dependency(%q<hoe-bundler>.freeze, ["~> 1.5"])
|
54
54
|
s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
|
55
55
|
s.add_dependency(%q<minitest>.freeze, ["~> 5.10"])
|
56
56
|
s.add_dependency(%q<mocha>.freeze, ["~> 1.5"])
|
57
|
-
s.add_dependency(%q<rubocop>.freeze, ["~> 0.
|
58
|
-
s.add_dependency(%q<test-unit>.freeze, ["~> 3.
|
59
|
-
s.add_dependency(%q<rdoc>.freeze, ["
|
57
|
+
s.add_dependency(%q<rubocop>.freeze, ["~> 0.93"])
|
58
|
+
s.add_dependency(%q<test-unit>.freeze, ["~> 3.5"])
|
59
|
+
s.add_dependency(%q<rdoc>.freeze, ["~> 6.4"])
|
60
60
|
s.add_dependency(%q<hoe>.freeze, ["~> 3.23"])
|
61
61
|
end
|
62
62
|
end
|
@@ -71,6 +71,12 @@
|
|
71
71
|
<td class="patch">{{diff.patch_timestamp}}</td>
|
72
72
|
<td class="diff"></td>
|
73
73
|
</tr>
|
74
|
+
<tr>
|
75
|
+
<td class="item">Exit Code</td>
|
76
|
+
<td class="base">{{diff.base_exit_code}} <a href="base_stdout.txt">stdout</a> | <a href="base_stderr.txt">stderr</a></td>
|
77
|
+
<td class="patch">{{diff.patch_exit_code}} <a href="patch_stdout.txt">stdout</a> | <a href="patch_stderr.txt">stderr</a></td>
|
78
|
+
<td class="diff"></td>
|
79
|
+
</tr>
|
74
80
|
<tr>
|
75
81
|
<td class="item">Full Report</td>
|
76
82
|
<td class="base"><a href="base_pmd_report.html">Base PMD Report</a></td>
|
@@ -53,6 +53,10 @@
|
|
53
53
|
<td class="item">Timestamp</td>
|
54
54
|
<td class="{{branch}}">{{report.timestamp}}</td>
|
55
55
|
</tr>
|
56
|
+
<tr>
|
57
|
+
<td class="item">Exit Code</td>
|
58
|
+
<td class="{{branch}}">{{report.exit_code}} <a href="{{branch}}_stdout.txt">stdout</a> | <a href="{{branch}}_stderr.txt">stderr</a></td>
|
59
|
+
</tr>
|
56
60
|
<tr>
|
57
61
|
<td class="item">Full Report</td>
|
58
62
|
<td class="{{branch}}"><a href="{{branch}}_pmd_report.xml">{{branch}}_pmd_report.xml</a></td>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pmdtester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Dangel
|
@@ -10,22 +10,22 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-05-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- - "
|
19
|
+
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
21
|
+
version: '1.13'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- - "
|
26
|
+
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 1.
|
28
|
+
version: '1.13'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: slop
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,14 +60,14 @@ dependencies:
|
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: '3.
|
63
|
+
version: '3.8'
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
68
|
- - "~>"
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: '3.
|
70
|
+
version: '3.8'
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: logger-colors
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,16 +86,16 @@ dependencies:
|
|
86
86
|
name: liquid
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
|
-
- - "
|
89
|
+
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version: '
|
91
|
+
version: '5.2'
|
92
92
|
type: :runtime
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
|
-
- - "
|
96
|
+
- - "~>"
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: '
|
98
|
+
version: '5.2'
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
100
|
name: hoe-bundler
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,48 +158,42 @@ dependencies:
|
|
158
158
|
requirements:
|
159
159
|
- - "~>"
|
160
160
|
- !ruby/object:Gem::Version
|
161
|
-
version: '0.
|
161
|
+
version: '0.93'
|
162
162
|
type: :development
|
163
163
|
prerelease: false
|
164
164
|
version_requirements: !ruby/object:Gem::Requirement
|
165
165
|
requirements:
|
166
166
|
- - "~>"
|
167
167
|
- !ruby/object:Gem::Version
|
168
|
-
version: '0.
|
168
|
+
version: '0.93'
|
169
169
|
- !ruby/object:Gem::Dependency
|
170
170
|
name: test-unit
|
171
171
|
requirement: !ruby/object:Gem::Requirement
|
172
172
|
requirements:
|
173
173
|
- - "~>"
|
174
174
|
- !ruby/object:Gem::Version
|
175
|
-
version: '3.
|
175
|
+
version: '3.5'
|
176
176
|
type: :development
|
177
177
|
prerelease: false
|
178
178
|
version_requirements: !ruby/object:Gem::Requirement
|
179
179
|
requirements:
|
180
180
|
- - "~>"
|
181
181
|
- !ruby/object:Gem::Version
|
182
|
-
version: '3.
|
182
|
+
version: '3.5'
|
183
183
|
- !ruby/object:Gem::Dependency
|
184
184
|
name: rdoc
|
185
185
|
requirement: !ruby/object:Gem::Requirement
|
186
186
|
requirements:
|
187
|
-
- - "
|
188
|
-
- !ruby/object:Gem::Version
|
189
|
-
version: '4.0'
|
190
|
-
- - "<"
|
187
|
+
- - "~>"
|
191
188
|
- !ruby/object:Gem::Version
|
192
|
-
version: '
|
189
|
+
version: '6.4'
|
193
190
|
type: :development
|
194
191
|
prerelease: false
|
195
192
|
version_requirements: !ruby/object:Gem::Requirement
|
196
193
|
requirements:
|
197
|
-
- - "
|
198
|
-
- !ruby/object:Gem::Version
|
199
|
-
version: '4.0'
|
200
|
-
- - "<"
|
194
|
+
- - "~>"
|
201
195
|
- !ruby/object:Gem::Version
|
202
|
-
version: '
|
196
|
+
version: '6.4'
|
203
197
|
- !ruby/object:Gem::Dependency
|
204
198
|
name: hoe
|
205
199
|
requirement: !ruby/object:Gem::Requirement
|