* The defaults are: *
* The defaults are: *
* The built-in rule set paths are: *
Specifies the character set encoding of the source code files. The default is {@code UTF-8}.
* *The valid values are the standard character sets of {@link java.nio.charset.Charset Charset}.
*/ public PmdOperation encoding(String encoding) { this.encoding = encoding; return this; } /** * Performs the PMD code analysis operation. * * @throws Exception when an exception occurs during the execution */ @Override public void execute() throws Exception { if (project == null) { throw new IllegalArgumentException("ERROR: project required."); } var commandName = project.getCurrentCommandName(); performPmdAnalysis(commandName, initConfiguration(commandName)); } /** * Sets whether the build will continue on warnings. */ public PmdOperation failOnViolation(boolean failOnViolation) { this.failOnViolation = failOnViolation; return this; } /** * Forces a language to be used for all input files, irrespective of file names. */ public PmdOperation forceVersion(LanguageVersion languageVersion) { this.forcedLanguageVersion = languageVersion; return this; } /** * Sets the path to the file containing a list of files to ignore, one path per line. */ public PmdOperation ignoreFile(Path ignoreFile) { this.ignoreFile = ignoreFile; return this; } /** * Enables or disables incremental analysis. */ public PmdOperation incrementalAnalysis(boolean incrementalAnalysis) { this.incrementalAnalysis = incrementalAnalysis; return this; } /** * Creates a new initialized configuration. */ public PMDConfiguration initConfiguration(String commandName) { PMDConfiguration config = new PMDConfiguration(); if (cache == null && project != null && incrementalAnalysis) { config.setAnalysisCacheLocation( Paths.get(project.buildDirectory().getPath(), PMD_DIR, PMD_DIR + "-cache").toFile().getAbsolutePath()); } else if (cache != null) { config.setAnalysisCacheLocation(cache.toFile().getAbsolutePath()); } config.setDebug(debug); config.setFailOnViolation(failOnViolation); if (languageVersions != null) { config.setDefaultLanguageVersions(languageVersions); } if (forcedLanguageVersion != null) { config.setForceLanguageVersion(forcedLanguageVersion); } if (ignoreFile != null) { config.setIgnoreFilePath(ignoreFile); } config.setIgnoreIncrementalAnalysis(!incrementalAnalysis); if (inputPaths.isEmpty()) { throw new IllegalArgumentException(commandName + ": InputPaths required."); } else { config.setInputPathList(inputPaths); } if (inputUri != null) { config.setInputUri(inputUri); } config.setMinimumPriority(rulePriority); if (project != null) { config.setReportFile(Objects.requireNonNullElseGet(reportFile, () -> Paths.get(project.buildDirectory().getPath(), PMD_DIR, PMD_DIR + "-report." + reportFormat))); } else { config.setReportFile(reportFile); } config.addRelativizeRoots(relativizeRoots); config.setReportFormat(reportFormat); config.setRuleSets(ruleSets); config.setShowSuppressedViolations(showSuppressed); config.setSourceEncoding(encoding); config.setSuppressMarker(suppressedMarker); config.setThreads(threads); return config; } /** * Sets the to source files, or directories containing source files to analyze. * Previously set paths will be disregarded. * * @see #addInputPath(Path...) */ public PmdOperation inputPaths(Path... inputPath) { inputPaths.clear(); inputPaths.addAll(List.of(inputPath)); return this; } /** * Performs the PMD analysis with the given config. */ public int performPmdAnalysis(String commandName, PMDConfiguration config) throws RuntimeException { var pmd = PmdAnalysis.create(config); var report = pmd.performAnalysisAndCollectReport(); if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info(String.format("[%s] ruleSets%s", commandName, ruleSets)); } var numErrors = report.getViolations().size(); if (numErrors > 0) { var msg = String.format( "[%s] %d rule violations were found. See the report at: %s", commandName, numErrors, config.getReportFilePath().toUri()); for (var v : report.getViolations()) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.warning(String.format("[%s] %s:%d\n\t%s (%s)\n\t\t--> %s", commandName, Paths.get(v.getFilename()).toUri(), v.getBeginLine(), v.getRule().getName(), v.getRule().getExternalInfoUrl(), v.getDescription())); } } if (config.isFailOnViolation()) { throw new RuntimeException(msg); // NOPMD } else { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.warning(msg); } } } else { var rules = pmd.getRulesets(); if (rules.size() > 0) { int count = 0; for (var rule : rules) { count += rule.getRules().size(); } if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info(String.format("[%s] %d rules were checked.", commandName, count)); } } } return numErrors; } /** * Sets several paths to shorten paths that are output in the report. Previous relative paths will be disregarded. * * @see #addRelativizeRoot(Path...) */ public PmdOperation relativizeRoots(Path... relativeRoot) { this.relativizeRoots.clear(); this.relativizeRoots.addAll(List.of(relativeRoot)); return this; } /** * Sets the output format of the analysis report. The default is {@code text}. */ public PmdOperation reportFormat(String reportFormat) { this.reportFormat = reportFormat; return this; } /** * Sets the rule set path(s), disregarding any previously set paths. ** The built-in rule set paths are: *