Skip to content

feat(manifest): quieter JVM output + fail-closed manifest generation (1.1.133)#1392

Merged
Jeppe Fredsgaard Blaabjerg (jfblaa) merged 6 commits into
v1.xfrom
jfblaa/manifest-quiet-tool-output
Jul 1, 2026
Merged

feat(manifest): quieter JVM output + fail-closed manifest generation (1.1.133)#1392
Jeppe Fredsgaard Blaabjerg (jfblaa) merged 6 commits into
v1.xfrom
jfblaa/manifest-quiet-tool-output

Conversation

@jfblaa

@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Improves the output and failure handling of JVM manifest generation (socket manifest gradle | sbt | maven, and --auto-manifest).

Quieter output

  • The build tool's full log (e.g. a multi-module Maven reactor's hundreds of [INFO] lines) no longer streams to the terminal. It's captured behind a progress spinner by default, matching the existing socket manifest gradle --pom UX. Pass --verbose to stream it live.
  • On a build crash, the tail of the captured output is shown under a Build output: group, so failures stay diagnosable without re-running.

Consistent, fail-closed error handling

  • Standalone socket manifest <tool> now matches the --pom generator: a failure sets a non-zero exit code (no more opaque "command failed").
  • Under --auto-manifest, a failed manifest generation now aborts the whole run — for Gradle, sbt, and Maven, in both Socket-facts and pom mode — instead of continuing with an incomplete SBOM.
  • A crashed build (missing JDK/build tool, unparseable project, OOM) always fails. ignoreUnresolved (socket.json / --ignore-unresolved) only tolerates dependencies a successful build couldn't resolve.
  • --reach-continue-on-install-errors is now purely a Coana concern; it no longer influences socket-cli's manifest ignoreUnresolved (the two were previously conflated).

Under the hood

  • runNeverThrow classifies a non-zero build exit by its numeric exit code (the utils/dlx.mts convention) rather than the registry's isSpawnError, which is broken upstream and never matches.

Verification

Full manifest unit suite passes (349); type-check and lint clean. Verified locally against Maven projects: quiet by default, --verbose streams the build log, a broken build fails with a clean message plus the captured output tail, and --auto-manifest aborts on a build failure.

Note

The always-false isSpawnError is an upstream @socketsecurity/registry bug (also deadens a check in utils/git.mts) worth fixing there; this PR just stops depending on it.


Note

Low Risk
UX and subprocess error-handling only for JVM manifest generation; no auth, API, or SBOM assembly logic changes beyond propagating captured output.

Overview
Gradle, sbt, and Maven manifest facts generation no longer streams the full build log by default. Output is captured with stdio: 'pipe', a progress spinner runs during resolution, and --verbose still passes through live tool output.

When a build exits non-zero without emitting facts or resolution failures, the CLI now prints the last ~40 lines of captured stdout/stderr under a Build output: group (unless --verbose already showed the stream), and the error message no longer tells users they must re-run with --verbose.

runNeverThrow stops using the registry’s broken isSpawnError helper and instead treats spawn rejections with a numeric code as a normal non-zero exit, returning captured stdout/stderr so the fail-closed path and error surfacing work reliably.

Reviewed by Cursor Bugbot for commit ac95036. Configure here.

`socket manifest gradle|sbt|maven` (and `--auto-manifest`) streamed the build
tool's full output to the terminal. Capture it by default and show a spinner
instead, streaming live only under --verbose. On a build crash the captured
output tail is surfaced so failures stay diagnosable without a rebuild.

Also fix runNeverThrow: the registry's isSpawnError is unreliable (it never
matches), so a non-zero build exit rethrew as an opaque "command failed" instead
of returning the exit code. Duck-type the numeric exit code directly.
Align the JVM facts path with convertGradleToMaven (the `--pom` generator),
which is the direct-spawn sibling of these commands rather than the coana dlx
wrapper:

- spinner + captured output by default, stream on --verbose (unchanged intent).
- On failure use process.exitCode = 1 + logger.fail(...) + return instead of
  throwing, so the facts path behaves identically to the pom path — including
  under --auto-manifest, where both now set exit 1 and continue the sequence.
- runNeverThrow classifies a non-zero build exit by a numeric `code` (the
  utils/dlx.mts convention), not the registry's isSpawnError, which is broken
  upstream and never matches.
Under --auto-manifest, a failed manifest generation now aborts the whole run
instead of continuing with a partial or empty SBOM (which silently under-reports
dependencies). This is enforced uniformly for every JVM path — Gradle, sbt, and
Maven, in both Socket-facts and pom mode — in generate_auto_manifest, keying off
the exit code each generator already sets. The standalone `socket manifest`
commands are unchanged (they exit non-zero, as before). Failures the user opted
to tolerate (ignoreUnresolved / --reach-continue-on-install-errors) warn without
setting an exit code, so they continue.
…olved

ignoreUnresolved (and --ignore-unresolved) means 'the build ran but some
dependencies could not be resolved; tolerate those'. It must not swallow the
build process itself failing (missing JDK/build tool, unparseable project, OOM,
plugin crash). Scope it to the blocking-resolution-failure branch only; a
crashed build now fails regardless.
…fest ignoreUnresolved

--reach-continue-on-install-errors is a Coana concern (it tells Coana to keep
going past its own install errors) and is threaded to Coana in
perform-reachability-analysis. It should not also decide whether socket-cli's
manifest generation tolerates unresolved dependencies — that is a separate
concern governed by the manifest's own ignoreUnresolved (socket.json /
--ignore-unresolved). Drop the resolveIgnoreUnresolved coupling so the two are
independent; the flag still reaches Coana unchanged.
@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) changed the title feat(manifest): quiet JVM build-tool output behind a spinner (1.1.133) feat(manifest): quieter JVM output + fail-closed manifest generation (1.1.133) Jul 1, 2026
@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) merged commit 5b41564 into v1.x Jul 1, 2026
13 checks passed
@jfblaa Jeppe Fredsgaard Blaabjerg (jfblaa) deleted the jfblaa/manifest-quiet-tool-output branch July 1, 2026 10:51
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.

2 participants