Merge branch 'master' into pr-5087

This commit is contained in:
Andreas Dangel
2024-07-11 09:49:04 +02:00
281 changed files with 6773 additions and 8798 deletions

View File

@ -7591,6 +7591,7 @@
"bug"
]
},
{
"login": "pablogomez2197",
"name": "pablogomez2197",
"avatar_url": "https://avatars.githubusercontent.com/u/110610165?v=4",
@ -7598,6 +7599,61 @@
"contributions": [
"bug"
]
},
{
"login": "stephen-carter-at-sf",
"name": "Stephen Carter",
"avatar_url": "https://avatars.githubusercontent.com/u/123964848?v=4",
"profile": "https://github.com/stephen-carter-at-sf",
"contributions": [
"bug"
]
},
{
"login": "Meijuh",
"name": "Jeroen Meijer",
"avatar_url": "https://avatars.githubusercontent.com/u/1567680?v=4",
"profile": "http://jmeijer.nl/",
"contributions": [
"bug"
]
},
{
"login": "codefriar",
"name": "Kevin Poorman",
"avatar_url": "https://avatars.githubusercontent.com/u/642589?v=4",
"profile": "http://www.codefriar.com/",
"contributions": [
"bug"
]
},
{
"login": "szymanp23",
"name": "szymanp23",
"avatar_url": "https://avatars.githubusercontent.com/u/4140681?v=4",
"profile": "https://github.com/szymanp23",
"contributions": [
"bug",
"code"
]
},
{
"login": "johnzhao9",
"name": "johnzhao9",
"avatar_url": "https://avatars.githubusercontent.com/u/13734035?v=4",
"profile": "https://github.com/johnzhao9",
"contributions": [
"bug"
]
},
{
"login": "duursma",
"name": "duursma",
"avatar_url": "https://avatars.githubusercontent.com/u/9378973?v=4",
"profile": "https://github.com/duursma",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

View File

@ -83,6 +83,16 @@ function build() {
./mvnw clean verify -Dskip-cli-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}"
else
# b) only pmd-cli and pmd-dist
#
# In the first stage build (without pmd-cli and pmd-dist), cyclonedx:makeAggregateBom tries to
# fetch the jars of the to-be-released modules, which don't exist yet. This is recorded in *.lastUpdated
# files in the local repo and might end up in the cache, that is used for this 2nd stage build.
# Trying to delete the files now, if they exist.
# Alternatively, we could run maven with flag "-U" to force update all dependencies...
pmd_ci_log_info "Cleanup local maven repo..."
find ~/.m2/repository -wholename "*/net/sourceforge/pmd/*/${PMD_CI_MAVEN_PROJECT_VERSION}/*.lastUpdated" | xargs rm -v
pmd_ci_log_info "Cleanup local maven repo finished."
./mvnw clean verify -pl pmd-cli,pmd-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}"
fi
else

View File

@ -48,8 +48,6 @@ jobs:
~/.cache
~/work/pmd/target/repositories
vendor/bundle
# avoid caching missed dependencies
!~/.m2/repository/**/*.lastUpdated
key: v3-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
v3-${{ runner.os }}-

Binary file not shown.

View File

@ -14,5 +14,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip

View File

@ -108,12 +108,12 @@ if [ "${BUILD_TOOLS_VERSION}" != "${BUILD_TOOLS_VERSION_RELEASE}" ]; then
exit 1
fi
echo "* Update date info in **docs/_config.yml**."
echo " date: $(date -u +%d-%B-%Y)"
echo
echo "* Update version info in **docs/_config.yml**."
echo " remove the SNAPSHOT from site.pmd.version"
echo
echo "* Update date info in **docs/_config.yml**."
echo " date: $(date -u +%Y-%m-%d)"
echo
echo "* Update **pmd-apex/src/main/resources/rulesets/apex/quickstart.xml** and"
echo " **pmd-java/src/main/resources/rulesets/java/quickstart.xml** with the new rules."
echo
@ -204,7 +204,7 @@ echo
echo "Tag has been pushed.... now check github actions: <https://github.com/pmd/pmd/actions>"
echo
echo "Now wait, until first stage of the release is finished successfully..."
echo "You don't need to wait until artifacts are in maven central, just the github action must be successful."
echo "You don't need to wait until artifacts are in maven central, just the GitHub Action must be successful."
echo
echo "If it is failing, you can fix the code/scripts and force push the tag via"
echo
@ -214,7 +214,7 @@ echo " git push origin tag \"pmd_releases/${RELEASE_VERSION}\" --force"
echo
echo "However: This is only possible, if the artefacts have not been pushed to maven central yet..."
echo
echo "Press enter to continue..."
echo "Press enter to continue, once the GitHub Action finished successfully..."
read -r
echo
@ -344,8 +344,8 @@ tweet="${tweet//#/%23}"
tweet="${tweet//\//%2F}"
tweet="${tweet//$'\r'/}"
tweet="${tweet//$'\n'/%0A}"
echo "* Tweet about this release on https://twitter.com/pmd_analyzer:"
echo " <https://twitter.com/intent/tweet?text=$tweet>"
echo "* Tweet about this release on https://x.com/pmd_analyzer:"
echo " <https://x.com/intent/post?text=$tweet>"
echo "* Post this also into <https://matrix.to/#/#pmd_pmd:gitter.im>:"
echo " PMD ${RELEASE_VERSION} released: https://github.com/pmd/pmd/releases/tag/pmd_releases/${RELEASE_VERSION} #PMD"
echo

View File

@ -1,9 +1,9 @@
repository: pmd/pmd
pmd:
version: 7.3.0-SNAPSHOT
previous_version: 7.2.0
date: 2024-06-28
version: 7.4.0-SNAPSHOT
previous_version: 7.3.0
date: 2024-07-26
# release types: major, minor, bugfix
release_type: minor

View File

@ -3,7 +3,7 @@ title: How to add a new CPD language
short_title: Adding a new CPD language
tags: [devdocs, extending]
summary: How to add a new language module with CPD support.
last_updated: April 2023 (7.0.0)
last_updated: June 2024 (7.3.0)
permalink: pmd_devdocs_major_adding_new_cpd_language.html
author: Matías Fraga, Clément Fournier
---
@ -45,8 +45,15 @@ Use the following guide to set up a new language module that supports CPD.
}
```
- If your language is case-insensitive, then you might want to overwrite `getImage(AntlrToken)`. There you can
change each token e.g. into uppercase, so that CPD sees the same strings and can find duplicates even when
the casing differs. See {% jdoc tsql::lang.tsql.cpd.TSqlCpdLexer %} for an example. You will also need a
"CaseChangingCharStream", so that antlr itself is case-insensitive.
- For JavaCC grammars, place your grammar in `etc/grammar` and edit the `pom.xml` like the [Python implementation](https://github.com/pmd/pmd/blob/master/pmd-python/pom.xml) does.
You can then subclass {% jdoc core::cpd.impl.JavaccCpdLexer %} instead of AntlrCpdLexer.
- If your JavaCC based language is case-insensitive (option `IGNORE_CASE=true`), then you need to implement
{%jdoc core::lang.ast.impl.javacc.JavaccTokenDocument.TokenDocumentBehavior %}, which can change each token
e.g. into uppercase. See {%jdoc plsql::lang.plsql.ast.PLSQLParser %} for an example.
- For any other scenario just implement the interface however you can. Look at the Scala or Apex module for existing implementations.
3. Create a {% jdoc core::lang.Language %} implementation, and make it implement {% jdoc core::cpd.CpdCapableLanguage %}.

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ tags: [userdocs]
keywords: [command, line, options, help, formats, renderers]
permalink: pmd_userdocs_cli_reference.html
author: Tom Copeland <tom@infoether.com>, Xavier Le Vourch <xlv@users.sourceforge.net>, Juan Martín Sotuyo Dodero <juansotuyo@gmail.com>
last_updated: June 2024 (7.3.0)
---
@ -19,7 +20,6 @@ The tool comes with a rather extensive help text, simply running with `--help`!
<th>Default value</th>
<th>Applies to</th>
</tr>
{% include custom/cli_option_row.html options="--rulesets,-R"
option_arg="refs"
description="Path to a ruleset xml file. The path may reference
@ -55,7 +55,6 @@ The tool comes with a rather extensive help text, simply running with `--help`!
(\":\" on Linux, \";\" on Windows) is used to separate the entries.
Alternatively, a single `file:` URL
to a text file containing path elements on consecutive lines can be specified.
<p>See also [Providing the auxiliary classpath](pmd_languages_java.html#providing-the-auxiliary-classpath).</p>"
languages="Java"
%}
@ -80,10 +79,15 @@ The tool comes with a rather extensive help text, simply running with `--help`!
The valid values are the standard character sets of `java.nio.charset.Charset`."
default="UTF-8"
%}
{% include custom/cli_option_row.html options="--[no-]fail-on-error"
description="Specifies whether PMD exits with non-zero status if recoverable errors occurred.
By default PMD exits with status 5 if recoverable errors occurred (whether there are violations or not).
Disable this option with `--no-fail-on-error` to exit with 0 instead. In any case, a report with the found violations will be written."
%}
{% include custom/cli_option_row.html options="--[no-]fail-on-violation"
description="Specifies whether PMD exits with non-zero status if violations are found.
By default PMD exits with status 4 if violations are found.
Disable this feature with `--no-fail-on-violation` to exit with 0 instead and just output the report."
Disable this feature with `--no-fail-on-violation` to exit with 0 instead. In any case a report with the found violations will be written."
%}
{% include custom/cli_option_row.html options="--file-list"
option_arg="filepath"
@ -98,9 +102,7 @@ The tool comes with a rather extensive help text, simply running with `--help`!
by extension is disabled and PMD tries to parse all files with
the given language `&lt;lang&gt;`. Parsing errors are ignored and unparsable files
are skipped.
<p>Use `--use-version` to specify the language version to use, if it is not the default.</p>
<p>This option allows to use the xml language for files, that don't
use xml as extension. See [example](#analyze-other-xml-formats) below.</p>"
%}
@ -125,7 +127,7 @@ The tool comes with a rather extensive help text, simply running with `--help`!
{% include custom/cli_option_row.html options="--minimum-priority"
option_arg="priority"
description="Rule priority threshold; rules with lower priority than configured here won't be used.
Valid values (case insensitive): High, Medium_High, Medium, Medium_Low, Low.
Valid values (case-insensitive): High, Medium_High, Medium, Medium_Low, Low.
An integer between 1 (High) and 5 (Low) is also supported. See [Configuring rules](pmd_userdocs_configuring_rules.html)
on how to override priorities in custom rulesets."
default="Low"
@ -141,7 +143,7 @@ The tool comes with a rather extensive help text, simply running with `--help`!
description="Enables / disable progress bar indicator of live analysis progress. This ie enabled by default."
%}
{% include custom/cli_option_row.html options="--property,-P"
option_arg="name>=<value"
option_arg="name&gt;=&lt;value"
description="Specifies a property for the report renderer. The option can be specified several times.
<p>Using `--help` will provide a complete list of supported properties for each report format</p>"
%}
@ -208,16 +210,23 @@ Or you can set the environment variable `CLASSPATH` before starting PMD, e.g.
## Exit Status
Please note that if PMD detects any violations, it will exit with status 4 (since 5.3).
Please note that if PMD detects any violations, it will exit with status 4 (since 5.3) or 5 (since 7.3.0).
This behavior has been introduced to ease PMD integration into scripts or hooks, such as SVN hooks.
<table>
<tr><td>0</td><td>Everything is fine, no violations found.</td></tr>
<tr><td>0</td><td>Everything is fine, no violations found and no recoverable error occurred.</td></tr>
<tr><td>1</td><td>PMD exited with an exception.</td></tr>
<tr><td>2</td><td>Usage error. Command-line parameters are invalid or missing.</td></tr>
<tr><td>4</td><td>At least one violation has been detected, unless <code>--no-fail-on-violation</code> is set.</td></tr>
<tr><td>4</td><td>At least one violation has been detected, unless <code>--no-fail-on-violation</code> is set.<p>Since PMD 5.3.</p></td></tr>
<tr><td>5</td><td>At least one recoverable error has occurred. There might be additionally zero or more violations detected.
To ignore recoverable errors, use <code>--no-fail-on-error</code>.<p>Since PMD 7.3.0.</p></td></tr>
</table>
{%include note.html content="If PMD exits with 5, then PMD had either trouble parsing one or more files or a rule failed with an exception.
That means, that either no violations for the entire file or for that rule are reported. These cases can be considered as false-negatives.
In any case, the root cause should be investigated. If it's a problem in PMD itself, please create a bug report. Recoverable errors
are usually part of the generated PMD report." %}
## Logging
PMD internally uses [slf4j](https://www.slf4j.org/) and ships with slf4j-simple as the logging implementation.

View File

@ -4,7 +4,7 @@ tags: [cpd, userdocs]
summary: "Learn how to use CPD, the copy-paste detector shipped with PMD."
permalink: pmd_userdocs_cpd.html
author: Tom Copeland <tom@infoether.com>
last_updated: August 2023 (7.0.0)
last_updated: June 2024 (7.3.0)
---
## Overview
@ -132,8 +132,8 @@ exactly identical.
description="Don't scan subdirectories. By default, subdirectories are considered."
%}
{% include custom/cli_option_row.html options="--skip-lexical-errors"
description="Skip files which can't be tokenized due to invalid characters instead of aborting CPD.
By default, CPD analysis is stopped on the first error."
description="<span class='label label-primary'>Deprecated</span> Skip files which can't be tokenized due to invalid characters instead of aborting CPD.
By default, CPD analysis is stopped on the first error. This is deprecated. Use `--fail-on-error` instead."
%}
{% include custom/cli_option_row.html options="--format,-f"
option_arg="format"
@ -150,6 +150,11 @@ exactly identical.
If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered
as absolute."
%}
{% include custom/cli_option_row.html options="--[no-]fail-on-error"
description="Specifies whether CPD exits with non-zero status if recoverable errors occurred.
By default CPD exits with status 5 if recoverable errors occurred (whether there are duplications or not).
Disable this option with `--no-fail-on-error` to exit with 0 instead. In any case, a report with the found duplications will be written."
%}
{% include custom/cli_option_row.html options="--[no-]fail-on-violation"
description="Specifies whether CPD exits with non-zero status if violations are found.
By default CPD exits with status 4 if violations are found.
@ -279,16 +284,22 @@ If you specify a source directory but don't want to scan the sub-directories, yo
### Exit status
Please note that if CPD detects duplicated source code, it will exit with status 4 (since 5.0).
Please note that if CPD detects duplicated source code, it will exit with status 4 (since 5.0) or 5 (since 7.3.0).
This behavior has been introduced to ease CPD integration into scripts or hooks, such as SVN hooks.
<table>
<tr><td>0</td><td>Everything is fine, no code duplications found.</td></tr>
<tr><td>0</td><td>Everything is fine, no code duplications found and no recoverable errors occurred.</td></tr>
<tr><td>1</td><td>CPD exited with an exception.</td></tr>
<tr><td>2</td><td>Usage error. Command-line parameters are invalid or missing.</td></tr>
<tr><td>4</td><td>At least one code duplication has been detected unless <code>--no-fail-on-violation</code> is set.</td></tr>
<tr><td>4</td><td>At least one code duplication has been detected unless <code>--no-fail-on-violation</code> is set.<p>Since PMD 5.0.</p></td></tr>
<tr><td>5</td><td>At least one recoverable error has occurred. There might be additionally zero or more duplications detected.
To ignore recoverable errors, use <code>--no-fail-on-error</code>.<p>Since PMD 7.3.0.</p></td></tr>
</table>
{%include note.html content="If PMD exits with 5, then PMD had trouble lexing one or more files.
That means, that no duplications for the entire file are reported. This can be considered as false-negative.
In any case, the root cause should be investigated. If it's a problem in PMD itself, please create a bug report." %}
## Logging
PMD internally uses [slf4j](https://www.slf4j.org/) and ships with slf4j-simple as the logging implementation.
@ -390,6 +401,10 @@ Andy Glover wrote an Ant task for CPD; here's how to use it:
keep their encoding.<br />
If not specified, CPD uses the system default encoding."
%}
{% include custom/cli_option_row.html options="failOnError"
description="Whether to fail the build if any errors occurred while processing the files. Since PMD 7.3.0."
default="true"
%}
{% include custom/cli_option_row.html options="format"
description="The format of the report (e.g. `csv`, `text`, `xml`)."
default="text"
@ -424,8 +439,10 @@ Andy Glover wrote an Ant task for CPD; here's how to use it:
default="false"
%}
{% include custom/cli_option_row.html options="skipLexicalErrors"
description="Skip files which can't be tokenized due to invalid characters instead of aborting CPD."
default="false"
description="<span class='label label-primary'>Deprecated</span> Skip files which can't be tokenized
due to invalid characters instead of aborting CPD. This parameter is deprecated and
ignored since PMD 7.3.0. It is now by default true. Use `failOnError` instead to fail the build."
default="true"
%}
{% include custom/cli_option_row.html options="skipBlocks"
description="Enables or disabled skipping of blocks like a pre-processor. See also option skipBlocksPattern."

View File

@ -4,6 +4,7 @@ tags: [pmd, userdocs]
summary: "Migrating to PMD 7 from PMD 6.x"
permalink: pmd_userdocs_migrating_to_pmd7.html
author: Andreas Dangel <andreas.dangel@pmd-code.org>
last_updated: June 2024 (7.3.0)
---
{% include important.html content="
@ -3363,8 +3364,9 @@ See the use case [I'm using only built-in rules](#im-using-only-built-in-rules)
#### Maven
* Due to some changes in PMD's API, you can't simply pull in the new PMD 7 dependency.
* See [Using PMD 7 with maven-pmd-plugin](pmd_userdocs_tools_maven.html#using-pmd-7-with-maven-pmd-plugin).
* Since maven-pmd-plugin 3.22.0, PMD 7 is supported directly.
* See [MPMD-379](https://issues.apache.org/jira/browse/MPMD-379)
* See [Using PMD 7 with maven-pmd-plugin](pmd_userdocs_tools_maven.html#using-pmd-7-with-maven-pmd-plugin)
#### Gradle

View File

@ -6,6 +6,7 @@ author: >
David Dixon-Peugh <dpeugh@users.sourceforge.net>,
Tom Copeland <tom@infoether.com>,
Xavier Le Vourch <xlv@users.sourceforge.net>
last_updated: June 2024 (7.3.0)
---
## PMD
@ -63,8 +64,8 @@ The examples below won't repeat this taskdef element, as this is always required
<td>Yes, unless the ruleset nested element is used</td>
</tr>
<tr>
<td>failonerror</td>
<td>Whether or not to fail the build if any errors occur while processing the files</td>
<td>failOnError</td>
<td>Whether or not to fail the build if any recoverable errors occurred while analyzing files.</td>
<td>No</td>
</tr>
<tr>

View File

@ -2,8 +2,8 @@
title: Maven PMD Plugin
tags: [userdocs, tools]
permalink: pmd_userdocs_tools_maven.html
last_updated: February 2024
mpmd_version: 3.21.2
last_updated: June 2024 (7.3.0)
mpmd_version: 3.23.0
author: >
Miguel Griffa <mikkey@users.sourceforge.net>,
Romain PELISSE <belaran@gmail.com>,
@ -72,7 +72,7 @@ This will add an entry to the 'project reports' section with the PMD report when
To run PMD on a Maven project without adding it as a report, simply run
mvn pmd:pmd
mvn complile pmd:pmd
The PMD plugin writes the report in XML which will then be formatted into more readable HTML.
@ -241,47 +241,25 @@ Maven plugin will use and benefit from the latest bugfixes and enhancements:
#### Using PMD 7 with maven-pmd-plugin
The Maven PMD plugin comes with a specific PMD version, which is documented on the
Since version 3.22.0 ([MPMD-379](https://issues.apache.org/jira/browse/MPMD-379)), maven-pmd-plugin uses
by default now PMD 7.0.0 and no extra configuration is required.
The specific PMD version used by maven-pmd-plugin might change. The exact version is documented on the
[plugin project page](https://maven.apache.org/plugins/maven-pmd-plugin/index.html).
This might not support PMD 7 out of the box.
Since PMD 7 is a major release which breaks compatibility in various ways, the solution described
above in [Upgrading the PMD version at runtime](#upgrading-the-pmd-version-at-runtime) doesn't work
directly.
In order to use newer versions of PMD 7, you can simply follow the guide
[Upgrading PMD at Runtime](https://maven.apache.org/plugins/maven-pmd-plugin/examples/upgrading-PMD-at-runtime.html).
In order to use PMD 7 with [maven-pmd-plugin](https://maven.apache.org/plugins/maven-pmd-plugin/) a new
compatibility module has been created. This allows to use PMD 7 by simply adding one additional dependency:
1. Follow the guide [Upgrading PMD at Runtime](https://maven.apache.org/plugins/maven-pmd-plugin/examples/upgrading-PMD-at-runtime.html)
2. Add additionally the following dependency:
```xml
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-compat6</artifactId>
<version>${pmdVersion}</version>
</dependency>
```
It is important to add this dependency as the **first** in the list, so that maven-pmd-plugin sees the (old)
compatible versions of some classes.
This module is available beginning with version 7.0.0-rc4 and will be there at least for the first
final version PMD 7 (7.0.0). It's not decided yet, whether we will keep updating it, after PMD 7 is finally
released.
Note: This compatibility module only works for the built-in rules, that are still available in PMD 7. E.g. you need
to review your rulesets and look out for deprecated rules and such. See the use case
[I'm using only built-in rules](pmd_userdocs_migrating_to_pmd7.html#im-using-only-built-in-rules)
in the [Migration Guide for PMD 7](pmd_userdocs_migrating_to_pmd7.html).
Note: If you upgrade from Maven PMD Plugin before 3.22.0 you are most likely updating from PMD 6 to PMD 7.
This upgrade is a major version change. If you use the default ruleset from Maven PMD Plugin, then everything should
just work. But if you use a custom ruleset, you most likely need to review your ruleset and migrate it to PMD 7.
Rules might have been renamed or replaced. See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html)
and [Migration Guide for PMD 7](pmd_userdocs_migrating_to_pmd7.html).
As PMD 7 revamped the Java module, if you have custom rules, you need to migrate these rules.
See the use case [I'm using custom rules](pmd_userdocs_migrating_to_pmd7.html#im-using-custom-rules)
in the Migration Guide.
### Reference
For more information, please see the well documented PMD plugin project page here:

View File

@ -15,46 +15,13 @@ This is a {{ site.pmd.release_type }} release.
### 🚀 New and noteworthy
### 🐛 Fixed Issues
* core
* [#4992](https://github.com/pmd/pmd/pull/4992): \[core] CPD: Include processing errors in XML report
* apex
* [#4922](https://github.com/pmd/pmd/issues/4922): \[apex] SOQL syntax error with TYPEOF in sub-query
* [#5053](https://github.com/pmd/pmd/issues/5053): \[apex] CPD fails to parse string literals with escaped characters
* [#5055](https://github.com/pmd/pmd/issues/5055): \[apex] SOSL syntax error with WITH USER_MODE or WITH SYSTEM_MODE
* apex-bestpractices
* [#5000](https://github.com/pmd/pmd/issues/5000): \[apex] UnusedLocalVariable FP with binds in SOSL / SOQL
* java-bestpractices
* [#5047](https://github.com/pmd/pmd/issues/5047): \[java] UnusedPrivateMethod FP for Generics & Overloads
* plsql
* [#1934](https://github.com/pmd/pmd/issues/1934): \[plsql] ParseException with MERGE statement in anonymous block
* [#2779](https://github.com/pmd/pmd/issues/2779): \[plsql] Error while parsing statement with (Oracle) DML Error Logging
* [#5086](https://github.com/pmd/pmd/pull/5086): \[plsql] Fixed issue with missing optional table alias in MERGE usage
### 🚨 API Changes
#### CPD Report Format XML
There are some important changes:
1. The XML format will now use an XSD schema, that is available at <https://pmd.github.io/schema/cpd-report_1_0_0.xsd>.
This schema defines the valid elements and attributes that one can expect from a CPD report.
2. The root element `pmd-cpd` contains the new attributes `pmdVersion`, `timestamp` and `version`. The latter is
the schema version and is currently "1.0.0".
3. The CPD XML report will now also contain recoverable errors as additional `<error>` elements.
See [Report formats for CPD](pmd_userdocs_cpd_report_formats.html#xml) for an example.
The XML format should be compatible as only attributes and elements have been added. However, if you parse
the document with a namespace aware parser, you might encounter some issues like no elements being found.
In case the new format doesn't work for you (e.g. namespaces, unexpected error elements), you can
go back using the old format with the renderer "xmlold" ({%jdoc core::cpd.XMLOldRenderer %}). Note, that
this old renderer is deprecated and only there for compatibility reasons. Whatever tooling is used to
read the XML format should be updated.
#### Deprecated for removal
* {%jdoc !!core::cpd.XMLOldRenderer %} (the CPD format "xmlold").
### ✨ External Contributions
* [#5086](https://github.com/pmd/pmd/pull/5086): \[plsql] Fixed issue with missing optional table alias in MERGE usage - [Arjen Duursma](https://github.com/duursma) (@duursma)
{% endtocmaker %}

View File

@ -5,6 +5,149 @@ permalink: pmd_release_notes_old.html
Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases)
## 28-June-2024 - 7.3.0
The PMD team is pleased to announce PMD 7.3.0.
This is a minor release.
### Table Of Contents
* [🚀 New and noteworthy](#new-and-noteworthy)
* [✨ New Rules](#new-rules)
* [💥 pmd-compat6 removed (breaking)](#pmd-compat6-removed-breaking)
* [🐛 Fixed Issues](#fixed-issues)
* [🚨 API Changes](#api-changes)
* [CPD Report Format XML](#cpd-report-format-xml)
* [CLI](#cli)
* [Ant](#ant)
* [Deprecated API](#deprecated-api)
* [Breaking changes: pmd-compat6 removed](#breaking-changes-pmd-compat6-removed)
* [📈 Stats](#stats)
### 🚀 New and noteworthy
#### ✨ New Rules
* The new Java rule [`UseEnumCollections`](https://docs.pmd-code.org/pmd-doc-7.3.0/pmd_rules_java_bestpractices.html#useenumcollections) reports usages for `HashSet` and `HashMap`
when the keys are of an enum type. The specialized enum collections are more space- and time-efficient.
#### 💥 pmd-compat6 removed (breaking)
The already deprecated PMD 6 compatibility module (pmd-compat6) has been removed. It was intended to be used with
older versions of the maven-pmd-plugin, but since maven-pmd-plugin 3.22.0, PMD 7 is supported directly and this
module is not needed anymore.
If you currently use this dependency (`net.sourceforge.pmd:pmd-compat6`), remove it and upgrade maven-pmd-plugin
to the latest version (3.23.0 or newer).
See also [Maven PMD Plugin](https://docs.pmd-code.org/pmd-doc-7.3.0/pmd_userdocs_tools_maven.html).
### 🐛 Fixed Issues
* cli
* [#2827](https://github.com/pmd/pmd/issues/2827): \[cli] Consider processing errors in exit status
* core
* [#4396](https://github.com/pmd/pmd/issues/4396): \[core] CPD is always case sensitive
* [#4992](https://github.com/pmd/pmd/pull/4992): \[core] CPD: Include processing errors in XML report
* [#5066](https://github.com/pmd/pmd/issues/5066): \[core] CPD throws java.lang.OutOfMemoryError: Java heap space (since 7.1.0)
* apex
* [#4922](https://github.com/pmd/pmd/issues/4922): \[apex] SOQL syntax error with TYPEOF in sub-query
* [#5053](https://github.com/pmd/pmd/issues/5053): \[apex] CPD fails to parse string literals with escaped characters
* [#5055](https://github.com/pmd/pmd/issues/5055): \[apex] SOSL syntax error with WITH USER_MODE or WITH SYSTEM_MODE
* apex-bestpractices
* [#5000](https://github.com/pmd/pmd/issues/5000): \[apex] UnusedLocalVariable FP with binds in SOSL / SOQL
* java
* [#4885](https://github.com/pmd/pmd/issues/4885): \[java] AssertionError: Method should be accessible
* [#5050](https://github.com/pmd/pmd/issues/5050): \[java] Problems with pattern variables in switch branches
* java-bestpractices
* [#577](https://github.com/pmd/pmd/issues/577): \[java] New Rule: Check that Map<K,V> is an EnumMap if K is an enum value
* [#5047](https://github.com/pmd/pmd/issues/5047): \[java] UnusedPrivateMethod FP for Generics & Overloads
* plsql
* [#1934](https://github.com/pmd/pmd/issues/1934): \[plsql] ParseException with MERGE statement in anonymous block
* [#2779](https://github.com/pmd/pmd/issues/2779): \[plsql] Error while parsing statement with (Oracle) DML Error Logging
* [#4270](https://github.com/pmd/pmd/issues/4270): \[plsql] Parsing exception COMPOUND TRIGGER with EXCEPTION handler
### 🚨 API Changes
#### CPD Report Format XML
There are some important changes:
1. The XML format will now use an XSD schema, that is available at <https://pmd.github.io/schema/cpd-report_1_0_0.xsd>.
This schema defines the valid elements and attributes that one can expect from a CPD report.
2. The root element `pmd-cpd` contains the new attributes `pmdVersion`, `timestamp` and `version`. The latter is
the schema version and is currently "1.0.0".
3. The CPD XML report will now also contain recoverable errors as additional `<error>` elements.
See [Report formats for CPD](pmd_userdocs_cpd_report_formats.html#xml) for an example.
The XML format should be compatible as only attributes and elements have been added. However, if you parse
the document with a namespace aware parser, you might encounter some issues like no elements being found.
In case the new format doesn't work for you (e.g. namespaces, unexpected error elements), you can
go back using the old format with the renderer "xmlold" (<a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/cpd/XMLOldRenderer.html#"><code>XMLOldRenderer</code></a>). Note, that
this old renderer is deprecated and only there for compatibility reasons. Whatever tooling is used to
read the XML format should be updated.
#### CLI
* New exit code 5 introduced. PMD and CPD will exit now by default with exit code 5, if any recoverable error
(e.g. parsing exception, lexing exception or rule exception) occurred. PMD will still create a report with
all detected violations or duplications if recoverable errors occurred. Such errors mean, that the report
might be incomplete, as either violations or duplications for an entire file or for a specific rule are missing.
These cases can be considered as false-negatives.
In any case, the root cause should be investigated. If it's a problem in PMD itself, please create a bug report.
* New CLI parameter `--no-fail-on-error` to ignore such errors and not exit with code 5. By default,
a build with errors will now fail and with that parameter, the previous behavior can be restored.
This parameter is available for both PMD and CPD.
* The CLI parameter `--skip-lexical-errors` is deprecated. By default, lexical errors are skipped but the
build is failed. Use the new parameter `--[no-]fail-on-error` instead to control whether to fail the build or not.
#### Ant
* CPDTask has a new parameter `failOnError`. It controls, whether to fail the build if any recoverable error occurred.
By default, the build will fail. CPD will still create a report with all detected duplications, but the report might
be incomplete.
* The parameter `skipLexicalError` in CPDTask is deprecated and ignored. Lexical errors are now always skipped.
Use the new parameter `failOnError` instead to control whether to fail the build or not.
#### Deprecated API
* pmd-ant
* <a href="https://docs.pmd-code.org/apidocs/pmd-ant/7.3.0/net/sourceforge/pmd/ant/CPDTask.html#setSkipLexicalErrors(boolean)"><code>CPDTask#setSkipLexicalErrors</code></a>: Use <a href="https://docs.pmd-code.org/apidocs/pmd-ant/7.3.0/net/sourceforge/pmd/ant/CPDTask.html#setFailOnError(boolean)"><code>setFailOnError</code></a>
instead to control, whether to ignore errors or fail the build.
* pmd-core
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/cpd/CPDConfiguration.html#isSkipLexicalErrors()"><code>CPDConfiguration#isSkipLexicalErrors</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/cpd/CPDConfiguration.html#setSkipLexicalErrors(boolean)"><code>setSkipLexicalErrors</code></a>:
Use <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/AbstractConfiguration.html#setFailOnError(boolean)"><code>setFailOnError</code></a> to control whether to ignore errors or fail the build.
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/cpd/XMLOldRenderer.html#"><code>net.sourceforge.pmd.cpd.XMLOldRenderer</code></a> (the CPD format "xmlold").
* The constructor
<a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.html#AntlrToken(org.antlr.v4.runtime.Token,net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken,net.sourceforge.pmd.lang.document.TextDocument)"><code>AntlrToken#AntlrToken</code></a>
shouldn't be used directly. Use <a href="https://docs.pmd-code.org/apidocs/pmd-core/7.3.0/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrTokenManager.html#"><code>AntlrTokenManager</code></a> instead.
* pmd-java
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0/net/sourceforge/pmd/lang/java/ast/ASTResource.html#getStableName()"><code>ASTResource#getStableName</code></a> and the corresponding attribute `@StableName`.
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0/net/sourceforge/pmd/lang/java/ast/ASTRecordPattern.html#getVarId()"><code>ASTRecordPattern#getVarId</code></a> This method was added here by mistake. Record
patterns don't declare a pattern variable for the whole pattern, but rather for individual record
components, which can be accessed via <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.3.0/net/sourceforge/pmd/lang/java/ast/ASTRecordPattern.html#getComponentPatterns()"><code>getComponentPatterns</code></a>.
* pmd-plsql
* <a href="https://docs.pmd-code.org/apidocs/pmd-plsql/7.3.0/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserImpl.html#"><code>PLSQLParserImpl</code></a> is deprecated now. It should have been package-private
because this is an implementation class that should not be used directly.
* The node <a href="https://docs.pmd-code.org/apidocs/pmd-plsql/7.3.0/net/sourceforge/pmd/lang/plsql/ast/ASTKEYWORD_UNRESERVED.html#"><code>ASTKEYWORD_UNRESERVED</code></a> is deprecated and is now removed from the AST.
#### Breaking changes: pmd-compat6 removed
The already deprecated PMD 6 compatibility module (pmd-compat6) has been removed.
See above for details.
### 📈 Stats
* 88 commits
* 32 closed tickets & PRs
* Days since last release: 27
## 31-May-2024 - 7.2.0
The PMD team is pleased to announce PMD 7.2.0.

477
mvnw vendored

File diff suppressed because it is too large Load Diff

267
mvnw.cmd vendored
View File

@ -1,3 +1,4 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@ -18,171 +19,131 @@
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
if ($env:MAVEN_USER_HOME) {
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
}
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
:error
set ERROR_CODE=1
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
cmd /C exit /B %ERROR_CODE%
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

View File

@ -7,7 +7,7 @@
<parent>
<artifactId>pmd</artifactId>
<groupId>net.sourceforge.pmd</groupId>
<version>7.3.0-SNAPSHOT</version>
<version>7.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -78,6 +78,7 @@ public class CPDTask extends Task {
private boolean ignoreIdentifiers;
private boolean ignoreAnnotations;
private boolean ignoreUsings;
@Deprecated
private boolean skipLexicalErrors;
private boolean skipDuplicateFiles;
private boolean skipBlocks = true;
@ -85,6 +86,7 @@ public class CPDTask extends Task {
private File outputFile;
private String encoding = System.getProperty("file.encoding");
private List<FileSet> filesets = new ArrayList<>();
private boolean failOnError = true;
@Override
public void execute() throws BuildException {
@ -102,7 +104,15 @@ public class CPDTask extends Task {
config.setOnlyRecognizeLanguage(config.getLanguageRegistry().getLanguageById(language));
config.setSourceEncoding(Charset.forName(encoding));
config.setSkipDuplicates(skipDuplicateFiles);
config.setSkipLexicalErrors(skipLexicalErrors);
if (skipLexicalErrors) {
log("skipLexicalErrors is deprecated since 7.3.0 and the property is ignored. "
+ "Lexical errors are now skipped by default and the build is failed. "
+ "Use failOnError=\"false\" to not fail the build.", Project.MSG_WARN);
}
// implicitly enable skipLexicalErrors, so that we can fail the build at the end. A report is created in any case.
config.setSkipLexicalErrors(true);
config.setIgnoreAnnotations(ignoreAnnotations);
config.setIgnoreLiterals(ignoreLiterals);
@ -121,12 +131,20 @@ public class CPDTask extends Task {
long timeTaken = System.currentTimeMillis() - start;
log("Done analyzing code; that took " + timeTaken + " milliseconds");
int errors = config.getReporter().numErrors();
if (errors > 0) {
String message = String.format("There were %d recovered errors during analysis.", errors);
if (failOnError) {
throw new BuildException(message + " Ignore these with failOnError=\"true\".");
} else {
log(message + " Not failing build, because failOnError=\"false\".", Project.MSG_WARN);
}
}
}
} catch (IOException ioe) {
log(ioe.toString(), Project.MSG_ERR);
throw new BuildException("IOException during task execution", ioe);
} catch (ReportException re) {
re.printStackTrace();
log(re.toString(), Project.MSG_ERR);
throw new BuildException("ReportException during task execution", re);
} finally {
@ -225,6 +243,10 @@ public class CPDTask extends Task {
this.ignoreUsings = value;
}
/**
* @deprecated Use {@link #setFailOnError(boolean)} instead.
*/
@Deprecated
public void setSkipLexicalErrors(boolean skipLexicalErrors) {
this.skipLexicalErrors = skipLexicalErrors;
}
@ -257,6 +279,15 @@ public class CPDTask extends Task {
this.skipBlocksPattern = skipBlocksPattern;
}
/**
* Whether to fail the build if any recoverable errors occurred while processing the files.
*
* @since 7.3.0
*/
public void setFailOnError(boolean failOnError) {
this.failOnError = failOnError;
}
public static class FormatAttribute extends EnumeratedAttribute {
private static final String[] FORMATS = new String[] { XML_FORMAT, TEXT_FORMAT, CSV_FORMAT, XMLOLD_FORMAT };

View File

@ -144,7 +144,7 @@ public class PMDTaskImpl {
pmd.performAnalysis();
stats = reportStatsListener.getResult();
if (failOnError && pmd.getReporter().numErrors() > 0) {
throw new BuildException("Some errors occurred while running PMD");
throw new BuildException("Some recoverable errors occurred while running PMD");
}
}

View File

@ -6,6 +6,7 @@ package net.sourceforge.pmd.ant;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
@ -14,6 +15,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.tools.ant.BuildException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -34,7 +36,25 @@ class CPDTaskTest extends AbstractAntTest {
@Test
void testBasic() throws IOException {
executeTarget("testBasic");
Path report = Paths.get("target/cpd.ant.tests");
assertReport("target/cpd.ant.tests");
}
@Test
void failOnErrorDefault() throws IOException {
BuildException buildException = assertThrows(BuildException.class, () -> executeTarget("failOnErrorDefault"));
assertThat(buildException.getMessage(), containsString("There were 1 recovered errors during analysis."));
assertReport("target/cpd.ant.tests");
}
@Test
void failOnErrorIgnore() throws IOException {
executeTarget("failOnErrorIgnore");
assertReport("target/cpd.ant.tests");
assertThat(log.toString(), containsString("There were 1 recovered errors during analysis."));
}
private static void assertReport(String path) throws IOException {
Path report = Paths.get(path);
assertTrue(Files.exists(report), "Report was not created");
String reportContent = IOUtil.readFileToString(report.toFile(), StandardCharsets.UTF_8);
assertThat(reportContent, containsString("Found a 1 line (21 tokens) duplication in the following files:"));

View File

@ -0,0 +1 @@
:throw_lex_source_exception:

View File

@ -11,7 +11,24 @@
<cpd minimumTokenCount="20" outputFile="${pmd.home}/target/cpd.ant.tests" language="dummy">
<fileset dir="${pmd.home}/${src}">
<include name="**/*.dummy"/>
<exclude name="sampleLexError.dummy"/>
</fileset>
</cpd>
</target>
<target name="failOnErrorDefault">
<cpd minimumTokenCount="20" outputFile="${pmd.home}/target/cpd.ant.tests" language="dummy">
<fileset dir="${pmd.home}/${src}">
<include name="**/*.dummy"/>
</fileset>
</cpd>
</target>
<target name="failOnErrorIgnore">
<cpd minimumTokenCount="20" outputFile="${pmd.home}/target/cpd.ant.tests" language="dummy" failOnError="false">
<fileset dir="${pmd.home}/${src}">
<include name="**/*.dummy"/>
</fileset>
</cpd>
</target>
</project>

View File

@ -16,4 +16,12 @@ Test Rule 2
Test Rule 3
</violation>
</file>
<file name="sampleLexError.dummy">
<violation beginline="1" endline="1" begincolumn="1" endcolumn="30" rule="SampleXPathRule" ruleset="Test Ruleset" package="foo" externalInfoUrl="${pmd.website.baseurl}/rules/dummy/basic.xml#SampleXPathRule" priority="3">
Test Rule 2
</violation>
<violation beginline="1" endline="1" begincolumn="1" endcolumn="30" rule="DeprecatedRule" ruleset="Test Ruleset" package="foo" externalInfoUrl="${pmd.website.baseurl}/rules/dummy/basic.xml#deprecatedrule" priority="3">
Test Rule 3
</violation>
</file>
</pmd>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.3.0-SNAPSHOT</version>
<version>7.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.3.0-SNAPSHOT</version>
<version>7.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -43,11 +43,17 @@ public abstract class AbstractAnalysisPmdSubcommand<C extends AbstractConfigurat
protected URI uri;
@Option(names = "--no-fail-on-violation",
description = "By default PMD exits with status 4 if violations are found. "
+ "Disable this option with '--no-fail-on-violation' to exit with 0 instead and just write the report.",
description = "By default PMD exits with status 4 if violations or duplications are found. "
+ "Disable this option with '--no-fail-on-violation' to exit with 0 instead. In any case a report with the found violations or duplications will be written.",
defaultValue = "true", negatable = true)
protected boolean failOnViolation;
@Option(names = "--no-fail-on-error",
description = "By default PMD exits with status 5 if recoverable errors occurred (whether or not there are violations or duplications). "
+ "Disable this option with '--no-fail-on-error' to exit with 0 instead. In any case, a report with the found violations or duplications will be written.",
defaultValue = "true", negatable = true)
protected boolean failOnError;
protected List<Path> relativizeRootPaths;
@Option(names = { "--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. "

View File

@ -68,8 +68,12 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand<CPDConfiguration>
@Option(names = "--ignore-sequences", description = "Ignore sequences of identifiers and literals")
private boolean ignoreIdentifierAndLiteralSequences;
/**
* @deprecated Use {@link #failOnError} instead.
*/
@Option(names = "--skip-lexical-errors",
description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error.")
description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error. Deprecated - use --[no-]fail-on-error instead.")
@Deprecated
private boolean skipLexicalErrors;
@Option(names = "--no-skip-blocks",
@ -103,6 +107,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand<CPDConfiguration>
configuration.addRelativizeRoots(relativizeRootPaths);
}
configuration.setFailOnViolation(failOnViolation);
configuration.setFailOnError(failOnError);
configuration.setInputFilePath(fileListPath);
if (inputPaths != null) {
configuration.setInputPathList(new ArrayList<>(inputPaths));
@ -123,6 +128,14 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand<CPDConfiguration>
configuration.setSourceEncoding(encoding.getEncoding());
configuration.setInputUri(uri);
if (skipLexicalErrors) {
configuration.getReporter().warn("--skip-lexical-errors is deprecated. Use --no-fail-on-error instead.");
configuration.setFailOnError(false);
}
// implicitly enable skipLexicalErrors, so that we can fail the build at the end. A report is created in any case.
configuration.setSkipLexicalErrors(true);
return configuration;
}
@ -133,6 +146,11 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand<CPDConfiguration>
MutableBoolean hasViolations = new MutableBoolean();
cpd.performAnalysis(report -> hasViolations.setValue(!report.getMatches().isEmpty()));
boolean hasErrors = configuration.getReporter().numErrors() > 0;
if (hasErrors && configuration.isFailOnError()) {
return CliExitCode.RECOVERED_ERRORS_OR_VIOLATIONS;
}
if (hasViolations.booleanValue() && configuration.isFailOnViolation()) {
return CliExitCode.VIOLATIONS_FOUND;
}

View File

@ -270,6 +270,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand<PMDConfiguration>
configuration.setSuppressMarker(suppressMarker);
configuration.setThreads(threads);
configuration.setFailOnViolation(failOnViolation);
configuration.setFailOnError(failOnError);
configuration.setAnalysisCacheLocation(cacheLocation != null ? cacheLocation.toString() : null);
configuration.setIgnoreIncrementalAnalysis(noCache);
@ -330,6 +331,8 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand<PMDConfiguration>
if (pmdReporter.numErrors() > 0) {
// processing errors are ignored
return CliExitCode.ERROR;
} else if (stats.getNumErrors() > 0 && configuration.isFailOnError()) {
return CliExitCode.RECOVERED_ERRORS_OR_VIOLATIONS;
} else if (stats.getNumViolations() > 0 && configuration.isFailOnViolation()) {
return CliExitCode.VIOLATIONS_FOUND;
} else {

Some files were not shown because too many files have changed in this diff Show More