pmdtester 1.2.0 → 1.4.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 +2 -2
- data/.ci/manual-integration-tests.sh +2 -2
- data/.github/workflows/build.yml +4 -3
- data/.github/workflows/manual-integration-tests.yml +9 -4
- data/History.md +25 -0
- data/Manifest.txt +1 -0
- data/README.rdoc +6 -7
- data/Rakefile +11 -6
- data/lib/pmdtester/builders/pmd_report_builder.rb +7 -1
- data/lib/pmdtester/builders/rule_set_builder.rb +113 -76
- data/lib/pmdtester/parsers/pmd_report_document.rb +3 -4
- data/lib/pmdtester/pmd_violation.rb +11 -1
- data/lib/pmdtester/runner.rb +7 -3
- data/lib/pmdtester/semver.rb +36 -0
- data/lib/pmdtester.rb +2 -1
- data/pmdtester.gemspec +18 -18
- data/resources/css/pmd-tester.css +17 -1
- data/resources/js/code-snippets.js +48 -15
- data/resources/js/project-report.js +3 -2
- metadata +23 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0002a7305089264a200552384fff3179d706c2a89b39ef28cec2f2c184e84331
|
|
4
|
+
data.tar.gz: b59758aa8ece040b8d90c3577fcdc05000615e5efb32504b6e96599686d0ee6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d18602b80cad2306aba780a338c90831aeaff5b17ebce880384a2e1b94405c7e45ae40e9842f878fe3ee514e8651b1bb856bfea35bab130f0f67606690ac53a7
|
|
7
|
+
data.tar.gz: 36c0c70dada772cfe44d595eeefd2cf131925db7a884dbd092bc4490cbf2ea948df23449c2dcdc78f39b75c4863b4c41b84d73a0346874c78c8aa5dee03a5ad4
|
data/.ci/build.sh
CHANGED
|
@@ -9,8 +9,8 @@ source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
|
|
|
9
9
|
|
|
10
10
|
function build() {
|
|
11
11
|
pmd_ci_log_group_start "Install OpenJDK 8+11"
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
pmd_ci_openjdk_install_adoptium 11
|
|
13
|
+
pmd_ci_openjdk_install_adoptium 8
|
|
14
14
|
pmd_ci_openjdk_setdefault 11
|
|
15
15
|
pmd_ci_log_group_end
|
|
16
16
|
|
|
@@ -9,8 +9,8 @@ source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
|
|
|
9
9
|
|
|
10
10
|
function build() {
|
|
11
11
|
pmd_ci_log_group_start "Install OpenJDK 8+11"
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
pmd_ci_openjdk_install_adoptium 11
|
|
13
|
+
pmd_ci_openjdk_install_adoptium 8
|
|
14
14
|
pmd_ci_openjdk_setdefault 11
|
|
15
15
|
pmd_ci_log_group_end
|
|
16
16
|
|
data/.github/workflows/build.yml
CHANGED
|
@@ -27,9 +27,9 @@ jobs:
|
|
|
27
27
|
~/.cache
|
|
28
28
|
vendor/bundle
|
|
29
29
|
target/repositories
|
|
30
|
-
key:
|
|
30
|
+
key: v1-${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
|
|
31
31
|
restore-keys: |
|
|
32
|
-
|
|
32
|
+
v1-${{ runner.os }}-
|
|
33
33
|
- name: Set up Ruby 2.7
|
|
34
34
|
uses: ruby/setup-ruby@v1
|
|
35
35
|
with:
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
run: |
|
|
40
40
|
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
|
41
41
|
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3" >> $GITHUB_ENV
|
|
42
|
-
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/
|
|
42
|
+
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/17/scripts" >> $GITHUB_ENV
|
|
43
43
|
- name: Check Environment
|
|
44
44
|
shell: bash
|
|
45
45
|
run: |
|
|
@@ -53,3 +53,4 @@ jobs:
|
|
|
53
53
|
shell: bash
|
|
54
54
|
env:
|
|
55
55
|
PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }}
|
|
56
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
name: manual-integration-tests
|
|
2
2
|
|
|
3
|
-
on:
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# build it monthly: At 08:30 on day-of-month 1.
|
|
6
|
+
- cron: '30 8 1 * *'
|
|
7
|
+
workflow_dispatch:
|
|
4
8
|
|
|
5
9
|
jobs:
|
|
6
10
|
build:
|
|
@@ -15,9 +19,9 @@ jobs:
|
|
|
15
19
|
~/.cache
|
|
16
20
|
vendor/bundle
|
|
17
21
|
target/repositories
|
|
18
|
-
key:
|
|
22
|
+
key: v1-${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
|
|
19
23
|
restore-keys: |
|
|
20
|
-
|
|
24
|
+
v1-${{ runner.os }}-
|
|
21
25
|
- name: Set up Ruby 2.7
|
|
22
26
|
uses: ruby/setup-ruby@v1
|
|
23
27
|
with:
|
|
@@ -27,7 +31,7 @@ jobs:
|
|
|
27
31
|
run: |
|
|
28
32
|
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
|
29
33
|
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3" >> $GITHUB_ENV
|
|
30
|
-
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/
|
|
34
|
+
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/17/scripts" >> $GITHUB_ENV
|
|
31
35
|
- name: Check Environment
|
|
32
36
|
shell: bash
|
|
33
37
|
run: |
|
|
@@ -41,3 +45,4 @@ jobs:
|
|
|
41
45
|
shell: bash
|
|
42
46
|
env:
|
|
43
47
|
PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }}
|
|
48
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
data/History.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
# 1.4.1 / 2022-04-12
|
|
2
|
+
|
|
3
|
+
## Fixed Issues
|
|
4
|
+
|
|
5
|
+
* [#104](https://github.com/pmd/pmd-regression-tester/issues/104): Baseline filtering is not working anymore
|
|
6
|
+
|
|
7
|
+
# 1.4.0 / 2022-03-24
|
|
8
|
+
|
|
9
|
+
## Enhancements
|
|
10
|
+
|
|
11
|
+
* [#103](https://github.com/pmd/pmd-regression-tester/pull/103): Support other languages besides java
|
|
12
|
+
|
|
13
|
+
# 1.3.0 / 2021-12-17
|
|
14
|
+
|
|
15
|
+
## Enhancements
|
|
16
|
+
|
|
17
|
+
* [#94](https://github.com/pmd/pmd-regression-tester/issues/94): Improve code snippet preview
|
|
18
|
+
* [#95](https://github.com/pmd/pmd-regression-tester/issues/95): Add length menu for datatable to allow configurable page size
|
|
19
|
+
|
|
20
|
+
## Fixed Issues
|
|
21
|
+
|
|
22
|
+
* [#86](https://github.com/pmd/pmd-regression-tester/issues/86): Uncaught TypeError: violation is undefined
|
|
23
|
+
* [#93](https://github.com/pmd/pmd-regression-tester/issues/93): Line numbers > 1000 are not displayed correctly
|
|
24
|
+
* [#96](https://github.com/pmd/pmd-regression-tester/issues/96): Fix failing integration tests
|
|
25
|
+
|
|
1
26
|
# 1.2.0 / 2021-06-20
|
|
2
27
|
|
|
3
28
|
## New and Noteworthy
|
data/Manifest.txt
CHANGED
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
|
|
|
@@ -97,11 +97,12 @@ module PmdTester
|
|
|
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
|
+
fail_on_violation = should_use_long_cli_options ? '--fail-on-violation false' : '-failOnViolation false'
|
|
100
101
|
pmd_cmd = "#{error_recovery_options}" \
|
|
101
102
|
"#{run_path} pmd -d #{project.local_source_path} -f xml " \
|
|
102
103
|
"-R #{project.get_config_path(@pmd_branch_name)} " \
|
|
103
104
|
"-r #{project.get_pmd_report_path(@pmd_branch_name)} " \
|
|
104
|
-
"
|
|
105
|
+
"#{fail_on_violation} -t #{@threads} " \
|
|
105
106
|
"#{project.auxclasspath}"
|
|
106
107
|
start_time = Time.now
|
|
107
108
|
if File.exist?(project.get_pmd_report_path(@pmd_branch_name))
|
|
@@ -194,5 +195,10 @@ module PmdTester
|
|
|
194
195
|
def wd_has_dirty_git_changes
|
|
195
196
|
!Cmd.execute('git status --porcelain').empty?
|
|
196
197
|
end
|
|
198
|
+
|
|
199
|
+
def should_use_long_cli_options
|
|
200
|
+
logger.debug "PMD Version: #{@pmd_version}"
|
|
201
|
+
Semver.compare(@pmd_version, '6.41.0') >= 0
|
|
202
|
+
end
|
|
197
203
|
end
|
|
198
204
|
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(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
|
|
@@ -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
|
|
|
@@ -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/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)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PmdTester
|
|
4
|
+
# Utility to deal with semantic versions
|
|
5
|
+
class Semver
|
|
6
|
+
def self.compare(version_a, version_b)
|
|
7
|
+
PmdTester.logger.debug "Comparing #{version_a} <=> #{version_b}"
|
|
8
|
+
m = /(\d+)\.(\d+)\.(\d+)(.*)/.match(version_a)
|
|
9
|
+
a_major = m[1].to_i
|
|
10
|
+
a_minor = m[2].to_i
|
|
11
|
+
a_patch = m[3].to_i
|
|
12
|
+
a_snapshot = m[4]
|
|
13
|
+
PmdTester.logger.debug " a_major: #{a_major} a_minor: #{a_minor} a_patch: #{a_patch} a_snapshot: #{a_snapshot}"
|
|
14
|
+
|
|
15
|
+
m = /(\d+)\.(\d+)\.(\d+)(.*)/.match(version_b)
|
|
16
|
+
b_major = m[1].to_i
|
|
17
|
+
b_minor = m[2].to_i
|
|
18
|
+
b_patch = m[3].to_i
|
|
19
|
+
b_snapshot = m[4]
|
|
20
|
+
PmdTester.logger.debug " b_major: #{b_major} b_minor: #{b_minor} b_patch: #{b_patch} b_snapshot: #{b_snapshot}"
|
|
21
|
+
|
|
22
|
+
return a_major <=> b_major if a_major != b_major
|
|
23
|
+
return a_minor <=> b_minor if a_minor != b_minor
|
|
24
|
+
return a_patch <=> b_patch if a_patch != b_patch
|
|
25
|
+
|
|
26
|
+
compare_snapshots(a_snapshot, b_snapshot)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private_class_method def self.compare_snapshots(a_snapshot, b_snapshot)
|
|
30
|
+
return -1 if a_snapshot == '-SNAPSHOT' && b_snapshot == ''
|
|
31
|
+
return 1 if a_snapshot == '' && b_snapshot == '-SNAPSHOT'
|
|
32
|
+
|
|
33
|
+
a_snapshot <=> b_snapshot
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/pmdtester.rb
CHANGED
|
@@ -15,6 +15,7 @@ require_relative 'pmdtester/project'
|
|
|
15
15
|
require_relative 'pmdtester/report_diff'
|
|
16
16
|
require_relative 'pmdtester/resource_locator'
|
|
17
17
|
require_relative 'pmdtester/runner'
|
|
18
|
+
require_relative 'pmdtester/semver'
|
|
18
19
|
|
|
19
20
|
require_relative 'pmdtester/builders/simple_progress_logger'
|
|
20
21
|
require_relative 'pmdtester/builders/project_builder'
|
|
@@ -32,7 +33,7 @@ require_relative 'pmdtester/parsers/projects_parser'
|
|
|
32
33
|
# and unexpected behaviors will not be introduced to PMD project
|
|
33
34
|
# after fixing an issue and new rules can work as expected.
|
|
34
35
|
module PmdTester
|
|
35
|
-
VERSION = '1.
|
|
36
|
+
VERSION = '1.4.1'
|
|
36
37
|
BASE = 'base'
|
|
37
38
|
PATCH = 'patch'
|
|
38
39
|
PR_NUM_ENV_VAR = 'PMD_CI_PULL_REQUEST_NUMBER' # see PmdBranchDetail
|
data/pmdtester.gemspec
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
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.4.1 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.4.1"
|
|
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-04-12"
|
|
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]
|
|
18
18
|
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, "config/projectlist_1_2_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]
|
|
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, "config/projectlist_1_2_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, "lib/pmdtester/semver.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]
|
|
20
20
|
s.homepage = "https://pmd.github.io".freeze
|
|
21
21
|
s.licenses = ["BSD-2-Clause".freeze]
|
|
22
22
|
s.rdoc_options = ["--main".freeze, "README.rdoc".freeze]
|
|
@@ -29,35 +29,35 @@ 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, ["
|
|
45
|
-
s.add_development_dependency(%q<hoe>.freeze, ["~> 3.
|
|
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
|
+
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, ["
|
|
60
|
-
s.add_dependency(%q<hoe>.freeze, ["~> 3.
|
|
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
|
+
s.add_dependency(%q<hoe>.freeze, ["~> 3.23"])
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -10,9 +10,25 @@ code {
|
|
|
10
10
|
font-size: 13pt;
|
|
11
11
|
white-space: pre;
|
|
12
12
|
}
|
|
13
|
-
code.highlight {
|
|
13
|
+
code.highlight, tr.highlight {
|
|
14
14
|
background-color: yellow;
|
|
15
15
|
}
|
|
16
|
+
table.code-snippet > tbody > tr > td {
|
|
17
|
+
padding: 0px;
|
|
18
|
+
border: none;
|
|
19
|
+
}
|
|
20
|
+
table.code-snippet > tbody > tr > td.line-number > code:before {
|
|
21
|
+
content: attr(data-line-number);
|
|
22
|
+
}
|
|
23
|
+
.btn-clipboard {
|
|
24
|
+
margin-top: 1rem;
|
|
25
|
+
display: block;
|
|
26
|
+
padding: .25rem .5rem;
|
|
27
|
+
color: #0d6efd;
|
|
28
|
+
background-color: #fff;
|
|
29
|
+
border: 1px solid;
|
|
30
|
+
border-radius: .25rem;
|
|
31
|
+
}
|
|
16
32
|
a {
|
|
17
33
|
text-decoration: none;
|
|
18
34
|
}
|
|
@@ -15,18 +15,18 @@
|
|
|
15
15
|
|
|
16
16
|
// returns text, not html
|
|
17
17
|
function formatLineNumber(number) {
|
|
18
|
-
let prefix;
|
|
18
|
+
let prefix = '';
|
|
19
19
|
if (number < 10) {
|
|
20
|
-
prefix =
|
|
20
|
+
prefix = nbsp.repeat(3);
|
|
21
21
|
} else if (number < 100) {
|
|
22
|
-
prefix =
|
|
22
|
+
prefix = nbsp.repeat(2);
|
|
23
23
|
} else if (number < 1000) {
|
|
24
24
|
prefix = nbsp;
|
|
25
25
|
}
|
|
26
26
|
return prefix + number;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function fetchSnippet(document, container, url,
|
|
29
|
+
function fetchSnippet(document, container, url, violationLineNumber, weburl) {
|
|
30
30
|
var weburl, requestUrl, oReq;
|
|
31
31
|
|
|
32
32
|
requestUrl = url.replace(/github.com/, "raw.githubusercontent.com");
|
|
@@ -34,37 +34,70 @@
|
|
|
34
34
|
|
|
35
35
|
oReq = new XMLHttpRequest();
|
|
36
36
|
oReq.addEventListener("load", function() {
|
|
37
|
-
let lines, start, deleteCount;
|
|
37
|
+
let lines, start, deleteCount, lineSeparator;
|
|
38
38
|
|
|
39
39
|
// we'll append stuff in the loop below
|
|
40
40
|
container.innerHTML = '<p><a href="' + weburl + '" target="_blank" rel="noopener noreferrer">' + weburl + '</a></p>';
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (this.responseText.indexOf('\r\n') >= 0) {
|
|
43
|
+
lineSeparator = '\r\n';
|
|
44
|
+
} else {
|
|
45
|
+
lineSeparator = '\n';
|
|
46
|
+
}
|
|
47
|
+
lines = this.responseText.split(lineSeparator);
|
|
48
|
+
start = violationLineNumber - contextLines;
|
|
44
49
|
if (start > 0) {
|
|
45
50
|
lines.splice(0, start); // remove lines before
|
|
46
51
|
}
|
|
47
52
|
deleteCount = lines.length - (2 * contextLines) + 1;
|
|
48
53
|
lines.splice(2 * contextLines - 1, deleteCount); // delete lines after
|
|
49
54
|
|
|
55
|
+
let table = document.createElement('table');
|
|
56
|
+
table.classList.add('code-snippet');
|
|
57
|
+
let tableBody = document.createElement('tbody');
|
|
58
|
+
table.appendChild(tableBody);
|
|
50
59
|
// now we have just the lines which will be displayed
|
|
51
60
|
lines.forEach(line => {
|
|
52
61
|
start++;
|
|
53
|
-
let
|
|
54
|
-
if (start ===
|
|
55
|
-
|
|
62
|
+
let tableRow = document.createElement('tr');
|
|
63
|
+
if (start === violationLineNumber) {
|
|
64
|
+
tableRow.classList.add("highlight");
|
|
56
65
|
}
|
|
66
|
+
|
|
67
|
+
let lineNumberColumn = document.createElement('td');
|
|
68
|
+
lineNumberColumn.classList.add('line-number');
|
|
69
|
+
tableRow.appendChild(lineNumberColumn);
|
|
70
|
+
let lineNumberElement = document.createElement('code');
|
|
71
|
+
lineNumberColumn.appendChild(lineNumberElement);
|
|
72
|
+
lineNumberElement.setAttribute('data-line-number', formatLineNumber(start));
|
|
73
|
+
|
|
74
|
+
let codeColumn = document.createElement('td');
|
|
75
|
+
tableRow.appendChild(codeColumn);
|
|
76
|
+
let codeElement = document.createElement("code");
|
|
77
|
+
codeColumn.appendChild(codeElement);
|
|
57
78
|
// createTextNode escapes special chars
|
|
58
|
-
|
|
59
|
-
lineElt.appendChild(document.createElement("br"));
|
|
79
|
+
codeElement.appendChild(document.createTextNode(line));
|
|
60
80
|
|
|
61
|
-
|
|
81
|
+
tableBody.appendChild(tableRow); // append row to the table
|
|
62
82
|
});
|
|
83
|
+
container.appendChild(table);
|
|
84
|
+
|
|
85
|
+
if (navigator.clipboard) {
|
|
86
|
+
let copyButton = document.createElement('button');
|
|
87
|
+
copyButton.classList.add('btn-clipboard');
|
|
88
|
+
copyButton.setAttribute('title', 'Copy to clipboard');
|
|
89
|
+
copyButton.appendChild(document.createTextNode('copy'));
|
|
90
|
+
copyButton.onclick = function() {
|
|
91
|
+
navigator.clipboard.writeText(lines.join(lineSeparator));
|
|
92
|
+
}
|
|
93
|
+
container.appendChild(copyButton);
|
|
94
|
+
}
|
|
63
95
|
});
|
|
64
|
-
oReq.open("GET", requestUrl);
|
|
65
|
-
oReq.send();
|
|
66
96
|
|
|
67
97
|
container.innerHTML = "<samp>fetching...</samp>";
|
|
98
|
+
|
|
99
|
+
oReq.open("GET", requestUrl);
|
|
100
|
+
oReq.send();
|
|
68
101
|
}
|
|
69
102
|
|
|
70
103
|
window.pmd_code_snippets = {
|
|
@@ -52,7 +52,7 @@ $(document).ready(function () {
|
|
|
52
52
|
],
|
|
53
53
|
deferRender: true,
|
|
54
54
|
// scrollY: "6000px",
|
|
55
|
-
dom: '
|
|
55
|
+
dom: 'Pfrtipl', // Search Panes, filtering input, processing display element, table, table information summary, pagination control, length changing input control
|
|
56
56
|
searchPanes: {
|
|
57
57
|
viewTotal: true,
|
|
58
58
|
cascadePanes: true,
|
|
@@ -113,12 +113,13 @@ $(document).ready(function () {
|
|
|
113
113
|
},
|
|
114
114
|
],
|
|
115
115
|
displayLength: 25,
|
|
116
|
+
lengthMenu: [ [10, 20, 25, 50, 100, -1], [10, 20, 25, 50, 100, "All"] ],
|
|
116
117
|
rowCallback(row, data, index) {
|
|
117
118
|
$(row).addClass(cssClass[data.t]);
|
|
118
119
|
},
|
|
119
120
|
});
|
|
120
121
|
|
|
121
|
-
$('#violationsTable tbody').on('click', 'tr', function() {
|
|
122
|
+
$('#violationsTable tbody').on('click', 'tr[role=row]', function() {
|
|
122
123
|
var tr = $(this).closest('tr');
|
|
123
124
|
var row = table.row( tr );
|
|
124
125
|
|
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.4.1
|
|
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-04-12 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,62 +158,56 @@ 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
|
|
206
200
|
requirements:
|
|
207
201
|
- - "~>"
|
|
208
202
|
- !ruby/object:Gem::Version
|
|
209
|
-
version: '3.
|
|
203
|
+
version: '3.23'
|
|
210
204
|
type: :development
|
|
211
205
|
prerelease: false
|
|
212
206
|
version_requirements: !ruby/object:Gem::Requirement
|
|
213
207
|
requirements:
|
|
214
208
|
- - "~>"
|
|
215
209
|
- !ruby/object:Gem::Version
|
|
216
|
-
version: '3.
|
|
210
|
+
version: '3.23'
|
|
217
211
|
description: A regression testing tool ensure that new problems and unexpected behaviors
|
|
218
212
|
will not be introduced to PMD project after fixing an issue , and new rules can
|
|
219
213
|
work as expected.
|
|
@@ -275,6 +269,7 @@ files:
|
|
|
275
269
|
- lib/pmdtester/report_diff.rb
|
|
276
270
|
- lib/pmdtester/resource_locator.rb
|
|
277
271
|
- lib/pmdtester/runner.rb
|
|
272
|
+
- lib/pmdtester/semver.rb
|
|
278
273
|
- pmdtester.gemspec
|
|
279
274
|
- resources/_includes/diff_pill_row.html
|
|
280
275
|
- resources/css/bootstrap.min.css
|