Skip to content

fix: deduplicate ReaderTestSupport between reader and builtins (fixes #1807)#1815

Merged
gnodet merged 2 commits into
jline:masterfrom
gnodet:ci-issue-1807
Apr 28, 2026
Merged

fix: deduplicate ReaderTestSupport between reader and builtins (fixes #1807)#1815
gnodet merged 2 commits into
jline:masterfrom
gnodet:ci-issue-1807

Conversation

@gnodet
Copy link
Copy Markdown
Member

@gnodet gnodet commented Apr 23, 2026

Summary

Eliminate the duplicated ReaderTestSupport class between reader and builtins modules by sharing it via a Maven test-jar.

  • Configure the reader module to produce a test-jar via maven-jar-plugin (scoped to ReaderTestSupport only)
  • Add a test-scoped dependency on the reader test-jar in builtins
  • Update OptionCompleterTest and TreeCompleterTest to import ReaderTestSupport from org.jline.reader.impl
  • Delete the duplicate ReaderTestSupport from builtins/src/test/java/org/jline/builtins/
  • Configure --patch-module and --add-reads for JPMS compatibility during test compilation and execution

Fixes #1807

Benefits

  • Eliminates 361 lines of duplicated code — the builtins copy was a verbatim duplicate with a TODO comment acknowledging the duplication
  • Single source of truth — future changes to ReaderTestSupport only need to happen in one place
  • Test-jar is scoped to minimal classes — only ReaderTestSupport and its inner classes are included (4 classes), not all reader tests

Downsides

  • Test-jar gets published to Maven Central — a small artifact containing only ReaderTestSupport will be published alongside the main jar (this is standard Maven behavior for test-jars)
  • JPMS complexity — the builtins POM needs --patch-module and --add-reads flags for both compilation and test execution, since ReaderTestSupport must be patched into the org.jline.reader module
  • Build ordering dependency — building builtins standalone (-pl builtins) requires that the reader module (including its test-jar) has been built first
  • Uses maven.multiModuleProjectDirectory — this is a Maven internal property (not part of the public API), used to construct the test-jar path for --patch-module; it works reliably in Maven 3.x and 4.x but is technically undocumented

Test plan

  • Reader module tests pass (201 tests)
  • Builtins module tests pass (1071 tests, including OptionCompleterTest and TreeCompleterTest which use the shared ReaderTestSupport)
  • Spotless formatting passes on both modules

…#1807)

Use a test-jar dependency from the reader module instead of maintaining
a separate copy in builtins. Configure --patch-module for JPMS
compatibility during test compilation and execution.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Consolidates duplicate test utilities by generating a jline-reader test-jar from the reader module, removes the builtins copy of ReaderTestSupport, and configures builtins to consume the test-jar with JPMS patching and runtime opens so tests compile and run against module org.jline.reader. (45 words)

Changes

Cohort / File(s) Summary
Reader test-jar generation
reader/pom.xml
Adds maven-jar-plugin execution to produce a test JAR containing ReaderTestSupport classes.
Dependency management (root)
pom.xml
Adds org.jline:jline-reader as a test-jar entry in dependencyManagement to allow resolving the reader test-jar.
Builtins build & JPMS test wiring
builtins/pom.xml
Adds property for reader.test.jar, adds test-scoped org.jline:jline-reader dependency of type test-jar, configures maven-compiler-plugin --patch-module for test compile and sets surefire.argLine to patch modules, add opens and add-reads for tests.
Builtins test imports
builtins/src/test/java/org/jline/builtins/OptionCompleterTest.java, builtins/src/test/java/org/jline/builtins/TreeCompleterTest.java
Replace local dependency on internal test class by importing org.jline.reader.impl.ReaderTestSupport from the reader test-jar (imports added).
Duplicate removal
builtins/src/test/java/org/jline/builtins/ReaderTestSupport.java
Removes the local duplicate ReaderTestSupport (and its nested helper types and test helpers); functionality now provided by the reader test-jar.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped between modules, found one true bed,
Shared tests bundled up, no duplicates spread.
Patch flags set, jars snug and tight,
One ReaderTestSupport, everything right. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: deduplicating ReaderTestSupport between two modules and fixing issue #1807.
Linked Issues check ✅ Passed All coding objectives from issue #1807 are met: reader module produces test-jar [reader/pom.xml], builtins depends on it [builtins/pom.xml], duplicate ReaderTestSupport is removed [builtins/src/test/java], tests updated to import from reader [OptionCompleterTest, TreeCompleterTest], and JPMS configuration is in place [--patch-module, --add-reads].
Out of Scope Changes check ✅ Passed All changes are directly related to deduplicating ReaderTestSupport: POM configurations for test-jar generation and consumption, removal of duplicate class, import updates in dependent tests, and JPMS compatibility setup. No extraneous changes present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@builtins/pom.xml`:
- Around line 27-28: The pom currently hardcodes reader.test.jar to
../reader/target/... and uses ${reader.test.jar} in the surefire.argLine and
compilerArgs, which breaks when the test-jar is resolved from the local repo;
replace this by using maven-dependency-plugin:properties to resolve the artifact
org.jline:jline-reader:jar:tests during initialize so Maven sets a property (the
standard property name will be ${org.jline:jline-reader:jar:tests}), then update
surefire.argLine and the default-testCompile compilerArgs to reference that
resolved property instead of ${reader.test.jar}; ensure the plugin execution has
<phase>initialize</phase> and the <goal>properties</goal> so the property is
available when Surefire and javac args are evaluated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0552c34d-cf1f-4190-b2ca-cf291d9d1300

📥 Commits

Reviewing files that changed from the base of the PR and between 3d65554 and 51e49be.

📒 Files selected for processing (6)
  • builtins/pom.xml
  • builtins/src/test/java/org/jline/builtins/OptionCompleterTest.java
  • builtins/src/test/java/org/jline/builtins/ReaderTestSupport.java
  • builtins/src/test/java/org/jline/builtins/TreeCompleterTest.java
  • pom.xml
  • reader/pom.xml
💤 Files with no reviewable changes (1)
  • builtins/src/test/java/org/jline/builtins/ReaderTestSupport.java

Comment thread builtins/pom.xml Outdated
Comment on lines +27 to +28
<reader.test.jar>${project.basedir}/../reader/target/jline-reader-${project.version}-tests.jar</reader.test.jar>
<surefire.argLine>--add-opens java.base/java.io=org.jline.nativ --add-opens java.base/java.io=org.jline.terminal --patch-module org.jline.reader=${reader.test.jar} --add-reads org.jline.reader=ALL-UNNAMED</surefire.argLine>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm the hardcoded path and check whether any CI workflow relies on the sibling target/ layout.
rg -nP 'reader\.test\.jar|\.\./reader/target' -C2
fd -t f -e yml -e yaml . .github 2>/dev/null | xargs -r rg -nP 'mvn|maven' -l

Repository: jline/jline3

Length of output: 1097


🏁 Script executed:

# Check the test-jar dependency declaration around lines 52-57
sed -n '45,65p' builtins/pom.xml

Repository: jline/jline3

Length of output: 764


🏁 Script executed:

# Get full context around lines 95-103 for the compiler configuration
sed -n '90,110p' builtins/pom.xml

Repository: jline/jline3

Length of output: 846


🏁 Script executed:

# Check GitHub workflows to see how they invoke Maven
cat .github/workflows/master-build.yml
cat .github/workflows/release.yml

Repository: jline/jline3

Length of output: 7218


🏁 Script executed:

# Verify maven-dependency-plugin:properties capability and check if it's used elsewhere in project
rg -n 'maven-dependency-plugin' -A3

Repository: jline/jline3

Length of output: 1456


🏁 Script executed:

# Check if any of these usages employ the properties goal
rg -n 'maven-dependency-plugin' -A10 | grep -E '(goal|properties)'

Repository: jline/jline3

Length of output: 926


Hardcoded relative path to reader's target/ bypasses Maven resolution.

${reader.test.jar} points at ../reader/target/jline-reader-${project.version}-tests.jar (line 27), so --patch-module only works when the reader module's target/ is freshly built in the same checkout. This breaks in common scenarios:

  • Running mvn -pl builtins test against an already-installed reader (the test-jar is in ~/.m2, not ../reader/target/).
  • Any consumer building builtins without a sibling reader/ directory.
  • Changes to finalName or artifact naming conventions.

The declared test-jar dependency (lines 52–57) is already resolved by Maven — prefer letting Maven give you the actual artifact path rather than guessing it.

♻️ Suggested approach using maven-dependency-plugin:properties

Use the properties goal to bind the resolved artifact path into a property (e.g., org.jline:jline-reader:jar:tests) during initialize, then reference that in --patch-module:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>resolve-test-jar</id>
            <phase>initialize</phase>
            <goals><goal>properties</goal></goals>
        </execution>
    </executions>
</plugin>

Then replace ${reader.test.jar} with ${org.jline:jline-reader:jar:tests} in both surefire.argLine (line 28) and the default-testCompile compilerArgs (line 100).

Also applies to: lines 95–103

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@builtins/pom.xml` around lines 27 - 28, The pom currently hardcodes
reader.test.jar to ../reader/target/... and uses ${reader.test.jar} in the
surefire.argLine and compilerArgs, which breaks when the test-jar is resolved
from the local repo; replace this by using maven-dependency-plugin:properties to
resolve the artifact org.jline:jline-reader:jar:tests during initialize so Maven
sets a property (the standard property name will be
${org.jline:jline-reader:jar:tests}), then update surefire.argLine and the
default-testCompile compilerArgs to reference that resolved property instead of
${reader.test.jar}; ensure the plugin execution has <phase>initialize</phase>
and the <goal>properties</goal> so the property is available when Surefire and
javac args are evaluated.

@gnodet
Copy link
Copy Markdown
Member Author

gnodet commented Apr 23, 2026

Re: CodeRabbit suggestion to use maven-dependency-plugin:properties instead of the hardcoded relative path:

I investigated this approach. Unfortunately it doesn't work in this project for two reasons:

  1. Nested property resolution: The surefire.argLine property is defined in <properties> and resolved at POM parsing time, before any plugin executes. So ${org.jline:jline-reader:jar:tests} embedded inside surefire.argLine is never resolved — Maven doesn't do recursive property expansion.

  2. Direct plugin configuration: Even configuring surefire's <argLine> directly (bypassing the property), the dependency:properties goal property isn't picked up by surefire at runtime — likely due to interaction with the Nisse POM inliner used in this project.

The relative path via ${project.basedir}/../reader/target/... works because this is a reactor-only multi-module build — builtins is never consumed independently of its sibling reader module. The Maven dependency declaration ensures correct reactor build ordering, and finalName is not customized.

Claude Code on behalf of Guillaume Nodet

@gnodet gnodet force-pushed the ci-issue-1807 branch 2 times, most recently from a14ec41 to 5dfb537 Compare April 23, 2026 20:51
Use ${maven.multiModuleProjectDirectory} instead of
${project.basedir}/.. for a more robust reference to the
project root directory.
@sonarqubecloud
Copy link
Copy Markdown

@gnodet gnodet added the chore label Apr 28, 2026
@gnodet gnodet added this to the 4.0.14 milestone Apr 28, 2026
@gnodet gnodet merged commit 8325740 into jline:master Apr 28, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ReaderTestSupport duplicated between builtins and reader test modules

1 participant