pmdtester 1.0.0.pre.beta2

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,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PmdTester
4
+ # This class represents all the diff report information,
5
+ # including the summary information of the original pmd reports,
6
+ # as well as the specific information of the diff report.
7
+ class ReportDiff
8
+ attr_accessor :base_violations_size
9
+ attr_accessor :patch_violations_size
10
+ attr_accessor :violation_diffs_size
11
+
12
+ attr_accessor :base_errors_size
13
+ attr_accessor :patch_errors_size
14
+ attr_accessor :error_diffs_size
15
+
16
+ attr_accessor :base_execution_time
17
+ attr_accessor :patch_execution_time
18
+ attr_accessor :diff_execution_time
19
+
20
+ attr_accessor :base_timestamp
21
+ attr_accessor :patch_timestamp
22
+
23
+ attr_accessor :violation_diffs
24
+ attr_accessor :error_diffs
25
+
26
+ 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
34
+
35
+ @base_execution_time = 0
36
+ @patch_execution_time = 0
37
+ @diff_execution_time = 0
38
+
39
+ @base_timestamp = ''
40
+ @patch_timestamp = ''
41
+
42
+ @violation_diffs = {}
43
+ @error_diffs = {}
44
+ end
45
+
46
+ def diffs_exist?
47
+ !error_diffs_size.zero? || !violation_diffs_size.zero?
48
+ end
49
+
50
+ def calculate_violations(base_violations, patch_violations)
51
+ @base_violations_size = base_violations.violations_size
52
+ @patch_violations_size = patch_violations.violations_size
53
+ violation_diffs = build_diffs(base_violations.violations, patch_violations.violations)
54
+ @violation_diffs = violation_diffs
55
+ @violation_diffs_size = get_diffs_size(violation_diffs)
56
+ end
57
+
58
+ def calculate_errors(base_errors, patch_errors)
59
+ @base_errors_size = base_errors.errors_size
60
+ @patch_errors_size = patch_errors.errors_size
61
+ error_diffs = build_diffs(base_errors.errors, patch_errors.errors)
62
+ @error_diffs = error_diffs
63
+ @error_diffs_size = get_diffs_size(error_diffs)
64
+ end
65
+
66
+ def calculate_details(base_info, patch_info)
67
+ base_details = PmdReportDetail.new
68
+ base_details.load(base_info) unless base_info.nil?
69
+ patch_details = PmdReportDetail.new
70
+ patch_details.load(patch_info) unless patch_info.nil?
71
+
72
+ @base_execution_time = base_details.format_execution_time
73
+ @patch_execution_time = patch_details.format_execution_time
74
+ @diff_execution_time =
75
+ PmdReportDetail.convert_seconds(base_details.execution_time -
76
+ patch_details.execution_time)
77
+
78
+ @base_timestamp = base_details.timestamp
79
+ @patch_timestamp = patch_details.timestamp
80
+ [base_details, patch_details]
81
+ end
82
+
83
+ def build_diffs(base_hash, patch_hash)
84
+ diffs = base_hash.merge(patch_hash) do |_key, base_value, patch_value|
85
+ (base_value | patch_value) - (base_value & patch_value)
86
+ end
87
+
88
+ diffs.delete_if do |_key, value|
89
+ value.empty?
90
+ end
91
+ end
92
+
93
+ def get_diffs_size(diffs_hash)
94
+ size = 0
95
+ diffs_hash.keys.each do |key|
96
+ size += diffs_hash[key].size
97
+ end
98
+ size
99
+ end
100
+
101
+ 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
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PmdTester
4
+ # This class is responsible for locating the static resources of PmdTester.
5
+ class ResourceLocator
6
+ def self.locate(resource_path)
7
+ File.expand_path(File.dirname(__FILE__) + "/../../#{resource_path}")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './builders/diff_builder.rb'
4
+ require_relative './builders/diff_report_builder.rb'
5
+ require_relative './builders/rule_set_builder'
6
+ require_relative './builders/summary_report_builder.rb'
7
+ require_relative './builders/pmd_report_builder.rb'
8
+ require_relative './parsers/options'
9
+ require_relative './parsers/projects_parser'
10
+ require_relative './pmdtester'
11
+ require_relative './pmd_branch_detail'
12
+
13
+ module PmdTester
14
+ # The Runner is a class responsible of organizing all PmdTester modules
15
+ # and running the PmdTester
16
+ class Runner
17
+ include PmdTester
18
+ def initialize(argv)
19
+ @options = Options.new(argv)
20
+ end
21
+
22
+ def run
23
+ case @options.mode
24
+ when Options::LOCAL
25
+ run_local_mode
26
+ when Options::ONLINE
27
+ run_online_mode
28
+ when Options::SINGLE
29
+ run_single_mode
30
+ end
31
+ end
32
+
33
+ def run_local_mode
34
+ logger.info "Mode: #{@options.mode}"
35
+ RuleSetBuilder.new(@options).build if @options.auto_config_flag
36
+
37
+ get_projects(@options.project_list) unless @options.nil?
38
+ PmdReportBuilder
39
+ .new(@options.base_config, @projects, @options.local_git_repo, @options.base_branch)
40
+ .build
41
+ PmdReportBuilder
42
+ .new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch)
43
+ .build
44
+
45
+ build_html_reports
46
+ end
47
+
48
+ def run_online_mode
49
+ logger.info "Mode: #{@options.mode}"
50
+
51
+ baseline_path = download_baseline(@options.base_branch)
52
+
53
+ if @options.auto_config_flag
54
+ RuleSetBuilder.new(@options).build
55
+ else
56
+ # patch branch build pmd reports with same configuration as base branch
57
+ @options.patch_config = "#{baseline_path}/config.xml"
58
+ end
59
+
60
+ # patch branch build pmd report with same list of projects as base branch
61
+ project_list = "#{baseline_path}/project-list.xml"
62
+ get_projects(project_list)
63
+
64
+ PmdReportBuilder
65
+ .new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch)
66
+ .build
67
+
68
+ build_html_reports
69
+ end
70
+
71
+ def download_baseline(branch_name)
72
+ branch_filename = PmdBranchDetail.branch_filename(branch_name)
73
+ zip_filename = "#{branch_filename}-baseline.zip"
74
+ target_path = 'target/reports'
75
+ FileUtils.mkdir_p(target_path) unless File.directory?(target_path)
76
+
77
+ url = get_baseline_url(zip_filename)
78
+ wget_cmd = "wget #{url}"
79
+ unzip_cmd = "unzip -qo #{zip_filename}"
80
+
81
+ Dir.chdir(target_path) do
82
+ Cmd.execute(wget_cmd) unless File.exist?(zip_filename)
83
+ Cmd.execute(unzip_cmd)
84
+ end
85
+
86
+ "#{target_path}/#{branch_filename}"
87
+ end
88
+
89
+ def get_baseline_url(zip_filename)
90
+ "https://sourceforge.net/projects/pmd/files/pmd-regression-tester/#{zip_filename}"
91
+ end
92
+
93
+ def run_single_mode
94
+ logger.info "Mode: #{@options.mode}"
95
+
96
+ get_projects(@options.project_list) unless @options.nil?
97
+ branch_details = PmdReportBuilder
98
+ .new(@options.patch_config, @projects,
99
+ @options.local_git_repo, @options.patch_branch)
100
+ .build
101
+ # copy list of projects file to the patch baseline
102
+ FileUtils.cp(@options.project_list, branch_details.target_branch_project_list_path)
103
+
104
+ build_html_reports unless @options.html_flag
105
+ end
106
+
107
+ def build_html_reports
108
+ build_diff_html_reports
109
+ SummaryReportBuilder.new.build(@projects, @options.base_branch, @options.patch_branch)
110
+ end
111
+
112
+ def build_diff_html_reports
113
+ @projects.each do |project|
114
+ logger.info "Preparing report for #{project.name}"
115
+ report_diffs = DiffBuilder.new.build(project.get_pmd_report_path(@options.base_branch),
116
+ project.get_pmd_report_path(@options.patch_branch),
117
+ project.get_report_info_path(@options.base_branch),
118
+ project.get_report_info_path(@options.patch_branch),
119
+ @options.filter_set)
120
+ project.report_diff = report_diffs
121
+ DiffReportBuilder.new.build(project)
122
+ end
123
+ logger.info 'Built all difference reports successfully!'
124
+ end
125
+
126
+ def get_projects(file_path)
127
+ @projects = ProjectsParser.new.parse(file_path)
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,155 @@
1
+ body {
2
+ margin: 0px;
3
+ padding: 0px;
4
+ }
5
+ img {
6
+ border:none;
7
+ }
8
+ table {
9
+ padding:0px;
10
+ width: 100%;
11
+ margin-left: -2px;
12
+ margin-right: -2px;
13
+ }
14
+ acronym {
15
+ cursor: help;
16
+ border-bottom: 1px dotted #feb;
17
+ }
18
+ table.bodyTable th, table.bodyTable td {
19
+ padding: 2px 4px 2px 4px;
20
+ vertical-align: top;
21
+ }
22
+ div.clear{
23
+ clear:both;
24
+ visibility: hidden;
25
+ }
26
+ div.clear hr{
27
+ display: none;
28
+ }
29
+ #bannerLeft, #bannerRight {
30
+ font-size: xx-large;
31
+ font-weight: bold;
32
+ }
33
+ #bannerLeft img, #bannerRight img {
34
+ margin: 0px;
35
+ }
36
+ .xleft, #bannerLeft img {
37
+ float:left;
38
+ }
39
+ .xright, #bannerRight {
40
+ float:right;
41
+ }
42
+ #banner {
43
+ padding: 0px;
44
+ }
45
+ #banner img {
46
+ border: none;
47
+ }
48
+ #breadcrumbs {
49
+ padding: 3px 10px 3px 10px;
50
+ }
51
+ #leftColumn {
52
+ width: 170px;
53
+ float:left;
54
+ overflow: auto;
55
+ }
56
+ #bodyColumn {
57
+ margin-right: 1.5em;
58
+ margin-left: 197px;
59
+ }
60
+ #legend {
61
+ padding: 8px 0 8px 0;
62
+ }
63
+ #navcolumn {
64
+ padding: 8px 4px 0 8px;
65
+ }
66
+ #navcolumn h5 {
67
+ margin: 0;
68
+ padding: 0;
69
+ font-size: small;
70
+ }
71
+ #navcolumn ul {
72
+ margin: 0;
73
+ padding: 0;
74
+ font-size: small;
75
+ }
76
+ #navcolumn li {
77
+ list-style-type: none;
78
+ background-image: none;
79
+ background-repeat: no-repeat;
80
+ background-position: 0 0.4em;
81
+ padding-left: 16px;
82
+ list-style-position: outside;
83
+ line-height: 1.2em;
84
+ font-size: smaller;
85
+ }
86
+ #navcolumn li.expanded {
87
+ background-image: url(../images/expanded.gif);
88
+ }
89
+ #navcolumn li.collapsed {
90
+ background-image: url(../images/collapsed.gif);
91
+ }
92
+ #navcolumn li.none {
93
+ text-indent: -1em;
94
+ margin-left: 1em;
95
+ }
96
+ #poweredBy {
97
+ text-align: center;
98
+ }
99
+ #navcolumn img {
100
+ margin-top: 10px;
101
+ margin-bottom: 3px;
102
+ }
103
+ #poweredBy img {
104
+ display:block;
105
+ margin: 20px 0 20px 17px;
106
+ }
107
+ #search img {
108
+ margin: 0px;
109
+ display: block;
110
+ }
111
+ #search #q, #search #btnG {
112
+ border: 1px solid #999;
113
+ margin-bottom:10px;
114
+ }
115
+ #search form {
116
+ margin: 0px;
117
+ }
118
+ #lastPublished {
119
+ font-size: x-small;
120
+ }
121
+ .navSection {
122
+ margin-bottom: 2px;
123
+ padding: 8px;
124
+ }
125
+ .navSectionHead {
126
+ font-weight: bold;
127
+ font-size: x-small;
128
+ }
129
+ .section {
130
+ padding: 4px;
131
+ }
132
+ #footer {
133
+ padding: 3px 10px 3px 10px;
134
+ font-size: x-small;
135
+ }
136
+ #breadcrumbs {
137
+ font-size: x-small;
138
+ margin: 0pt;
139
+ }
140
+ .source {
141
+ padding: 12px;
142
+ margin: 1em 7px 1em 7px;
143
+ }
144
+ .source pre {
145
+ margin: 0px;
146
+ padding: 0px;
147
+ }
148
+ #navcolumn img.imageLink, .imageLink {
149
+ padding-left: 0px;
150
+ padding-bottom: 0px;
151
+ padding-top: 0px;
152
+ padding-right: 2px;
153
+ border: 0px;
154
+ margin: 0px;
155
+ }
@@ -0,0 +1,171 @@
1
+ body {
2
+ padding: 0px 0px 10px 0px;
3
+ }
4
+ body, td, select, input, li{
5
+ font-family: Verdana, Helvetica, Arial, sans-serif;
6
+ font-size: 13px;
7
+ }
8
+ code{
9
+ font-family: Courier, monospace;
10
+ font-size: 13px;
11
+ }
12
+ a {
13
+ text-decoration: none;
14
+ }
15
+ a:link {
16
+ color:#36a;
17
+ }
18
+ a:visited {
19
+ color:#47a;
20
+ }
21
+ a:active, a:hover {
22
+ color:#69c;
23
+ }
24
+ #legend li.externalLink {
25
+ background: url(../images/external.png) left top no-repeat;
26
+ padding-left: 18px;
27
+ }
28
+ a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
29
+ background: url(../images/external.png) right center no-repeat;
30
+ padding-right: 18px;
31
+ }
32
+ #legend li.newWindow {
33
+ background: url(../images/newwindow.png) left top no-repeat;
34
+ padding-left: 18px;
35
+ }
36
+ a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
37
+ background: url(../images/newwindow.png) right center no-repeat;
38
+ padding-right: 18px;
39
+ }
40
+ h2 {
41
+ padding: 4px 4px 4px 6px;
42
+ border: 1px solid #999;
43
+ color: #900;
44
+ background-color: #ddd;
45
+ font-weight:900;
46
+ font-size: x-large;
47
+ }
48
+ h3 {
49
+ padding: 4px 4px 4px 6px;
50
+ border: 1px solid #aaa;
51
+ color: #900;
52
+ background-color: #eee;
53
+ font-weight: normal;
54
+ font-size: large;
55
+ }
56
+ h4 {
57
+ font-weight: normal;
58
+ font-size: large;
59
+ }
60
+ h5 {
61
+ padding: 4px 4px 4px 6px;
62
+ color: #900;
63
+ font-size: normal;
64
+ }
65
+ p {
66
+ line-height: 1.3em;
67
+ font-size: small;
68
+ }
69
+ #breadcrumbs {
70
+ border-top: 1px solid #aaa;
71
+ border-bottom: 1px solid #aaa;
72
+ background-color: #ccc;
73
+ }
74
+ #leftColumn {
75
+ margin: 10px 0 0 5px;
76
+ border: 1px solid #999;
77
+ background-color: #eee;
78
+ }
79
+ #navcolumn h5 {
80
+ font-size: smaller;
81
+ border-bottom: 1px solid #aaaaaa;
82
+ padding-top: 2px;
83
+ color: #000;
84
+ }
85
+
86
+ table.bodyTable th {
87
+ color: white;
88
+ background-color: #bbb;
89
+ text-align: left;
90
+ font-weight: bold;
91
+ }
92
+
93
+ table.bodyTable th, table.bodyTable td {
94
+ font-size: 1em;
95
+ }
96
+
97
+ table.bodyTable tr.a {
98
+ background-color: #af8;
99
+ }
100
+
101
+ table.bodyTable tr.b {
102
+ background-color: #fca;
103
+ }
104
+
105
+ table.bodyTable tr.c {
106
+ background-color: #eee;
107
+ }
108
+
109
+ table.bodyTable tr.d {
110
+ background-color: #fef7bc;
111
+ }
112
+
113
+ table.bodyTable td.a {
114
+ background-color: #af8;
115
+ }
116
+
117
+ table.bodyTable td.b {
118
+ background-color: #fca;
119
+ }
120
+
121
+ table.bodyTable td.c {
122
+ background-color: #eee;
123
+ }
124
+
125
+ .source {
126
+ border: 1px solid #999;
127
+ }
128
+ dl {
129
+ padding: 4px 4px 4px 6px;
130
+ border: 1px solid #aaa;
131
+ background-color: #ffc;
132
+ }
133
+ dt {
134
+ color: #900;
135
+ }
136
+
137
+ #banner {
138
+ border-bottom: 1px solid #fff;
139
+ }
140
+
141
+ button {
142
+ background-color: #ddd;
143
+ border: none;
144
+ color: #900;
145
+ padding: 6px 12px;
146
+ text-align: center;
147
+ text-decoration: none;
148
+ display: inline-block;
149
+ font-size: 25px;
150
+ margin: 4px 2px;
151
+ cursor: pointer;
152
+ }
153
+
154
+ #example {
155
+ position: relative;
156
+ }
157
+
158
+ #example-checkbox {
159
+ display: none;
160
+ }
161
+
162
+ #example-checkbox:checked + #example:after {
163
+ content: attr(data-text);
164
+ position: absolute;
165
+ top: 0;
166
+ left: 0;
167
+ right: 0;
168
+ bottom: 0;
169
+ background: white;
170
+ }
171
+