pmdtester 1.2.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
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