blob: 2fcb1b37950e7d4905d348877948a2a517cfbf3c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.plugins.pmd;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.pmd.model.PmdErrorDetail;
import org.apache.maven.plugins.pmd.model.PmdFile;
import org.apache.maven.plugins.pmd.model.Violation;
import org.apache.maven.plugins.pmd.model.io.xpp3.PmdXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/**
* Fails the build if there were any PMD violations in the source code.
*
* @version $Id$
* @since 2.0
*/
@Mojo(name = "check", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
@Execute(goal = "pmd")
public class PmdViolationCheckMojo extends AbstractPmdViolationCheckMojo<Violation> {
/**
* Default constructor. Initializes with the correct {@link ExcludeViolationsFromFile}.
*/
public PmdViolationCheckMojo() {
super(new ExcludeViolationsFromFile());
}
/**
* What priority level to fail the build on.
* PMD violations are assigned a priority from 1 (most severe) to 5 (least severe) according the
* the rule's priority.
* Violations at or less than this priority level are considered failures and will fail
* the build if {@code failOnViolation=true} and the count exceeds {@code maxAllowedViolations}.
* The other violations will be regarded as warnings and will be displayed in the build output
* if {@code verbose=true}.
* Setting a value of 5 will treat all violations as failures, which may cause the build to fail.
* Setting a value of 1 will treat all violations as warnings.
* Only values from 1 to 5 are valid.
*/
@Parameter(property = "pmd.failurePriority", defaultValue = "5", required = true)
private int failurePriority = 5;
/**
* Skip the PMD checks. Most useful on the command line via "-Dpmd.skip=true".
*/
@Parameter(property = "pmd.skip", defaultValue = "false")
private boolean skip;
/**
* {@inheritDoc}
*/
public void execute() throws MojoExecutionException, MojoFailureException {
if (skip) {
getLog().info("Skipping PMD execution");
return;
}
executeCheck("pmd.xml", "violation", "PMD violation", failurePriority);
}
/**
* {@inheritDoc}
*/
protected void printError(Violation item, String severity) {
StringBuilder buff = new StringBuilder(100);
buff.append("PMD ").append(severity).append(": ");
if (item.getViolationClass() != null) {
if (item.getViolationPackage() != null) {
buff.append(item.getViolationPackage());
buff.append(".");
}
buff.append(item.getViolationClass());
} else {
buff.append(item.getFileName());
}
buff.append(":");
buff.append(item.getBeginline());
buff.append(" Rule:").append(item.getRule());
buff.append(" Priority:").append(item.getPriority());
buff.append(" ").append(item.getText()).append(".");
this.getLog().info(buff.toString());
}
@Override
protected List<Violation> getErrorDetails(File pmdFile) throws XmlPullParserException, IOException {
try (InputStream in = new FileInputStream(pmdFile)) {
PmdXpp3Reader reader = new PmdXpp3Reader();
PmdErrorDetail details = reader.read(in, false);
List<Violation> violations = new ArrayList<>();
for (PmdFile file : details.getFiles()) {
String fullPath = file.getName();
for (Violation violation : file.getViolations()) {
violation.setFileName(getFilename(fullPath, violation.getViolationPackage()));
violations.add(violation);
}
}
return violations;
}
}
@Override
protected int getPriority(Violation errorDetail) {
return errorDetail.getPriority();
}
@Override
protected ViolationDetails<Violation> newViolationDetailsInstance() {
return new ViolationDetails<>();
}
private String getFilename(String fullpath, String pkg) {
int index = fullpath.lastIndexOf(File.separatorChar);
while (pkg != null && !pkg.isEmpty()) {
index = fullpath.substring(0, index).lastIndexOf(File.separatorChar);
int dot = pkg.indexOf('.');
if (dot < 0) {
break;
}
pkg = pkg.substring(dot + 1);
}
return fullpath.substring(index + 1);
}
}