pmdtester 1.0.0.pre.beta3 → 1.0.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.
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PmdTester
4
+ # This class is used to store pmd config errors and its size.
5
+ class PmdConfigErrors
6
+ attr_reader :errors
7
+ attr_reader :size
8
+
9
+ def initialize
10
+ # key:rulename as String => value:PmdConfigError Array
11
+ @errors = {}
12
+ @size = 0
13
+ end
14
+
15
+ def add_error(error)
16
+ rulename = error.rulename
17
+ if @errors.key?(rulename)
18
+ @errors[rulename].push(error)
19
+ else
20
+ @errors.store(rulename, [error])
21
+ end
22
+ @size += 1
23
+ end
24
+ end
25
+
26
+ # This class represents a 'configerror' element of Pmd xml report
27
+ # and which Pmd branch the 'configerror' is from
28
+ class PmdConfigError
29
+ # The pmd branch type, 'base' or 'patch'
30
+ attr_reader :branch
31
+
32
+ # The schema of 'configerror' node:
33
+ # <xs:complexType name="configerror">
34
+ # <xs:attribute name="rule" type="xs:string" use="required" />
35
+ # <xs:attribute name="msg" type="xs:string" use="required" />
36
+ # </xs:complexType>
37
+ attr_reader :attrs
38
+ attr_accessor :text
39
+
40
+ def initialize(attrs, branch)
41
+ @attrs = attrs
42
+
43
+ @branch = branch
44
+ @text = ''
45
+ end
46
+
47
+ def rulename
48
+ @attrs['rule']
49
+ end
50
+
51
+ def msg
52
+ @attrs['msg']
53
+ end
54
+
55
+ def eql?(other)
56
+ rulename.eql?(other.rulename) && msg.eql?(other.msg)
57
+ end
58
+
59
+ def hash
60
+ [rulename, msg].hash
61
+ end
62
+ end
63
+ end
@@ -13,6 +13,8 @@ module PmdTester
13
13
  end
14
14
 
15
15
  def add_violations_by_filename(filename, violations)
16
+ return if violations.empty?
17
+
16
18
  @violations.store(filename, violations)
17
19
  @violations_size += violations.size
18
20
  end
@@ -32,7 +32,7 @@ module PmdTester
32
32
  @exclude_pattern.push(ep.text)
33
33
  end
34
34
 
35
- @report_diff = nil
35
+ @report_diff = ReportDiff.new
36
36
  end
37
37
 
38
38
  # Generate the default webview url for the projects
@@ -74,6 +74,14 @@ module PmdTester
74
74
  end
75
75
  end
76
76
 
77
+ def get_config_path(branch_name)
78
+ if branch_name.nil?
79
+ nil
80
+ else
81
+ "#{get_project_target_dir(branch_name)}/config.xml"
82
+ end
83
+ end
84
+
77
85
  def get_project_target_dir(branch_name)
78
86
  branch_filename = PmdBranchDetail.branch_filename(branch_name)
79
87
  dir = "target/reports/#{branch_filename}/#{@name}"
@@ -100,11 +108,35 @@ module PmdTester
100
108
  end
101
109
 
102
110
  def diffs_exist?
103
- @report_diff.diffs_exist?
111
+ @report_diff.nil? ? false : @report_diff.diffs_exist?
104
112
  end
105
113
 
106
114
  def introduce_new_errors?
107
- @report_diff.introduce_new_errors?
115
+ @report_diff.nil? ? false : @report_diff.introduce_new_errors?
116
+ end
117
+
118
+ def removed_errors_size
119
+ @report_diff.removed_errors_size
120
+ end
121
+
122
+ def new_errors_size
123
+ @report_diff.new_errors_size
124
+ end
125
+
126
+ def removed_violations_size
127
+ @report_diff.removed_violations_size
128
+ end
129
+
130
+ def new_violations_size
131
+ @report_diff.new_violations_size
132
+ end
133
+
134
+ def removed_configerrors_size
135
+ @report_diff.removed_configerrors_size
136
+ end
137
+
138
+ def new_configerrors_size
139
+ @report_diff.new_configerrors_size
108
140
  end
109
141
  end
110
142
  end
@@ -5,14 +5,26 @@ module PmdTester
5
5
  # including the summary information of the original pmd reports,
6
6
  # as well as the specific information of the diff report.
7
7
  class ReportDiff
8
+ include PmdTester
9
+
8
10
  attr_accessor :base_violations_size
9
11
  attr_accessor :patch_violations_size
12
+ attr_accessor :new_violations_size
13
+ attr_accessor :removed_violations_size
10
14
  attr_accessor :violation_diffs_size
11
15
 
12
16
  attr_accessor :base_errors_size
13
17
  attr_accessor :patch_errors_size
18
+ attr_accessor :new_errors_size
19
+ attr_accessor :removed_errors_size
14
20
  attr_accessor :error_diffs_size
15
21
 
22
+ attr_accessor :base_configerrors_size
23
+ attr_accessor :patch_configerrors_size
24
+ attr_accessor :new_configerrors_size
25
+ attr_accessor :removed_configerrors_size
26
+ attr_accessor :configerrors_diffs_size
27
+
16
28
  attr_accessor :base_execution_time
17
29
  attr_accessor :patch_execution_time
18
30
  attr_accessor :diff_execution_time
@@ -22,15 +34,12 @@ module PmdTester
22
34
 
23
35
  attr_accessor :violation_diffs
24
36
  attr_accessor :error_diffs
37
+ attr_accessor :configerrors_diffs
25
38
 
26
39
  def initialize
27
- @base_violations_size = 0
28
- @patch_violations_size = 0
29
- @violation_diffs_size = 0
30
-
31
- @base_errors_size = 0
32
- @patch_errors_size = 0
33
- @error_diffs_size = 0
40
+ init_violations
41
+ init_errors
42
+ init_configerrors
34
43
 
35
44
  @base_execution_time = 0
36
45
  @patch_execution_time = 0
@@ -41,10 +50,39 @@ module PmdTester
41
50
 
42
51
  @violation_diffs = {}
43
52
  @error_diffs = {}
53
+ @configerrors_diffs = {}
54
+ end
55
+
56
+ def init_violations
57
+ @base_violations_size = 0
58
+ @patch_violations_size = 0
59
+ @new_violations_size = 0
60
+ @removed_violations_size = 0
61
+ @violation_diffs_size = 0
62
+ end
63
+
64
+ def init_errors
65
+ @base_errors_size = 0
66
+ @patch_errors_size = 0
67
+ @new_errors_size = 0
68
+ @removed_errors_size = 0
69
+ @error_diffs_size = 0
70
+ end
71
+
72
+ def init_configerrors
73
+ @base_configerrors_size = 0
74
+ @patch_configerrors_size = 0
75
+ @new_configerrors_size = 0
76
+ @removed_configerrors_size = 0
77
+ @configerrors_diffs_size = 0
78
+ end
79
+
80
+ def self.comparable?(errors)
81
+ errors.size == 2 && errors[0].branch != errors[1].branch
44
82
  end
45
83
 
46
84
  def diffs_exist?
47
- !error_diffs_size.zero? || !violation_diffs_size.zero?
85
+ !error_diffs_size.zero? || !violation_diffs_size.zero? || !configerrors_diffs_size.zero?
48
86
  end
49
87
 
50
88
  def calculate_violations(base_violations, patch_violations)
@@ -52,7 +90,8 @@ module PmdTester
52
90
  @patch_violations_size = patch_violations.violations_size
53
91
  violation_diffs = build_diffs(base_violations.violations, patch_violations.violations)
54
92
  @violation_diffs = violation_diffs
55
- @violation_diffs_size = get_diffs_size(violation_diffs)
93
+ @new_violations_size, @removed_violations_size = get_diffs_size(violation_diffs)
94
+ @violation_diffs_size = @new_violations_size + @removed_violations_size
56
95
  end
57
96
 
58
97
  def calculate_errors(base_errors, patch_errors)
@@ -60,7 +99,17 @@ module PmdTester
60
99
  @patch_errors_size = patch_errors.errors_size
61
100
  error_diffs = build_diffs(base_errors.errors, patch_errors.errors)
62
101
  @error_diffs = error_diffs
63
- @error_diffs_size = get_diffs_size(error_diffs)
102
+ @new_errors_size, @removed_errors_size = get_diffs_size(error_diffs)
103
+ @error_diffs_size = @new_errors_size + @removed_errors_size
104
+ end
105
+
106
+ def calculate_configerrors(base_configerrors, patch_configerrors)
107
+ @base_configerrors_size = base_configerrors.size
108
+ @patch_configerrors_size = patch_configerrors.size
109
+ configerrors_diffs = build_diffs(base_configerrors.errors, patch_configerrors.errors)
110
+ @configerrors_diffs = configerrors_diffs
111
+ @new_configerrors_size, @removed_configerrors_size = get_diffs_size(configerrors_diffs)
112
+ @configerrors_diffs_size = @new_configerrors_size + @removed_configerrors_size
64
113
  end
65
114
 
66
115
  def calculate_details(base_info, patch_info)
@@ -91,21 +140,18 @@ module PmdTester
91
140
  end
92
141
 
93
142
  def get_diffs_size(diffs_hash)
94
- size = 0
95
- diffs_hash.keys.each do |key|
96
- size += diffs_hash[key].size
143
+ new_size = 0
144
+ removed_size = 0
145
+ diffs_hash.each_value do |value|
146
+ value.each do |item|
147
+ item.branch.eql?(BASE) ? removed_size += 1 : new_size += 1
148
+ end
97
149
  end
98
- size
150
+ [new_size, removed_size]
99
151
  end
100
152
 
101
153
  def introduce_new_errors?
102
- @error_diffs.values.each do |pmd_errors|
103
- pmd_errors.each do |pmd_error|
104
- return true if pmd_error.branch.eql?('patch')
105
- end
106
- end
107
-
108
- false
154
+ !@new_errors_size.zero? || !@new_configerrors_size.zero?
109
155
  end
110
156
  end
111
157
  end
@@ -10,6 +10,7 @@ module PmdTester
10
10
  end
11
11
 
12
12
  def run
13
+ clean
13
14
  case @options.mode
14
15
  when Options::LOCAL
15
16
  run_local_mode
@@ -18,19 +19,28 @@ module PmdTester
18
19
  when Options::SINGLE
19
20
  run_single_mode
20
21
  end
21
- introduce_new_pmd_error?
22
+
23
+ summarize_diffs
24
+ end
25
+
26
+ def clean
27
+ clean_target = 'target/reports'
28
+ FileUtils.remove_dir(clean_target) if Dir.exist?(clean_target)
22
29
  end
23
30
 
24
31
  def run_local_mode
25
32
  logger.info "Mode: #{@options.mode}"
26
- RuleSetBuilder.new(@options).build if @options.auto_config_flag
27
-
28
33
  get_projects(@options.project_list) unless @options.nil?
34
+ rule_sets = RuleSetBuilder.new(@options).build if @options.auto_config_flag
35
+ return if rule_sets&.empty?
36
+
29
37
  PmdReportBuilder
30
- .new(@options.base_config, @projects, @options.local_git_repo, @options.base_branch)
38
+ .new(@options.base_config, @projects, @options.local_git_repo, @options.base_branch,
39
+ @options.threads)
31
40
  .build
32
41
  PmdReportBuilder
33
- .new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch)
42
+ .new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch,
43
+ @options.threads)
34
44
  .build
35
45
 
36
46
  build_html_reports
@@ -41,19 +51,20 @@ module PmdTester
41
51
 
42
52
  baseline_path = download_baseline(@options.base_branch)
43
53
 
54
+ # patch branch build pmd report with same list of projects as base branch
55
+ project_list = "#{baseline_path}/project-list.xml"
56
+ get_projects(project_list)
57
+
44
58
  if @options.auto_config_flag
45
- RuleSetBuilder.new(@options).build
59
+ return if RuleSetBuilder.new(@options).build.empty?
46
60
  else
47
61
  # patch branch build pmd reports with same configuration as base branch
48
62
  @options.patch_config = "#{baseline_path}/config.xml"
49
63
  end
50
64
 
51
- # patch branch build pmd report with same list of projects as base branch
52
- project_list = "#{baseline_path}/project-list.xml"
53
- get_projects(project_list)
54
-
55
65
  PmdReportBuilder
56
- .new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch)
66
+ .new(@options.patch_config, @projects,
67
+ @options.local_git_repo, @options.patch_branch, @options.threads)
57
68
  .build
58
69
 
59
70
  build_html_reports
@@ -87,7 +98,8 @@ module PmdTester
87
98
  get_projects(@options.project_list) unless @options.nil?
88
99
  branch_details = PmdReportBuilder
89
100
  .new(@options.patch_config, @projects,
90
- @options.local_git_repo, @options.patch_branch)
101
+ @options.local_git_repo, @options.patch_branch,
102
+ @options.threads)
91
103
  .build
92
104
  # copy list of projects file to the patch baseline
93
105
  FileUtils.cp(@options.project_list, branch_details.target_branch_project_list_path)
@@ -118,11 +130,24 @@ module PmdTester
118
130
  @projects = ProjectsParser.new.parse(file_path)
119
131
  end
120
132
 
121
- def introduce_new_pmd_error?
133
+ def summarize_diffs
134
+ new_errors_size = 0
135
+ removed_errors_size = 0
136
+ new_violations_size = 0
137
+ removed_violations_size = 0
138
+ new_configerrors_size = 0
139
+ removed_configerrors_size = 0
122
140
  @projects.each do |project|
123
- return true if project.introduce_new_errors?
141
+ new_errors_size += project.new_errors_size
142
+ removed_errors_size += project.removed_errors_size
143
+ new_violations_size += project.new_violations_size
144
+ removed_violations_size += project.removed_violations_size
145
+ new_configerrors_size += project.new_configerrors_size
146
+ removed_configerrors_size += project.removed_configerrors_size
124
147
  end
125
- false
148
+
149
+ [new_errors_size, removed_errors_size, new_violations_size, removed_violations_size,
150
+ new_configerrors_size, removed_configerrors_size]
126
151
  end
127
152
  end
128
153
  end
data/pmdtester.gemspec ADDED
@@ -0,0 +1,73 @@
1
+ # DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake hoe:spec`.
2
+
3
+ # -*- encoding: utf-8 -*-
4
+ # stub: pmdtester 1.0.0 ruby lib
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "pmdtester".freeze
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
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
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Andreas Dangel".freeze, "Binguo Bao".freeze]
14
+ s.date = "2020-04-25"
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
+ s.email = ["andreas.dangel@adangel.org".freeze, "djydewang@gmail.com".freeze]
17
+ s.executables = ["pmdtester".freeze]
18
+ s.extra_rdoc_files = ["History.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze]
19
+ s.files = [".hoerc".freeze, ".rubocop.yml".freeze, ".rubocop_todo.yml".freeze, ".travis.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, "lib/pmdtester.rb".freeze, "lib/pmdtester/builders/diff_builder.rb".freeze, "lib/pmdtester/builders/diff_report/configerrors.rb".freeze, "lib/pmdtester/builders/diff_report/errors.rb".freeze, "lib/pmdtester/builders/diff_report/violations.rb".freeze, "lib/pmdtester/builders/diff_report_builder.rb".freeze, "lib/pmdtester/builders/html_report_builder.rb".freeze, "lib/pmdtester/builders/pmd_report_builder.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/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_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/css/maven-base.css".freeze, "resources/css/maven-theme.css".freeze]
20
+ s.homepage = "https://pmd.github.io".freeze
21
+ s.licenses = ["BSD-2-Clause".freeze]
22
+ s.rdoc_options = ["--main".freeze, "README.rdoc".freeze]
23
+ s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze)
24
+ s.rubygems_version = "2.7.7".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
26
+
27
+ if s.respond_to? :specification_version then
28
+ s.specification_version = 4
29
+
30
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
31
+ s.add_runtime_dependency(%q<nokogiri>.freeze, ["~> 1.8"])
32
+ s.add_runtime_dependency(%q<slop>.freeze, ["~> 4.6"])
33
+ s.add_runtime_dependency(%q<differ>.freeze, ["~> 0.1"])
34
+ s.add_runtime_dependency(%q<rufus-scheduler>.freeze, ["~> 3.5"])
35
+ s.add_development_dependency(%q<hoe-bundler>.freeze, ["~> 1.5"])
36
+ s.add_development_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
37
+ s.add_development_dependency(%q<minitest>.freeze, ["~> 5.10"])
38
+ s.add_development_dependency(%q<mocha>.freeze, ["~> 1.5"])
39
+ s.add_development_dependency(%q<rubocop>.freeze, ["~> 0.81"])
40
+ s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.2"])
41
+ s.add_development_dependency(%q<rdoc>.freeze, ["< 7", ">= 4.0"])
42
+ s.add_development_dependency(%q<hoe>.freeze, ["~> 3.22"])
43
+ else
44
+ s.add_dependency(%q<nokogiri>.freeze, ["~> 1.8"])
45
+ s.add_dependency(%q<slop>.freeze, ["~> 4.6"])
46
+ s.add_dependency(%q<differ>.freeze, ["~> 0.1"])
47
+ s.add_dependency(%q<rufus-scheduler>.freeze, ["~> 3.5"])
48
+ s.add_dependency(%q<hoe-bundler>.freeze, ["~> 1.5"])
49
+ s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
50
+ s.add_dependency(%q<minitest>.freeze, ["~> 5.10"])
51
+ s.add_dependency(%q<mocha>.freeze, ["~> 1.5"])
52
+ s.add_dependency(%q<rubocop>.freeze, ["~> 0.81"])
53
+ s.add_dependency(%q<test-unit>.freeze, ["~> 3.2"])
54
+ s.add_dependency(%q<rdoc>.freeze, ["< 7", ">= 4.0"])
55
+ s.add_dependency(%q<hoe>.freeze, ["~> 3.22"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<nokogiri>.freeze, ["~> 1.8"])
59
+ s.add_dependency(%q<slop>.freeze, ["~> 4.6"])
60
+ s.add_dependency(%q<differ>.freeze, ["~> 0.1"])
61
+ s.add_dependency(%q<rufus-scheduler>.freeze, ["~> 3.5"])
62
+ s.add_dependency(%q<hoe-bundler>.freeze, ["~> 1.5"])
63
+ s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
64
+ s.add_dependency(%q<minitest>.freeze, ["~> 5.10"])
65
+ s.add_dependency(%q<mocha>.freeze, ["~> 1.5"])
66
+ s.add_dependency(%q<rubocop>.freeze, ["~> 0.81"])
67
+ s.add_dependency(%q<test-unit>.freeze, ["~> 3.2"])
68
+ s.add_dependency(%q<rdoc>.freeze, ["< 7", ">= 4.0"])
69
+ s.add_dependency(%q<hoe>.freeze, ["~> 3.22"])
70
+ end
71
+ end
72
+
73
+ # DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake hoe:spec`.