Merge branch 'master' into xpath-seq-attributes
@ -7462,6 +7462,78 @@
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "BurovnikovEvgeniy",
|
||||
"name": "BurovnikovEvgeniy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/71849985?v=4",
|
||||
"profile": "https://github.com/BurovnikovEvgeniy",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kohlschuetter",
|
||||
"name": "Dr. Christian Kohlschütter",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/822690?v=4",
|
||||
"profile": "https://kohlschuetter.github.io/blog/",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Luro02",
|
||||
"name": "Lucas",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/24826124?v=4",
|
||||
"profile": "https://github.com/Luro02",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "rs23",
|
||||
"name": "Reinhard Schiedermeier",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12321337?v=4",
|
||||
"profile": "http://sol.cs.hm.edu/rs",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "andygoossens",
|
||||
"name": "Andy Goossens",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2099087?v=4",
|
||||
"profile": "https://github.com/andygoossens",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mitchspano",
|
||||
"name": "Mitch Spano",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/18402464?v=4",
|
||||
"profile": "https://github.com/mitchspano",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mfvanek",
|
||||
"name": "Ivan Vakhrushev",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/37612014?v=4",
|
||||
"profile": "https://www.linkedin.com/in/mfvanek/",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "VishV-Android",
|
||||
"name": "Vishv_Android",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/126696109?v=4",
|
||||
"profile": "https://github.com/VishV-Android",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
4
.github/workflows/build.yml
vendored
@ -48,6 +48,8 @@ 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 }}-
|
||||
@ -60,7 +62,7 @@ jobs:
|
||||
run: |
|
||||
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
||||
echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/24/scripts" >> $GITHUB_ENV
|
||||
- name: Check Environment
|
||||
shell: bash
|
||||
run: |
|
||||
|
2
.github/workflows/git-repo-sync.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/24/scripts" >> $GITHUB_ENV
|
||||
- name: Sync
|
||||
run: .ci/git-repo-sync.sh
|
||||
shell: bash
|
||||
|
2
.github/workflows/troubleshooting.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
run: |
|
||||
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
|
||||
echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
|
||||
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/24/scripts" >> $GITHUB_ENV
|
||||
- name: Check Environment
|
||||
shell: bash
|
||||
run: |
|
||||
|
@ -44,7 +44,7 @@ def run_pmdtester
|
||||
@base_branch = 'master'
|
||||
@logger.info "\n\n--------------------------------------"
|
||||
@logger.info "Run against #{@base_branch}"
|
||||
@summary = PmdTester::Runner.new(get_args(@base_branch, FALSE, 'target/diff1/patch_config.xml')).run
|
||||
@summary = PmdTester::Runner.new(get_args(@base_branch, false, 'target/diff1/patch_config.xml')).run
|
||||
|
||||
# move the generated report out of the way
|
||||
FileUtils.mv 'target/reports/diff', 'target/diff2'
|
||||
@ -53,12 +53,12 @@ def run_pmdtester
|
||||
|
||||
tar_report
|
||||
|
||||
message1 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']})"
|
||||
message1 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']}?pr=#{ENV['PMD_CI_PULL_REQUEST_NUMBER']})"
|
||||
# set value of sticky to true and the message is kept after new commits are submitted to the PR
|
||||
message(message1, sticky: true)
|
||||
|
||||
if message2
|
||||
message2 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']})"
|
||||
message2 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']}?pr=#{ENV['PMD_CI_PULL_REQUEST_NUMBER']})"
|
||||
# set value of sticky to true and the message is kept after new commits are submitted to the PR
|
||||
message(message2, sticky: true)
|
||||
end
|
||||
|
@ -204,6 +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
|
||||
echo "If it is failing, you can fix the code/scripts and force push the tag via"
|
||||
echo
|
||||
@ -245,9 +246,6 @@ ${NEW_RELEASE_NOTES}
|
||||
|
||||
${OLD_RELEASE_NOTES}" > docs/pages/release_notes_old.md
|
||||
|
||||
# update release_notes_pmd7 with prerendered version (jdoc tags are replaced with released version)
|
||||
echo "$RELEASE_NOTES_PMD7" > docs/pages/release_notes_pmd7.md
|
||||
|
||||
# reset release notes template
|
||||
cat > docs/pages/release_notes.md <<EOF
|
||||
---
|
||||
@ -348,6 +346,8 @@ 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 "* 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
|
||||
echo
|
||||
echo "Now waiting for the release to be finished..."
|
||||
|
@ -1,9 +1,9 @@
|
||||
repository: pmd/pmd
|
||||
|
||||
pmd:
|
||||
version: 7.1.0-SNAPSHOT
|
||||
previous_version: 7.0.0
|
||||
date: 26-April-2024
|
||||
version: 7.2.0-SNAPSHOT
|
||||
previous_version: 7.1.0
|
||||
date: 31-May-2024
|
||||
release_type: minor
|
||||
|
||||
# release types: major, minor, bugfix
|
||||
|
76
docs/images/logo/PMD_small.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="300"
|
||||
height="300"
|
||||
viewBox="0 0 79.374998 79.375"
|
||||
version="1.1"
|
||||
id="svg247"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="PMD_small.svg"
|
||||
inkscape:export-filename="pmd-logo-small-64px.png"
|
||||
inkscape:export-xdpi="20.48"
|
||||
inkscape:export-ydpi="20.48"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview249"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.56819522"
|
||||
inkscape:cx="-48.398859"
|
||||
inkscape:cy="568.46659"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1131"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs244" />
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
fill="none"
|
||||
d="m 178.59473,145.37516 h -6.58813 v 20.98146 h 6.90563 c 5.66208,0 9.81604,-4.2598 9.81604,-10.45105 0.0265,-6.2177 -4.33917,-10.53041 -10.13354,-10.53041 z"
|
||||
id="path4"
|
||||
style="stroke-width:0.264583" />
|
||||
<g
|
||||
id="g358"
|
||||
transform="translate(-66.292186,-115.39785)">
|
||||
<path
|
||||
fill="#58595b"
|
||||
d="m 81.968898,178.10412 c -0.132292,-0.82021 -0.291042,-1.64042 -0.291042,-2.46063 -0.02646,-4.65667 0,-9.31333 -0.05292,-13.97 -0.02646,-1.93146 -0.502708,-3.75708 -1.878541,-5.21229 -0.47625,-0.50271 -1.031875,-0.9525 -1.561042,-1.42875 0.529167,-0.47625 1.084792,-0.92604 1.561042,-1.42875 1.375833,-1.45521 1.852083,-3.25438 1.878541,-5.21229 0.05292,-4.65667 0.02646,-9.31334 0.05292,-13.97 0,-0.82021 0.15875,-1.64042 0.291042,-2.46063 0.15875,-1.05833 0.820208,-1.66687 1.852083,-1.79916 h 5.503333 v -5.87375 h -3.783541 c -2.963334,-0.1323 -5.820834,0.26458 -8.281459,2.38125 -2.010833,1.74625 -2.672291,4.10104 -2.725208,6.61458 -0.105833,4.31271 -0.02646,8.62542 -0.07937,12.93812 0,0.9525 -0.105833,1.905 -0.343958,2.83105 -0.02646,0.0794 -0.05292,0.15875 -0.07937,0.23812 -0.3175,0.84667 -0.846667,1.40229 -1.481667,1.79917 -0.3175,0.18521 -0.687916,0.34396 -1.084791,0.44979 -0.343959,0.10583 -0.635,0.15875 -0.846667,0.23812 -0.211667,0.0265 -0.396875,0.0529 -0.582083,0.0794 h -2.248959 v 3.12208 3.12209 H 70.0362 c 0.185208,0.0265 0.370416,0.0265 0.582083,0.0794 0.211667,0.0794 0.47625,0.15875 0.846667,0.23813 0.396875,0.10583 0.767291,0.26458 1.084791,0.44979 0.608542,0.39687 1.164167,0.9525 1.481667,1.79916 0.02646,0.0794 0.05292,0.15875 0.07937,0.23813 0.238125,0.92604 0.343958,1.87854 0.343958,2.83104 0.05292,4.31271 -0.02646,8.62542 0.07937,12.93813 0.05292,2.51354 0.740834,4.86833 2.725208,6.61458 2.460625,2.14312 5.318125,2.51354 8.281459,2.38125 h 3.783541 v -5.87375 h -5.503333 c -1.005417,-0.0265 -1.693333,-0.635 -1.852083,-1.69333 z"
|
||||
id="path60"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
fill="#58595b"
|
||||
d="m 141.92317,151.96328 c -0.18521,-0.0265 -0.37042,-0.0265 -0.58209,-0.0794 -0.21166,-0.0794 -0.47625,-0.15875 -0.84666,-0.23813 -0.39688,-0.10583 -0.76729,-0.26458 -1.08479,-0.44979 -0.60855,-0.39687 -1.16417,-0.9525 -1.48167,-1.79917 -0.0265,-0.0794 -0.0529,-0.15875 -0.0794,-0.23812 -0.23812,-0.92604 -0.34395,-1.87854 -0.34395,-2.83104 -0.0529,-4.31271 0.0264,-8.62542 -0.0794,-12.93813 -0.0529,-2.51354 -0.74083,-4.86833 -2.72521,-6.61458 -2.46062,-2.14313 -5.31812,-2.51354 -8.28146,-2.38125 H 122.635 v 5.87375 h 5.50334 c 1.03187,0.13229 1.69333,0.74083 1.85208,1.79917 0.13229,0.8202 0.29104,1.64041 0.29104,2.46062 0.0265,4.65667 0,9.31333 0.0529,13.97 0.0265,1.93146 0.50271,3.75708 1.87854,5.21229 0.47625,0.50271 1.03187,0.9525 1.56104,1.42875 -0.52917,0.47625 -1.08479,0.92604 -1.56104,1.42875 -1.37583,1.45521 -1.85208,3.25438 -1.87854,5.21229 -0.0529,4.65667 -0.0265,9.31334 -0.0529,13.97 0,0.82021 -0.15875,1.64042 -0.29104,2.46063 -0.15875,1.05833 -0.82021,1.66687 -1.85208,1.79917 H 122.635 v 5.87375 h 3.78354 c 2.96334,0.13229 5.82084,-0.26459 8.28146,-2.38125 2.01084,-1.74625 2.67229,-4.10105 2.72521,-6.61459 0.10583,-4.31271 0.0265,-8.62541 0.0794,-12.93812 0,-0.9525 0.10583,-1.905 0.34395,-2.83104 0.0265,-0.0794 0.0529,-0.15875 0.0794,-0.23813 0.3175,-0.84667 0.84667,-1.40229 1.48167,-1.79917 0.3175,-0.1852 0.68791,-0.34395 1.08479,-0.44979 0.34396,-0.10583 0.635,-0.15875 0.84666,-0.23812 0.21167,-0.0265 0.39688,-0.0529 0.58209,-0.0794 h 2.24896 v -3.12208 -3.12208 h -2.24896 z"
|
||||
id="path62"
|
||||
style="stroke-width:0.264583" />
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-68.737767,-2.3681738)">
|
||||
|
||||
|
||||
<path
|
||||
fill="#1dbf73"
|
||||
d="m 723.3,525.6 c -4,2.2 -7.9,4.7 -11.7,7.2 -7.4,5 -14.1,10.3 -19.8,15.2 -2.7,2.4 -5.2,4.6 -7.4,6.7 -1.1,0.9 -2.1,1.8 -3.1,2.7 -3.4,3 -6.6,6 -9.7,8.8 -17,15.8 -29.2,28.9 -29.2,28.9 l -16,-18 -8,-8.9 -5.7,-6.4 c 0.6,-3.1 2.9,-5.7 5.7,-7.9 1.9,-1.5 4,-2.7 6.1,-3.8 4.1,-2.1 7.7,-3.2 7.7,-3.2 l 2.7,3.2 6.8,7.9 8,9.3 c 2.9,-3 5.8,-5.9 8.6,-8.6 3.2,-3.1 6.4,-6 9.5,-8.6 2.2,-1.9 4.4,-3.8 6.6,-5.5 2.1,-1.6 4.2,-3.1 6.5,-4.6 -7.8,-3.8 -17.6,-5.9 -29,-5.9 H 597.6 V 662 h 28.9 v -36.5 h 25.4 c 32.5,0 51.2,-17.2 51.2,-47 0,-9.9 -2.3,-18.4 -6.7,-25.1 z"
|
||||
id="path68" />
|
||||
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
docs/images/logo/pmd-logo-small-300px.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
docs/images/logo/pmd-logo-small-64px.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
docs/images/logo/pmd-logo-small-white-300px.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
docs/images/logo/pmd-logo-small-white-64px.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
@ -2,7 +2,7 @@
|
||||
title: Release process
|
||||
permalink: pmd_projectdocs_committers_releasing.html
|
||||
author: Romain Pelisse <rpelisse@users.sourceforge.net>, Andreas Dangel <andreas.dangel@pmd-code.org>
|
||||
last_updated: April 2021
|
||||
last_updated: April 2024
|
||||
---
|
||||
|
||||
This page describes the current status of the release process.
|
||||
@ -72,13 +72,13 @@ in order to release version "6.34.0", the configuration should look like this:
|
||||
|
||||
```yaml
|
||||
pmd:
|
||||
version: 6.34.0
|
||||
previous_version: 6.33.0
|
||||
date: 24-April-2021
|
||||
version: 7.2.0
|
||||
previous_version: 7.1.0
|
||||
date: 31-May-2024
|
||||
release_type: minor
|
||||
```
|
||||
|
||||
The release type could be one of "bugfix" (e.g. 6.34.x), "minor" (6.x.0), or "major" (x.0.0).
|
||||
The release type could be one of "bugfix" (e.g. 7.1.x), "minor" (7.x.0), or "major" (x.0.0).
|
||||
|
||||
The release notes usually mention any new rules that have been added since the last release.
|
||||
|
||||
@ -88,7 +88,7 @@ Add the new rules as comments to the quickstart rulesets:
|
||||
|
||||
The designer lives at [pmd/pmd-designer](https://github.com/pmd/pmd-designer).
|
||||
Update property `pmd-designer.version` in **pom.xml** to reference the new version, that will be released
|
||||
shortly. Note: This version does at the moment not exist. That means, that a full build of the sources
|
||||
shortly. Note: This new version does at the moment not exist. That means, that a full build of the sources
|
||||
will currently fail. That's why the first phase of the release will build only pmd-core and languages but
|
||||
not pmd-cli and pmd-dist.
|
||||
|
||||
@ -97,13 +97,14 @@ Then we can skip the release of pmd-designer and immediately start the second ph
|
||||
|
||||
Starting with PMD 6.23.0 we'll provide small statistics for every release. This needs to be added
|
||||
to the release notes as the last section. To count the closed issues and pull requests, the milestone
|
||||
on GitHub with the title of the new release is searched. Make sure, there is a milestone
|
||||
on <https://github.com/pmd/pmd/milestones>. The following snippet will
|
||||
on GitHub with the title of the new release is searched. It is important, that the due date of the milestone
|
||||
is correctly set, as the returned milestones in the API call are sorted by due date.
|
||||
Make sure, there is such a milestone on <https://github.com/pmd/pmd/milestones>. The following snippet will
|
||||
create the numbers, that can be attached to the release notes as a last section:
|
||||
|
||||
```shell
|
||||
LAST_VERSION=6.33.0
|
||||
NEW_VERSION=6.34.0
|
||||
LAST_VERSION=7.1.0
|
||||
NEW_VERSION=7.2.0
|
||||
NEW_VERSION_COMMITISH=HEAD
|
||||
|
||||
echo "### Stats"
|
||||
@ -129,14 +130,14 @@ The new version needs to be entered into `_config.yml`, e.g.:
|
||||
|
||||
```yaml
|
||||
pmd:
|
||||
latestVersion: 6.34.0
|
||||
latestVersionDate: 24-April-2021
|
||||
latestVersion: 7.2.0
|
||||
latestVersionDate: 31-May-2024
|
||||
```
|
||||
|
||||
Also move the previous version down into the "downloads" section. We usually keep only the last 3 versions
|
||||
in this list, so remove the oldest version.
|
||||
|
||||
Then create a new page for the new release, e.g. `_posts/2021-04-24-PMD-6.34.0.md` and copy
|
||||
Then create a new page for the new release, e.g. `_posts/2024-05-31-PMD-7.2.0.md` and copy
|
||||
the release notes into this page. This will appear under the news section.
|
||||
|
||||
Note: The release notes typically contain some Jekyll macros for linking to the rule pages. These macros won't
|
||||
@ -164,7 +165,7 @@ Check in all (version, blog post) changes to branch master:
|
||||
|
||||
The actual release is done by changing the versions, creating a tag and pushing this tag. Previously this was done
|
||||
by calling _maven-release-plugin_, but these steps are done without the plugin to have more control. And since we
|
||||
might reference a not yet released pmd-designer version, the test-build will fail.
|
||||
might reference a not yet released pmd-designer version, the test-build would fail.
|
||||
|
||||
We first change the version of PMD and all modules by basically removing the "-SNAPSHOT" suffix, building the changed
|
||||
project locally with tests (and with skipping pmd-cli and pmd-dist) in order to be sure, everything is in working
|
||||
@ -176,8 +177,8 @@ next snapshot version after the release. Skipping the builds of pmd-cli and pmd-
|
||||
the property `skip-cli-dist`.
|
||||
|
||||
```shell
|
||||
RELEASE_VERSION=6.34.0
|
||||
DEVELOPMENT_VERSION=6.35.0-SNAPSHOT
|
||||
RELEASE_VERSION=7.2.0
|
||||
DEVELOPMENT_VERSION=7.3.0-SNAPSHOT
|
||||
# Change version in the POMs to ${RELEASE_VERSION} and update build timestamp
|
||||
./mvnw --quiet versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false -DupdateBuildOutputTimestampPolicy=always
|
||||
# Transform the SCM information in the POM
|
||||
@ -218,18 +219,18 @@ Here is, what happens:
|
||||
* Render the documentation in `docs/` with `bundle exec jekyll build` and create a zip file from it.
|
||||
* Upload the doc zip file to the current (draft) GitHub Release under <https://github.com/pmd/pmd/releases> and
|
||||
to <https://sourceforge.net/projects/pmd/files/pmd/>.
|
||||
* Upload the documentation to <https://docs.pmd-code.org>, e.g. <https://docs.pmd-code.org/pmd-doc-6.34.0/> and
|
||||
* Upload the documentation to <https://docs.pmd-code.org>, e.g. <https://docs.pmd-code.org/pmd-doc-7.2.0/> and
|
||||
create a symlink, so that <https://docs.pmd-code.org/latest/> points to the new version.
|
||||
* Remove the old snapshot documentation, e.g. so that <https://docs.pmd-code.org/pmd-doc-6.34.0-SNAPSHOT/> is gone.
|
||||
Also create a symlink from pmd-doc-6.34.0-SNAPSHOT to pmd-doc-6.34.0, so that old references still work, e.g.
|
||||
<https://docs.pmd-code.org/pmd-doc-6.34.0-SNAPSHOT/> points to the released version.
|
||||
* Remove the old snapshot documentation, e.g. so that <https://docs.pmd-code.org/pmd-doc-7.2.0-SNAPSHOT/> is gone.
|
||||
Also create a symlink from pmd-doc-7.2.0-SNAPSHOT to pmd-doc-7.2.0, so that old references still work, e.g.
|
||||
<https://docs.pmd-code.org/pmd-doc-7.2.0-SNAPSHOT/> points to the released version.
|
||||
* Deploy javadoc to "https://docs.pmd-code.org/apidocs/*/RELEASE_VERSION/", e.g.
|
||||
<https://docs.pmd-code.org/apidocs/pmd-core/6.34.0/>. This is done for all modules.
|
||||
* Remove old javadoc for the SNAPSHOT version, e.g. delete <https://docs.pmd-code.org/apidocs/pmd-core/6.34.0-SNAPSHOT/>.
|
||||
<https://docs.pmd-code.org/apidocs/pmd-core/7.2.0/>. This is done for all modules.
|
||||
* Remove old javadoc for the SNAPSHOT version, e.g. delete <https://docs.pmd-code.org/apidocs/pmd-core/7.2.0-SNAPSHOT/>.
|
||||
* Create a draft news post on <https://sourceforge.net/p/pmd/news/> for the new release. This contains the
|
||||
rendered release notes.
|
||||
* Copy the documentation to sourceforge's web space, so that it is available as
|
||||
<https://pmd.sourceforge.io/pmd-6.34.0/>. All previously copied versions are listed
|
||||
<https://pmd.sourceforge.io/pmd-7.2.0/>. All previously copied versions are listed
|
||||
under <https://pmd.sourceforge.io/archive.phtml>.
|
||||
|
||||
The release on GitHub Actions currently takes about 30-45 minutes. Once this is done, you
|
||||
@ -271,6 +272,7 @@ Tweet on <https://twitter.com/pmd_analyzer>, eg.:
|
||||
|
||||
PMD 6.34.0 released: https://github.com/pmd/pmd/releases/tag/pmd_releases/6.34.0 #PMD
|
||||
|
||||
* Post the same twitter message into the gitter chat at <https://matrix.to/#/#pmd_pmd:gitter.im>
|
||||
|
||||
### Checklist
|
||||
|
||||
@ -289,6 +291,7 @@ Tweet on <https://twitter.com/pmd_analyzer>, eg.:
|
||||
| regression-tester | New release baseline is uploaded | <https://pmd-code.org/pmd-regression-tester> | <input type="checkbox"> |
|
||||
| mailing list | announcement on mailing list is sent | <https://sourceforge.net/p/pmd/mailman/pmd-devel/> | <input type="checkbox"> |
|
||||
| twitter | tweet about the new release | <https://twitter.com/pmd_analyzer> | <input type="checkbox"> |
|
||||
| gitter | message about the new release | <https://matrix.to/#/#pmd_pmd:gitter.im> | <input type="checkbox"> |
|
||||
|
||||
## Prepare the next release
|
||||
|
||||
@ -302,9 +305,9 @@ There are a couple of manual steps needed to prepare the current main branch for
|
||||
|
||||
```yaml
|
||||
pmd:
|
||||
version: 6.35.0-SNAPSHOT
|
||||
previous_version: 6.34.0
|
||||
date: ??-??-2021
|
||||
version: 7.3.0-SNAPSHOT
|
||||
previous_version: 7.2.0
|
||||
date: ??-??-2024
|
||||
release_type: minor
|
||||
```
|
||||
|
||||
@ -329,13 +332,13 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
{% tocmaker %}
|
||||
|
||||
### New and noteworthy
|
||||
### 🚀 New and noteworthy
|
||||
|
||||
### Fixed Issues
|
||||
### 🐛 Fixed Issues
|
||||
|
||||
### API Changes
|
||||
### 🚨 API Changes
|
||||
|
||||
### External Contributions
|
||||
### ✨ External Contributions
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
@ -368,15 +371,11 @@ from there. Then merge into the `master` branch and release from there. This way
|
||||
automatically the latest release on <https://docs.pmd-code.org/latest/> and on sourceforge.
|
||||
|
||||
|
||||
### (Optional) Create a new release branch
|
||||
### (Optional) Create a new maintenance branch
|
||||
|
||||
At some point, it might be time for a new maintenance branch. Such a branch is usually created from
|
||||
the `master` branch. Here are the steps:
|
||||
the tag. Here are the steps:
|
||||
|
||||
* Create a new branch: `git branch pmd/5.6.x master`
|
||||
* Update the version in both the new branch and master, e.g. `mvn versions:set -DnewVersion=5.6.1-SNAPSHOT`
|
||||
and `mvn versions:set -DnewVersion=5.7.0-SNAPSHOT`.
|
||||
* Update the release notes on both the new branch and master
|
||||
|
||||
The maintenance or bugfix branch could also be created later when needed from the actual tag. Then only the version on
|
||||
the maintenance branch needs to be set.
|
||||
* Create a new branch: `git branch pmd/7.1.x pmd_releases/7.1.0`
|
||||
* Update the version in both the new branch, e.g. `mvn versions:set -DnewVersion=7.1.1-SNAPSHOT`.
|
||||
* Update the release notes on both the new branch
|
||||
|
@ -24,7 +24,13 @@ The following PMD Logos and Icons are licensed under [CC BY 4.0](https://creativ
|
||||
* [Logo (600px, white)](images/logo/pmd-logo-white-600px.png)
|
||||
* [Logo (600px, white, suqare shape)](images/logo/pmd-logo-white-600px-squared.png)
|
||||
|
||||
* [Favicon (16x16)](images/logo/favicon.ico)
|
||||
Small variants, square shaped:
|
||||
* [PMD_small.svg](images/logo/PMD_small.svg)
|
||||
* [Small Logo (64px, transparent)](images/logo/pmd-logo-small-64px.png)
|
||||
* [Small Logo (64px, white)](images/logo/pmd-logo-small-white-64px.png)
|
||||
* [Small Logo (300px, transparent)](images/logo/pmd-logo-small-300px.png)
|
||||
* [Small Logo (300px, white)](images/logo/pmd-logo-small-white-300px.png)
|
||||
* [Favicon (32x32)](images/logo/favicon.ico)
|
||||
|
||||
This new greenish logo was introduced with PMD 7.
|
||||
|
||||
|
@ -24,70 +24,15 @@ Since this release, PMD will also expose any getter returning a collection of an
|
||||
/UserClass[@InterfaceNames = 'Queueable']
|
||||
```
|
||||
|
||||
### ✨ New rules
|
||||
|
||||
- The new Java rule {%rule java/bestpractices/UnnecessaryVarargsArrayCreation %} reports explicit array creation
|
||||
when a varargs is expected. This is more heavy to read and could be simplified.
|
||||
|
||||
### 🌟 Rule Changes
|
||||
|
||||
* {%rule java/bestpractices/JUnitTestsShouldIncludeAssert %} and {% rule java/bestpractices/JUnitTestContainsTooManyAsserts %}
|
||||
have a new property named `extraAssertMethodNames`. With this property, you can configure which additional static
|
||||
methods should be considered as valid verification methods. This allows to use custom mocking or assertion libraries.
|
||||
|
||||
### 🐛 Fixed Issues
|
||||
* core
|
||||
* [#494](https://github.com/pmd/pmd/issues/494): \[core] Adopt JApiCmp to enforce control over API changes
|
||||
* [#4942](https://github.com/pmd/pmd/issues/4942): \[core] CPD: `--skip-duplicate-files` has no effect (7.0.0 regression)
|
||||
* [#4959](https://github.com/pmd/pmd/pull/4959): \[core] Upgrade saxon to 12.4
|
||||
* cli
|
||||
* [#4791](https://github.com/pmd/pmd/issues/4791): \[cli] Could not find or load main class
|
||||
* [#4913](https://github.com/pmd/pmd/issues/4913): \[cli] cpd-gui closes immediately
|
||||
* doc
|
||||
* [#4901](https://github.com/pmd/pmd/issues/4901): \[doc] Improve documentation on usage of violationSuppressXPath
|
||||
* apex
|
||||
* [#4418](https://github.com/pmd/pmd/issues/4418): \[apex] ASTAnnotation.getImage() does not return value as written in the class
|
||||
* apex-errorprone
|
||||
* [#3953](https://github.com/pmd/pmd/issues/3953): \[apex] EmptyCatchBlock false positive with formal (doc) comments
|
||||
* java
|
||||
* [#4899](https://github.com/pmd/pmd/issues/4899): \[java] Parsing failed in ParseLock#doParse() java.io.IOException: Stream closed
|
||||
* [#4902](https://github.com/pmd/pmd/issues/4902): \[java] "Bad intersection, unrelated class types" for Constable\[] and Enum\[]
|
||||
* [#4947](https://github.com/pmd/pmd/issues/4947): \[java] Broken TextBlock parser
|
||||
|
||||
* java-bestpractices
|
||||
* [#1084](https://github.com/pmd/pmd/issues/1084): \[java] Allow JUnitTestsShouldIncludeAssert to configure verification methods
|
||||
* [#3216](https://github.com/pmd/pmd/issues/3216): \[java] New rule: UnnecessaryVarargsArrayCreation
|
||||
* [#4435](https://github.com/pmd/pmd/issues/4435): \[java] \[7.0-rc1] UnusedAssignment for used field
|
||||
* [#4569](https://github.com/pmd/pmd/issues/4569): \[java] ForLoopCanBeForeach reports on loop `for (int i = 0; i < list.size(); i += 2)`
|
||||
* [#4618](https://github.com/pmd/pmd/issues/4618): \[java] UnusedAssignment false positive with conditional assignments of fields
|
||||
* java-codestyle
|
||||
* [#4602](https://github.com/pmd/pmd/issues/4602): \[java] UnnecessaryImport: false positives with static imports
|
||||
* [#4785](https://github.com/pmd/pmd/issues/4785): \[java] False Positive: PMD Incorrectly report violation for UnnecessaryImport
|
||||
* [#4779](https://github.com/pmd/pmd/issues/4779): \[java] Examples in documentation of MethodArgumentCanBeFinal do not trigger the rule
|
||||
* [#4881](https://github.com/pmd/pmd/issues/4881): \[java] ClassNamingConventions: interfaces are identified as abstract classes (regression in 7.0.0)
|
||||
* java-design
|
||||
* [#2440](https://github.com/pmd/pmd/issues/2440): \[java] FinalFieldCouldBeStatic FN when the right side of the assignment is a constant expression
|
||||
* [#3694](https://github.com/pmd/pmd/issues/3694): \[java] SingularField ignores static variables
|
||||
* [#4873](https://github.com/pmd/pmd/issues/4873): \[java] AvoidCatchingGenericException: Can no longer suppress on the exception itself
|
||||
* java-errorprone
|
||||
* [#2056](https://github.com/pmd/pmd/issues/2056): \[java] CloseResource false-positive with URLClassLoader in cast expression
|
||||
* [#4928](https://github.com/pmd/pmd/issues/4928): \[java] EmptyCatchBlock false negative when allowCommentedBlocks=true
|
||||
* java-performance
|
||||
* [#3845](https://github.com/pmd/pmd/issues/3845): \[java] InsufficientStringBufferDeclaration should consider literal expression
|
||||
* [#4874](https://github.com/pmd/pmd/issues/4874): \[java] StringInstantiation: False-positive when using `new String(charArray)`
|
||||
* [#4886](https://github.com/pmd/pmd/issues/4886): \[java] BigIntegerInstantiation: False Positive with Java 17 and BigDecimal.TWO
|
||||
* pom-errorprone
|
||||
* [#4388](https://github.com/pmd/pmd/issues/4388): \[pom] InvalidDependencyTypes doesn't consider dependencies at all
|
||||
* [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name
|
||||
* [#4975](https://github.com/pmd/pmd/issues/4975): \[java] UnusedPrivateMethod false positive when using @MethodSource on a @Nested test
|
||||
|
||||
### 🚨 API Changes
|
||||
|
||||
#### Deprecated methods
|
||||
|
||||
* {%jdoc java::lang.java.rule.design.SingularFieldRule#mayBeSingular(java::lang.java.ast.ModifierOwner) %} has been deprecated for
|
||||
removal. The method is only useful for the rule itself and shouldn't be used otherwise.
|
||||
|
||||
### ✨ External Contributions
|
||||
* [#4864](https://github.com/pmd/pmd/pull/4864): Fix #1084 \[Java] add extra assert method names to Junit rules - [Erwan Moutymbo](https://github.com/emouty) (@emouty)
|
||||
* [#4894](https://github.com/pmd/pmd/pull/4894): Fix #4791 Error caused by space in JDK path - [Scrates1](https://github.com/Scrates1) (@Scrates1)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
|
@ -5,6 +5,113 @@ permalink: pmd_release_notes_old.html
|
||||
|
||||
Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases)
|
||||
|
||||
## 26-April-2024 - 7.1.0
|
||||
|
||||
The PMD team is pleased to announce PMD 7.1.0.
|
||||
|
||||
This is a minor release.
|
||||
|
||||
### Table Of Contents
|
||||
|
||||
* [🚀 New and noteworthy](#new-and-noteworthy)
|
||||
* [More robust CPD reports](#more-robust-cpd-reports)
|
||||
* [✨ New Rules](#new-rules)
|
||||
* [🌟 Rule Changes](#rule-changes)
|
||||
* [🐛 Fixed Issues](#fixed-issues)
|
||||
* [🚨 API Changes](#api-changes)
|
||||
* [Deprecated methods](#deprecated-methods)
|
||||
* [✨ External Contributions](#external-contributions)
|
||||
* [📈 Stats](#stats)
|
||||
|
||||
### 🚀 New and noteworthy
|
||||
|
||||
#### More robust CPD reports
|
||||
There were a number of circumstances, specially around (but not limited to) literal sequences, were CPD would
|
||||
report duplicate overlapping or partially overlapping matches. These have now been fixed, and CPD will report
|
||||
only the longest non-overlapping duplicate.
|
||||
|
||||
These improvements apply to all supported languages, irrespective of supported flags.
|
||||
|
||||
#### ✨ New Rules
|
||||
- The new Java rule [`UnnecessaryVarargsArrayCreation`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_bestpractices.html#unnecessaryvarargsarraycreation) reports explicit array creation
|
||||
when a varargs is expected. This is more heavy to read and could be simplified.
|
||||
- The new Java rule [`ConfusingArgumentToVarargsMethod`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_errorprone.html#confusingargumenttovarargsmethod) reports some confusing situations
|
||||
where a varargs method is called with an inexact argument type. These may end up in a mismatch between the expected
|
||||
parameter type and the actual value.
|
||||
- The new Java rule [`LambdaCanBeMethodReference`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_codestyle.html#lambdacanbemethodreference) reports lambda expressions that can be replaced
|
||||
with a method reference. Please read the documentation of the rule for more info. This rule is now part of the Quickstart
|
||||
ruleset.
|
||||
|
||||
#### 🌟 Rule Changes
|
||||
* [`JUnitTestsShouldIncludeAssert`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_bestpractices.html#junittestsshouldincludeassert) and [`JUnitTestContainsTooManyAsserts`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_bestpractices.html#junittestcontainstoomanyasserts)
|
||||
have a new property named `extraAssertMethodNames`. With this property, you can configure which additional static
|
||||
methods should be considered as valid verification methods. This allows to use custom mocking or assertion libraries.
|
||||
|
||||
### 🐛 Fixed Issues
|
||||
* core
|
||||
* [#494](https://github.com/pmd/pmd/issues/494): \[core] Adopt JApiCmp to enforce control over API changes
|
||||
* [#4942](https://github.com/pmd/pmd/issues/4942): \[core] CPD: `--skip-duplicate-files` has no effect (7.0.0 regression)
|
||||
* [#4959](https://github.com/pmd/pmd/pull/4959): \[core] Upgrade saxon to 12.4
|
||||
* cli
|
||||
* [#4791](https://github.com/pmd/pmd/issues/4791): \[cli] Could not find or load main class
|
||||
* [#4913](https://github.com/pmd/pmd/issues/4913): \[cli] cpd-gui closes immediately
|
||||
* doc
|
||||
* [#4901](https://github.com/pmd/pmd/issues/4901): \[doc] Improve documentation on usage of violationSuppressXPath
|
||||
* apex
|
||||
* [#4418](https://github.com/pmd/pmd/issues/4418): \[apex] ASTAnnotation.getImage() does not return value as written in the class
|
||||
* apex-errorprone
|
||||
* [#3953](https://github.com/pmd/pmd/issues/3953): \[apex] EmptyCatchBlock false positive with formal (doc) comments
|
||||
* cpp
|
||||
* [#2438](https://github.com/pmd/pmd/issues/2438): \[cpp] Repeated Duplication blocks
|
||||
* java
|
||||
* [#4899](https://github.com/pmd/pmd/issues/4899): \[java] Parsing failed in ParseLock#doParse() java.io.IOException: Stream closed
|
||||
* [#4902](https://github.com/pmd/pmd/issues/4902): \[java] "Bad intersection, unrelated class types" for Constable\[] and Enum\[]
|
||||
* [#4947](https://github.com/pmd/pmd/issues/4947): \[java] Broken TextBlock parser
|
||||
* java-bestpractices
|
||||
* [#1084](https://github.com/pmd/pmd/issues/1084): \[java] Allow JUnitTestsShouldIncludeAssert to configure verification methods
|
||||
* [#3216](https://github.com/pmd/pmd/issues/3216): \[java] New rule: UnnecessaryVarargsArrayCreation
|
||||
* [#4435](https://github.com/pmd/pmd/issues/4435): \[java] \[7.0-rc1] UnusedAssignment for used field
|
||||
* [#4569](https://github.com/pmd/pmd/issues/4569): \[java] ForLoopCanBeForeach reports on loop `for (int i = 0; i < list.size(); i += 2)`
|
||||
* [#4618](https://github.com/pmd/pmd/issues/4618): \[java] UnusedAssignment false positive with conditional assignments of fields
|
||||
* java-codestyle
|
||||
* [#4602](https://github.com/pmd/pmd/issues/4602): \[java] UnnecessaryImport: false positives with static imports
|
||||
* [#4785](https://github.com/pmd/pmd/issues/4785): \[java] False Positive: PMD Incorrectly report violation for UnnecessaryImport
|
||||
* [#4779](https://github.com/pmd/pmd/issues/4779): \[java] Examples in documentation of MethodArgumentCanBeFinal do not trigger the rule
|
||||
* [#4881](https://github.com/pmd/pmd/issues/4881): \[java] ClassNamingConventions: interfaces are identified as abstract classes (regression in 7.0.0)
|
||||
* java-design
|
||||
* [#2440](https://github.com/pmd/pmd/issues/2440): \[java] FinalFieldCouldBeStatic FN when the right side of the assignment is a constant expression
|
||||
* [#3694](https://github.com/pmd/pmd/issues/3694): \[java] SingularField ignores static variables
|
||||
* [#4873](https://github.com/pmd/pmd/issues/4873): \[java] AvoidCatchingGenericException: Can no longer suppress on the exception itself
|
||||
* java-errorprone
|
||||
* [#2056](https://github.com/pmd/pmd/issues/2056): \[java] CloseResource false-positive with URLClassLoader in cast expression
|
||||
* [#4751](https://github.com/pmd/pmd/issues/4751): \[java] PMD crashes when analyzing CloseResource Rule
|
||||
* [#4928](https://github.com/pmd/pmd/issues/4928): \[java] EmptyCatchBlock false negative when allowCommentedBlocks=true
|
||||
* [#4948](https://github.com/pmd/pmd/issues/4948): \[java] ImplicitSwitchFallThrough: False-positive with nested switch statements
|
||||
* java-performance
|
||||
* [#3845](https://github.com/pmd/pmd/issues/3845): \[java] InsufficientStringBufferDeclaration should consider literal expression
|
||||
* [#4874](https://github.com/pmd/pmd/issues/4874): \[java] StringInstantiation: False-positive when using `new String(charArray)`
|
||||
* [#4886](https://github.com/pmd/pmd/issues/4886): \[java] BigIntegerInstantiation: False Positive with Java 17 and BigDecimal.TWO
|
||||
* pom-errorprone
|
||||
* [#4388](https://github.com/pmd/pmd/issues/4388): \[pom] InvalidDependencyTypes doesn't consider dependencies at all
|
||||
* misc
|
||||
* [#4967](https://github.com/pmd/pmd/pull/4967): Fix reproducible build issues with 7.0.0
|
||||
|
||||
### 🚨 API Changes
|
||||
#### Deprecated methods
|
||||
* pmd-java
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.1.0/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.html#getBlock()"><code>ASTLambdaExpression#getBlock</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.1.0/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.html#getExpression()"><code>ASTLambdaExpression#getExpression</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.1.0/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.html#mayBeSingular(net.sourceforge.pmd.lang.java.ast.ModifierOwner)"><code>SingularFieldRule#mayBeSingular</code></a> has been deprecated for
|
||||
removal. The method is only useful for the rule itself and shouldn't be used otherwise.
|
||||
|
||||
### ✨ External Contributions
|
||||
* [#4864](https://github.com/pmd/pmd/pull/4864): Fix #1084 \[Java] add extra assert method names to Junit rules - [Erwan Moutymbo](https://github.com/emouty) (@emouty)
|
||||
* [#4894](https://github.com/pmd/pmd/pull/4894): Fix #4791 Error caused by space in JDK path - [Scrates1](https://github.com/Scrates1) (@Scrates1)
|
||||
|
||||
### 📈 Stats
|
||||
* 205 commits
|
||||
* 71 closed tickets & PRs
|
||||
* Days since last release: 34
|
||||
|
||||
|
||||
|
||||
## 22-March-2024 - 7.0.0
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<artifactId>pmd</artifactId>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -75,7 +75,7 @@ public class CognitiveComplexityRule extends AbstractApexRule {
|
||||
String.valueOf(classLevelThreshold),
|
||||
};
|
||||
|
||||
asCtx(data).addViolation(node, messageParams);
|
||||
asCtx(data).addViolation(node, (Object[]) messageParams);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
@ -78,7 +78,7 @@ public class CyclomaticComplexityRule extends AbstractApexRule {
|
||||
" total",
|
||||
classWmc + " (highest " + classHighest + ")", };
|
||||
|
||||
asCtx(data).addViolation(node, messageParams);
|
||||
asCtx(data).addViolation(node, (Object[]) messageParams);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pmd-compat6</artifactId>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -5,14 +5,20 @@
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
class MatchCollector {
|
||||
|
||||
private final List<Match> matchList = new ArrayList<>();
|
||||
private final Map<Integer, Map<Integer, Match>> matchTree = new TreeMap<>();
|
||||
private final Map<Integer, List<Match>> matchTree = new TreeMap<>();
|
||||
|
||||
private final Map<Integer, Set<Integer>> tokenMatchSets = new HashMap<>();
|
||||
|
||||
private final MatchAlgorithm ma;
|
||||
|
||||
MatchCollector(MatchAlgorithm ma) {
|
||||
@ -21,12 +27,18 @@ class MatchCollector {
|
||||
|
||||
public void collect(List<TokenEntry> marks) {
|
||||
// first get a pairwise collection of all maximal matches
|
||||
for (int i = 0; i < marks.size() - 1; i++) {
|
||||
int skipped;
|
||||
for (int i = 0; i < marks.size() - 1; i += skipped + 1) {
|
||||
skipped = 0;
|
||||
TokenEntry mark1 = marks.get(i);
|
||||
for (int j = i + 1; j < marks.size(); j++) {
|
||||
TokenEntry mark2 = marks.get(j);
|
||||
int diff = mark1.getIndex() - mark2.getIndex();
|
||||
if (-diff < ma.getMinimumTileSize()) {
|
||||
// self-repeating sequence such as ABBABBABB with min 6,
|
||||
// will match 2 against any other occurrence of ABBABB
|
||||
// avoid duplicate overlapping reports by skipping it on the next outer loop
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
if (hasPreviousDupe(mark1, mark2)) {
|
||||
@ -38,7 +50,7 @@ class MatchCollector {
|
||||
if (dupes < ma.getMinimumTileSize()) {
|
||||
continue;
|
||||
}
|
||||
// is it still too close together
|
||||
// both blocks overlap
|
||||
if (diff + dupes >= 1) {
|
||||
continue;
|
||||
}
|
||||
@ -48,37 +60,71 @@ class MatchCollector {
|
||||
}
|
||||
|
||||
private void reportMatch(TokenEntry mark1, TokenEntry mark2, int dupes) {
|
||||
matchTree.compute(dupes, (dupCount, matches) -> {
|
||||
if (matches == null) {
|
||||
matches = new TreeMap<>();
|
||||
addNewMatch(mark1, mark2, dupCount, matches);
|
||||
} else {
|
||||
Match matchA = matches.get(mark1.getIndex());
|
||||
Match matchB = matches.get(mark2.getIndex());
|
||||
/*
|
||||
* Check if the match is previously know. This can happen when a snippet is duplicated more than once.
|
||||
* If A, B and C are identical snippets, MatchAlgorithm will find the matching pairs:
|
||||
* - AB
|
||||
* - AC
|
||||
* - BC
|
||||
* It should be reduced to a single match with 3 marks
|
||||
*/
|
||||
if (tokenMatchSets.computeIfAbsent(mark1.getIndex(), HashSet::new).contains(mark2.getIndex())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (matchA == null && matchB == null) {
|
||||
addNewMatch(mark1, mark2, dupes, matches);
|
||||
} else if (matchA == null) {
|
||||
matchB.addMark(mark1);
|
||||
matches.put(mark1.getIndex(), matchB);
|
||||
} else if (matchB == null) {
|
||||
matchA.addMark(mark2);
|
||||
matches.put(mark2.getIndex(), matchA);
|
||||
// This may not be a "new match", but actually a sub-match of a larger one.
|
||||
// always rely on the lowest mark index, as that's the order in which process them
|
||||
final int lowestKey = tokenMatchSets.get(mark1.getIndex()).stream().reduce(mark1.getIndex(), Math::min);
|
||||
|
||||
List<Match> matches = matchTree.computeIfAbsent(lowestKey, ArrayList::new);
|
||||
Iterator<Match> matchIterator = matches.iterator();
|
||||
while (matchIterator.hasNext()) {
|
||||
Match m = matchIterator.next();
|
||||
|
||||
// Check all other marks
|
||||
for (Mark otherMark : m.getMarkSet()) {
|
||||
TokenEntry otherEnd = otherMark.getToken();
|
||||
if (otherEnd.getIndex() == mark1.getIndex()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// does the new match supersedes this one?
|
||||
if (otherEnd.getIndex() < mark2.getIndex() && otherEnd.getIndex() + m.getTokenCount() >= mark2.getIndex() + dupes) {
|
||||
// this match is embedded in the previous one… ignore it.
|
||||
return;
|
||||
} else if (mark2.getIndex() < otherEnd.getIndex() && mark2.getIndex() + dupes >= otherEnd.getIndex() + m.getTokenCount()) {
|
||||
// the new match is longer and overlaps with the old one - replace it
|
||||
matchIterator.remove();
|
||||
break;
|
||||
} else if (dupes == m.getTokenCount()) {
|
||||
// we found yet another exact match of the same snippet. Roll it together
|
||||
|
||||
// Add this adjacency to all combinations
|
||||
m.iterator().forEachRemaining(other -> registerTokenMatch(other.getToken(), mark2));
|
||||
|
||||
m.addMark(mark2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
});
|
||||
}
|
||||
|
||||
// this is a new match, add it
|
||||
matches.add(new Match(dupes, mark1, mark2));
|
||||
|
||||
// add matches in both directions
|
||||
registerTokenMatch(mark1, mark2);
|
||||
}
|
||||
|
||||
private void addNewMatch(TokenEntry mark1, TokenEntry mark2, int dupes, Map<Integer, Match> matches) {
|
||||
Match match = new Match(dupes, mark1, mark2);
|
||||
matches.put(mark1.getIndex(), match);
|
||||
matches.put(mark2.getIndex(), match);
|
||||
matchList.add(match);
|
||||
private void registerTokenMatch(TokenEntry mark1, TokenEntry mark2) {
|
||||
tokenMatchSets.computeIfAbsent(mark1.getIndex(), HashSet::new).add(mark2.getIndex());
|
||||
tokenMatchSets.computeIfAbsent(mark2.getIndex(), HashSet::new).add(mark1.getIndex());
|
||||
}
|
||||
|
||||
List<Match> getMatches() {
|
||||
return matchList;
|
||||
return matchTree.values().stream().reduce(new ArrayList<>(), (acc, matches) -> {
|
||||
acc.addAll(matches);
|
||||
return acc;
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasPreviousDupe(TokenEntry mark1, TokenEntry mark2) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
package net.sourceforge.pmd.lang.rule.xpath.internal;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
@ -105,16 +106,15 @@ abstract class BaseNodeInfo extends AbstractNodeWrapper implements SiblingCounti
|
||||
return iterateList(nodes, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
static AxisIterator iterateList(List<? extends NodeInfo> nodes, boolean forwards) {
|
||||
return forwards ? new NodeListIterator((List<NodeInfo>) nodes)
|
||||
: new RevListAxisIterator((List<NodeInfo>) nodes);
|
||||
static <N extends NodeInfo> AxisIterator iterateList(List<N> nodes, boolean forwards) {
|
||||
return forwards ? new NodeListIterator(Collections.unmodifiableList(nodes))
|
||||
: new RevListAxisIterator<>(nodes);
|
||||
}
|
||||
|
||||
private static class RevListAxisIterator implements AxisIterator {
|
||||
private final ListIterator<NodeInfo> iter;
|
||||
private static class RevListAxisIterator<N extends NodeInfo> implements AxisIterator {
|
||||
private final ListIterator<N> iter;
|
||||
|
||||
RevListAxisIterator(List<NodeInfo> list) {
|
||||
RevListAxisIterator(List<N> list) {
|
||||
iter = list.listIterator(list.size());
|
||||
}
|
||||
|
||||
|
@ -662,6 +662,18 @@ public final class CollectionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Union of two PSets, which avoids creating a new pset if possible.
|
||||
*/
|
||||
public static <V> PSet<V> union(PSet<V> as, PSet<V> bs) {
|
||||
if (as.isEmpty()) {
|
||||
return bs;
|
||||
} else if (bs.isEmpty()) {
|
||||
return as;
|
||||
}
|
||||
return as.plusAll(bs);
|
||||
}
|
||||
|
||||
public static @NonNull <T> List<T> makeUnmodifiableAndNonNull(@Nullable List<? extends T> list) {
|
||||
if (list instanceof PSequence) {
|
||||
return (List<T>) list;
|
||||
|