Class: PmdTester::PmdReportBuilder

Inherits:
Object
  • Object
show all
Includes:
PmdTester
Defined in:
lib/pmdtester/builders/pmd_report_builder.rb

Overview

Building pmd xml reports according to a list of standard projects and branch of pmd source code

Constant Summary

Constants included from PmdTester

BASE, PATCH, PR_NUM_ENV_VAR, VERSION

Instance Method Summary collapse

Methods included from PmdTester

#logger, logger

Constructor Details

#initialize(projects, options, branch_config, branch_name) ⇒ PmdReportBuilder

Returns a new instance of PmdReportBuilder.



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 12

def initialize(projects, options, branch_config, branch_name)
  @projects = projects
  @local_git_repo = options.local_git_repo
  @threads = options.threads
  @error_recovery = options.error_recovery
  @branch_config = branch_config
  @pmd_branch_name = branch_name
  @pwd = Dir.getwd

  @pmd_branch_details = PmdBranchDetail.new(@pmd_branch_name)
  @project_builder = ProjectBuilder.new(@projects)
end

Instance Method Details

#buildObject

returns the branch details



156
157
158
159
160
161
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 156

def build
  @project_builder.clone_projects
  @project_builder.build_projects
  get_pmd_binary_file
  generate_pmd_reports
end

#build_pmd(into_dir:) ⇒ Object

builds pmd on currently checked out branch



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 53

def build_pmd(into_dir:)
  # in CI there might have been a build performed already. In that case
  # we reuse the build result, otherwise we build PMD freshly
  pmd_dist_target, binary_exists = find_pmd_dist_target
  if binary_exists
    # that's a warning, because we don't know, whether this build really
    # belongs to the current branch or whether it's from a previous branch.
    # In CI, that's not a problem, because the workspace is always fresh.
    logger.warn "#{@pmd_branch_name}: Reusing already existing #{pmd_dist_target}"
  else
    build_pmd_with_maven
    pmd_dist_target, binary_exists = find_pmd_dist_target
    unless binary_exists
      logger.error "#{@pmd_branch_name}: Dist zip not found at #{pmd_dist_target}!"
      raise "No Dist zip found at #{pmd_dist_target}"
    end
  end

  logger.info "#{@pmd_branch_name}: Extracting the zip"
  Cmd.execute_successfully("unzip -qo #{pmd_dist_target} -d pmd-dist/target/exploded")
  Cmd.execute_successfully("mv pmd-dist/target/exploded/pmd-bin-#{@pmd_version} #{into_dir}")
end

#determine_pmd_versionObject



76
77
78
79
80
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 76

def determine_pmd_version
  version_cmd = "./mvnw -q -Dexec.executable=\"echo\" -Dexec.args='${project.version}' " \
                '--non-recursive org.codehaus.mojo:exec-maven-plugin:1.5.0:exec'
  Cmd.execute_successfully(version_cmd)
end

#generate_config_for(project) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 116

def generate_config_for(project)
  logger.debug "Generating ruleset with excludes from #{@branch_config}"
  doc = Nokogiri::XML(File.read(@branch_config))
  ruleset = doc.at_css('ruleset')
  ruleset.add_child("\n")
  project.exclude_patterns.each do |exclude_pattern|
    ruleset.add_child("    <exclude-pattern>#{exclude_pattern}</exclude-pattern>\n")
  end

  File.open(project.get_config_path(@pmd_branch_name), 'w') do |x|
    x << doc.to_s
  end

  logger.debug "Created file #{project.get_config_path(@pmd_branch_name)}"
end

#generate_pmd_report(project) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 92

def generate_pmd_report(project)
  error_recovery_options = @error_recovery ? 'PMD_JAVA_OPTS="-Dpmd.error_recovery -ea" ' : ''
  fail_on_violation = create_failonviolation_option
  auxclasspath_option = create_auxclasspath_option(project)
  pmd_cmd = "#{error_recovery_options}" \
            "#{determine_run_path} -d #{project.local_source_path} -f xml " \
            "-R #{project.get_config_path(@pmd_branch_name)} " \
            "-r #{project.get_pmd_report_path(@pmd_branch_name)} " \
            "#{fail_on_violation} -t #{@threads} " \
            "#{auxclasspath_option}" \
            "#{pmd7? ? ' --no-progress' : ''}"
  start_time = Time.now
  exit_code = nil
  if File.exist?(project.get_pmd_report_path(@pmd_branch_name))
    logger.warn "#{@pmd_branch_name}: Skipping PMD run - report " \
                "#{project.get_pmd_report_path(@pmd_branch_name)} already exists"
  else
    status = Cmd.execute(pmd_cmd, project.get_project_target_dir(@pmd_branch_name))
    exit_code = status.exitstatus
  end
  end_time = Time.now
  [end_time - start_time, end_time, exit_code]
end

#generate_pmd_reportsObject



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 132

def generate_pmd_reports
  logger.info "Generating PMD report started -- branch #{@pmd_branch_name}"

  sum_time = 0
  @projects.each do |project|
    progress_logger = SimpleProgressLogger.new("generating #{project.name}'s PMD report")
    progress_logger.start
    generate_config_for(project)
    execution_time, end_time, exit_code = generate_pmd_report(project)
    progress_logger.stop
    sum_time += execution_time

    PmdReportDetail.create(execution_time: execution_time, timestamp: end_time,
                           exit_code: exit_code, report_info_path: project.get_report_info_path(@pmd_branch_name))
    logger.info "#{project.name}'s PMD report was generated successfully (exit code: #{exit_code})"
  end

  @pmd_branch_details.execution_time = sum_time
  @pmd_branch_details.save
  FileUtils.cp(@branch_config, @pmd_branch_details.target_branch_config_path)
  @pmd_branch_details
end

#get_last_commit_messageObject



87
88
89
90
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 87

def get_last_commit_message
  get_last_commit_message_cmd = 'git log -1 --pretty=%B'
  Cmd.execute_successfully(get_last_commit_message_cmd)
end

#get_last_commit_shaObject



82
83
84
85
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 82

def get_last_commit_sha
  get_last_commit_sha_cmd = 'git rev-parse HEAD^{commit}'
  Cmd.execute_successfully(get_last_commit_sha_cmd)
end

#get_pmd_binary_fileObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/pmdtester/builders/pmd_report_builder.rb', line 25

def get_pmd_binary_file
  logger.info "#{@pmd_branch_name}: Start packaging PMD"
  Dir.chdir(@local_git_repo) do
    build_branch_sha = Cmd.execute_successfully("git rev-parse #{@pmd_branch_name}^{commit}")

    checkout_build_branch # needs a clean working tree, otherwise fails

    raise "Wrong branch #{get_last_commit_sha}" unless build_branch_sha == get_last_commit_sha

    distro_path = saved_distro_path(build_branch_sha)
    logger.debug "#{@pmd_branch_name}: PMD Version is #{@pmd_version} " \
                 "(sha=#{build_branch_sha})"
    logger.debug "#{@pmd_branch_name}: distro_path=#{distro_path}"
    if File.directory?(distro_path)
      logger.info "#{@pmd_branch_name}: Skipping packaging - saved version exists " \
                  " in #{distro_path}"
    else
      build_pmd(into_dir: distro_path)
    end

    # we're still on the build branch
    @pmd_branch_details.branch_last_sha = build_branch_sha
    @pmd_branch_details.branch_last_message = get_last_commit_message
  end
  logger.info "#{@pmd_branch_name}: Packaging PMD completed"
end