Skip to content

Commit 6ef766e

Browse files
committed
feat(manifest): fail closed under --auto-manifest on a JVM build failure
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.
1 parent a5fc144 commit 6ef766e

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
88

99
### Changed
1010
- Quieter `socket manifest gradle`, `sbt`, and `maven`: the build tool's output is now hidden behind a progress spinner and shown only if the build fails. Pass `--verbose` to stream it live.
11+
- `--auto-manifest` now fails fast: if a Gradle, sbt, or Maven build can't be resolved, the run stops instead of continuing with an incomplete SBOM. Opt into tolerating install errors to keep going.
1112

1213
## [1.1.132](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.132) - 2026-06-30
1314

src/commands/manifest/generate_auto_manifest.mts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { parseBuildToolOpts } from './parse-build-tool-opts.mts'
1313
import { resolveBuildToolBin } from './scripts/build-tool.mts'
1414
import { serializeSidecar } from './scripts/sidecar.mts'
1515
import { REQUIREMENTS_TXT, SOCKET_JSON } from '../../constants.mts'
16+
import { InputError } from '../../utils/errors.mts'
1617
import { readOrDefaultSocketJson } from '../../utils/socket-json.mts'
1718

1819
import type { GeneratableManifests } from './detect-manifest-actions.mts'
@@ -28,6 +29,23 @@ export type GenerateAutoManifestResult = {
2829
resolvedPathsSidecar?: ResolvedPathsSidecar | undefined
2930
}
3031

32+
// Under --auto-manifest, a manifest generator that failed — raising the exit
33+
// code above the value captured before it ran — aborts the whole run: a partial
34+
// or empty SBOM silently under-reports dependencies. The generator has already
35+
// logged the specifics. Tolerated failures (ignoreUnresolved /
36+
// reachContinueOnInstallErrors) warn without touching the exit code, so they
37+
// pass through here and the run continues.
38+
function abortManifestRunIfFailed(
39+
ecosystem: string,
40+
beforeExitCode: string | number | undefined,
41+
): void {
42+
if (process.exitCode && process.exitCode !== beforeExitCode) {
43+
throw new InputError(
44+
`Auto-manifest generation failed for the ${ecosystem} project; aborting (see the errors above).`,
45+
)
46+
}
47+
}
48+
3149
export async function generateAutoManifest({
3250
computeArtifactsSidecar,
3351
cwd,
@@ -77,6 +95,7 @@ export async function generateAutoManifest({
7795
// `defaults.manifest.sbt.facts: false` in socket.json.
7896
if (sockJson.defaults?.manifest?.sbt?.facts !== false) {
7997
logger.log('Detected a Scala sbt build, generating Socket facts...')
98+
const beforeExitCode = process.exitCode
8099
await convertSbtToFacts({
81100
...sbtArgs,
82101
excludeConfigs: sockJson.defaults?.manifest?.sbt?.excludeConfigs ?? '',
@@ -87,12 +106,15 @@ export async function generateAutoManifest({
87106
sidecarAcc,
88107
withFiles: computeArtifactsSidecar,
89108
})
109+
abortManifestRunIfFailed('sbt', beforeExitCode)
90110
} else {
91111
logger.log('Detected a Scala sbt build, generating pom files with sbt...')
112+
const beforeExitCode = process.exitCode
92113
await convertSbtToMaven({
93114
...sbtArgs,
94115
out: sockJson.defaults?.manifest?.sbt?.outfile ?? './pom.xml',
95116
})
117+
abortManifestRunIfFailed('sbt', beforeExitCode)
96118
}
97119
}
98120

@@ -114,6 +136,7 @@ export async function generateAutoManifest({
114136
logger.log(
115137
'Detected a gradle build (Gradle, Kotlin, Scala), generating Socket facts...',
116138
)
139+
const beforeExitCode = process.exitCode
117140
await convertGradleToFacts({
118141
...gradleArgs,
119142
excludeConfigs:
@@ -126,16 +149,20 @@ export async function generateAutoManifest({
126149
sidecarAcc,
127150
withFiles: computeArtifactsSidecar,
128151
})
152+
abortManifestRunIfFailed('gradle', beforeExitCode)
129153
} else {
130154
logger.log(
131155
'Detected a gradle build (Gradle, Kotlin, Scala), running default gradle generator...',
132156
)
157+
const beforeExitCode = process.exitCode
133158
await convertGradleToMaven(gradleArgs)
159+
abortManifestRunIfFailed('gradle', beforeExitCode)
134160
}
135161
}
136162

137163
if (!sockJson?.defaults?.manifest?.maven?.disabled && detected.maven) {
138164
logger.log('Detected a Maven pom.xml build, generating Socket facts...')
165+
const beforeExitCode = process.exitCode
139166
await convertMavenToFacts({
140167
// Configured bin wins; else prefer ./mvnw, else mvn on PATH.
141168
bin:
@@ -154,6 +181,7 @@ export async function generateAutoManifest({
154181
verbose: Boolean(sockJson.defaults?.manifest?.maven?.verbose),
155182
withFiles: computeArtifactsSidecar,
156183
})
184+
abortManifestRunIfFailed('maven', beforeExitCode)
157185
}
158186

159187
if (!sockJson?.defaults?.manifest?.conda?.disabled && detected.conda) {

0 commit comments

Comments
 (0)