pmdtester 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/build.sh +99 -0
  3. data/.ci/inc/fetch_ci_scripts.bash +19 -0
  4. data/.ci/manual-integration-tests.sh +37 -0
  5. data/.github/workflows/build.yml +55 -0
  6. data/.github/workflows/manual-integration-tests.yml +43 -0
  7. data/.gitignore +9 -0
  8. data/.hoerc +1 -1
  9. data/.rubocop.yml +9 -2
  10. data/.ruby-version +1 -0
  11. data/History.md +79 -0
  12. data/Manifest.txt +28 -9
  13. data/README.rdoc +59 -33
  14. data/Rakefile +7 -5
  15. data/config/all-java.xml +1 -1
  16. data/config/design.xml +1 -1
  17. data/config/project-list.xml +8 -7
  18. data/config/projectlist_1_0_0.xsd +2 -1
  19. data/config/projectlist_1_1_0.xsd +31 -0
  20. data/config/projectlist_1_2_0.xsd +39 -0
  21. data/lib/pmdtester.rb +8 -7
  22. data/lib/pmdtester/builders/liquid_renderer.rb +130 -0
  23. data/lib/pmdtester/builders/pmd_report_builder.rb +107 -79
  24. data/lib/pmdtester/builders/project_builder.rb +105 -0
  25. data/lib/pmdtester/builders/project_hasher.rb +128 -0
  26. data/lib/pmdtester/builders/rule_set_builder.rb +96 -47
  27. data/lib/pmdtester/builders/simple_progress_logger.rb +4 -4
  28. data/lib/pmdtester/builders/summary_report_builder.rb +63 -131
  29. data/lib/pmdtester/collection_by_file.rb +55 -0
  30. data/lib/pmdtester/parsers/options.rb +24 -0
  31. data/lib/pmdtester/parsers/pmd_report_document.rb +72 -28
  32. data/lib/pmdtester/parsers/projects_parser.rb +2 -4
  33. data/lib/pmdtester/pmd_branch_detail.rb +35 -19
  34. data/lib/pmdtester/pmd_configerror.rb +23 -24
  35. data/lib/pmdtester/pmd_error.rb +34 -34
  36. data/lib/pmdtester/pmd_report_detail.rb +10 -13
  37. data/lib/pmdtester/pmd_tester_utils.rb +58 -0
  38. data/lib/pmdtester/pmd_violation.rb +66 -28
  39. data/lib/pmdtester/project.rb +42 -56
  40. data/lib/pmdtester/report_diff.rb +203 -109
  41. data/lib/pmdtester/resource_locator.rb +4 -0
  42. data/lib/pmdtester/runner.rb +67 -64
  43. data/pmdtester.gemspec +28 -37
  44. data/resources/_includes/diff_pill_row.html +6 -0
  45. data/resources/css/bootstrap.min.css +7 -0
  46. data/resources/css/datatables.min.css +36 -0
  47. data/resources/css/pmd-tester.css +132 -0
  48. data/resources/js/bootstrap.min.js +7 -0
  49. data/resources/js/code-snippets.js +73 -0
  50. data/resources/js/datatables.min.js +726 -0
  51. data/resources/js/jquery-3.2.1.slim.min.js +4 -0
  52. data/resources/js/jquery.min.js +2 -0
  53. data/resources/js/popper.min.js +5 -0
  54. data/resources/js/project-report.js +137 -0
  55. data/resources/project_diff_report.html +214 -0
  56. data/resources/project_index.html +113 -0
  57. data/resources/project_pmd_report.html +186 -0
  58. metadata +73 -25
  59. data/.travis.yml +0 -40
  60. data/lib/pmdtester/builders/diff_builder.rb +0 -31
  61. data/lib/pmdtester/builders/diff_report/configerrors.rb +0 -50
  62. data/lib/pmdtester/builders/diff_report/errors.rb +0 -71
  63. data/lib/pmdtester/builders/diff_report/violations.rb +0 -77
  64. data/lib/pmdtester/builders/diff_report_builder.rb +0 -99
  65. data/lib/pmdtester/builders/html_report_builder.rb +0 -56
  66. data/resources/css/maven-base.css +0 -155
  67. data/resources/css/maven-theme.css +0 -171
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Contains methods to write out html for the configuration errors.
4
- # This mixin is used by DiffReportBuilder.
5
- module DiffReportBuilderConfigErrors
6
- def build_configerrors_section(doc, configerrors_diffs)
7
- doc.div(class: 'section', id: 'configerrors') do
8
- doc.h2 'Configuration Errors:'
9
-
10
- doc.h3 PmdTester::HtmlReportBuilder::NO_DIFFERENCES_MESSAGE if configerrors_diffs.empty?
11
- configerrors_diffs.each do |key, value|
12
- doc.div(class: 'section') do
13
- doc.h3 key
14
- build_configerrors_table(doc, value)
15
- end
16
- end
17
- end
18
- end
19
-
20
- def build_configerrors_table(doc, errors)
21
- doc.table(class: 'bodyTable', border: '0') do
22
- build_configerrors_table_head(doc)
23
- build_configerrors_table_body(doc, errors)
24
- end
25
- end
26
-
27
- def build_configerrors_table_head(doc)
28
- build_table_head(doc, '', 'Rule', 'Message')
29
- end
30
-
31
- def build_configerrors_table_body(doc, errors)
32
- doc.tbody do
33
- errors.each { |pmd_configerror| build_configerrors_table_row(doc, pmd_configerror) }
34
- end
35
- end
36
-
37
- def build_configerrors_table_row(doc, pmd_configerror)
38
- doc.tr(class: pmd_configerror.branch == PmdTester::BASE ? 'b' : 'a') do
39
- build_table_anchor_column(doc, 'C', increment_configerror_index)
40
-
41
- doc.td pmd_configerror.rulename
42
- doc.td pmd_configerror.msg
43
- end
44
- end
45
-
46
- def increment_configerror_index
47
- @configerror_index ||= 0 # init with 0
48
- @configerror_index += 1
49
- end
50
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Contains methods to write out html for the errors.
4
- # This mixin is used by DiffReportBuilder.
5
- module DiffReportBuilderErrors
6
- def build_errors_section(doc, error_diffs)
7
- doc.div(class: 'section', id: 'Errors') do
8
- doc.h2 'Errors:'
9
-
10
- doc.h3 PmdTester::HtmlReportBuilder::NO_DIFFERENCES_MESSAGE if error_diffs.empty?
11
- error_diffs.each do |key, value|
12
- doc.div(class: 'section') do
13
- build_filename_h3(doc, key)
14
- build_errors_table(doc, value)
15
- end
16
- end
17
- end
18
- end
19
-
20
- def build_errors_table(doc, errors)
21
- doc.table(class: 'bodyTable', border: '0') do
22
- build_errors_table_head(doc)
23
- build_errors_table_body(doc, errors)
24
- end
25
- end
26
-
27
- def build_errors_table_head(doc)
28
- build_table_head(doc, '', 'Message', 'Details')
29
- end
30
-
31
- def build_errors_table_body(doc, errors)
32
- if PmdTester::ReportDiff.comparable?(errors)
33
- # we have only two errors and those are from base and patch, so we
34
- # can compare them and display a nice diff
35
- pmd_error_a = errors[0]
36
- pmd_error_b = errors[1]
37
- diff_a = Differ.diff_by_line(pmd_error_a.text, pmd_error_b.text).format_as(:html)
38
- diff_b = Differ.diff_by_line(pmd_error_b.text, pmd_error_a.text).format_as(:html)
39
- doc.tbody do
40
- build_errors_table_row(doc, pmd_error_a, diff_a)
41
- build_errors_table_row(doc, pmd_error_b, diff_b)
42
- end
43
- else
44
- # many errors, just report them one by one
45
- doc.tbody do
46
- errors.each { |pmd_error| build_errors_table_row(doc, pmd_error) }
47
- end
48
- end
49
- end
50
-
51
- def build_errors_table_row(doc, pmd_error, text = nil)
52
- doc.tr(class: pmd_error.branch == PmdTester::BASE ? 'b' : 'a') do
53
- build_table_anchor_column(doc, 'B', increment_error_index)
54
-
55
- text = pmd_error.text if text.nil?
56
-
57
- # The error message
58
- doc.td pmd_error.msg
59
- doc.td do
60
- doc.pre do
61
- doc << text
62
- end
63
- end
64
- end
65
- end
66
-
67
- def increment_error_index
68
- @error_index ||= 0 # init with 0
69
- @error_index += 1
70
- end
71
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Contains methods to write out html for the violations.
4
- # This mixin is used by DiffReportBuilder.
5
- module DiffReportBuilderViolations
6
- def build_violations_section(doc, violation_diffs)
7
- doc.div(class: 'section', id: 'Violations') do
8
- doc.h2 'Violations:'
9
-
10
- doc.h3 PmdTester::HtmlReportBuilder::NO_DIFFERENCES_MESSAGE if violation_diffs.empty?
11
- violation_diffs.each do |key, value|
12
- doc.div(class: 'section') do
13
- build_filename_h3(doc, key)
14
- build_violation_table(doc, key, value)
15
- end
16
- end
17
- end
18
- end
19
-
20
- def build_violation_table(doc, key, value)
21
- doc.table(class: 'bodyTable', border: '0') do
22
- build_violation_table_head(doc)
23
- build_violation_table_body(doc, key, value)
24
- end
25
- end
26
-
27
- def build_violation_table_head(doc)
28
- build_table_head(doc, '', 'Priority', 'Rule', 'Message', 'Line')
29
- end
30
-
31
- def build_violation_table_body(doc, key, value)
32
- doc.tbody do
33
- value.each do |pmd_violation|
34
- build_violation_table_row(doc, key, pmd_violation)
35
- end
36
- end
37
- end
38
-
39
- def build_violation_table_row(doc, key, pmd_violation)
40
- doc.tr(class: pmd_violation.branch == PmdTester::BASE ? 'b' : 'a') do
41
- build_table_anchor_column(doc, 'A', increment_violation_index)
42
-
43
- violation = pmd_violation.attrs
44
-
45
- # The priority of the rule
46
- doc.td violation['priority']
47
-
48
- # The rule that trigger the violation
49
- doc.td do
50
- doc.a(href: (violation['externalInfoUrl']).to_s) { doc.text violation['rule'] }
51
- end
52
-
53
- # The violation message
54
- doc.td pmd_violation.text
55
-
56
- # The begin line of the violation
57
- line = violation['beginline']
58
-
59
- # The link to the source file
60
- doc.td do
61
- link = get_link_to_source(violation, key)
62
- doc.a(href: link.to_s) { doc.text line }
63
- end
64
- end
65
- end
66
-
67
- def get_link_to_source(violation, key)
68
- l_str = @project.type == 'git' ? 'L' : 'l'
69
- line_str = "##{l_str}#{violation['beginline']}"
70
- @project.get_webview_url(key) + line_str
71
- end
72
-
73
- def increment_violation_index
74
- @violation_index ||= 0 # init with 0
75
- @violation_index += 1
76
- end
77
- end
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'nokogiri'
4
- require 'differ'
5
-
6
- module PmdTester
7
- # Building diff report for a single project
8
- class DiffReportBuilder < HtmlReportBuilder
9
- include PmdTester
10
- include DiffReportBuilderViolations
11
- include DiffReportBuilderErrors
12
- include DiffReportBuilderConfigErrors
13
-
14
- def build(project)
15
- @project = project
16
- @report_diff = project.report_diff
17
-
18
- index = File.new(project.diff_report_index_path, 'w')
19
-
20
- html_report = build_html_report('pmd xml difference report')
21
- copy_css(project.target_diff_report_path)
22
-
23
- index.puts html_report
24
- index.close
25
-
26
- logger.info "Built difference report of #{project.name} successfully!"
27
- end
28
-
29
- def build_body(doc)
30
- violation_diffs = @report_diff.violation_diffs
31
- error_diffs = @report_diff.error_diffs
32
- configerrors_diffs = @report_diff.configerrors_diffs
33
- doc.body(class: 'composite') do
34
- doc.div(id: 'contentBox') do
35
- build_summary_section(doc)
36
- build_violations_section(doc, violation_diffs)
37
- build_errors_section(doc, error_diffs)
38
- build_configerrors_section(doc, configerrors_diffs)
39
- end
40
- end
41
- end
42
-
43
- def build_summary_section(doc)
44
- doc.div(class: 'section', id: 'Summary') do
45
- doc.h2 'Summary:'
46
- build_summary_table(doc)
47
- end
48
- end
49
-
50
- def build_summary_table(doc)
51
- doc.table(class: 'bodyTable', border: '0') do
52
- build_table_head(doc, 'Item', 'Base', 'Patch', 'Difference')
53
- build_summary_table_body(doc)
54
- end
55
- end
56
-
57
- def build_summary_table_body(doc)
58
- doc.tbody do
59
- build_summary_row(doc, 'number of errors', @report_diff.base_errors_size,
60
- @report_diff.patch_errors_size, @report_diff.removed_errors_size,
61
- @report_diff.new_errors_size)
62
- build_summary_row(doc, 'number of violations', @report_diff.base_violations_size,
63
- @report_diff.patch_violations_size, @report_diff.removed_violations_size,
64
- @report_diff.new_violations_size)
65
- build_summary_row(doc, 'number of config errors', @report_diff.base_configerrors_size,
66
- @report_diff.patch_configerrors_size,
67
- @report_diff.removed_configerrors_size,
68
- @report_diff.new_configerrors_size)
69
- build_summary_row(doc, 'execution time', @report_diff.base_execution_time,
70
- @report_diff.patch_execution_time, @report_diff.diff_execution_time)
71
- build_summary_row(doc, 'timestamp', @report_diff.base_timestamp,
72
- @report_diff.patch_timestamp, '')
73
- end
74
- end
75
-
76
- def build_summary_row(doc, item, base, patch, *diff)
77
- doc.tr do
78
- doc.td(class: 'c') { doc.text item }
79
- doc.td(class: 'b') { doc.text base }
80
- doc.td(class: 'a') { doc.text patch }
81
- doc.td(class: 'c') do
82
- if diff.size == 1
83
- doc.text diff[0]
84
- else
85
- build_table_content_for(doc, diff[0], diff[1])
86
- end
87
- end
88
- end
89
- end
90
-
91
- def build_filename_h3(doc, filename)
92
- doc.h3 do
93
- doc.a(href: @project.get_webview_url(filename)) do
94
- doc.text @project.get_path_inside_project(filename)
95
- end
96
- end
97
- end
98
- end
99
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PmdTester
4
- # This class is the parent of all classes which is used to build html report
5
- class HtmlReportBuilder
6
- CSS_SRC_DIR = ResourceLocator.locate('resources/css')
7
- NO_DIFFERENCES_MESSAGE = 'No differences found!'
8
-
9
- def build_html_report(title_name)
10
- html_builder = Nokogiri::HTML::Builder.new do |doc|
11
- doc.html do
12
- build_head(doc, title_name)
13
- build_body(doc)
14
- end
15
- end
16
- html_builder.to_html
17
- end
18
-
19
- def build_head(doc, title_name)
20
- doc.head do
21
- doc.title title_name
22
-
23
- doc.style(type: 'text/css', media: 'all') do
24
- doc.text '@import url("./css/maven-base.css");@import url("./css/maven-theme.css");'
25
- end
26
- end
27
- end
28
-
29
- def build_table_head(doc, *columns)
30
- doc.thead do
31
- doc.tr do
32
- columns.each do |column|
33
- doc.th column
34
- end
35
- end
36
- end
37
- end
38
-
39
- def build_table_anchor_column(doc, prefix, index)
40
- doc.td do
41
- doc.a(id: "#{prefix}#{index}", href: "##{prefix}#{index}") { doc.text '#' }
42
- end
43
- end
44
-
45
- def copy_css(report_dir)
46
- css_dest_dir = "#{report_dir}/css"
47
- FileUtils.copy_entry(CSS_SRC_DIR, css_dest_dir)
48
- end
49
-
50
- def build_table_content_for(doc, removed_size, new_size)
51
- doc.font(color: 'red') { doc.text "-#{removed_size}" }
52
- doc.text ' | '
53
- doc.font(color: 'green') { doc.text "+#{new_size}" }
54
- end
55
- end
56
- end
@@ -1,155 +0,0 @@
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
- }