refactor!: collapse to single Maven module; drop skill+plugin concept (0.2.0-SNAPSHOT)#6
Merged
Merged
Conversation
…skill+plugin
The Claude Code / Copilot CLI plugin path and the agent skill concept are gone.
The reactor (protocol+daemon+cli+dist) is collapsed into one Maven project at
root with src/{main,test}/{java,resources}. Distribution is now a single zip
shipped on GitHub Release + Maven Central.
Deletions
plugin/ (.claude-plugin/plugin.json, SKILL.md, bin/sonar copies, config.env,
agents/sonar-scanner-{claude,copilot}.md)
.claude-plugin/marketplace.json
protocol/, daemon/, cli/, dist/ as separate Maven modules — their sources
hoist into the single root tree, sub-poms
deleted.
Source-tree moves (git mv preserves history)
protocol/src/main/java/... -> src/main/java/dev/sonarcli/protocol/
daemon/src/main/java/... -> src/main/java/dev/sonarcli/daemon/
cli/src/main/java/... -> src/main/java/dev/sonarcli/cli/
*the same for src/test/java/
daemon/src/test/resources/fixtures/ -> src/test/resources/daemon/fixtures/
cli/src/test/resources/fixtures/ -> src/test/resources/cli/fixtures/
(separated to avoid the Clean.java fixture collision; test FIXTURES paths
updated accordingly in 11 test classes)
dist/src/assembly/skill.xml -> src/main/assembly/dist.xml (rewritten)
dist/src/main/scripts/sonar{,.bat} -> src/main/staging/bin/sonar{,.bat}
Build (pom.xml)
packaging=jar (so the default lifecycle binds compile/test/jar auto)
maven-shade-plugin: two executions producing
target/sonar-predictor-cli.jar (Main-Class dev.sonarcli.cli.SonarCommand)
target/sonar-predictor-daemon.jar (Main-Class dev.sonarcli.daemon.DaemonMain)
maven-dependency-plugin: two executions copy the 10 SonarSource analyzer
plugin jars into ./plugins/ (for tests) and target/plugins/ (for assembly)
maven-assembly-plugin: produces target/sonar-predictor-dist-${version}.zip
with bin/+lib/+plugins/
jacoco: single coverage report at target/site/jacoco/jacoco.xml
release profile: source+javadoc jars (Central requirement) + GPG sign +
central-publishing-maven-plugin + build-helper attaches
the dist zip + src zip with classifiers dist/src.
Version bump
0.1.0-SNAPSHOT -> 0.2.0-SNAPSHOT (signals breaking distribution change)
CI (.github/workflows)
publish.yml: drop the config.env version-pin sync step (no config.env any
more), deploy single project, GH Release attaches
target/sonar-predictor-dist-${version}.zip
sonar.yml + parity.yml: derive version from pom.xml at runtime; point
SONAR_PREDICTOR_HOME at
target/sonar-predictor-dist-<v>/sonar-predictor; build cmd
drops the -pl/-am reactor flags.
README rewritten: install via GitHub Release / Maven Central / build from
source. Claude Code + Copilot marketplace sections removed.
Stale-language sweep: "skill bundle" -> "distribution bundle" /
"plugin/engine" -> "analyzer/engine" in DaemonLauncher javadoc,
SetupCommand javadoc, bin/sonar + bin/sonar.bat.
.gitignore: daemon/plugins/*.jar -> plugins/*.jar
Verify
mvn -B -ntp clean verify -> BUILD SUCCESS
323 tests pass, 0 failures, 0 errors
target/sonar-predictor-dist-0.2.0-SNAPSHOT.zip = 161 MB, 18 entries
bin/sonar --help -> exit 0, prints help
…real jar CI broke on PR #6 with 11 failures + 8 errors all variants of "could not locate the daemon jar". In the old multi-module reactor, daemon-module's package phase produced its jar BEFORE cli-module's test phase ran, so DaemonLauncherTest / DaemonClientTest / CliIntegrationTest could spawn the daemon. Collapsing to a single module broke that ordering: shade ran in `package`, AFTER `test`, so the jar was missing when tests that exec the launcher's resolveDaemonJar() ran. Three coordinated changes restore the invariant: 1. pom.xml — bind maven-jar-plugin's default-jar execution to process-classes, and move both shade executions (shade-cli, shade-daemon) from package to process-test-classes. Result lifecycle: compile → process-classes (primary jar) → test-compile → process-test-classes (shade × 2) → test → … → package Both shaded fat jars exist when DaemonLauncher tests fire. 2. pom.xml — change shade finalName to include the version (sonar-predictor-{cli,daemon}-${project.version}). The output filename matches DAEMON_JAR_PREFIX="sonar-predictor-daemon-" in DaemonLauncher, which test devDefaultResolvesShadedJar already asserts on. The launcher scripts glob the version away so they stay version-agnostic. 3. DaemonLauncher.findDevDefaultJar — search both target/ (single-module layout) and daemon/target/ (legacy multi-module) for the shaded jar. No behaviour change for an old checkout; a new checkout finds the jar at root target/. Adjacent updates: - src/main/assembly/dist.xml: glob `sonar-predictor-{cli,daemon}-*.jar` (versioned names), exclude `original-*.jar` (the unshaded artifact shade also leaves behind). - src/main/staging/bin/sonar: replace hardcoded CLI_JAR/DAEMON_JAR paths with POSIX for-loop globs against lib/sonar-predictor-{cli,daemon}-*.jar. - src/main/staging/bin/sonar.bat: same for Windows (cmd FOR loops). Verify mvn -B -ntp clean verify -Dsurefire.failIfNoSpecifiedTests=false BUILD SUCCESS — 323/323 tests pass target/sonar-predictor-dist-0.2.0-SNAPSHOT.zip contains lib/sonar-predictor-cli-0.2.0-SNAPSHOT.jar lib/sonar-predictor-daemon-0.2.0-SNAPSHOT.jar ./bin/sonar --help → exit 0
…d skill-shell wrapper The self-scan + parity workflows invoked '$SONAR_PREDICTOR_HOME/bin/sonar agent-scan analyze .', but 'agent-scan' was never a CLI subcommand — it was a shell function defined inside the OLD plugin/skills/sonar-predictor/bin/sonar wrapper that this branch deletes. The new distribution's bin/sonar is a thin pass-through to the Java CLI, so the call now errors: Unmatched argument at index 0: 'agent-scan' Did you mean: sonar analyze? Replace with the equivalent direct invocation: sonar --format json --save .sonar-predictor/scan.json analyze . --coverage <jacoco.xml> --save was already a global option on the CLI (visible in sonar --help) — it captures the same JSON the old wrapper redirected to scan.json. The downstream Render scan summary / Quality gate / Upload artifact steps in both workflows already read .sonar-predictor/scan.json, so no change needed there.
…es (S2095) SonarCloud quality gate flagged java:S2095 BLOCKER on DaemonClient.roundTrip: the OutputStream and InputStream returned by Channels.newOutputStream/newInputStream weren't explicitly closed. In practice they delegate to the SocketChannel which IS in try-with-resources, so the underlying resource closes correctly, but the static analyzer can't prove that — and the wrappers' close() may flush state we relied on implicit-close for. Move both into the try-with-resources head; resources close in reverse declaration order (in → out → channel), which is the order we want. Verify mvn -B -ntp test -Dtest=DaemonClientTest → 4/4 pass
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
protocol+daemon+cli+dist) into one Maven project at root withsrc/{main,test}/{java,resources}.plugin/and.claude-plugin/marketplace.jsonare gone.SKILL.md,config.env,SONAR_BUNDLE_VERSIONlazy-fetch). Distribution is now a singlesonar-predictor-dist-X.Y.Z.zipon GitHub Release + Maven Central.0.1.0-SNAPSHOT→0.2.0-SNAPSHOT(breaking distribution change).Why
The skill-bundle wrapper + 4-module reactor added a lot of moving parts for a ~15 KLOC project (8.4K prod / 7.2K test). With the marketplace install path retired and the distribution narrowed to "download a zip and run", a single Maven module is simpler to understand, build, test, and publish.
Verify locally
What ships on Maven Central per release
sonar-predictor-X.Y.Z.pomsonar-predictor-X.Y.Z.jar(slim primary, ~200 KB)sonar-predictor-X.Y.Z-cli.jar(shaded fat jar, runnable)sonar-predictor-X.Y.Z-daemon.jar(shaded fat jar, runnable)sonar-predictor-X.Y.Z-dist.zip⟵ the bundle users actually runsonar-predictor-X.Y.Z-src.zip(whole-repo source)sonar-predictor-X.Y.Z-sources.jar+-javadoc.jar(Central requires these for jar packaging)Breaking changes for downstream users
/plugin marketplace add RandomCodeSpace/sonar-predictinstall path is gone.sonar-scanner-claude/sonar-scanner-copilotsubagents that shipped inside the plugin are gone (they were thin wrappers — agents can callbin/sonardirectly).SONAR_BUNDLE_VERSION/config.envknobs are gone (no lazy-fetch any more — the zip is fully self-contained from extract).Test plan
mvn -B -ntp clean verifyis green locally (323/323 tests pass)bin/+lib/+plugins/, 18 entries, ~161 MB)bin/sonar --help) exits 0v0.2.0to validate the rewritten publish.yml end-to-end (Maven Central + GitHub Release)Notes
<artifactSet>scoping; not blocking.OSS_NEXUS_USER,OSS_NEXUS_PASS,MAVEN_GPG_PRIVATE_KEY,MAVEN_GPG_PASSPHRASE).