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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db98cbb787ccaa595c939ddee83316347edbf0daf746ca38daea53d3dab3fb77
4
- data.tar.gz: 158cc9f948c7e680725dc2596e4d65dabac35f9f06188c8c4670d060f9889dff
3
+ metadata.gz: 0002a7305089264a200552384fff3179d706c2a89b39ef28cec2f2c184e84331
4
+ data.tar.gz: b59758aa8ece040b8d90c3577fcdc05000615e5efb32504b6e96599686d0ee6a
5
5
  SHA512:
6
- metadata.gz: 28ea491ac20cddb4b51f0c418c479ce7394d5839d05dfacd04cb5c128590b7d8100b232a60d4cfafc0110249ccbe001b1e9426632679df4dcf2f6dcdc9415121
7
- data.tar.gz: 2f12577c68058fb20bbc10e64de84ce574d45e6d7c0c766907b4e4342054bc95f992a654b620ced49130379db66aa5b21425114d327a9332021f04b6544e094a
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
- pmd_ci_openjdk_install_adoptopenjdk 11
13
- pmd_ci_openjdk_install_adoptopenjdk 8
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
- pmd_ci_openjdk_install_adoptopenjdk 11
13
- pmd_ci_openjdk_install_adoptopenjdk 8
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
 
@@ -27,9 +27,9 @@ jobs:
27
27
  ~/.cache
28
28
  vendor/bundle
29
29
  target/repositories
30
- key: ${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
30
+ key: v1-${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
31
31
  restore-keys: |
32
- ${{ runner.os }}-
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/14/scripts" >> $GITHUB_ENV
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: workflow_dispatch
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: ${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
22
+ key: v1-${{ runner.os }}-${{ hashFiles('pmdtester.gemspec') }}
19
23
  restore-keys: |
20
- ${{ runner.os }}-
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/14/scripts" >> $GITHUB_ENV
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
@@ -44,6 +44,7 @@ lib/pmdtester/project.rb
44
44
  lib/pmdtester/report_diff.rb
45
45
  lib/pmdtester/resource_locator.rb
46
46
  lib/pmdtester/runner.rb
47
+ lib/pmdtester/semver.rb
47
48
  pmdtester.gemspec
48
49
  resources/_includes/diff_pill_row.html
49
50
  resources/css/bootstrap.min.css
data/README.rdoc CHANGED
@@ -105,23 +105,22 @@ The tool creates the following folders:
105
105
 
106
106
  === Runtime dependency
107
107
 
108
- nokogiri >= 1.11.0.rc4
108
+ nokogiri ~> 1.13
109
109
  slop ~> 4.6
110
110
  differ ~> 0.1
111
- rufus-scheduler ~> 3.5
111
+ rufus-scheduler ~> 3.8
112
112
  logger-colors ~> 1.0
113
- liquid >= 4.0
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
- rdoc < 7, >= 4.0
123
- rubocop ~> 0.81
124
- test-unit ~> 3.2
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 += [['nokogiri', '>= 1.11.0.rc4'], ['slop', '~> 4.6'], ['differ', '~> 0.1'],
23
- ['rufus-scheduler', '~> 3.5'], ['logger-colors', '~> 1.0'],
24
- ['liquid', '>= 4.0']]
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.81'],
32
- ['test-unit', '~> 3.2'],
33
- ['rdoc', ['>= 4.0', '< 7']]
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
- "-failOnViolation false -t #{@threads} " \
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
- NO_JAVA_RULES_CHANGED_MESSAGE = 'No java rules have been changed!'
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
- def build
28
- filenames = diff_filenames
29
- rule_refs = get_rule_refs(filenames)
30
- output_filter_set(rule_refs)
31
- build_config_file(rule_refs)
32
- logger.debug "Dynamic configuration: #{[rule_refs]}"
33
- rule_refs
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(ALL_CATEGORIES)
39
+ output_filter_set([])
38
40
  end
39
41
 
40
42
  def output_filter_set(rule_refs)
41
- if rule_refs == ALL_CATEGORIES
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/java/')
50
+ ref.delete_prefix!('category/')
49
51
  @options.filter_set.add(ref)
50
52
  end
51
53
 
52
- logger.debug "Using filter based on patch config #{@options.patch_config}: " \
54
+ logger.info "Using filter based on patch config #{@options.patch_config}: " \
53
55
  "#{@options.filter_set}"
54
56
  else
55
- # if `rule_refs` contains all categories, then no need to filter the baseline
56
- logger.debug 'No filter when comparing patch to baseline'
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.debug "Filter is now #{rule_refs}"
62
+ logger.info "Filter is now #{rule_refs}"
61
63
  @options.filter_set = rule_refs
62
64
  end
63
65
  end
64
66
 
65
- def diff_filenames
66
- filenames = nil
67
- Dir.chdir(@options.local_git_repo) do
68
- base = @options.base_branch
69
- patch = @options.patch_branch
70
- # We only need to support git here, since PMD's repo is using git.
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/java/#{entry}")
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
- ruleset_attr = violation.ruleset_name.delete(' ').downcase! << '.xml'
93
- return true if @filter_set.include?(ruleset_attr)
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
@@ -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
- rule_sets = RuleSetBuilder.new(@options).build if @options.auto_config_flag
37
- return if rule_sets&.empty?
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
- return if RuleSetBuilder.new(@options).build.empty?
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.2.0'
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.2.0 ruby lib
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.2.0"
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 = "2021-06-20"
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, [">= 1.11.0.rc4"])
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.5"])
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, [">= 4.0"])
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.81"])
43
- s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.2"])
44
- s.add_development_dependency(%q<rdoc>.freeze, [">= 4.0", "< 7"])
45
- s.add_development_dependency(%q<hoe>.freeze, ["~> 3.22"])
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, [">= 1.11.0.rc4"])
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.5"])
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, [">= 4.0"])
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.81"])
58
- s.add_dependency(%q<test-unit>.freeze, ["~> 3.2"])
59
- s.add_dependency(%q<rdoc>.freeze, [">= 4.0", "< 7"])
60
- s.add_dependency(%q<hoe>.freeze, ["~> 3.22"])
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 = nbsp.repeat(3);
20
+ prefix = nbsp.repeat(3);
21
21
  } else if (number < 100) {
22
- prefix = nbsp.repeat(2);
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, line, weburl) {
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
- lines = this.responseText.split(/\r\n|\n/);
43
- start = line - contextLines;
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 lineElt = document.createElement("code");
54
- if (start === line) {
55
- lineElt.classList.add("highlight");
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
- lineElt.appendChild(document.createTextNode(formatLineNumber(start) + nbsp + line));
59
- lineElt.appendChild(document.createElement("br"));
79
+ codeElement.appendChild(document.createTextNode(line));
60
80
 
61
- container.appendChild(lineElt); // append to the container
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: 'Pfrtip', // Search Panes, filtering input, processing display element, table, table information summary, pagination control
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.2.0
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: 2021-06-20 00:00:00.000000000 Z
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.11.0.rc4
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.11.0.rc4
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.5'
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.5'
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: '4.0'
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: '4.0'
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.81'
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.81'
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.2'
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.2'
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: '7'
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: '7'
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.22'
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.22'
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