Skip to content

fix(manifest): cover recursive build roots by build file, not directory - #1620

Open
Jeppe Fredsgaard Blaabjerg (jfblaa) wants to merge 1 commit into
v1.xfrom
jfblaa/file-based-build-coverage
Open

Jeppe Fredsgaard Blaabjerg (jfblaa) wants to merge 1 commit into
v1.xfrom
jfblaa/file-based-build-coverage

Conversation

@jfblaa

@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

LLM Description written by Claude Code:claude-opus-5-5

socket manifest dynamic-sbom-inference, --dynamic-sbom-inference and the recursive setup wizard skip a discovered build root that another build already includes. That coverage was tracked per ecosystem by directory, so an independent build sharing a directory with a module of another build of the same tool was never generated, e.g. a reactor module declared as <module>sub/alt.xml</module> hid a standalone sub/pom.xml.

Coverage is now one tool-agnostic set of build files: the manifestFiles each processed build reports for its projects. A root is skipped only when one of its own build files is in the set. Files outside the build root (sibling modules, relocated Gradle projects) or absent on disk (Gradle reports configured build files that don't exist) never count.

Changes outside the coverage logic:

  • The workspace-enumeration scripts (Gradle, sbt, Maven extension) now emit buildRoot and projectBuild records, so the setup wizard uses the same rule and resolves paths against the real build root.
  • sbt facts output: each project's manifestFiles now also includes its base directory's build.sbt when present. sbt loads that file into the project (Load.configurationSources) even when it defines nothing scoped to it, which setting positions alone miss; without it, a subproject with an empty build.sbt would be generated again as its own build. Other *.sbt files are not added. Coana and depscan will see this extra entry for such subprojects.

Testing:

  • Unit tests for co-located builds, an empty sbt subproject build.sbt, absent Gradle build files, and the wizard; the co-located case fails on the old code.
  • test/run-compat.sh matrix passes for Gradle 1.12–9.2.1, Maven 3.2.5–4.0.0-rc-6 and sbt 0.13.18–1.9.9, with the workspace smoke tests now asserting the new records.
  • Real dynamic-sbom-inference runs on small Maven, Gradle and sbt builds exercising each case above.

Note

Medium Risk
Changes which Maven/Gradle/sbt roots get SBOMs in monorepos and co-located layouts; behavior is narrower (fewer false skips) but affects scan/fix dynamic inference paths.

Overview
Fixes recursive JVM build-root skipping for socket manifest dynamic-sbom-inference, --dynamic-sbom-inference, and the recursive setup wizard.

Coverage is now keyed by build files, not directories. After each facts run, the walker records the existing manifestFiles reported for that build (resolved against the real build root). A later candidate is skipped only if one of its ecosystem marker files (pom.xml, build.gradle, build.sbt, etc.) is already in that set. Independent builds that share a folder with a reactor module (e.g. reactor uses shared/alt.xml but shared/pom.xml is separate) are generated again; sibling or relocated modules outside the build root are not suppressed; Gradle-reported build files that are missing on disk do not count.

Workspace enumeration (Gradle init script, sbt workspaces plugin, Maven extension) now emits buildRoot and projectBuild so setup uses the same rule; enumerateWorkspaces requires buildRoot and fails closed without it. sbt facts also attach each subproject’s base build.sbt to manifestFiles when present, so empty member build.sbt files are covered by the parent run.

Help text, changelog, compat smoke tests, and unit tests cover co-located builds, absent Gradle files, and relocated roots.

Reviewed by Cursor Bugbot for commit 66fb96d. Configure here.

Recursive facts generation and the recursive setup wizard skipped a
discovered build root whenever its directory was a subproject of an
already-processed build, tracked separately per ecosystem. A directory
shared by a module of one build and an independent build of the same tool
(e.g. a reactor module declared as `sub/alt.xml` next to a standalone
`sub/pom.xml`) was therefore never generated.

Coverage is now a single set of the build files each processed build
reports for its projects (`manifestFiles`); a root is skipped only when one
of its own build files is in it. Files outside the build root or absent on
disk never count.

- The workspace-enumeration scripts emit `buildRoot` and `projectBuild`
  records, so the setup wizard uses the same rule.
- sbt projects also list their base directory's `build.sbt`: sbt loads it
  into that project even when it sets nothing, which setting positions
  alone miss.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant