pmdtester 1.0.0.pre.beta3 → 1.0.0

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