Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
094be5d
feat(manifest): add --facts mode to socket manifest gradle (REA-442)
jfblaa May 19, 2026
8aab9dd
test(manifest): drop gradle facts integration suite, match existing s…
jfblaa May 19, 2026
44f6739
fix(manifest): don't emit the scan-target project as a facts component
jfblaa May 19, 2026
5c0ac03
feat(manifest): mirror --facts onto kotlin and auto-detect paths
jfblaa May 19, 2026
3043215
feat(manifest): surface --facts in socket manifest setup wizard
jfblaa May 19, 2026
2753566
test(manifest): restore gradle facts integration test, install JDK+Gr…
jfblaa May 19, 2026
37d8e62
feat(manifest): cover Android Gradle Plugin variants in --facts
jfblaa May 19, 2026
bfd09fb
test(manifest): add Kotlin Multiplatform fixture for --facts
jfblaa May 19, 2026
bedd243
feat(manifest): emit `tooling` flag on facts components
jfblaa May 19, 2026
f557a83
fix(manifest): make --verbose actually stream gradle output live
jfblaa May 19, 2026
732d5b8
perf(manifest): stop downloading artifact files in facts init script
jfblaa May 19, 2026
e26981e
feat(manifest): emit single facts file per build, drop intra-project …
jfblaa May 19, 2026
8d72b01
fix(ci): correct gradle/actions v4 commit SHA pin
jfblaa May 19, 2026
eab397b
fix(scan): stop stripping .socket.facts.json from --reach upload; cle…
jfblaa May 22, 2026
d6a49f7
chore(gitignore): scope gradle-facts ignores to a nested .gitignore
jfblaa May 22, 2026
71a2a3e
review(#1318): address PR feedback (findings 1, 2, 3, 4, 6, 8)
jfblaa May 22, 2026
62d6dc4
release: v1.1.98
jfblaa May 22, 2026
ca68ffb
Merge branch 'v1.x' into jfblaa/rea-442-socket-manifest-gradle-facts-…
jfblaa May 22, 2026
7098825
ci: probe — comment out gradle/actions/setup-gradle to isolate startu…
jfblaa May 22, 2026
2972c06
ci: probe 2 — also remove setup-java to verify nothing in my changes …
jfblaa May 22, 2026
5f3c35b
ci: revert e2e-tests.yml + drop gradle integration suite
jfblaa May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .config/rollup.dist.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ async function copyInitGradle() {
await fs.copyFile(filepath, destPath)
}

async function copySocketFactsInitGradle() {
const filepath = path.join(
constants.srcPath,
'commands/manifest/socket-facts.init.gradle',
)
const destPath = path.join(constants.distPath, 'socket-facts.init.gradle')
await fs.copyFile(filepath, destPath)
}

async function copyBashCompletion() {
const filepath = path.join(
constants.srcPath,
Expand Down Expand Up @@ -458,6 +467,7 @@ export default async () => {
async writeBundle() {
await Promise.all([
copyInitGradle(),
copySocketFactsInitGradle(),
copyBashCompletion(),
updatePackageJson(),
// Remove dist/vendor.js.map file.
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Added
- **`socket manifest bazel [beta]`** — Generate Bazel JVM SBOM manifests by running `bazel query` against discovered Maven repos in a Bazel workspace. Closes the inline-Maven-declaration gap that lockfile-only parsing misses for repos like envoy, ray, tensorflow, tink-java, and or-tools. Auto-detects Bzlmod and legacy `WORKSPACE`.
- **`socket scan create --auto-manifest`** now covers Bazel workspaces in addition to Gradle/Scala/Kotlin/Conda. Repos with `MODULE.bazel`, `WORKSPACE`, or `WORKSPACE.bazel` are detected automatically and their Maven dependencies extracted as part of the standard scan-create flow.

## [1.1.98](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.98) - 2026-05-22

### Added
- **`socket manifest gradle --facts [beta]`** (and its `socket manifest kotlin --facts` alias) — Emit a `.socket.facts.json` dependency graph from a Gradle build, consumable by `socket scan create --reach` as pregenerated SBOM input for Tier 1 reachability. Toggle also exposed via the `socket manifest setup` wizard for use with `--auto-manifest`.

### Changed
- Updated the Coana CLI to v `15.3.8`.

## [1.1.101](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.101) - 2026-05-22

### Changed
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "socket",
"version": "1.1.101",
"version": "1.1.102",
"description": "CLI for Socket.dev",
"homepage": "https://github.com/SocketDev/socket-cli",
"license": "MIT AND OFL-1.1",
Expand Down
36 changes: 31 additions & 5 deletions src/commands/manifest/cmd-manifest-gradle.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'node:path'
import { debugFn } from '@socketsecurity/registry/lib/debug'
import { logger } from '@socketsecurity/registry/lib/logger'

import { convertGradleToFacts } from './convert-gradle-to-facts.mts'
import { convertGradleToMaven } from './convert_gradle_to_maven.mts'
import constants, { REQUIREMENTS_TXT, SOCKET_JSON } from '../../constants.mts'
import { commonFlags } from '../../flags.mts'
Expand All @@ -28,6 +29,11 @@ const config: CliCommandConfig = {
type: 'string',
description: 'Location of gradlew binary to use, default: CWD/gradlew',
},
facts: {
type: 'boolean',
description:
'Emit a Socket facts JSON file (`.socket.facts.json`) describing the resolved dependency graph instead of generating `pom.xml` files',
},
gradleOpts: {
type: 'string',
description:
Expand Down Expand Up @@ -110,7 +116,7 @@ async function run(
sockJson?.defaults?.manifest?.gradle,
)

let { bin, gradleOpts, verbose } = cli.flags
let { bin, facts, gradleOpts, verbose } = cli.flags

// Set defaults for any flag/arg that is not given. Check socket.json first.
if (!bin) {
Expand Down Expand Up @@ -140,6 +146,14 @@ async function run(
verbose = false
}
}
if (facts === undefined) {
if (sockJson.defaults?.manifest?.gradle?.facts !== undefined) {
facts = sockJson.defaults?.manifest?.gradle?.facts
logger.info(`Using default --facts from ${SOCKET_JSON}:`, facts)
} else {
facts = false
}
}

if (verbose) {
logger.group('- ', parentName, config.commandName, ':')
Expand Down Expand Up @@ -175,13 +189,25 @@ async function run(
return
}

const parsedGradleOpts = String(gradleOpts || '')
.split(' ')
.map(s => s.trim())
.filter(Boolean)

if (facts) {
await convertGradleToFacts({
bin: String(bin),
cwd,
gradleOpts: parsedGradleOpts,
verbose: Boolean(verbose),
})
return
}

await convertGradleToMaven({
bin: String(bin),
cwd,
gradleOpts: String(gradleOpts || '')
.split(' ')
.map(s => s.trim())
.filter(Boolean),
gradleOpts: parsedGradleOpts,
verbose: Boolean(verbose),
})
}
19 changes: 19 additions & 0 deletions src/commands/manifest/cmd-manifest-gradle.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('socket manifest gradle', async () => {

Options
--bin Location of gradlew binary to use, default: CWD/gradlew
--facts Emit a Socket facts JSON file (\`.socket.facts.json\`) describing the resolved dependency graph instead of generating \`pom.xml\` files
--gradle-opts Additional options to pass on to ./gradlew, see \`./gradlew --help\`
--verbose Print debug messages

Expand Down Expand Up @@ -85,4 +86,22 @@ describe('socket manifest gradle', async () => {
expect(code, 'dry-run should exit with code 0 if input ok').toBe(0)
},
)

cmdit(
['manifest', 'gradle', '--facts', FLAG_DRY_RUN, FLAG_CONFIG, '{}'],
'should accept --facts with dry-run',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
_____ _ _ /---------------
| __|___ ___| |_ ___| |_ | CLI: <redacted>
|__ | * | _| '_| -_| _| | token: <redacted>, org: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket manifest gradle\`, cwd: <redacted>"
`)

expect(code, '--facts --dry-run should exit with code 0').toBe(0)
},
)
})
36 changes: 31 additions & 5 deletions src/commands/manifest/cmd-manifest-kotlin.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'node:path'
import { debugFn } from '@socketsecurity/registry/lib/debug'
import { logger } from '@socketsecurity/registry/lib/logger'

import { convertGradleToFacts } from './convert-gradle-to-facts.mts'
import { convertGradleToMaven } from './convert_gradle_to_maven.mts'
import constants, { REQUIREMENTS_TXT, SOCKET_JSON } from '../../constants.mts'
import { commonFlags } from '../../flags.mts'
Expand Down Expand Up @@ -33,6 +34,11 @@ const config: CliCommandConfig = {
type: 'string',
description: 'Location of gradlew binary to use, default: CWD/gradlew',
},
facts: {
type: 'boolean',
description:
'Emit a Socket facts JSON file (`.socket.facts.json`) describing the resolved dependency graph instead of generating `pom.xml` files',
},
gradleOpts: {
type: 'string',
description:
Expand Down Expand Up @@ -115,7 +121,7 @@ async function run(
sockJson?.defaults?.manifest?.gradle,
)

let { bin, gradleOpts, verbose } = cli.flags
let { bin, facts, gradleOpts, verbose } = cli.flags

// Set defaults for any flag/arg that is not given. Check socket.json first.
if (!bin) {
Expand Down Expand Up @@ -145,6 +151,14 @@ async function run(
verbose = false
}
}
if (facts === undefined) {
if (sockJson.defaults?.manifest?.gradle?.facts !== undefined) {
facts = sockJson.defaults?.manifest?.gradle?.facts
logger.info(`Using default --facts from ${SOCKET_JSON}:`, facts)
} else {
facts = false
}
}

if (verbose) {
logger.group('- ', parentName, config.commandName, ':')
Expand Down Expand Up @@ -180,13 +194,25 @@ async function run(
return
}

const parsedGradleOpts = String(gradleOpts || '')
.split(' ')
.map(s => s.trim())
.filter(Boolean)

if (facts) {
await convertGradleToFacts({
bin: String(bin),
cwd,
gradleOpts: parsedGradleOpts,
verbose: Boolean(verbose),
})
return
}

await convertGradleToMaven({
bin: String(bin),
cwd,
gradleOpts: String(gradleOpts || '')
.split(' ')
.map(s => s.trim())
.filter(Boolean),
gradleOpts: parsedGradleOpts,
verbose: Boolean(verbose),
})
}
19 changes: 19 additions & 0 deletions src/commands/manifest/cmd-manifest-kotlin.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('socket manifest kotlin', async () => {

Options
--bin Location of gradlew binary to use, default: CWD/gradlew
--facts Emit a Socket facts JSON file (\`.socket.facts.json\`) describing the resolved dependency graph instead of generating \`pom.xml\` files
--gradle-opts Additional options to pass on to ./gradlew, see \`./gradlew --help\`
--verbose Print debug messages

Expand Down Expand Up @@ -85,4 +86,22 @@ describe('socket manifest kotlin', async () => {
expect(code, 'dry-run should exit with code 0 if input ok').toBe(0)
},
)

cmdit(
['manifest', 'kotlin', '--facts', FLAG_DRY_RUN, FLAG_CONFIG, '{}'],
'should accept --facts with dry-run',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
_____ _ _ /---------------
| __|___ ___| |_ ___| |_ | CLI: <redacted>
|__ | * | _| '_| -_| _| | token: <redacted>, org: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket manifest kotlin\`, cwd: <redacted>"
`)

expect(code, '--facts --dry-run should exit with code 0').toBe(0)
},
)
})
Loading
Loading