pmdtester 1.0.1 → 1.1.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/build.sh +91 -0
  3. data/.ci/files/env.gpg +1 -0
  4. data/.github/workflows/build.yml +39 -0
  5. data/.gitignore +9 -0
  6. data/.hoerc +1 -1
  7. data/.rubocop.yml +6 -2
  8. data/.ruby-version +1 -0
  9. data/History.md +40 -0
  10. data/Manifest.txt +24 -9
  11. data/README.rdoc +45 -30
  12. data/Rakefile +5 -3
  13. data/config/all-java.xml +1 -1
  14. data/config/design.xml +1 -1
  15. data/config/projectlist_1_0_0.xsd +2 -1
  16. data/config/projectlist_1_1_0.xsd +31 -0
  17. data/lib/pmdtester.rb +8 -7
  18. data/lib/pmdtester/builders/liquid_renderer.rb +73 -0
  19. data/lib/pmdtester/builders/pmd_report_builder.rb +102 -78
  20. data/lib/pmdtester/builders/project_builder.rb +100 -0
  21. data/lib/pmdtester/builders/project_hasher.rb +126 -0
  22. data/lib/pmdtester/builders/rule_set_builder.rb +92 -47
  23. data/lib/pmdtester/builders/simple_progress_logger.rb +4 -4
  24. data/lib/pmdtester/builders/summary_report_builder.rb +62 -131
  25. data/lib/pmdtester/collection_by_file.rb +55 -0
  26. data/lib/pmdtester/parsers/options.rb +19 -0
  27. data/lib/pmdtester/parsers/pmd_report_document.rb +74 -29
  28. data/lib/pmdtester/parsers/projects_parser.rb +2 -4
  29. data/lib/pmdtester/pmd_branch_detail.rb +29 -19
  30. data/lib/pmdtester/pmd_configerror.rb +23 -24
  31. data/lib/pmdtester/pmd_error.rb +34 -34
  32. data/lib/pmdtester/pmd_report_detail.rb +9 -12
  33. data/lib/pmdtester/pmd_tester_utils.rb +55 -0
  34. data/lib/pmdtester/pmd_violation.rb +66 -28
  35. data/lib/pmdtester/project.rb +21 -48
  36. data/lib/pmdtester/report_diff.rb +179 -111
  37. data/lib/pmdtester/resource_locator.rb +4 -0
  38. data/lib/pmdtester/runner.rb +66 -64
  39. data/pmdtester.gemspec +27 -36
  40. data/resources/_includes/diff_pill_row.html +6 -0
  41. data/resources/css/bootstrap.min.css +7 -0
  42. data/resources/css/datatables.min.css +36 -0
  43. data/resources/css/pmd-tester.css +131 -0
  44. data/resources/js/bootstrap.min.js +7 -0
  45. data/resources/js/code-snippets.js +66 -0
  46. data/resources/js/datatables.min.js +726 -0
  47. data/resources/js/jquery-3.2.1.slim.min.js +4 -0
  48. data/resources/js/jquery.min.js +2 -0
  49. data/resources/js/popper.min.js +5 -0
  50. data/resources/js/project-report.js +136 -0
  51. data/resources/project_diff_report.html +205 -0
  52. data/resources/project_index.html +102 -0
  53. metadata +64 -20
  54. data/.travis.yml +0 -40
  55. data/lib/pmdtester/builders/diff_builder.rb +0 -31
  56. data/lib/pmdtester/builders/diff_report/configerrors.rb +0 -50
  57. data/lib/pmdtester/builders/diff_report/errors.rb +0 -71
  58. data/lib/pmdtester/builders/diff_report/violations.rb +0 -77
  59. data/lib/pmdtester/builders/diff_report_builder.rb +0 -99
  60. data/lib/pmdtester/builders/html_report_builder.rb +0 -56
  61. data/resources/css/maven-base.css +0 -155
  62. data/resources/css/maven-theme.css +0 -171
@@ -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>
@@ -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.1'
35
+ VERSION = '1.1.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,73 @@
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
+ end
61
+
62
+ def dump_violations_json(project)
63
+ h = {
64
+ 'source_link_base' => project.webview_url,
65
+ 'source_link_template' => link_template(project),
66
+ **violations_to_hash(project)
67
+ }
68
+
69
+ project_data = JSON.fast_generate(h)
70
+ "let project = #{project_data}"
71
+ end
72
+ end
73
+ end
@@ -8,92 +8,70 @@ module PmdTester
8
8
  # projects and branch of pmd source code
9
9
  class PmdReportBuilder
10
10
  include PmdTester
11
- def initialize(branch_config, projects, local_git_repo, pmd_branch_name, threads = 1)
12
- @branch_config = branch_config
11
+
12
+ def initialize(projects, options, branch_config, branch_name)
13
13
  @projects = projects
14
- @local_git_repo = local_git_repo
15
- @pmd_branch_name = pmd_branch_name
16
- @threads = threads
14
+ @local_git_repo = options.local_git_repo
15
+ @threads = options.threads
16
+ @error_recovery = options.error_recovery
17
+ @branch_config = branch_config
18
+ @pmd_branch_name = branch_name
17
19
  @pwd = Dir.getwd
18
20
 
19
- @pmd_branch_details = PmdBranchDetail.new(pmd_branch_name)
20
- end
21
-
22
- def execute_reset_cmd(type, tag)
23
- case type
24
- when 'git'
25
- reset_cmd = "git reset --hard #{tag}"
26
- when 'hg'
27
- reset_cmd = "hg up #{tag}"
28
- end
29
-
30
- Cmd.execute(reset_cmd)
31
- end
32
-
33
- def clone_projects
34
- logger.info 'Cloning projects started'
35
-
36
- @projects.each do |project|
37
- logger.info "Start cloning #{project.name} repository"
38
- path = project.local_source_path
39
- clone_cmd = "#{project.type} clone #{project.connection} #{path}"
40
- if File.exist?(path)
41
- logger.warn "Skipping clone, project path #{path} already exists"
42
- else
43
- Cmd.execute(clone_cmd)
44
- end
45
-
46
- Dir.chdir(path) do
47
- execute_reset_cmd(project.type, project.tag)
48
- end
49
- logger.info "Cloning #{project.name} completed"
50
- end
51
-
52
- logger.info 'Cloning projects completed'
21
+ @pmd_branch_details = PmdBranchDetail.new(@pmd_branch_name)
22
+ @project_builder = ProjectBuilder.new(@projects)
53
23
  end
54
24
 
55
25
  def get_pmd_binary_file
56
26
  logger.info "#{@pmd_branch_name}: Start packaging PMD"
57
27
  Dir.chdir(@local_git_repo) do
58
- current_head_sha = Cmd.execute('git rev-parse HEAD')
59
- current_branch_sha = Cmd.execute("git rev-parse #{@pmd_branch_name}")
28
+ build_branch_sha = Cmd.execute("git rev-parse #{@pmd_branch_name}^{commit}")
29
+
30
+ checkout_build_branch # needs a clean working tree, otherwise fails
60
31
 
61
- @pmd_version = determine_pmd_version
32
+ raise "Wrong branch #{get_last_commit_sha}" unless build_branch_sha == get_last_commit_sha
62
33
 
63
- # in case we are already on the correct branch
64
- # and a binary zip already exists...
65
- if current_head_sha == current_branch_sha &&
66
- File.exist?("pmd-dist/target/pmd-bin-#{@pmd_version}.zip")
67
- logger.warn "#{@pmd_branch_name}: Skipping packaging - zip for " \
68
- "#{@pmd_version} already exists"
34
+ logger.debug "#{@pmd_branch_name}: PMD Version is #{@pmd_version} " \
35
+ "(sha=#{build_branch_sha})"
36
+ distro_path = saved_distro_path(build_branch_sha)
37
+ if File.directory?(distro_path)
38
+ logger.info "#{@pmd_branch_name}: Skipping packaging - saved version exists " \
39
+ " in #{distro_path}"
69
40
  else
70
- build_pmd
41
+ build_pmd(into_dir: distro_path)
71
42
  end
72
43
 
73
- @pmd_branch_details.branch_last_sha = get_last_commit_sha
44
+ # we're still on the build branch
45
+ @pmd_branch_details.branch_last_sha = build_branch_sha
74
46
  @pmd_branch_details.branch_last_message = get_last_commit_message
75
-
76
- logger.info "#{@pmd_branch_name}: Extracting the zip"
77
- unzip_cmd = "unzip -qo pmd-dist/target/pmd-bin-#{@pmd_version}.zip -d #{@pwd}/target"
78
- Cmd.execute(unzip_cmd)
79
47
  end
80
48
  logger.info "#{@pmd_branch_name}: Packaging PMD completed"
81
49
  end
82
50
 
83
- def build_pmd
84
- logger.info "#{@pmd_branch_name}: Checking out the branch"
85
- checkout_cmd = "git checkout #{@pmd_branch_name}"
86
- Cmd.execute(checkout_cmd)
87
-
88
- # determine the version again - it might be different in the other branch
89
- @pmd_version = determine_pmd_version
51
+ # builds pmd on currently checked out branch
52
+ def build_pmd(into_dir:)
53
+ # in CI there might have been a build performed already. In that case
54
+ # we reuse the build result, otherwise we build PMD freshly
55
+ pmd_dist_target = "pmd-dist/target/pmd-bin-#{@pmd_version}.zip"
56
+ if File.exist?("#{@local_git_repo}/#{pmd_dist_target}")
57
+ # that's a warning, because we don't know, whether this build really
58
+ # belongs to the current branch or whether it's from a previous branch.
59
+ # In CI, that's not a problem, because the workspace is always fresh.
60
+ logger.warn "#{@pmd_branch_name}: Reusing already existing #{pmd_dist_target}"
61
+ else
62
+ logger.info "#{@pmd_branch_name}: Building PMD #{@pmd_version}..."
63
+ package_cmd = './mvnw clean package' \
64
+ ' -Dmaven.test.skip=true' \
65
+ ' -Dmaven.javadoc.skip=true' \
66
+ ' -Dmaven.source.skip=true' \
67
+ ' -Dcheckstyle.skip=true' \
68
+ ' -T1C'
69
+ Cmd.execute(package_cmd)
70
+ end
90
71
 
91
- logger.info "#{@pmd_branch_name}: Building PMD #{@pmd_version}..."
92
- package_cmd = './mvnw clean package' \
93
- ' -Dmaven.test.skip=true' \
94
- ' -Dmaven.javadoc.skip=true' \
95
- ' -Dmaven.source.skip=true'
96
- Cmd.execute(package_cmd)
72
+ logger.info "#{@pmd_branch_name}: Extracting the zip"
73
+ Cmd.execute("unzip -qo #{pmd_dist_target} -d pmd-dist/target/exploded")
74
+ Cmd.execute("mv pmd-dist/target/exploded/pmd-bin-#{@pmd_version} #{into_dir}")
97
75
  end
98
76
 
99
77
  def determine_pmd_version
@@ -103,7 +81,7 @@ module PmdTester
103
81
  end
104
82
 
105
83
  def get_last_commit_sha
106
- get_last_commit_sha_cmd = 'git rev-parse HEAD'
84
+ get_last_commit_sha_cmd = 'git rev-parse HEAD^{commit}'
107
85
  Cmd.execute(get_last_commit_sha_cmd)
108
86
  end
109
87
 
@@ -113,27 +91,39 @@ module PmdTester
113
91
  end
114
92
 
115
93
  def generate_pmd_report(project)
116
- run_path = "target/pmd-bin-#{@pmd_version}/bin/run.sh"
117
- pmd_cmd = "#{run_path} pmd -d #{project.local_source_path} -f xml " \
94
+ error_recovery_options = @error_recovery ? 'PMD_JAVA_OPTS="-Dpmd.error_recovery -ea" ' : ''
95
+ run_path = "#{saved_distro_path(@pmd_branch_details.branch_last_sha)}/bin/run.sh"
96
+ pmd_cmd = "#{error_recovery_options}" \
97
+ "#{run_path} pmd -d #{project.local_source_path} -f xml " \
118
98
  "-R #{project.get_config_path(@pmd_branch_name)} " \
119
99
  "-r #{project.get_pmd_report_path(@pmd_branch_name)} " \
120
- "-failOnViolation false -t #{@threads}"
100
+ "-failOnViolation false -t #{@threads} " \
101
+ "#{project.auxclasspath}"
121
102
  start_time = Time.now
122
- Cmd.execute(pmd_cmd)
103
+ if File.exist?(project.get_pmd_report_path(@pmd_branch_name))
104
+ logger.warn "#{@pmd_branch_name}: Skipping PMD run - report " \
105
+ "#{project.get_pmd_report_path(@pmd_branch_name)} already exists"
106
+ else
107
+ Cmd.execute(pmd_cmd)
108
+ end
123
109
  end_time = Time.now
124
110
  [end_time - start_time, end_time]
125
111
  end
126
112
 
127
113
  def generate_config_for(project)
114
+ logger.debug "Generating ruleset with excludes from #{@branch_config}"
128
115
  doc = Nokogiri::XML(File.read(@branch_config))
129
116
  ruleset = doc.at_css('ruleset')
117
+ ruleset.add_child("\n")
130
118
  project.exclude_pattern.each do |exclude_pattern|
131
- ruleset.add_child("<exclude-pattern>#{exclude_pattern}</exclude-pattern>")
119
+ ruleset.add_child(" <exclude-pattern>#{exclude_pattern}</exclude-pattern>\n")
132
120
  end
133
121
 
134
122
  File.open(project.get_config_path(@pmd_branch_name), 'w') do |x|
135
123
  x << doc.to_s
136
124
  end
125
+
126
+ logger.debug "Created file #{project.get_config_path(@pmd_branch_name)}"
137
127
  end
138
128
 
139
129
  def generate_pmd_reports
@@ -141,16 +131,14 @@ module PmdTester
141
131
 
142
132
  sum_time = 0
143
133
  @projects.each do |project|
144
- progress_logger = SimpleProgressLogger.new(project.name)
134
+ progress_logger = SimpleProgressLogger.new("generating #{project.name}'s PMD report")
145
135
  progress_logger.start
146
136
  generate_config_for(project)
147
137
  execution_time, end_time = generate_pmd_report(project)
148
138
  progress_logger.stop
149
139
  sum_time += execution_time
150
140
 
151
- report_details = PmdReportDetail.new
152
- report_details.execution_time = execution_time
153
- report_details.timestamp = end_time
141
+ report_details = PmdReportDetail.new(execution_time: execution_time, timestamp: end_time)
154
142
  report_details.save(project.get_report_info_path(@pmd_branch_name))
155
143
  logger.info "#{project.name}'s PMD report was generated successfully"
156
144
  end
@@ -161,10 +149,46 @@ module PmdTester
161
149
  @pmd_branch_details
162
150
  end
163
151
 
152
+ # returns the branch details
164
153
  def build
165
- clone_projects
154
+ @project_builder.clone_projects
155
+ @project_builder.build_projects
166
156
  get_pmd_binary_file
167
157
  generate_pmd_reports
168
158
  end
159
+
160
+ private
161
+
162
+ def checkout_build_branch
163
+ logger.info "#{@pmd_branch_name}: Checking out the branch"
164
+ # note that this would fail if the tree is dirty
165
+ Cmd.execute("git checkout #{@pmd_branch_name}")
166
+
167
+ # determine the version
168
+ @pmd_version = determine_pmd_version
169
+
170
+ return unless wd_has_dirty_git_changes
171
+
172
+ # working dir is dirty....
173
+ # we don't allow this because we need the SHA to address the zip file
174
+ logger.error "#{@pmd_branch_name}: Won\'t build without a clean working tree, " \
175
+ 'commit your changes'
176
+ end
177
+
178
+ def work_dir
179
+ "#{@pwd}/target"
180
+ end
181
+
182
+ # path to the unzipped distribution
183
+ # e.g. <cwd>/pmd-bin-<version>-<branch>-<sha>
184
+ def saved_distro_path(build_sha)
185
+ "#{work_dir}/pmd-bin-#{@pmd_version}" \
186
+ "-#{PmdBranchDetail.branch_filename(@pmd_branch_name)}" \
187
+ "-#{build_sha}"
188
+ end
189
+
190
+ def wd_has_dirty_git_changes
191
+ !Cmd.execute('git status --porcelain').empty?
192
+ end
169
193
  end
170
194
  end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'tempfile'
5
+
6
+ module PmdTester
7
+ # Clones and builds the projects, that are configured in the project-list.xml
8
+ class ProjectBuilder
9
+ include PmdTester
10
+
11
+ def initialize(projects)
12
+ @projects = projects
13
+ end
14
+
15
+ def clone_projects
16
+ logger.info 'Cloning projects started'
17
+
18
+ @projects.each do |project|
19
+ logger.info "Start cloning #{project.name} repository"
20
+ path = project.local_source_path
21
+ clone_cmd = "#{project.type} clone #{project.connection} #{path}"
22
+ if File.exist?(path)
23
+ logger.warn "Skipping clone, project path #{path} already exists"
24
+ else
25
+ Cmd.execute(clone_cmd)
26
+ end
27
+
28
+ Dir.chdir(path) do
29
+ execute_reset_cmd(project.type, project.tag)
30
+ end
31
+ logger.info "Cloning #{project.name} completed"
32
+ end
33
+
34
+ logger.info 'Cloning projects completed'
35
+ end
36
+
37
+ def build_projects
38
+ logger.info 'Building projects started'
39
+
40
+ @projects.each do |project|
41
+ path = project.local_source_path
42
+ Dir.chdir(path) do
43
+ progress_logger = SimpleProgressLogger.new("building #{project.name} in #{path}")
44
+ progress_logger.start
45
+ prepare_project(project)
46
+ progress_logger.stop
47
+ end
48
+ logger.info "Building #{project.name} completed"
49
+ end
50
+
51
+ logger.info 'Building projects completed'
52
+ end
53
+
54
+ private
55
+
56
+ def prepare_project(project)
57
+ # Note: current working directory is the project directory,
58
+ # where the source code has been cloned to
59
+ if project.build_command
60
+ logger.debug "Executing build-command: #{project.build_command}"
61
+ run_as_script(Dir.getwd, project.build_command)
62
+ end
63
+ if project.auxclasspath_command
64
+ logger.debug "Executing auxclasspath-command: #{project.auxclasspath_command}"
65
+ auxclasspath = run_as_script(Dir.getwd, project.auxclasspath_command)
66
+ project.auxclasspath = "-auxclasspath #{auxclasspath}"
67
+ else
68
+ project.auxclasspath = ''
69
+ end
70
+ end
71
+
72
+ def run_as_script(path, command)
73
+ script = Tempfile.new(['pmd-regression-', '.sh'], path)
74
+ logger.debug "Creating script #{script.path}"
75
+ begin
76
+ script.write(command)
77
+ script.close
78
+ shell = 'sh -xe'
79
+ if command.start_with?('#!')
80
+ shell = command.lines[0].chomp[2..] # remove leading "#!"
81
+ end
82
+ stdout = Cmd.execute("#{shell} #{script.path}")
83
+ ensure
84
+ script.unlink
85
+ end
86
+ stdout
87
+ end
88
+
89
+ def execute_reset_cmd(type, tag)
90
+ case type
91
+ when 'git'
92
+ reset_cmd = "git checkout #{tag}; git reset --hard #{tag}"
93
+ when 'hg'
94
+ reset_cmd = "hg up #{tag}"
95
+ end
96
+
97
+ Cmd.execute(reset_cmd)
98
+ end
99
+ end
100
+ end