Remove PathSelector, replaced by Maven 4 PathMatcherFactory. - #1106
Remove PathSelector, replaced by Maven 4 PathMatcherFactory.#1106desruisseaux wants to merge 2 commits into
Conversation
ascheman
left a comment
There was a problem hiding this comment.
I went through this change and built it locally (JDK 17, Maven 4.0.0-rc-6): clean verify is green, and the ITs pass — includes-excludes, modular-sources, module-info-patch, jpms_patch-module, multirelease-with-modules and all multirelease-patterns/* among them (62 IT projects in total). Removing the duplicated PathSelector in favour of the core service looks right to me, and it is a net win for test coverage: the plugin copy had no unit tests, while core has PathSelectorTest + DefaultPathMatcherFactoryTest.
Nothing blocking — one behaviour change I think deserves a note, plus a javadoc nit inline and an optional follow-up.
Explicit glob: patterns now match relative to the source root
To convince myself the replacement is equivalent, I compiled the deleted PathSelector standalone and compared it against DefaultPathMatcherFactory from maven-impl:4.0.0-rc-6 over 140 include/exclude combinations × 14 representative paths. The verdicts are identical everywhere except for patterns that carry an explicit glob: prefix.
Reason: the deleted copy set needRelativize = false when every normalized pattern started with glob:**/, and then matched the absolute path. In Maven syntax that never triggered, because the normalizer adds variants that do not start with **/, which forces relativization. It only took effect when a user wrote the prefix explicitly. Core's PathSelector always relativizes.
Two observable consequences, both reproduced:
-
glob:**/*.javano longer matches sources directly in the source root (Foo.java,module-info.java,package-info.java) — previously**/consumed the leading directories of the absolute path. -
Directories above the source root could satisfy pattern components. For a project under
/home/user/impl/projectwith<include>glob:**/impl/**</include>:com/example/App.java old=true new=false com/example/impl/AppImpl.java old=true new=truecom/example/App.javais below noimpldirectory at all — the old match came purely from the checkout location.
So the new behaviour is the correct one (both javadocs state that pathnames are relative to the base directory), and this PR quietly fixes that. It is still user-visible, though: a project using glob:-prefixed includes may end up with fewer files compiled. Would you consider mentioning it in the PR description / release notes, and perhaps adding an explicit-prefix case to src/it/includes-excludes, which currently only exercises Maven syntax?
Optional follow-up: directory pruning
PathMatcherFactory.deriveDirectoryMatcher() would let PathFilter.preVisitDirectory skip whole subtrees; today it only skips hidden directories. The removed couldHoldSelected(Path) offered the same thing and was already unused here, so this PR changes nothing — just a cheap win left on the table on large source trees (and maybe what the javadoc nit below was anticipating).
gnodet
left a comment
There was a problem hiding this comment.
Review Summary
Clean, well-scoped PR that consolidates the plugin-local PathSelector class into Maven core's PathMatcherFactory service. Three review questions were investigated — all resolved as non-issues:
- Behavioral parity:
PathMatcherFactory.createPathMatcher()replaces thenew PathSelector(…).simplify()pattern. The author (Martin Desruisseaux) is the primary author of the originalPathSelector, so this is the author moving their own code upstream — not a third-party swap. ThecouldHoldSelected()optimization was never called byPathFilter, so nothing is lost. CI passes on all 20 OS/JDK matrix entries. - Stale references: No orphan references to
PathSelectorremain outside the files modified by this PR. - Test coverage: No dedicated
PathSelectorTestexisted before this PR. The include/exclude filtering behavior is exercised by existing integration tests (confirmed by 20 green CI jobs).
Net result: −549 lines of plugin-local code replaced by a single @Inject-ed core service. 👍
This review does not replace specialized review tools such as CodeRabbit or Sourcery, or static analyzers such as SonarCloud. This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
… Javadoc: rename a field as documented and add the missing field for directories.
|
I updated the description for mentioning the behavioural change. There is no test in the compiler plugin, but a test has already been added by apache/maven#12621 for the problem described in above comment with the |
Following the upgrade to Maven 4.0.0-rc-6, it is now possible to remove the
PathSelectorclass. It is replaced by thePathMatcherFactoryservice provided by Maven core. The behaviour is nearly identical, except when the pattern starts withglob:**/. For example, theglob:**/*.javapattern no longer matches files in the root directory such asmodule-info.java. The new behaviour is compliant with thejava.nio.file.PathMatcherspecification. See the comment below for more details.