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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ 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/).

## [1.1.144](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.144) - 2026-07-23

### Fixed
- `--reach-ecosystems` now rejects ecosystems the reachability engine cannot analyze, failing fast at the CLI with a clear message listing the supported ecosystems instead of erroring partway through a scan.

## [1.1.143](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.143) - 2026-07-10

### 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.143",
"version": "1.1.144",
"description": "CLI for Socket.dev",
"homepage": "https://github.com/SocketDev/socket-cli",
"license": "MIT",
Expand Down
20 changes: 5 additions & 15 deletions src/commands/scan/cmd-scan-create.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { existsSync } from 'node:fs'
import path from 'node:path'

import { joinAnd } from '@socketsecurity/registry/lib/arrays'
import { logger } from '@socketsecurity/registry/lib/logger'

import { assertValidExcludePaths } from './exclude-paths.mts'
Expand All @@ -20,7 +19,7 @@ import { commonFlags, outputFlags } from '../../flags.mts'
import { checkCommandInput } from '../../utils/check-input.mts'
import { cmdFlagValueToArray } from '../../utils/cmd.mts'
import { determineOrgSlug } from '../../utils/determine-org-slug.mts'
import { getEcosystemChoicesForMeow } from '../../utils/ecosystem.mts'
import { parseReachEcosystems } from '../../utils/ecosystem.mts'
import { getOutputKind } from '../../utils/get-output-kind.mts'
import {
detectDefaultBranch,
Expand All @@ -39,7 +38,6 @@ import { detectManifestActions } from '../manifest/detect-manifest-actions.mts'

import type { REPORT_LEVEL } from './types.mts'
import type { MeowFlags } from '../../flags.mts'
import type { PURL_Type } from '../../utils/ecosystem.mts'
import type {
CliCommandConfig,
CliCommandContext,
Expand Down Expand Up @@ -308,18 +306,10 @@ async function run(
reachVersion: string | undefined
}

// Validate ecosystem values.
const reachEcosystems: PURL_Type[] = []
const reachEcosystemsRaw = cmdFlagValueToArray(cli.flags['reachEcosystems'])
const validEcosystems = getEcosystemChoicesForMeow()
for (const ecosystem of reachEcosystemsRaw) {
if (!validEcosystems.includes(ecosystem)) {
throw new Error(
`Invalid ecosystem: "${ecosystem}". Valid values are: ${joinAnd(validEcosystems)}`,
)
}
reachEcosystems.push(ecosystem as PURL_Type)
}
// Validate ecosystem values against the reachability-supported set.
const reachEcosystems = parseReachEcosystems(
cmdFlagValueToArray(cli.flags['reachEcosystems']),
)

const dryRun = !!cli.flags['dryRun']

Expand Down
2 changes: 1 addition & 1 deletion src/commands/scan/cmd-scan-create.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('socket scan create', async () => {
--reach-detailed-analysis-log-file A log file with detailed analysis logs is written to root of each analyzed workspace.
--reach-disable-analytics Disable reachability analytics sharing with Socket. Also disables caching-based optimizations.
--reach-disable-external-tool-checks Disable external tool checks during reachability analysis.
--reach-ecosystems List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Defaults to all ecosystems.
--reach-ecosystems List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Supported: cargo, composer, gem, golang, maven, npm, nuget, pypi. Defaults to all supported ecosystems.
--reach-enable-analysis-splitting Allow the reachability analysis to partition CVEs into buckets that are processed in separate analysis runs. May improve accuracy, but not recommended by default.
--reach-retain-facts-file Keep the \`.socket.facts.json\` reachability report that the analysis writes to the scan directory instead of deleting it after a successful scan. IMPORTANT: you must delete this file before running a fresh full application reachability scan. A stale \`.socket.facts.json\` left in place is picked up as a pre-generated input and silently overrides fresh analysis, so the new scan results will not be reliable.
--reach-skip-cache Skip caching-based optimizations. By default, the reachability analysis will use cached configurations from previous runs to speed up the analysis.
Expand Down
17 changes: 3 additions & 14 deletions src/commands/scan/cmd-scan-reach.mts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from 'node:path'

import { joinAnd } from '@socketsecurity/registry/lib/arrays'
import { logger } from '@socketsecurity/registry/lib/logger'

import { assertValidExcludePaths } from './exclude-paths.mts'
Expand All @@ -13,7 +12,7 @@ import { commonFlags, outputFlags } from '../../flags.mts'
import { checkCommandInput } from '../../utils/check-input.mts'
import { cmdFlagValueToArray } from '../../utils/cmd.mts'
import { determineOrgSlug } from '../../utils/determine-org-slug.mts'
import { getEcosystemChoicesForMeow } from '../../utils/ecosystem.mts'
import { parseReachEcosystems } from '../../utils/ecosystem.mts'
import { getOutputKind } from '../../utils/get-output-kind.mts'
import { meowOrExit } from '../../utils/meow-with-subcommands.mts'
import {
Expand All @@ -23,7 +22,6 @@ import {
import { hasDefaultApiToken } from '../../utils/sdk.mts'

import type { MeowFlags } from '../../flags.mts'
import type { PURL_Type } from '../../utils/ecosystem.mts'
import type {
CliCommandConfig,
CliCommandContext,
Expand Down Expand Up @@ -176,17 +174,8 @@ async function run(
const reachExcludePaths = cmdFlagValueToArray(cli.flags['reachExcludePaths'])
assertValidExcludePaths(excludePaths)

// Validate ecosystem values.
const reachEcosystems: PURL_Type[] = []
const validEcosystems = getEcosystemChoicesForMeow()
for (const ecosystem of reachEcosystemsRaw) {
if (!validEcosystems.includes(ecosystem)) {
throw new Error(
`Invalid ecosystem: "${ecosystem}". Valid values are: ${joinAnd(validEcosystems)}`,
)
}
reachEcosystems.push(ecosystem as PURL_Type)
}
// Validate ecosystem values against the reachability-supported set.
const reachEcosystems = parseReachEcosystems(reachEcosystemsRaw)

const processCwd = process.cwd()
const cwd =
Expand Down
23 changes: 22 additions & 1 deletion src/commands/scan/cmd-scan-reach.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('socket scan reach', async () => {
--reach-detailed-analysis-log-file A log file with detailed analysis logs is written to root of each analyzed workspace.
--reach-disable-analytics Disable reachability analytics sharing with Socket. Also disables caching-based optimizations.
--reach-disable-external-tool-checks Disable external tool checks during reachability analysis.
--reach-ecosystems List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Defaults to all ecosystems.
--reach-ecosystems List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Supported: cargo, composer, gem, golang, maven, npm, nuget, pypi. Defaults to all supported ecosystems.
--reach-enable-analysis-splitting Allow the reachability analysis to partition CVEs into buckets that are processed in separate analysis runs. May improve accuracy, but not recommended by default.
--reach-retain-facts-file Keep the \`.socket.facts.json\` reachability report that the analysis writes to the scan directory instead of deleting it after a successful scan. IMPORTANT: you must delete this file before running a fresh full application reachability scan. A stale \`.socket.facts.json\` left in place is picked up as a pre-generated input and silently overrides fresh analysis, so the new scan results will not be reliable.
--reach-skip-cache Skip caching-based optimizations. By default, the reachability analysis will use cached configurations from previous runs to speed up the analysis.
Expand Down Expand Up @@ -291,6 +291,27 @@ describe('socket scan reach', async () => {
},
)

cmdit(
[
'scan',
'reach',
'--reach-ecosystems',
'conda',
'--org',
'fakeOrg',
FLAG_CONFIG,
'{"apiToken":"fakeToken"}',
],
'should reject a purl type that lacks reachability support',
async cmd => {
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
const output = stdout + stderr
expect(output).toContain('Invalid ecosystem: "conda"')
expect(output).toContain('maven')
expect(code, 'should exit with non-zero code').not.toBe(0)
},
)

cmdit(
[
'scan',
Expand Down
4 changes: 2 additions & 2 deletions src/commands/scan/reachability-flags.mts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import constants from '../../constants.mts'
import { getReachabilityEcosystemChoices } from '../../utils/ecosystem.mts'

import type { MeowFlags } from '../../flags.mts'

Expand Down Expand Up @@ -88,8 +89,7 @@ export const reachabilityFlags: MeowFlags = {
reachEcosystems: {
type: 'string',
isMultiple: true,
description:
'List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Defaults to all ecosystems.',
description: `List of ecosystems to conduct reachability analysis on, as either a comma separated value or as multiple flags. Supported: ${getReachabilityEcosystemChoices().join(', ')}. Defaults to all supported ecosystems.`,
},
reachExcludePaths: {
type: 'string',
Expand Down
36 changes: 36 additions & 0 deletions src/utils/ecosystem.mts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
* - Ensures type safety for ecosystem operations
*/

import { joinAnd } from '@socketsecurity/registry/lib/arrays'

import { NPM } from '../constants.mts'
import { InputError } from './errors.mts'

import type { EcosystemString } from '@socketsecurity/registry'
import type { components } from '@socketsecurity/sdk/types/api'
Expand Down Expand Up @@ -87,10 +90,29 @@ export type _Check_ALL_ECOSYSTEMS_has_no_extras =

export const ALL_SUPPORTED_ECOSYSTEMS = new Set<string>(ALL_ECOSYSTEMS)

// Purl types accepted by Coana's reachability `--purl-types` gate
// (@coana-tech/cli `getAdvisoryEcosystemFromPurlType`), narrower than
// ALL_ECOSYSTEMS. Values outside this set are rejected by the engine at scan
// time, so we validate up front. Keep in sync when bumping @coana-tech/cli.
export const REACHABILITY_SUPPORTED_ECOSYSTEMS = [
'cargo',
'composer',
'gem',
'golang',
'maven',
NPM,
'nuget',
'pypi',
] as const satisfies readonly PURL_Type[]

export function getEcosystemChoicesForMeow(): string[] {
return [...ALL_ECOSYSTEMS]
}

export function getReachabilityEcosystemChoices(): string[] {
return [...REACHABILITY_SUPPORTED_ECOSYSTEMS]
}

export function isValidEcosystem(value: string): value is PURL_Type {
return ALL_SUPPORTED_ECOSYSTEMS.has(value)
}
Expand All @@ -108,3 +130,17 @@ export function parseEcosystems(

return values.filter(isValidEcosystem)
}

export function parseReachEcosystems(raw: readonly string[]): PURL_Type[] {
const choices = getReachabilityEcosystemChoices()
const result: PURL_Type[] = []
for (const ecosystem of raw) {
if (!choices.includes(ecosystem)) {
throw new InputError(
`Invalid ecosystem: "${ecosystem}". Valid values are: ${joinAnd(choices)}`,
)
}
result.push(ecosystem as PURL_Type)
}
return result
}