Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Changed
- **Bazel diagnostics** — `socket manifest bazel --verbose` now emits bounded subprocess traces with argv, cwd, duration, exit status, output sizes, and failure stderr tails to make customer log-only triage safer and faster.

## [1.1.107](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.107) - 2026-05-28

### Changed
- **`socket manifest gradle --facts [beta]`** (and its `kotlin` alias) gained `--configs` and `--ignore-unresolved`, matching `socket manifest scala --facts`. `--configs` takes comma-separated glob patterns (e.g. `*CompileClasspath,*RuntimeClasspath`) to restrict resolution to matching Gradle configurations; unresolved dependencies are now a fatal error by default — pass `--ignore-unresolved` for the previous lenient behavior.
- **`socket manifest scala --facts --configs`** now accepts glob patterns too (e.g. `*Test*`) for consistency with the gradle command. Bare names (no `*`/`?`) keep working as exact-name filters, so existing usages are unchanged.

### Fixed
- **`socket manifest gradle --facts`** now works on Gradle builds with the configuration cache enabled (default on Gradle 9), which previously failed with `Task.project at execution time` errors.

## [1.1.106](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.106) - 2026-05-27

### Added
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.106",
"version": "1.1.107",
"description": "CLI for Socket.dev",
"homepage": "https://github.com/SocketDev/socket-cli",
"license": "MIT AND OFL-1.1",
Expand Down
57 changes: 56 additions & 1 deletion src/commands/manifest/cmd-manifest-gradle.mts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ const config: CliCommandConfig = {
description:
'Emit a Socket facts JSON file (`.socket.facts.json`) describing the resolved dependency graph instead of generating `pom.xml` files',
},
configs: {
type: 'string',
description:
'With --facts: comma-separated glob patterns matched against Gradle configuration names (case-sensitive, `*` and `?` wildcards). e.g. `*CompileClasspath,*RuntimeClasspath` to skip tooling configs. Default: every resolvable configuration except AGP instrumented-test classpaths',
},
ignoreUnresolved: {
type: 'boolean',
description:
'With --facts: warn on unresolved dependencies instead of failing the run (unresolved deps are not emitted to the facts file)',
},
gradleOpts: {
type: 'string',
description:
Expand Down Expand Up @@ -69,11 +79,20 @@ const config: CliCommandConfig = {

- it works with your \`gradlew\` from your repo and local settings and config

Pass --facts to instead emit a single \`.socket.facts.json\` describing the
resolved dependency graph of the whole build (no \`pom.xml\` files). An
unresolved dependency is a fatal error. With --facts you can pass
--configs=<comma-separated glob patterns> to restrict resolution to
matching configurations (e.g. \`*CompileClasspath,*RuntimeClasspath\`),
and --ignore-unresolved to warn on unresolved dependencies instead of
failing the run.

Support is beta. Please report issues or give us feedback on what's missing.

Examples

$ ${command} .
$ ${command} --facts .
$ ${command} --bin=../gradlew .
`,
}
Expand Down Expand Up @@ -116,7 +135,7 @@ async function run(
sockJson?.defaults?.manifest?.gradle,
)

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

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

// `--configs` and `--ignore-unresolved` only affect --facts; the pom path
// (the legacy `socketGenerateMaven` task) has no equivalent knobs. Warn
// rather than silently ignore an explicitly-passed flag. (socket.json
// defaults don't trip this — only a flag actually present on the command
// line does.)
if (
!facts &&
(cli.flags['configs'] !== undefined ||
cli.flags['ignoreUnresolved'] !== undefined)
) {
logger.warn(
'The `--configs` and `--ignore-unresolved` options only apply with `--facts`; ignoring them.',
)
}

if (verbose) {
logger.group('- ', parentName, config.commandName, ':')
Expand Down Expand Up @@ -197,8 +250,10 @@ async function run(
if (facts) {
await convertGradleToFacts({
bin: String(bin),
configs: String(configs || ''),
cwd,
gradleOpts: parsedGradleOpts,
ignoreUnresolved: Boolean(ignoreUnresolved),
verbose: Boolean(verbose),
})
return
Expand Down
11 changes: 11 additions & 0 deletions src/commands/manifest/cmd-manifest-gradle.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ describe('socket manifest gradle', async () => {

Options
--bin Location of gradlew binary to use, default: CWD/gradlew
--configs With --facts: comma-separated glob patterns matched against Gradle configuration names (case-sensitive, \`*\` and \`?\` wildcards). e.g. \`*CompileClasspath,*RuntimeClasspath\` to skip tooling configs. Default: every resolvable configuration except AGP instrumented-test classpaths
--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\`
--ignore-unresolved With --facts: warn on unresolved dependencies instead of failing the run (unresolved deps are not emitted to the facts file)
--verbose Print debug messages

Uses gradle, preferably through your local project \`gradlew\`, to generate a
Expand All @@ -46,11 +48,20 @@ describe('socket manifest gradle', async () => {

- it works with your \`gradlew\` from your repo and local settings and config

Pass --facts to instead emit a single \`.socket.facts.json\` describing the
resolved dependency graph of the whole build (no \`pom.xml\` files). An
unresolved dependency is a fatal error. With --facts you can pass
--configs=<comma-separated glob patterns> to restrict resolution to
matching configurations (e.g. \`*CompileClasspath,*RuntimeClasspath\`),
and --ignore-unresolved to warn on unresolved dependencies instead of
failing the run.

Support is beta. Please report issues or give us feedback on what's missing.

Examples

$ socket manifest gradle .
$ socket manifest gradle --facts .
$ socket manifest gradle --bin=../gradlew ."
`,
)
Expand Down
43 changes: 42 additions & 1 deletion src/commands/manifest/cmd-manifest-kotlin.mts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ const config: CliCommandConfig = {
description:
'Emit a Socket facts JSON file (`.socket.facts.json`) describing the resolved dependency graph instead of generating `pom.xml` files',
},
configs: {
type: 'string',
description:
'With --facts: comma-separated glob patterns matched against Gradle configuration names (case-sensitive, `*` and `?` wildcards). e.g. `*CompileClasspath,*RuntimeClasspath` to skip tooling configs. Default: every resolvable configuration except AGP instrumented-test classpaths',
},
ignoreUnresolved: {
type: 'boolean',
description:
'With --facts: warn on unresolved dependencies instead of failing the run (unresolved deps are not emitted to the facts file)',
},
gradleOpts: {
type: 'string',
description:
Expand Down Expand Up @@ -121,7 +131,7 @@ async function run(
sockJson?.defaults?.manifest?.gradle,
)

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

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

if (
!facts &&
(cli.flags['configs'] !== undefined ||
cli.flags['ignoreUnresolved'] !== undefined)
) {
logger.warn(
'The `--configs` and `--ignore-unresolved` options only apply with `--facts`; ignoring them.',
)
}

if (verbose) {
logger.group('- ', parentName, config.commandName, ':')
Expand Down Expand Up @@ -202,8 +241,10 @@ async function run(
if (facts) {
await convertGradleToFacts({
bin: String(bin),
configs: String(configs || ''),
cwd,
gradleOpts: parsedGradleOpts,
ignoreUnresolved: Boolean(ignoreUnresolved),
verbose: Boolean(verbose),
})
return
Expand Down
2 changes: 2 additions & 0 deletions src/commands/manifest/cmd-manifest-kotlin.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ describe('socket manifest kotlin', async () => {

Options
--bin Location of gradlew binary to use, default: CWD/gradlew
--configs With --facts: comma-separated glob patterns matched against Gradle configuration names (case-sensitive, \`*\` and \`?\` wildcards). e.g. \`*CompileClasspath,*RuntimeClasspath\` to skip tooling configs. Default: every resolvable configuration except AGP instrumented-test classpaths
--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\`
--ignore-unresolved With --facts: warn on unresolved dependencies instead of failing the run (unresolved deps are not emitted to the facts file)
--verbose Print debug messages

Uses gradle, preferably through your local project \`gradlew\`, to generate a
Expand Down
10 changes: 6 additions & 4 deletions src/commands/manifest/cmd-manifest-scala.mts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ const config: CliCommandConfig = {
configs: {
type: 'string',
description:
'With --facts: comma-separated sbt configurations to resolve (default: compile,optional,provided,runtime,test)',
'With --facts: comma-separated glob patterns matched against sbt configuration names (case-sensitive, `*` and `?` wildcards). Bare names (no wildcards) act as exact-name filters. Default: compile,optional,provided,runtime,test',
},
ignoreUnresolved: {
type: 'boolean',
description:
'With --facts: skip dependencies that fail to resolve instead of failing the run',
'With --facts: warn on unresolved dependencies instead of failing the run (unresolved deps are not emitted to the facts file)',
},
out: {
type: 'string',
Expand Down Expand Up @@ -95,8 +95,10 @@ const config: CliCommandConfig = {
resolved dependency graph of the whole build (no \`pom.xml\` files). It reads
dependency metadata only and never downloads artifacts; an unresolved
dependency is a fatal error. With --facts you can pass
--configs=compile,test to choose which sbt configurations to resolve, and
--ignore-unresolved to skip dependencies that fail to resolve.
--configs=<comma-separated glob patterns> to choose which sbt configurations
to resolve (e.g. \`compile,test\` for exact names or \`*Test*\` for variants),
and --ignore-unresolved to warn on unresolved dependencies instead of
failing the run.

Support is beta. Please report issues or give us feedback on what's missing.

Expand Down
10 changes: 6 additions & 4 deletions src/commands/manifest/cmd-manifest-scala.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ describe('socket manifest scala', async () => {

Options
--bin Location of sbt binary to use
--configs With --facts: comma-separated sbt configurations to resolve (default: compile,optional,provided,runtime,test)
--configs With --facts: comma-separated glob patterns matched against sbt configuration names (case-sensitive, \`*\` and \`?\` wildcards). Bare names (no wildcards) act as exact-name filters. Default: compile,optional,provided,runtime,test
--facts Emit a Socket facts JSON file (\`.socket.facts.json\`) describing the resolved dependency graph instead of generating \`pom.xml\` files
--ignore-unresolved With --facts: skip dependencies that fail to resolve instead of failing the run
--ignore-unresolved With --facts: warn on unresolved dependencies instead of failing the run (unresolved deps are not emitted to the facts file)
--out Path of output file; where to store the resulting manifest, see also --stdout
--sbt-opts Additional options to pass on to sbt, as per \`sbt --help\`
--stdout Print resulting pom.xml to stdout (supersedes --out)
Expand Down Expand Up @@ -58,8 +58,10 @@ describe('socket manifest scala', async () => {
resolved dependency graph of the whole build (no \`pom.xml\` files). It reads
dependency metadata only and never downloads artifacts; an unresolved
dependency is a fatal error. With --facts you can pass
--configs=compile,test to choose which sbt configurations to resolve, and
--ignore-unresolved to skip dependencies that fail to resolve.
--configs=<comma-separated glob patterns> to choose which sbt configurations
to resolve (e.g. \`compile,test\` for exact names or \`*Test*\` for variants),
and --ignore-unresolved to warn on unresolved dependencies instead of
failing the run.

Support is beta. Please report issues or give us feedback on what's missing.

Expand Down
31 changes: 31 additions & 0 deletions src/commands/manifest/convert-gradle-to-facts.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import constants from '../../constants.mts'

export async function convertGradleToFacts({
bin,
configs,
cwd,
gradleOpts,
ignoreUnresolved,
verbose,
}: {
bin: string
configs: string
cwd: string
gradleOpts: string[]
ignoreUnresolved: boolean
verbose: boolean
}): Promise<void> {
const rBin = path.resolve(cwd, bin)
Expand Down Expand Up @@ -43,7 +47,34 @@ export async function convertGradleToFacts({
constants.distPath,
'socket-facts.init.gradle',
)
// Disable Gradle's configuration cache for the facts run. The init
// script resolves dependencies via the legacy
// `Configuration.resolvedConfiguration` API (the only public API that
// surfaces classifier + extension metadata) and registers per-
// subproject tasks that share a `gradle.ext` accumulator — neither
// pattern is compatible with the configuration cache, which would
// otherwise be on by default for projects with
// `org.gradle.configuration-cache=true` in `gradle.properties`. The
// Provider-based CC-safe alternatives (`ResolutionResult` /
// `ArtifactView.resolvedArtifacts`) only exist in Gradle 7.4+ and
// they don't expose classifier/extension, so they aren't a usable
// replacement here. Using `-D` rather than `--no-configuration-cache`
// keeps us compatible with older Gradle versions that don't recognize
// the flag — the system property is silently ignored when the
// feature doesn't exist.
// Both knobs are passed as Gradle project properties so the init script
// can read them via `rp.findProperty(...)`, matching how
// `socket.outputDirectory` / `socket.outputFile` are already wired.
const socketProps: string[] = []
if (ignoreUnresolved) {
socketProps.push('-Psocket.ignoreUnresolved=true')
}
if (configs) {
socketProps.push(`-Psocket.configs=${configs}`)
}
const commandArgs = [
'-Dorg.gradle.configuration-cache=false',
...socketProps,
'--init-script',
initLocation,
...gradleOpts,
Expand Down
8 changes: 7 additions & 1 deletion src/commands/manifest/generate_auto_manifest.mts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,13 @@ export async function generateAutoManifest({
logger.log(
'Detected a gradle build (Gradle, Kotlin, Scala), generating Socket facts...',
)
await convertGradleToFacts(gradleArgs)
await convertGradleToFacts({
...gradleArgs,
configs: sockJson.defaults?.manifest?.gradle?.configs ?? '',
ignoreUnresolved: Boolean(
sockJson.defaults?.manifest?.gradle?.ignoreUnresolved,
),
})
} else {
logger.log(
'Detected a gradle build (Gradle, Kotlin, Scala), running default gradle generator...',
Expand Down
Loading
Loading