Skip to content

[MNG-8686] Add SourceRoot.matcher(boolean) method #2236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 12, 2025

Conversation

desruisseaux
Copy link
Contributor

@desruisseaux desruisseaux commented Apr 5, 2025

Following the revert of includes/excludes filters from PathMatcher to String in #2232, this pull request adds a new SourceRoot.matcher(boolean) method which provides the PathMatcher. Contrarily to the previous methods, this new method provides a single matcher combining the work of all includes and all excludes. The default implementation is ported from apache/maven-clean-plugin#243.

JIRA issue: MNG-8686

Copy link
Contributor

@elharo elharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have/need a JIRA issue?

@desruisseaux
Copy link
Contributor Author

JIRA issue created: https://issues.apache.org/jira/browse/MNG-8686

@desruisseaux desruisseaux changed the title Add SourceRoot.matcher(boolean) method [MNG-8686] Add SourceRoot.matcher(boolean) method Apr 12, 2025
@gnodet
Copy link
Contributor

gnodet commented Apr 13, 2025

Following the revert of includes/excludes filters from PathMatcher to String in #2232, this pull request adds a new SourceRoot.matcher(boolean) method which provides the PathMatcher. Contrarily to the previous methods, this new method provides a single matcher combining the work of all includes and all excludes. The default implementation is ported from apache/maven-clean-plugin#243.

We'd need to carefully review the maven-resources-plugins various options and see if they can fit this API. IIRC, there are options such as symlinks following, but there may be others.

@desruisseaux
Copy link
Contributor Author

We'd need to carefully review the maven-resources-plugins various options and see if they can fit this API. IIRC, there are options such as symlinks following, but there may be others.

Yes. This is another aspect replaced by standard Java now, with java.nio.file.FileVisitOption.FOLLOW_LINKS. One issue is that it behaves differently than the current Maven for one kind of link specific to the Windows platform: NTFS "junction links". This is handled by a special case in apache/maven-clean-plugin#243. Thankfully, the maven-cleaner-plugin has a quite extensive test suite that covers this case among others.

Symbolic links are not handled by the PathSelector class proposed in this pull request. They need to be handled later, in our use of java.nio.file.FileVisitor, which is not part of this PR. I was thinking to address FileVisitor in a separated PR.

@gnodet gnodet added this to the 4.0.0-rc-4 milestone May 9, 2025
@gnodet
Copy link
Contributor

gnodet commented May 9, 2025

@desruisseaux can you rebase or merge master branch to fix the conflict ?

…), add a `SourceRoot.matcher(boolean)` method.

The matcher returned by that method combines the effects of all includes and excludes.

When using the Maven syntax, escape the special characters [ ] { } \ before to delegate to the glob syntax.
Optimization: omit excludes that are unnecessary because they will never match a file accepted by includes.
This is especially useful when the default excludes are added, because there is a lot of them.
@desruisseaux
Copy link
Contributor Author

Rebasing done.

Copy link
Contributor

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polish

Copy link
Contributor

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider Migrate JUnit asserts to AssertJ

String s = matcher.toString();
assertTrue(s.contains("glob:**/*.java"));
assertFalse(s.contains("project.pj")); // Unnecessary exclusion should have been omitted.
assertFalse(s.contains(".DS_Store"));
Copy link
Contributor

@Pankraz76 Pankraz76 May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assertFalse(s.contains(".DS_Store"));
assertThat(s).contains(".DS_Store");

new code, already, considered, outdated - therefore increasing technical dept.

to reach next lvl, we need leadership and team up to standardize DOD.

image

consider migration to avoid boilerplate API usage.

Still new manual interaction due to bug:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do the refactoring in the other PR related to AssertJ migration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: VIP <8830888+Pankraz76@users.noreply.github.com>
Copy link
Contributor

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warnings

* Note that a prefix or suffix may be the empty string, which match everything.
*/
final Iterator<String> it = excludes.iterator();
nextExclude:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused label 'nextExclude'

image

* @return the given array, or a smaller array if some fragments were discarded because redundant
*/
private static String[] sortByLength(final String[] fragments, final boolean suffix) {
Arrays.sort(fragments, (s1, s2) -> s1.length() - s2.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be replaced with 'Comparator.comparingInt'

Suggested change
Arrays.sort(fragments, (s1, s2) -> s1.length() - s2.length());
Arrays.sort(fragments, Comparator.comparingInt(String::length));
image

* <p><b>Source:</b> this list is copied from {@code plexus-utils-4.0.2} (released in
* September 23, 2024), class {@code org.codehaus.plexus.util.AbstractScanner}.</p>
*/
private static final List<String> DEFAULT_EXCLUDES = List.of(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might use simple alphabetical order sorter like in .propertie files - to get sort and grouping out of the box:

The comments mostly DRY.

Suggested change
private static final List<String> DEFAULT_EXCLUDES = List.of(
private static final List<String> DEFAULT_EXCLUDES = List.of(
"**/*~",
"**/#*#",
"**/.#*",
"**/%*%",
"**/._*",
"**/CVS",
"**/CVS/**",
"**/.cvsignore",
"**/RCS",
"**/RCS/**",
"**/SCCS",
"**/SCCS/**",
"**/vssver.scc",
"**/project.pj",
"**/.svn",
"**/.svn/**",
"**/.arch-ids",
"**/.arch-ids/**",
"**/.bzr",
"**/.bzr/**",
"**/.MySCMServerInfo",
"**/.DS_Store",
"**/.metadata",
"**/.metadata/**",
"**/.hg",
"**/.hg/**",
"**/.git",
"**/.git/**",
"**/.gitignore",
"**/BitKeeper",
"**/BitKeeper/**",
"**/ChangeSet",
"**/ChangeSet/**",
"**/_darcs",
"**/_darcs/**",
"**/.darcsrepo",
"**/.darcsrepo/**",
"**/-darcs-backup*",
"**/.darcs-temp-mail"
);

Copy link
Contributor

@Pankraz76 Pankraz76 May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (baseDirectory.equals(directory)) {
return true;
}
directory = baseDirectory.relativize(directory);
Copy link
Contributor

@Pankraz76 Pankraz76 May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smell never reassign params as we live in final land.

give dedication method and apply functional programming.

https://pmd.github.io/pmd/pmd_rules_java_bestpractices.html#avoidreassigningparameters

Copy link
Contributor

@Pankraz76 Pankraz76 May 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    public boolean couldHoldSelected(Path directory) {
        return baseDirectory.equals(directory) || isABoolean(baseDirectory.relativize(directory));
    }

    private boolean isABoolean(Path directory) {
        return dirIncludes.length == 0 || isMatched(directory, dirIncludes)
                && (dirExcludes.length == 0 || !isMatched(directory, dirExcludes));
    }
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

important AvoidReassigningParameters is of course part of bestpractices .

Still not encountered in

image

Copy link
Contributor

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkup

@gnodet gnodet merged commit 75b6c11 into apache:master May 12, 2025
13 checks passed
@Pankraz76
Copy link
Contributor

leveraging PMD will prevent flaws from being merged.

@Pankraz76
Copy link
Contributor

this could not compile with help of https://docs.openrewrite.org/recipes/staticanalysis/finalizemethodarguments

@Pankraz76
Copy link
Contributor

rewrite would make the boilerplate way i would prefer silent PMD.

https://adabeat.com/fp/immutability-in-functional-programming/

We make everywhere boilerplate to throw NPE ourselfs. This would really help to make thinks more robust. immutability is/should be the default case. Kotlin is all about being final and avoiding silly NPE. Thats why we want to live in final existence. Trying to reach invinity.

Pankraz76 added a commit to Pankraz76/maven that referenced this pull request May 12, 2025
The matcher returned by that method combines the effects of all includes and excludes.

When using the Maven syntax, escape the special characters [ ] { } \ before to delegate to the glob syntax.
Optimization: omit excludes that are unnecessary because they will never match a file accepted by includes.
This is especially useful when the default excludes are added, because there is a lot of them.

---------

Co-authored-by: VIP <8830888+Pankraz76@users.noreply.github.com>
@gnodet
Copy link
Contributor

gnodet commented May 12, 2025

rewrite would make the boilerplate way i would prefer silent PMD.

https://adabeat.com/fp/immutability-in-functional-programming/

We make everywhere boilerplate to throw NPE ourselfs. This would really help to make thinks more robust. immutability is/should be the default case. Kotlin is all about being final and avoiding silly NPE. Thats why we want to live in final existence. Trying to reach invinity.

I don't think we want additional reports. Or that would nice as a GitHub action that runs on PRs.
Additional reports without any automatic way to fix the issue on a big codebase it just useless.

@Pankraz76
Copy link
Contributor

useless

disagree, its called best practise for reason.

agree, with help of rewrite, we can get benefits for free. Enforcing really strong coding guidelines.

@Pankraz76
Copy link
Contributor

Pankraz76 commented May 13, 2025

just need to use what we already got:

image

I see plugin in pom, but not running. So im this should be our SPOT meaning single point of truth.

https://pmd.github.io/pmd/pmd_rules_java_bestpractices.html

Then we dont have friction about final params. Im sure @desruisseaux very capable of, and would like to, following patterns to avoid bugs. We all want to best for the code.

@gnodet
Copy link
Contributor

gnodet commented May 13, 2025

rewrite would make the boilerplate way i would prefer silent PMD.
https://adabeat.com/fp/immutability-in-functional-programming/
We make everywhere boilerplate to throw NPE ourselfs. This would really help to make thinks more robust. immutability is/should be the default case. Kotlin is all about being final and avoiding silly NPE. Thats why we want to live in final existence. Trying to reach invinity.

I don't think we want additional reports. Or that would nice as a GitHub action that runs on PRs. Additional reports without any automatic way to fix the issue on a big codebase it just useless.

Actually, they are available at https://maven.apache.org/ref/4.0.0-rc-3/maven-impl-modules/maven-core/pmd.html but I don't think we'll keep them on the long term.

@Pankraz76
Copy link
Contributor

Pankraz76 commented May 13, 2025

long term

yes, rewrite has ability to dominate.

@desruisseaux
Copy link
Contributor Author

If the discussion is about avoiding to reassign parameter values, those best practices are guidelines, often improving software but not always. For example, reassigning a parameter with something unrelated is dangerous. In that case, the best practice applies. But reassigning a parameter with a "fixed" (from the perspective of what the method wants to do) value can be good since it guarantees that the potentially broken value is never used. For example, if a method said that it ignores leading and trailing spaces, doing arg = arg.strip() at the beginning guarantees the "wrong" (from method's perspective) value with spaces will never be used.

@Pankraz76
Copy link
Contributor

not always

yes, will always allow suppression making exception, for good argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants