Output, transport and consumer POM robustness fixes - #12951
Conversation
52ce9a5 to
a118910
Compare
gnodet
left a comment
There was a problem hiding this comment.
✅ Solid PR — Two Minor Style Observations
Well-structured multi-topic robustness PR with good test coverage across all changes: control character sanitization, fail-closed mirror matching, transport path traversal prevention, settings decryption message improvement, consumer POM repository restriction, and mvnup settings resolution. This is the master sibling of #12946 (maven-4.0.x), which was already approved.
Minor observations (non-blocking):
-
Style (
MavenITgh10210SettingsXmlDecryptTest.java:77):assertTrue(!log.contains(...))→assertFalse(log.contains(...))for readability and better assertion failure messages. -
Logging level (
DefaultConsumerPomBuilder.java:603): The "publishing repository" message for retained repositories is logged atWARN. Unlike the dropped-repository message (which is genuinely a warning about a behavioral change), this message is purely informational — it confirms that a repository the project declared is being kept. UsingWARNhere will be noisy for projects declaring custom repositories, especially in CI pipelines that fail-on-warn.INFOorDEBUGwould be more appropriate.
📋 PR Metadata
| Aspect | Current | Suggested |
|---|---|---|
| Milestone | (none) | 4.1.0 |
🔀 Backport Status
- ✅
maven-4.0.x— #12946 (OPEN, reviewed & approved)
🤖 This review was generated by ForgeBot.
Repository-supplied strings (checksum mismatch messages, resource names, repository ids/urls) were written straight to the console or logger without any filtering of control characters. Add a small sanitize() helper to AbstractMavenTransferListener (impl/maven-cli and the deprecated compat/maven-embedder copy) that replaces C0 controls other than tab/newline, DEL, and C1 controls with visible \uXXXX escapes, and apply it everywhere these listeners print remote-derived text, so terminal output always reflects what was actually printed.
Normalize the repository base URI to end with a slash before resolving a relative get/put location, and centralize the containment check in a shared helper. This keeps URI.resolve() on a whole path segment boundary and makes get/put behave consistently regardless of whether the configured repository URL carries a trailing slash.
isExternalRepo/isExternalHttpRepo parsed the repository URL with java.net.URL, which has no stream handler for the dav/dav:http/dav+http schemes wagon-webdav speaks and throws for any other unparseable URL; both methods caught the exception and returned false, so such a repository was classified as neither external nor external-http and silently skipped the external:*/external:http:* mirror rules, including the shipped external:http:* blocker. Parse the scheme and host textually instead, the way the resolver's own mirror matcher does, so these URLs are classified and matched like any other.
199708d to
30611a1
Compare
The consumer POM's <repositories> section previously published every effective-model repository except 'central', including repositories that only reached the effective model through parent-POM inheritance or an active settings.xml profile. Restrict publication to repository ids declared in the project's own raw POM (model or profiles); everything else is dropped, with a WARN naming each dropped repository and an INFO naming each retained repository so operators can see what a deploy will publish. The new user property maven.consumer.pom.sanitizeRepositories (default true) restores the previous behavior when set to false.
The existing regression tests for consumer-POM repository scoping only checked the intermediate Model object returned by transformNonPom(). Add a test that builds a bom-packaged project through the real public PomBuilder entry point and serializes the result with the same MavenStaxWriter the production ConsumerPomArtifactTransformer uses, so the assertion is against the actual generated POM XML.
mvnup's compatibility and plugin-upgrade strategies built effective models with a standalone session that always remapped user.home to a test directory and hardcoded Maven Central plus an Apache snapshots repository, ignoring the operator's real settings.xml (mirrors, proxies, offline mode, blocked repositories) entirely. ApiRunner.createSession() gains an isolateUserHome flag (existing callers keep isolation; production callers can opt out). mvnup now builds its session against the operator's real settings and local repository when settings were loaded, drops the hardcoded snapshots repository, and skips remote-model-dependent analysis with a warning when the effective settings declare a mirror, proxy or offline mode the standalone resolver cannot honor, instead of resolving around it.
isExternalRepo/isExternalHttpRepo in the legacy DefaultMirrorSelector parsed the repository URL with java.net.URL, which has no stream handler for the dav/dav:http/dav+http schemes wagon-webdav speaks and throws for any other unparseable URL, silently skipping the external:*/external:http:* mirror rules for such repositories. Parse the scheme and host textually instead, matching the fix already applied to MavenRepositorySystem.
30611a1 to
225e9f1
Compare
Robustness fixes across the CLI, transport and consumer POM.
isExternalRepo/isExternalHttpRepoparsed withjava.net.URL, which throws ondav:,dav:http:anddav+http:— leaving those branches unreachable — and returnedfalseon any parse failure, so an unparseable URL matched noexternal:*mirror. Parsing is now textual and an unparseable URL is treated as external.settings.xmlprofile are dropped, with a warning naming each.maven.consumer.pom.sanitizeRepositories=falserestores the previous behaviour. This changes a published artifact format — see the note below.mvnupreused hardcoded repositories and forceduser.home, so a realsettings.xmlwas never read. It now uses the settings the CLI already loaded and the configured local repository. Where the standalone resolver cannot honour the configuration — offline mode, a redirecting mirror, an active proxy — it is given no remote repositories and the affected strategies skip their remote work with a warning.Release note for the consumer POM change: a downstream consumer relying on inheriting a repository declaration that existed only in a parent POM or the publisher's settings will need to declare that repository itself.
Each change is a separate commit.
Draft while related code paths are reviewed — the same guard may be needed in sibling implementations of these interfaces, and I would rather establish that before asking for review time.