pmdtester 1.6.2 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/build.yml +7 -7
  4. data/.github/workflows/manual-integration-tests.yml +7 -7
  5. data/.github/workflows/publish-release.yml +9 -9
  6. data/.hoerc +1 -1
  7. data/.rubocop_todo.yml +1 -14
  8. data/.vscode/launch.json +32 -0
  9. data/History.md +47 -0
  10. data/Manifest.txt +13 -0
  11. data/README.rdoc +76 -30
  12. data/Rakefile +11 -11
  13. data/config/custom.jfc +1126 -0
  14. data/config/project-list-with-cpd.xml +268 -0
  15. data/config/projectlist_1_2_0.xsd +1 -1
  16. data/config/projectlist_1_3_0.xsd +53 -0
  17. data/lib/pmdtester/builders/cpd_project_hasher.rb +70 -0
  18. data/lib/pmdtester/builders/liquid_renderer.rb +111 -16
  19. data/lib/pmdtester/builders/pmd_report_builder.rb +133 -37
  20. data/lib/pmdtester/builders/project_hasher.rb +24 -25
  21. data/lib/pmdtester/builders/rule_set_builder.rb +2 -0
  22. data/lib/pmdtester/builders/summary_report_builder.rb +6 -1
  23. data/lib/pmdtester/cmd.rb +16 -7
  24. data/lib/pmdtester/cpd_report_diff.rb +99 -0
  25. data/lib/pmdtester/jfr_summary.rb +119 -0
  26. data/lib/pmdtester/location.rb +38 -0
  27. data/lib/pmdtester/parsers/cpd_report_document.rb +241 -0
  28. data/lib/pmdtester/parsers/options.rb +19 -0
  29. data/lib/pmdtester/parsers/pmd_report_document.rb +14 -1
  30. data/lib/pmdtester/parsers/projects_parser.rb +1 -1
  31. data/lib/pmdtester/pmd_branch_detail.rb +29 -9
  32. data/lib/pmdtester/pmd_report_detail.rb +54 -13
  33. data/lib/pmdtester/pmd_tester_utils.rb +45 -17
  34. data/lib/pmdtester/pmd_violation.rb +15 -6
  35. data/lib/pmdtester/project.rb +63 -3
  36. data/lib/pmdtester/report_diff.rb +5 -13
  37. data/lib/pmdtester/runner.rb +185 -37
  38. data/lib/pmdtester/system_info.rb +58 -0
  39. data/lib/pmdtester/word_differ.rb +132 -0
  40. data/lib/pmdtester.rb +8 -1
  41. data/pmdtester.gemspec +17 -17
  42. data/resources/css/pmd-tester.css +15 -0
  43. data/resources/js/project-report.js +293 -112
  44. data/resources/project_cpd_report.html +144 -0
  45. data/resources/project_diff_report.html +151 -18
  46. data/resources/project_index.html +12 -3
  47. data/resources/project_pmd_report.html +17 -2
  48. metadata +63 -43
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PmdTester
4
+ # Utility to diff two strings by word and format the result as HTML
5
+ class WordDiffer
6
+ def self.diff_words(old_str, new_str)
7
+ diff = Diff.new(old_str, new_str)
8
+ diff.diff
9
+ end
10
+ end
11
+
12
+ # The implementation of a simple word differ
13
+ class Diff
14
+ def initialize(old_str, new_str)
15
+ @old_str = old_str
16
+ @new_str = new_str
17
+ end
18
+
19
+ def diff
20
+ # split old_str by word barriers, keeping the delimiters
21
+ @old_words = @old_str.split(/\b/)
22
+ @new_words = @new_str.split(/\b/)
23
+
24
+ # loop through old words by index
25
+ @old_index = 0
26
+ @new_index = 0
27
+ @result = ''
28
+ while @old_index < @old_words.length || @new_index < @new_words.length
29
+ old_word = @old_words[@old_index]
30
+ new_word = @new_words[@new_index]
31
+
32
+ if old_word == new_word
33
+ @result += old_word
34
+ @old_index += 1
35
+ @new_index += 1
36
+ else
37
+ found_addition = find_addition(old_word)
38
+ next if found_addition
39
+
40
+ found_deletion = find_deletion(new_word)
41
+ next if found_deletion
42
+
43
+ # if we reach here, it's a substitution
44
+ handle_substition(old_word, new_word)
45
+ end
46
+ end
47
+ @result
48
+ end
49
+
50
+ def find_addition(old_word)
51
+ if old_word.nil?
52
+ # remaining is addition
53
+ add_additions
54
+ return true
55
+ end
56
+
57
+ # look ahead in new_words
58
+ look_ahead_index = @new_index + 1
59
+
60
+ found_addition = false
61
+ while look_ahead_index < @new_words.length
62
+ if old_word == @new_words[look_ahead_index]
63
+ # found partial addition
64
+ add_additions(look_ahead_index)
65
+ found_addition = true
66
+ break
67
+ end
68
+ look_ahead_index += 1
69
+ end
70
+ found_addition
71
+ end
72
+
73
+ def add_additions(end_index = @new_words.length)
74
+ @result += '<ins class="differ">'
75
+ (@new_index...end_index).each do |i|
76
+ @result += @new_words[i].to_s
77
+ end
78
+ @result += '</ins>'
79
+ @new_index = end_index
80
+ end
81
+
82
+ def add_deletions(end_index = @old_words.length)
83
+ @result += '<del class="differ">'
84
+ (@old_index...end_index).each do |i|
85
+ @result += @old_words[i].to_s
86
+ end
87
+ @result += '</del>'
88
+ @old_index = end_index
89
+ end
90
+
91
+ def find_deletion(new_word)
92
+ if new_word.nil?
93
+ # remaining is deletion
94
+ add_deletions
95
+ return true
96
+ end
97
+
98
+ # look ahead in old_words
99
+ look_ahead_index = @old_index + 1
100
+
101
+ found_deletion = false
102
+ while look_ahead_index < @old_words.length
103
+ if new_word == @old_words[look_ahead_index]
104
+ # found partial deletion
105
+ add_deletions(look_ahead_index)
106
+ found_deletion = true
107
+ break
108
+ end
109
+ look_ahead_index += 1
110
+ end
111
+ found_deletion
112
+ end
113
+
114
+ def handle_substition(old_word, new_word)
115
+ if old_word
116
+ @result += '<del class="differ">'
117
+ @result += old_word
118
+ @result += '</del>'
119
+ @old_index += 1
120
+ end
121
+
122
+ return unless new_word
123
+
124
+ @result += '<ins class="differ">'
125
+ @result += new_word
126
+ @result += '</ins>'
127
+ @new_index += 1
128
+ end
129
+ end
130
+
131
+ private_constant :Diff
132
+ end
data/lib/pmdtester.rb CHANGED
@@ -5,18 +5,24 @@ require 'logger/colors'
5
5
 
6
6
  require_relative 'pmdtester/cmd'
7
7
  require_relative 'pmdtester/collection_by_file'
8
+ require_relative 'pmdtester/cpd_report_diff'
9
+ require_relative 'pmdtester/jfr_summary'
8
10
  require_relative 'pmdtester/pmd_branch_detail'
9
11
  require_relative 'pmdtester/pmd_configerror'
10
12
  require_relative 'pmdtester/pmd_error'
11
13
  require_relative 'pmdtester/pmd_report_detail'
12
14
  require_relative 'pmdtester/pmd_tester_utils'
13
15
  require_relative 'pmdtester/pmd_violation'
16
+ require_relative 'pmdtester/location'
14
17
  require_relative 'pmdtester/project'
15
18
  require_relative 'pmdtester/report_diff'
16
19
  require_relative 'pmdtester/resource_locator'
17
20
  require_relative 'pmdtester/runner'
18
21
  require_relative 'pmdtester/semver'
22
+ require_relative 'pmdtester/system_info'
23
+ require_relative 'pmdtester/word_differ'
19
24
 
25
+ require_relative 'pmdtester/builders/cpd_project_hasher'
20
26
  require_relative 'pmdtester/builders/simple_progress_logger'
21
27
  require_relative 'pmdtester/builders/project_builder'
22
28
  require_relative 'pmdtester/builders/project_hasher'
@@ -25,6 +31,7 @@ require_relative 'pmdtester/builders/liquid_renderer'
25
31
  require_relative 'pmdtester/builders/rule_set_builder'
26
32
  require_relative 'pmdtester/builders/summary_report_builder'
27
33
 
34
+ require_relative 'pmdtester/parsers/cpd_report_document'
28
35
  require_relative 'pmdtester/parsers/options'
29
36
  require_relative 'pmdtester/parsers/pmd_report_document'
30
37
  require_relative 'pmdtester/parsers/projects_parser'
@@ -33,7 +40,7 @@ require_relative 'pmdtester/parsers/projects_parser'
33
40
  # and unexpected behaviors will not be introduced to PMD project
34
41
  # after fixing an issue and new rules can work as expected.
35
42
  module PmdTester
36
- VERSION = '1.6.2'
43
+ VERSION = '1.7.0'
37
44
  BASE = 'base'
38
45
  PATCH = 'patch'
39
46
  PR_NUM_ENV_VAR = 'PMD_CI_PULL_REQUEST_NUMBER' # see PmdBranchDetail
data/pmdtester.gemspec CHANGED
@@ -1,49 +1,49 @@
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.6.2 ruby lib
4
+ # stub: pmdtester 1.7.0 ruby lib
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "pmdtester".freeze
8
- s.version = "1.6.2".freeze
8
+ s.version = "1.7.0".freeze
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
14
  s.date = "1980-01-02"
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
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\nand new rules work as expected.\n\n== Features/Problems:\n\nThe diff report can be generated according to the base and patch branch of PMD\non a list of standard projects (e.g. Spring Framework, Checkstyle, OpenJDK, etc.).\n\nRule violations and code duplications are compared to report, which are new, removed or changed.\n\nWhile executing PMD, JDK Flight Recorder (jfr) is enabled and a recording is created. This allows to investigate\nperformance and memory issues afterwards.".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, "resources/js/README.md".freeze]
19
- s.files = [".github/workflows/build-pr.yml".freeze, ".github/workflows/build-release.yml".freeze, ".github/workflows/build-snapshot.yml".freeze, ".github/workflows/build.yml".freeze, ".github/workflows/manual-integration-tests.yml".freeze, ".github/workflows/publish-release.yml".freeze, ".gitignore".freeze, ".hoerc".freeze, ".rubocop.yml".freeze, ".rubocop_todo.yml".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-5.3.0-alpha3.min.css".freeze, "resources/css/datatables.min.css".freeze, "resources/css/pmd-tester.css".freeze, "resources/js/README.md".freeze, "resources/js/bootstrap-5.3.0-alpha3.min.js".freeze, "resources/js/code-snippets.js".freeze, "resources/js/datatables.min.js".freeze, "resources/js/jquery-3.6.4.slim.min.js".freeze, "resources/js/popper-2.11.7.min.js".freeze, "resources/js/project-report.js".freeze, "resources/maven-settings.xml".freeze, "resources/project_diff_report.html".freeze, "resources/project_index.html".freeze, "resources/project_pmd_report.html".freeze]
19
+ s.files = [".github/dependabot.yml".freeze, ".github/workflows/build-pr.yml".freeze, ".github/workflows/build-release.yml".freeze, ".github/workflows/build-snapshot.yml".freeze, ".github/workflows/build.yml".freeze, ".github/workflows/manual-integration-tests.yml".freeze, ".github/workflows/publish-release.yml".freeze, ".gitignore".freeze, ".hoerc".freeze, ".rubocop.yml".freeze, ".rubocop_todo.yml".freeze, ".vscode/launch.json".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/custom.jfc".freeze, "config/design.xml".freeze, "config/project-list-with-cpd.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, "config/projectlist_1_3_0.xsd".freeze, "lib/pmdtester.rb".freeze, "lib/pmdtester/builders/cpd_project_hasher.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/cpd_report_diff.rb".freeze, "lib/pmdtester/jfr_summary.rb".freeze, "lib/pmdtester/location.rb".freeze, "lib/pmdtester/parsers/cpd_report_document.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, "lib/pmdtester/system_info.rb".freeze, "lib/pmdtester/word_differ.rb".freeze, "pmdtester.gemspec".freeze, "resources/_includes/diff_pill_row.html".freeze, "resources/css/bootstrap-5.3.0-alpha3.min.css".freeze, "resources/css/datatables.min.css".freeze, "resources/css/pmd-tester.css".freeze, "resources/js/README.md".freeze, "resources/js/bootstrap-5.3.0-alpha3.min.js".freeze, "resources/js/code-snippets.js".freeze, "resources/js/datatables.min.js".freeze, "resources/js/jquery-3.6.4.slim.min.js".freeze, "resources/js/popper-2.11.7.min.js".freeze, "resources/js/project-report.js".freeze, "resources/maven-settings.xml".freeze, "resources/project_cpd_report.html".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]
23
- s.required_ruby_version = Gem::Requirement.new(">= 3.3".freeze)
24
- s.rubygems_version = "3.6.9".freeze
25
- s.summary = "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
23
+ s.required_ruby_version = Gem::Requirement.new(">= 4".freeze)
24
+ s.rubygems_version = "4.0.3".freeze
25
+ s.summary = "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 work as expected".freeze
26
26
 
27
27
  s.specification_version = 4
28
28
 
29
- s.add_runtime_dependency(%q<nokogiri>.freeze, ["~> 1.18".freeze])
29
+ s.add_runtime_dependency(%q<nokogiri>.freeze, ["~> 1.19".freeze])
30
30
  s.add_runtime_dependency(%q<slop>.freeze, ["~> 4.10".freeze])
31
- s.add_runtime_dependency(%q<differ>.freeze, ["~> 0.1".freeze])
32
31
  s.add_runtime_dependency(%q<rufus-scheduler>.freeze, ["~> 3.9".freeze])
33
- s.add_runtime_dependency(%q<logger-colors>.freeze, ["~> 1.0".freeze])
34
- s.add_runtime_dependency(%q<liquid>.freeze, ["~> 5.8".freeze])
32
+ s.add_runtime_dependency(%q<logger-colors>.freeze, ["~> 1.1".freeze])
33
+ s.add_runtime_dependency(%q<liquid>.freeze, ["~> 5.11".freeze])
35
34
  s.add_runtime_dependency(%q<base64>.freeze, ["~> 0.3".freeze])
36
- s.add_runtime_dependency(%q<bigdecimal>.freeze, ["~> 3.2".freeze])
35
+ s.add_runtime_dependency(%q<bigdecimal>.freeze, ["~> 4.0".freeze])
37
36
  s.add_runtime_dependency(%q<logger>.freeze, ["~> 1.7".freeze])
38
37
  s.add_development_dependency(%q<hoe-bundler>.freeze, ["~> 1.5".freeze])
39
38
  s.add_development_dependency(%q<hoe-git>.freeze, ["~> 1.6".freeze])
40
- s.add_development_dependency(%q<minitest>.freeze, ["~> 5.25".freeze])
41
- s.add_development_dependency(%q<mocha>.freeze, ["~> 2.7".freeze])
42
- s.add_development_dependency(%q<rubocop>.freeze, ["~> 1.79".freeze])
39
+ s.add_development_dependency(%q<minitest>.freeze, ["~> 6.0".freeze])
40
+ s.add_development_dependency(%q<mocha>.freeze, ["~> 3.0".freeze])
41
+ s.add_development_dependency(%q<rubocop>.freeze, ["~> 1.84".freeze])
43
42
  s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.7".freeze])
44
- s.add_development_dependency(%q<rdoc>.freeze, ["~> 6.12".freeze])
43
+ s.add_development_dependency(%q<rdoc>.freeze, ["~> 7.2".freeze])
45
44
  s.add_development_dependency(%q<rake>.freeze, ["~> 13.3".freeze])
46
- s.add_development_dependency(%q<hoe>.freeze, ["~> 4.2".freeze])
45
+ s.add_development_dependency(%q<hoe>.freeze, ["~> 4.6".freeze])
46
+ s.add_development_dependency(%q<debug>.freeze, ["~> 1.11".freeze])
47
47
  end
48
48
 
49
49
  # DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake hoe:spec`.
@@ -20,6 +20,10 @@ table.code-snippet > tbody > tr > td {
20
20
  table.code-snippet > tbody > tr > td.line-number > code:before {
21
21
  content: attr(data-line-number);
22
22
  }
23
+ table.code-snippet > tbody > tr > td:nth-child(2) {
24
+ width: 100%;
25
+ padding-left: 1ex;
26
+ }
23
27
  .btn-clipboard {
24
28
  margin-top: 1rem;
25
29
  display: block;
@@ -85,18 +89,21 @@ div.section-content {
85
89
 
86
90
  table.dataTable > tbody > tr.added,
87
91
  #error-table tr.added,
92
+ #cpd-error-table tr.added,
88
93
  #rule-summary td.added {
89
94
  background-color: #af8;
90
95
  }
91
96
 
92
97
  table.dataTable > tbody > tr.removed,
93
98
  #error-table tr.removed,
99
+ #cpd-error-table tr.removed,
94
100
  #rule-summary td.removed {
95
101
  background-color: #fca;
96
102
  }
97
103
 
98
104
  table.dataTable > tbody > tr.changed,
99
105
  #error-table tr.changed,
106
+ #cpd-error-table tr.changed,
100
107
  #rule-summary td.changed {
101
108
  background-color: #fef7bc;
102
109
  }
@@ -105,6 +112,9 @@ table.dataTable > tbody > tr.changed,
105
112
  #rule-summary td {
106
113
  background-color: #fefefe;
107
114
  }
115
+ #rule-summary tr:hover td.rulename {
116
+ background: lightgray;
117
+ }
108
118
 
109
119
  .external-link-secondary {
110
120
  font-size: small;
@@ -152,3 +162,8 @@ span.meta-var {
152
162
  span.stack-trace-method {
153
163
  font-weight: bold;
154
164
  }
165
+
166
+ /* cmdline inside summary table */
167
+ .table details code {
168
+ white-space: normal;
169
+ }