CAMEL-23492: Replace npm/Yarn/Gulp doc build with a Maven plugin#23198
Conversation
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
|
🧪 CI tested the following changed modules:
Build reactor — dependencies compiled but only changed modules were tested (2 modules)
|
| components.asciidoc = new KindSpec( | ||
| List.of( | ||
| "core/camel-base/src/main/docs/*-component.adoc", | ||
| "components/*/src/main/docs/*-component.adoc", |
There was a problem hiding this comment.
I've used this syntax to limit the number of subtrees the file walker can reach, matching gulpfile.js's behavior. Is this really necessary?
gnodet
left a comment
There was a problem hiding this comment.
Review: CAMEL-23492 - Replace npm/Yarn/Gulp doc build with Maven plugin
Overall Assessment: Well-executed port. Removing the Node.js toolchain eliminates a significant external dependency and simplifies the build. The byte-for-byte equivalence verification is the right way to validate a port like this. The code is well-structured with good Javadoc explaining design decisions.
Recommendation: Approve with minor fix needed.
Strengths
- Clean removal of the entire Node toolchain (yarn 3.2.3, gulpfile, package.json, yarn.lock) — net -5,782 lines
- Byte-for-byte equivalence verification provides strong confidence
- Windows symlink fallback handling (matches vinyl-fs behavior)
- Good unit tests for the trickiest logic — NavComparator transitivity, template substitution, title extraction
- The NavComparator actually fixes a latent bug in the gulpfile's
compare()which was not antisymmetric (returned1when both titles were equal, violating the comparator contract). The filename tiebreaker makes the ordering total and stable.
Issue to fix
FQCN usage for java.io.File: Lines 92 and 100 of PrepareDocSymlinksMojo.java use java.io.File as a fully-qualified type instead of importing it. Please add import java.io.File; and use the simple class name — this follows the project's import style convention.
Minor observations (non-blocking)
1. Subtle glob differences from gulpfile (non-observable)
- "others" depth: The mojo includes
components/*/*/*/src/main/docs/*.adocfor the "others" group, while the gulpfile only matches up to 2 levels ({*,*/*}). Currently produces identical output (no 3-level non-component adoc exists), but is slightly more liberal. - PRUNED_DIRS: The mojo prunes
.camel-jbangby exact name match, while the gulpfile uses.camel-jbang*glob (would also exclude.camel-jbang-worketc.). Not currently observable.
Both are academic — the byte-for-byte diff proves equivalence on the current tree.
2. Non-recursive nav file scanning: createNav() uses Files.list() (flat) while the gulpfile uses **/*.adoc (recursive). Not a problem since all symlinked files are flat, but worth noting the assumption.
Test Coverage
The tests cover the trickiest logic well (replaceBlock, extractTitle, NavComparator transitivity). The remaining methods (matchesJsonFilter, clean, walk, createExampleSymlinks) are covered by the byte-equivalence diff — reasonable tradeoff.
Claude Code on behalf of Guillaume Nodet
|
Pulling back to review |
|
Update on review items and a latent issue surfaced by improved logging Pushed changes addressing the review:
Additional improvements made while verifying parity:
Latent issue surfaced (pre-existing on The new logging revealed 4 basename collisions in the dataformats group, where the Jackson 3.x components (
The effect is visible on the public dataformats index — the "JSON Jackson" entry on https://camel.apache.org/components/next/dataformats/index.html resolves to the Jackson 3 page rather than Jackson 2:
This collision exists on Verification: Claude Code on behalf of Adriano Machado |
|
about jackson vs jackson3, then lets tackle this in another PR. We should skip the jackson3 so we keep it as today. The jackson3 are special for SB4 and will eventually replace when we drop jackson2 later - but today too much is still jackson2 dependent. |
|
There are uncommitted changes |
Port docs/gulpfile.js to a new prepare-doc-symlinks goal in camel-package-maven-plugin and remove the Node toolchain (package.json, yarn.lock, .yarnrc.yml, .yarn/, gulpfile.js). Output is byte-for-byte equivalent with the previous gulp pipeline. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Adriano Machado <60320+ammachado@users.noreply.github.com> rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED
rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED
rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED
|
LGTM @ammachado do you mind creating a JIRA about the jackson2 vs 3 issue you identified and you are welcome to work on another PR to fix/improve this |
|
CAMEL-23531 was created to track JSON Jackson issue identified above. |

Description
CAMEL-23492: Replace npm/Yarn/Gulp doc build with a Maven plugin
Replaces the Node.js/Yarn/Gulp pipeline in
docs/with a newprepare-doc-symlinksgoal incamel-package-maven-plugin, and removes the Node toolchain entirely (package.json,yarn.lock,.yarnrc.yml,.yarn/,gulpfile.js).The new mojo ports the three responsibilities of
docs/gulpfile.js:.adoc, image and.jsonfiles fromcomponents/**,core/**,dsl/**into the Antora source tree underdocs/components/modules/...andcore/camel-core-engine/src/main/docs/modules/eips/....nav.adocfiles fromdocs/*-nav.adoc.template, using each file's:doctitle:and optional:group:. Sort order matches the original gulpcompare()(case-insensitive, summary-before-group), with a filename tiebreaker for TimSort transitivity.include::{examplesdir}/...references from each linked.adocand symlink the referenced examples undercomponents/modules/ROOT/examples/....Wiring changes:
docs/pom.xml: removes thefrontend-maven-pluginblock; adds acamel-package-maven-pluginprepare-doc-symlinksexecution bound togenerate-resourcesbefore the existingxref-check. The${skipOnUnsupported}property is now read by the mojo as<skip>.pom.xml: drops the now-unused.yarn/yarn.lock/yarn*.cjsApache RAT excludes.Cross-platform notes:
Files.createSymbolicLinkrequires Developer Mode or Administrator. The mojo tries a real symlink first and falls back to a plain file copy onFileSystemException, logging once per build (matches thevinyl-fsbehaviour gulp had).PathMatcherhas*,**,?,{a,b}and character classes but no extglob!(...). gulp negations are expressed asexcludeslists perKindSpec, post-filtered by the walker. The{,**/}*.jsonbrace form is used where gulp's**/*.jsonmatched across zero intermediate dirs.Locale.ROOTis used for case-folding.Verification:
mainand on this branch anddiffthem — empty diff means no regression. Snapshot command is embedded in the test class Javadoc. Locally on macOS the diff is 0 lines.mvnd test -pl tooling/maven/camel-package-maven-plugin -Dtest=PrepareDocSymlinksMojoTest: 12/12 pass. Tests coverreplaceBlock,extractTitle, andNavComparator(incl. transitivity).mvnd -pl docs generate-resources -Dci.env.name=local: succeeds; no Node / Yarn downloaded.Target
mainbranch)Tracking
Apache Camel coding standards and style
mvn clean install -DskipTestslocally from root folder and I have committed all auto-generated changes.Claude Code on behalf of Adriano Machado