Fix Maven scope and version selection in the POM dependency report#690
Merged
Conversation
The aggregated dependency report (`docs/dependencies/pom.xml` in consumer
repos) could mark a production dependency as `test` scope when a test-only
module also used the same artifact. `deduplicate()` collapsed same-GAV entries
with `distinctBy { it.gav }`, keeping the first-encountered occurrence, whose
configuration then dictated the reported scope. Observed in
`core-jvm-compiler` PR #94, where `io.spine:spine-base` flipped to `test`.
Rework `deduplicate()` to group by `group:name`, retain the newest version,
and among that version's usages report the widest Maven scope. Version
selection now uses a new numeric-aware `VersionComparator` instead of a
lexicographic string compare, so `10.0.0` outranks `9.2.0` and
`2.0.0-SNAPSHOT.100` outranks `...99`. `dependencyPriority()` is re-ranked into
the conventional Maven order (compile < provided < runtime < test < system <
undefined) and drives both scope selection and `pom.xml` layout, so
`compileOnly`/`annotationProcessor` usages report as `provided` rather than
`test`.
Add `VersionComparatorSpec` (7 tests) and `DependencyWriterSpec` (19 tests,
ProjectBuilder-based) covering scope precedence, numeric version selection, and
the end-to-end `pom.xml` regression.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
armiol
approved these changes
Jun 15, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes correctness issues in the Gradle-to-POM dependency report generator used across Spine SDK consumer repos, ensuring duplicated dependencies are reported with the newest semantic version and the widest (most production-relevant) Maven scope.
Changes:
- Reworked dependency de-duplication to (a) select the newest version via a numeric-aware comparator and (b) select the widest Maven scope among usages of that retained version.
- Introduced
VersionComparator(SemVer-flavored ordering) and added end-to-end and unit tests covering scope precedence and version selection. - Minor maintenance updates: scope-priority ordering aligned with Maven conventions; SSH log message typo fixed; added/updated agent task + memory docs.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| buildSrc/src/main/kotlin/io/spine/gradle/report/pom/DependencyWriter.kt | Fixes de-duplication to choose newest semantic version and widest scope for the retained version. |
| buildSrc/src/main/kotlin/io/spine/gradle/report/pom/ScopedDependency.kt | Updates scope priority to conventional Maven order (compile → provided → runtime → test → system → undefined). |
| buildSrc/src/main/kotlin/io/spine/gradle/report/pom/VersionComparator.kt | Adds a numeric-aware version comparator to avoid lexicographic mis-ordering (e.g., 10.x vs 9.x). |
| buildSrc/src/test/kotlin/io/spine/gradle/report/pom/DependencyWriterSpec.kt | Adds regression and precedence tests for scope merging, version selection, and XML layout ordering. |
| buildSrc/src/test/kotlin/io/spine/gradle/report/pom/VersionComparatorSpec.kt | Adds focused unit tests for semantic version comparison edge cases. |
| buildSrc/src/main/kotlin/io/spine/gradle/github/pages/SshKey.kt | Fixes an SSH config log message typo (“key file” → “config file”). |
| .agents/tasks/archive/pom-report-scope-merge.md | Archives the task plan/log for the dependency report scope/version fixes. |
| .agents/memory/project/porting-buildsrc-from-consumer-repos.md | Adds guidance for back-porting buildSrc improvements from consumer repos. |
| .agents/memory/project/config-build-verification.md | Documents the correct local verification command for buildSrc changes in config. |
| .agents/memory/MEMORY.md | Registers the newly added project memory entries in the index. |
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.
What & why
The aggregated dependency report (
docs/dependencies/pom.xmlin consumer repos)could mislabel a production dependency as
<scope>test</scope>whenever atest-only module happened to depend on the same artifact. Observed in
SpineEventEngine/core-jvm-compilerPR #94,where
io.spine:spine-base— anapidependency of production modules — flippedto
testscope.Root cause:
deduplicate()collapsed same-GAV entries withdistinctBy { it.gav }, keeping the first-encountered occurrence, whoseconfiguration then dictated the reported scope. Version selection was also a
plain lexicographic string compare, so
9.2.0incorrectly outranked10.0.0.Changes
deduplicate()now groups bygroup:name, retains thenewest version, and among that version's usages reports the widest Maven
scope. A dependency used via
apiin one module andtestImplementationinanother is reported as
compile, nottest.VersionComparator(new) — numeric-aware, SemVer-flavored versionordering:
10.0.0>9.2.0,2.0.0-SNAPSHOT.100>2.0.0-SNAPSHOT.99,release > pre-release. Replaces the lexicographic compare. No new dependency.
dependencyPriority()— re-ranked into the conventional Maven scope order(
compile < provided < runtime < test < system < undefined) as an exhaustivewhenover the scope enum. The single ranking drives both scope selection andpom.xmllayout, socompileOnly/annotationProcessorusages report asprovidedrather thantest.Tests
VersionComparatorSpec— 7 tests (numeric ordering, release-vs-pre-release,segment edge cases).
DependencyWriterSpec— 19 tests (ProjectBuilder-based): scope precedence,numeric version selection, and the end-to-end
pom.xmlregression../gradlew :buildSrc:test detektgreen;spine-code-review,kotlin-engineer,and
review-docsall APPROVE.Also on this branch
group-of-fixesbundles two small unrelated commits: an SSH log-message typofix (
SshKey.kt) and agent-memory additions under.agents/memory/.One-time downstream effect
On the next regeneration, consumer
pom.xmlreports listprovideddependencies above
runtime— a one-time layout shift toward the Mavenconvention.
🤖 Generated with Claude Code