pmdtester 1.0.0 → 1.2.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 (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
data/README.rdoc CHANGED
@@ -4,7 +4,9 @@ home :: https://pmd.github.io
4
4
  code :: https://github.com/pmd/pmd-regression-tester
5
5
  bugs :: https://github.com/pmd/pmd-regression-tester/issues
6
6
 
7
- build-status :: {<img src="https://travis-ci.com/pmd/pmd-regression-tester.svg?branch=master" alt="Build Status" />}[https://travis-ci.com/pmd/pmd-regression-tester]
7
+ build-status :: {<img src="https://github.com/pmd/pmd-regression-tester/workflows/build/badge.svg?branch=master" alt="Build Status" />}[https://github.com/pmd/pmd-regression-tester/actions?query=workflow%3Abuild]
8
+
9
+ gem-version :: {<img src="https://badge.fury.io/rb/pmdtester.svg" alt="Gem Version" />}[https://rubygems.org/gems/pmdtester]
8
10
 
9
11
  == DESCRIPTION:
10
12
 
@@ -18,26 +20,30 @@ on a list of standard projects(Spring Framework, Hibernate, Solr, etc.)
18
20
  == SYNOPSIS:
19
21
 
20
22
  === Options:
21
- -r, --local-git-repo path to the local PMD repository
22
- -b, --base-branch name of the base branch in local PMD repository
23
- -p, --patch-branch name of the patch branch in local PMD repository
24
- -bc, --base-config path to the base PMD configuration file default:PMDTESTER_INSTALLED_DIR/config/all-java.xml
25
- -pc, --patch-config path to the patch PMD configuration file default:PMDTESTER_INSTALLED_DIR/config/all-java.xml
26
- -c, --config path to the base and patch PMD configuration file
27
- -l, --list-of-project path to the file which contains the list of standard projects default:PMDTESTER_INSTALLED_DIR/config/project-list.xml
28
- -m, --mode the mode of the tool: 'local', 'online' or 'single'
23
+ -r, --local-git-repo path to the local PMD repository
24
+ -b, --base-branch name of the base branch in local PMD repository
25
+ -p, --patch-branch name of the patch branch in local PMD repository
26
+ -bc, --base-config path to the base PMD configuration file
27
+ -pc, --patch-config path to the patch PMD configuration file
28
+ -c, --config path to the base and patch PMD configuration file
29
+ -l, --list-of-project path to the file which contains the list of standard projects
30
+ -m, --mode the mode of the tool: 'local', 'online' or 'single'
29
31
  single: Set this option to 'single' if your patch branch contains changes
30
32
  for any option that can't work on master/base branch
31
33
  online: Set this option to 'online' if you want to download
32
34
  the PMD report of master/base branch rather than generating it locally
33
35
  local: Default option is 'local', PMD reports for the base and patch branches are generated locally.
34
36
 
35
- -t, --threads Sets the number of threads used by PMD. Set threads to 0 to disable multi-threading processing. default:1
36
- -f, --html-flag whether to not generate the html diff report in single mode
37
- -a, --auto-gen-config whether to generate configurations automatically based on branch differences,this option only works in online and local mode
38
- -d, --debug whether change log level to DEBUG to see more information
39
- -v, --version
40
- -h, --help
37
+ -t, --threads Sets the number of threads used by PMD. Set threads to 0 to disable multi-threading processing.
38
+ -f, --html-flag whether to not generate the html diff report in single mode
39
+ -a, --auto-gen-config whether to generate configurations automatically based on branch differences,this option only works in online and local mode
40
+ --filter-with-patch-config whether to use patch config to filter baseline result as if --auto-gen-config has been used. This option only works in online mode.
41
+ --keep-reports whether to keep old reports and skip running PMD again if possible
42
+ -d, --debug whether change log level to DEBUG to see more information
43
+ --error-recovery enable error recovery mode when executing PMD. Might help to analyze errors.
44
+ --baseline-download-url download url prefix from where to download the baseline in online mode
45
+ -v, --version
46
+ -h, --help
41
47
 
42
48
  === Quick start
43
49
 
@@ -60,19 +66,24 @@ The tool creates the following folders:
60
66
  │ ├── PROJECT_NAME_1
61
67
  │ ├── ......
62
68
  │ └── PROJECT_NAME_n
63
- └── reports
64
- ├── BASE_BRANCH_NAME <- the base baseline is placed here
65
- ├── PATCH_BRANCH_NAME <- the patch baseline is placed here
66
- └── diff
67
- ├── index.xml <- the summary report of diff reports
68
- ├── base_config.xml <- the resources of the summary report
69
- ├── patch_config.xml <- the resources fo the summary report
70
- ├── css <- css reources are placed here
71
- ├── PROJECT_NAME_1
72
- └── index.xml <- the diff report of PROJECT_1
73
- ├── .......
74
- └── PROJECT_NAME_n
75
- └── index.xml <- the diff report of PROJECT_N
69
+ ├── reports
70
+ ├── BASE_BRANCH_NAME <- the base baseline is placed here
71
+ ├── PATCH_BRANCH_NAME <- the patch baseline is placed here
72
+ └── diff
73
+ ├── index.html <- the summary report of diff reports
74
+ ├── base_config.xml <- pmd config from the base branch
75
+ ├── patch_config.xml <- pmd config from the patch branch
76
+ ├── css <- css resources are placed here
77
+ ├── js <- js resources
78
+ │ ├── PROJECT_NAME_1
79
+ │ │ ├── project_data.js <- contains the violations as js/json
80
+ │ │ └── index.html <- the diff report of PROJECT_1
81
+ │ ├── .......
82
+ │ └── PROJECT_NAME_n
83
+ │ ├── project_data.js <- contains the violations as js/json
84
+ │ └── index.xml <- the diff report of PROJECT_N
85
+ ├── pmd-bin-<version>-<branch_name>-<sha1> <- cached pmd builds that are reused
86
+ └── pmd-bin-....
76
87
 
77
88
  ==== The baseline format
78
89
  branch_name
@@ -90,14 +101,16 @@ The tool creates the following folders:
90
101
 
91
102
  == REQUIREMENTS:
92
103
 
93
- * Ruby 2.4.1 or higher
104
+ * Ruby 2.7 or higher
94
105
 
95
106
  === Runtime dependency
96
107
 
97
- nokogiri ~> 1.8
108
+ nokogiri >= 1.11.0.rc4
98
109
  slop ~> 4.6
99
110
  differ ~> 0.1
100
111
  rufus-scheduler ~> 3.5
112
+ logger-colors ~> 1.0
113
+ liquid >= 4.0
101
114
 
102
115
  === Development dependency
103
116
 
@@ -122,11 +135,24 @@ The tool creates the following folders:
122
135
  bundle install # once
123
136
  bundle exec rake verify # run this command before commit your changes
124
137
  bundle exec pmdtester ... # run this to directly execute pmdtester from source
138
+
139
+ Run a single test class, e.g.:
140
+ bundle exec ruby -I test test/test_diff_report_builder.rb
141
+
142
+ Run a single test, e.g.:
143
+ bundle exec ruby -I test test/test_diff_report_builder.rb -n test_diff_report_builder
125
144
 
126
145
  === Releasing
127
146
 
128
147
  * Update +History.md+ (version and date)
129
148
  * Update +lib/pmdtester.rb+ (version)
130
- * Commit ("Prepare release x.y.z"), tag, push. Travis will build and publish the new gem.
131
- * Update History.md and lib/pmdtester.rb for the next development version
132
- ("Prepare next development version x.y.z-SNAPSHOT").
149
+ * Run "bundle exec rake verify" and add new +pmdtester.gemspec+ (new version)
150
+ * Commit ("Prepare release x.y.z").
151
+ * Tag this commit ("git tag vx.y.z").
152
+ * Update History.md and lib/pmdtester.rb for the next development version,
153
+ run again "bundle exec rake verify"
154
+ * Commit ("Prepare next development version x.y.z-SNAPSHOT").
155
+ * Push to master.
156
+ * Push the tag. Github Actions will build and publish the new gem
157
+ * A github release is automatically created, verify it on https://github.com/pmd/pmd-regression-tester/releases
158
+ * To make pmd's main CI use the new version (in [pmd/pmd](https://github.com/pmd/pmd/)), go to the root directory and run `bundle lock --update`. Commit these changes.
data/Rakefile CHANGED
@@ -14,12 +14,14 @@ Hoe.plugin :git
14
14
  hoe = Hoe.spec 'pmdtester' do
15
15
  self.version = PmdTester::VERSION
16
16
 
17
- developer 'Andreas Dangel', 'andreas.dangel@adangel.org'
17
+ developer 'Andreas Dangel', 'andreas.dangel@pmd-code.org'
18
18
  developer 'Binguo Bao', 'djydewang@gmail.com'
19
+ developer 'Clément Fournier', 'clement.fournier76@gmail.com'
19
20
 
20
- self.clean_globs = %w[target/reports/**/* target/test/**/* Gemfile.lock]
21
- self.extra_deps += [['nokogiri', '~> 1.8'], ['slop', '~> 4.6'], ['differ', '~> 0.1'],
22
- ['rufus-scheduler', '~> 3.5']]
21
+ self.clean_globs = %w[target/reports/**/* target/test/**/* target/dynamic-config.xml Gemfile.lock]
22
+ self.extra_deps += [['nokogiri', '>= 1.11.0.rc4'], ['slop', '~> 4.6'], ['differ', '~> 0.1'],
23
+ ['rufus-scheduler', '~> 3.5'], ['logger-colors', '~> 1.0'],
24
+ ['liquid', '>= 4.0']]
23
25
  self.extra_dev_deps += [
24
26
  ['hoe-bundler', '~> 1.5'],
25
27
  ['hoe-git', '~> 1.6'],
@@ -30,7 +32,7 @@ hoe = Hoe.spec 'pmdtester' do
30
32
  ['test-unit', '~> 3.2'],
31
33
  ['rdoc', ['>= 4.0', '< 7']]
32
34
  ]
33
- spec_extras[:required_ruby_version] = '>= 2.2'
35
+ spec_extras[:required_ruby_version] = '>= 2.7'
34
36
 
35
37
  license 'BSD-2-Clause'
36
38
  end
data/config/all-java.xml CHANGED
@@ -3,7 +3,7 @@
3
3
  <ruleset name="All Java Rules"
4
4
  xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
5
5
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
- xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
6
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
7
7
  <description>Every Java Rule in PMD</description>
8
8
 
9
9
  <rule ref="category/java/bestpractices.xml" />
data/config/design.xml CHANGED
@@ -3,7 +3,7 @@
3
3
  <ruleset name="Design"
4
4
  xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
5
5
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
- xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
6
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
7
7
 
8
8
  <description>
9
9
  The Design ruleset contains rules that flag suboptimal code implementations. Alternate approaches
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0"?>
2
2
 
3
3
  <projectlist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
- xsi:noNamespaceSchemaLocation="projectlist_1_0_0.xsd">
4
+ xsi:noNamespaceSchemaLocation="projectlist_1_2_0.xsd">
5
5
  <description>Standard Projects</description>
6
6
 
7
7
  <project>
@@ -20,10 +20,11 @@ xsi:noNamespaceSchemaLocation="projectlist_1_0_0.xsd">
20
20
  <tag>v5.0.6.RELEASE</tag>
21
21
  </project>
22
22
 
23
- <!---<project>
24
- <name>openjdk10</name>
25
- <type>hg</type>
26
- <connection>http://hg.openjdk.java.net/jdk10/jdk10/jdk</connection>
27
- <webview-url>http://hg.openjdk.java.net/jdk10/jdk10/jdk/file/777356696811</webview-url>
28
- </project> -->
23
+ <project>
24
+ <name>openjdk-11</name>
25
+ <type>git</type>
26
+ <connection>https://github.com/openjdk/jdk</connection>
27
+ <tag>jdk-11+28</tag>
28
+ <src-subpath>src/java.base</src-subpath>
29
+ </project>
29
30
  </projectlist>
@@ -1,4 +1,5 @@
1
1
  <?xml version="1.0" ?>
2
+ <!-- version 1.0.0 -->
2
3
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3
4
  <xs:element name="projectlist">
4
5
  <xs:complexType>
@@ -25,4 +26,4 @@
25
26
  <xs:element name="exclude-pattern" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
26
27
  </xs:sequence>
27
28
  </xs:complexType>
28
- </xs:schema>
29
+ </xs:schema>
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0" ?>
2
+ <!-- version 1.1.0 -->
3
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
4
+ <xs:element name="projectlist">
5
+ <xs:complexType>
6
+ <xs:sequence>
7
+ <xs:element name="description" type="xs:string" minOccurs="1" maxOccurs="1"/>
8
+ <xs:element name="project" type="project" minOccurs="1" maxOccurs="unbounded"/>
9
+ </xs:sequence>
10
+ </xs:complexType>
11
+ </xs:element>
12
+ <xs:complexType name="project">
13
+ <xs:sequence>
14
+ <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
15
+ <xs:element name="type" minOccurs="1" maxOccurs="1">
16
+ <xs:simpleType>
17
+ <xs:restriction base="xs:string">
18
+ <xs:enumeration value="git"/>
19
+ <xs:enumeration value="hg"/>
20
+ </xs:restriction>
21
+ </xs:simpleType>
22
+ </xs:element>
23
+ <xs:element name="connection" type="xs:string" minOccurs="1" maxOccurs="1"/>
24
+ <xs:element name="webview-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
25
+ <xs:element name="tag" type="xs:string" minOccurs="0" maxOccurs="1"/>
26
+ <xs:element name="exclude-pattern" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
27
+ <xs:element name="build-command" type="xs:string" minOccurs="0" maxOccurs="1"/>
28
+ <xs:element name="auxclasspath-command" type="xs:string" minOccurs="0" maxOccurs="1"/>
29
+ </xs:sequence>
30
+ </xs:complexType>
31
+ </xs:schema>
@@ -0,0 +1,39 @@
1
+ <?xml version="1.0" ?>
2
+ <!-- version 1.1.0 -->
3
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
4
+ <xs:element name="projectlist">
5
+ <xs:complexType>
6
+ <xs:sequence>
7
+ <xs:element name="description" type="xs:string" minOccurs="1" maxOccurs="1"/>
8
+ <xs:element name="project" type="project" minOccurs="1" maxOccurs="unbounded"/>
9
+ </xs:sequence>
10
+ </xs:complexType>
11
+ </xs:element>
12
+ <xs:complexType name="project">
13
+ <xs:sequence>
14
+ <xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
15
+ <xs:element name="type" minOccurs="1" maxOccurs="1">
16
+ <xs:simpleType>
17
+ <xs:restriction base="xs:string">
18
+ <xs:enumeration value="git"/>
19
+ </xs:restriction>
20
+ </xs:simpleType>
21
+ </xs:element>
22
+ <xs:element name="connection" type="xs:string" minOccurs="1" maxOccurs="1"/>
23
+ <xs:element name="webview-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
24
+ <xs:element name="tag" type="xs:string" minOccurs="0" maxOccurs="1"/>
25
+ <xs:element name="src-subpath" type="xs:string" minOccurs="0" maxOccurs="1" default=".">
26
+ <xs:annotation>
27
+ <xs:documentation>
28
+ Value of the -dir option for the PMD run.
29
+ The value must be a directory path relative to the root directory of the clone.
30
+ Defaults to just '.', ie the entire directory.
31
+ </xs:documentation>
32
+ </xs:annotation>
33
+ </xs:element>
34
+ <xs:element name="exclude-pattern" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
35
+ <xs:element name="build-command" type="xs:string" minOccurs="0" maxOccurs="1"/>
36
+ <xs:element name="auxclasspath-command" type="xs:string" minOccurs="0" maxOccurs="1"/>
37
+ </xs:sequence>
38
+ </xs:complexType>
39
+ </xs:schema>
data/lib/pmdtester.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'logger'
4
+ require 'logger/colors'
4
5
 
5
6
  require_relative 'pmdtester/cmd'
7
+ require_relative 'pmdtester/collection_by_file'
6
8
  require_relative 'pmdtester/pmd_branch_detail'
7
9
  require_relative 'pmdtester/pmd_configerror'
8
10
  require_relative 'pmdtester/pmd_error'
9
11
  require_relative 'pmdtester/pmd_report_detail'
12
+ require_relative 'pmdtester/pmd_tester_utils'
10
13
  require_relative 'pmdtester/pmd_violation'
11
14
  require_relative 'pmdtester/project'
12
15
  require_relative 'pmdtester/report_diff'
@@ -14,13 +17,10 @@ require_relative 'pmdtester/resource_locator'
14
17
  require_relative 'pmdtester/runner'
15
18
 
16
19
  require_relative 'pmdtester/builders/simple_progress_logger'
17
- require_relative 'pmdtester/builders/html_report_builder'
18
- require_relative 'pmdtester/builders/diff_builder'
19
- require_relative 'pmdtester/builders/diff_report/violations'
20
- require_relative 'pmdtester/builders/diff_report/configerrors'
21
- require_relative 'pmdtester/builders/diff_report/errors'
22
- require_relative 'pmdtester/builders/diff_report_builder'
20
+ require_relative 'pmdtester/builders/project_builder'
21
+ require_relative 'pmdtester/builders/project_hasher'
23
22
  require_relative 'pmdtester/builders/pmd_report_builder'
23
+ require_relative 'pmdtester/builders/liquid_renderer'
24
24
  require_relative 'pmdtester/builders/rule_set_builder'
25
25
  require_relative 'pmdtester/builders/summary_report_builder'
26
26
 
@@ -32,9 +32,10 @@ require_relative 'pmdtester/parsers/projects_parser'
32
32
  # and unexpected behaviors will not be introduced to PMD project
33
33
  # after fixing an issue and new rules can work as expected.
34
34
  module PmdTester
35
- VERSION = '1.0.0'
35
+ VERSION = '1.2.0'
36
36
  BASE = 'base'
37
37
  PATCH = 'patch'
38
+ PR_NUM_ENV_VAR = 'PMD_CI_PULL_REQUEST_NUMBER' # see PmdBranchDetail
38
39
 
39
40
  def logger
40
41
  PmdTester.logger
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'liquid'
4
+ require 'json'
5
+
6
+ module PmdTester
7
+ # A module to include in classes that use a Liquid template
8
+ # to generate content.
9
+ module LiquidRenderer
10
+ include PmdTester
11
+
12
+ def render_liquid(template_path, env)
13
+ to_render = File.read(ResourceLocator.resource(template_path))
14
+ includes = Liquid::LocalFileSystem.new(ResourceLocator.resource('_includes'), '%s.html')
15
+ Liquid::Template.file_system = includes
16
+ template = Liquid::Template.parse(to_render, error_mode: :strict)
17
+ template.render!(env, { strict_variables: true })
18
+ end
19
+
20
+ def render_and_write(template_path, target_file, env)
21
+ write_file(target_file, render_liquid(template_path, env))
22
+ end
23
+
24
+ def write_file(target_file, contents)
25
+ dir = File.dirname(target_file)
26
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
27
+
28
+ index = File.new(target_file, 'w')
29
+ index&.puts contents # may be nil when stubbing
30
+ logger&.info "Written #{target_file}"
31
+ ensure
32
+ index&.close
33
+ end
34
+
35
+ def copy_resource(dir, to_root)
36
+ src = ResourceLocator.resource(dir)
37
+ dest = "#{to_root}/#{dir}"
38
+ FileUtils.copy_entry(src, dest)
39
+ end
40
+ end
41
+
42
+ # Renders the index of a project diff report.
43
+ class LiquidProjectRenderer
44
+ include PmdTester
45
+ include ProjectHasher
46
+ include LiquidRenderer
47
+
48
+ def write_project_index(project, root)
49
+ liquid_env = {
50
+ 'diff' => report_diff_to_h(project.report_diff),
51
+ 'error_diffs' => errors_to_h(project),
52
+ 'configerror_diffs' => configerrors_to_h(project),
53
+ 'project_name' => project.name
54
+ }
55
+
56
+ # Renders index.html using liquid
57
+ write_file("#{root}/index.html", render_liquid('project_diff_report.html', liquid_env))
58
+ # generate array of violations in json
59
+ write_file("#{root}/project_data.js", dump_violations_json(project))
60
+ # copy original pmd reports
61
+ copy_file("#{root}/base_pmd_report.xml", project.report_diff.base_report.file)
62
+ copy_file("#{root}/patch_pmd_report.xml", project.report_diff.patch_report.file)
63
+ # render full pmd reports
64
+ write_file("#{root}/base_pmd_report.html",
65
+ render_liquid('project_pmd_report.html', pmd_report_liquid_env(project, BASE)))
66
+ write_file("#{root}/base_data.js", dump_violations_json(project, BASE))
67
+ write_file("#{root}/patch_pmd_report.html",
68
+ render_liquid('project_pmd_report.html', pmd_report_liquid_env(project, PATCH)))
69
+ write_file("#{root}/patch_data.js", dump_violations_json(project, PATCH))
70
+ end
71
+
72
+ def dump_violations_json(project, branch = 'diff')
73
+ violations_by_file = if branch == BASE
74
+ project.report_diff.base_report.violations_by_file.to_h
75
+ elsif branch == PATCH
76
+ project.report_diff.patch_report.violations_by_file.to_h
77
+ else
78
+ project.report_diff.violation_diffs_by_file
79
+ end
80
+
81
+ h = {
82
+ 'source_link_base' => project.webview_url,
83
+ 'source_link_template' => link_template(project),
84
+ **violations_to_hash(project, violations_by_file, branch == 'diff')
85
+ }
86
+
87
+ project_data = JSON.fast_generate(h, indent: ' ', object_nl: "\n", array_nl: "\n")
88
+ "let project = #{project_data}"
89
+ end
90
+
91
+ private
92
+
93
+ def copy_file(target_file, source_file)
94
+ if File.exist? source_file
95
+ FileUtils.cp(source_file, target_file)
96
+ logger&.info "Written #{target_file}"
97
+ else
98
+ logger&.warn "File #{source_file} not found"
99
+ end
100
+ end
101
+
102
+ def pmd_report_liquid_env(project, branch)
103
+ report = if branch == BASE
104
+ project.report_diff.base_report
105
+ else
106
+ project.report_diff.patch_report
107
+ end
108
+ {
109
+ 'project_name' => project.name,
110
+ 'branch' => branch,
111
+ 'report' => report_to_h(project, report)
112
+ }
113
+ end
114
+
115
+ def report_to_h(project, report)
116
+ {
117
+ 'violation_counts' => report.violations_by_file.total_size,
118
+ 'error_counts' => report.errors_by_file.total_size,
119
+ 'configerror_counts' => report.configerrors_by_rule.values.flatten.length,
120
+
121
+ 'execution_time' => PmdReportDetail.convert_seconds(report.exec_time),
122
+ 'timestamp' => report.timestamp,
123
+
124
+ 'rules' => report.rule_summaries,
125
+ 'errors' => report.errors_by_file.all_values.map { |e| error_to_hash(e, project) },
126
+ 'configerrors' => report.configerrors_by_rule.values.flatten.map { |e| configerror_to_hash(e) }
127
+ }
128
+ end
129
+ end
130
+ end