diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f19429b..6597be631 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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.29](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.29) - 2025-11-16 + +### Added +- Added options `--reach-concurrency ` and `--reach-disable-analysis-splitting` for `socket scan create --reach` + ## [1.1.28](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.28) - 2025-11-13 ### Added diff --git a/package.json b/package.json index 4ffe3e708..631fa85c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socket", - "version": "1.1.28", + "version": "1.1.29", "description": "CLI for Socket.dev", "homepage": "https://github.com/SocketDev/socket-cli", "license": "MIT AND OFL-1.1", diff --git a/src/commands/ci/handle-ci.mts b/src/commands/ci/handle-ci.mts index 48725f039..a81442292 100644 --- a/src/commands/ci/handle-ci.mts +++ b/src/commands/ci/handle-ci.mts @@ -53,7 +53,9 @@ export async function handleCi(autoManifest: boolean): Promise { reach: { reachAnalysisTimeout: 0, reachAnalysisMemoryLimit: 0, + reachConcurrency: 1, reachDisableAnalytics: false, + reachDisableAnalysisSplitting: false, reachEcosystems: [], reachExcludePaths: [], reachSkipCache: false, diff --git a/src/commands/scan/cmd-scan-create.mts b/src/commands/scan/cmd-scan-create.mts index fc367c6fd..6c0188432 100644 --- a/src/commands/scan/cmd-scan-create.mts +++ b/src/commands/scan/cmd-scan-create.mts @@ -238,6 +238,8 @@ async function run( reach, reachAnalysisMemoryLimit, reachAnalysisTimeout, + reachConcurrency, + reachDisableAnalysisSplitting, reachDisableAnalytics, reachSkipCache, readOnly, @@ -263,7 +265,9 @@ async function run( reach: boolean reachAnalysisTimeout: number reachAnalysisMemoryLimit: number + reachConcurrency: number reachDisableAnalytics: boolean + reachDisableAnalysisSplitting: boolean reachSkipCache: boolean } @@ -430,6 +434,9 @@ async function run( const isUsingNonDefaultTimeout = reachAnalysisTimeout !== reachabilityFlags['reachAnalysisTimeout']?.default + const isUsingNonDefaultConcurrency = + reachConcurrency !== reachabilityFlags['reachConcurrency']?.default + const isUsingNonDefaultAnalytics = reachDisableAnalytics !== reachabilityFlags['reachDisableAnalytics']?.default @@ -437,10 +444,12 @@ async function run( const isUsingAnyReachabilityFlags = isUsingNonDefaultMemoryLimit || isUsingNonDefaultTimeout || + isUsingNonDefaultConcurrency || isUsingNonDefaultAnalytics || hasReachEcosystems || hasReachExcludePaths || - reachSkipCache + reachSkipCache || + reachDisableAnalysisSplitting const wasValidInput = checkCommandInput( outputKind, @@ -513,6 +522,8 @@ async function run( reachDisableAnalytics: Boolean(reachDisableAnalytics), reachAnalysisTimeout: Number(reachAnalysisTimeout), reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit), + reachConcurrency: Number(reachConcurrency), + reachDisableAnalysisSplitting: Boolean(reachDisableAnalysisSplitting), reachEcosystems, reachExcludePaths, reachSkipCache: Boolean(reachSkipCache), diff --git a/src/commands/scan/cmd-scan-reach.mts b/src/commands/scan/cmd-scan-reach.mts index 8fcd446a2..3bc7fd609 100644 --- a/src/commands/scan/cmd-scan-reach.mts +++ b/src/commands/scan/cmd-scan-reach.mts @@ -111,6 +111,8 @@ async function run( org: orgFlag, reachAnalysisMemoryLimit, reachAnalysisTimeout, + reachConcurrency, + reachDisableAnalysisSplitting, reachDisableAnalytics, reachSkipCache, } = cli.flags as { @@ -121,7 +123,9 @@ async function run( org: string reachAnalysisTimeout: number reachAnalysisMemoryLimit: number + reachConcurrency: number reachDisableAnalytics: boolean + reachDisableAnalysisSplitting: boolean reachSkipCache: boolean } @@ -202,7 +206,9 @@ async function run( reachabilityOptions: { reachAnalysisTimeout: Number(reachAnalysisTimeout), reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit), + reachConcurrency: Number(reachConcurrency), reachDisableAnalytics: Boolean(reachDisableAnalytics), + reachDisableAnalysisSplitting: Boolean(reachDisableAnalysisSplitting), reachEcosystems, reachExcludePaths, reachSkipCache: Boolean(reachSkipCache), diff --git a/src/commands/scan/cmd-scan-reach.test.mts b/src/commands/scan/cmd-scan-reach.test.mts index 9ef444cce..c543d739f 100644 --- a/src/commands/scan/cmd-scan-reach.test.mts +++ b/src/commands/scan/cmd-scan-reach.test.mts @@ -38,7 +38,9 @@ describe('socket scan reach', async () => { Reachability Options --reach-analysis-memory-limit The maximum memory in MB to use for the reachability analysis. The default is 8192MB. --reach-analysis-timeout Set timeout for the reachability analysis. Split analysis runs may cause the total scan time to exceed this timeout significantly. + --reach-concurrency Set the maximum number of concurrent reachability analysis runs. It is recommended to choose a concurrency level that ensures each analysis run has at least the --reach-analysis-memory-limit amount of memory available. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM. --reach-disable-analytics Disable reachability analytics sharing with Socket. Also disables caching-based optimizations. + --reach-disable-analysis-splitting Limits Coana to at most 1 reachability analysis run per workspace. --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-exclude-paths List of paths to exclude from reachability analysis, as either a comma separated value or as multiple flags. --reach-skip-cache Skip caching-based optimizations. By default, the reachability analysis will use cached configurations from previous runs to speed up the analysis. @@ -155,6 +157,45 @@ describe('socket scan reach', async () => { }, ) + cmdit( + [ + 'scan', + 'reach', + FLAG_DRY_RUN, + '--reach-concurrency', + '4', + '--org', + 'fakeOrg', + FLAG_CONFIG, + '{"apiToken":"fakeToken"}', + ], + 'should accept --reach-concurrency flag', + async cmd => { + const { code, stdout } = await spawnSocketCli(binCliPath, cmd) + expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`) + expect(code, 'should exit with code 0').toBe(0) + }, + ) + + cmdit( + [ + 'scan', + 'reach', + FLAG_DRY_RUN, + '--reach-disable-analysis-splitting', + '--org', + 'fakeOrg', + FLAG_CONFIG, + '{"apiToken":"fakeToken"}', + ], + 'should accept --reach-disable-analysis-splitting flag', + async cmd => { + const { code, stdout } = await spawnSocketCli(binCliPath, cmd) + expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`) + expect(code, 'should exit with code 0').toBe(0) + }, + ) + cmdit( [ 'scan', @@ -269,6 +310,9 @@ describe('socket scan reach', async () => { '4096', '--reach-analysis-timeout', '3600', + '--reach-concurrency', + '2', + '--reach-disable-analysis-splitting', '--reach-ecosystems', 'npm,pypi', '--reach-exclude-paths', diff --git a/src/commands/scan/create-scan-from-github.mts b/src/commands/scan/create-scan-from-github.mts index e4ab7e87a..77530cc75 100644 --- a/src/commands/scan/create-scan-from-github.mts +++ b/src/commands/scan/create-scan-from-github.mts @@ -253,6 +253,8 @@ async function scanOneRepo( reachDisableAnalytics: false, reachAnalysisTimeout: 0, reachAnalysisMemoryLimit: 0, + reachConcurrency: 1, + reachDisableAnalysisSplitting: false, reachEcosystems: [], reachExcludePaths: [], reachSkipCache: false, diff --git a/src/commands/scan/perform-reachability-analysis.mts b/src/commands/scan/perform-reachability-analysis.mts index 2df390386..847abce01 100644 --- a/src/commands/scan/perform-reachability-analysis.mts +++ b/src/commands/scan/perform-reachability-analysis.mts @@ -16,7 +16,9 @@ import type { Spinner } from '@socketsecurity/registry/lib/spinner' export type ReachabilityOptions = { reachAnalysisTimeout: number reachAnalysisMemoryLimit: number + reachConcurrency: number reachDisableAnalytics: boolean + reachDisableAnalysisSplitting: boolean reachEcosystems: PURL_Type[] reachExcludePaths: string[] reachSkipCache: boolean @@ -146,9 +148,15 @@ export async function performReachabilityAnalysis( ...(reachabilityOptions.reachAnalysisMemoryLimit ? ['--memory-limit', `${reachabilityOptions.reachAnalysisMemoryLimit}`] : []), + ...(reachabilityOptions.reachConcurrency + ? ['--concurrency', `${reachabilityOptions.reachConcurrency}`] + : []), ...(reachabilityOptions.reachDisableAnalytics ? ['--disable-analytics-sharing'] : []), + ...(reachabilityOptions.reachDisableAnalysisSplitting + ? ['--disable-analysis-splitting'] + : []), ...(tarHash ? ['--run-without-docker', '--manifests-tar-hash', tarHash] : []), diff --git a/src/commands/scan/reachability-flags.mts b/src/commands/scan/reachability-flags.mts index 0cd9278a6..fd309b10d 100644 --- a/src/commands/scan/reachability-flags.mts +++ b/src/commands/scan/reachability-flags.mts @@ -13,12 +13,24 @@ export const reachabilityFlags: MeowFlags = { description: 'Set timeout for the reachability analysis. Split analysis runs may cause the total scan time to exceed this timeout significantly.', }, + reachConcurrency: { + type: 'number', + default: 1, + description: + 'Set the maximum number of concurrent reachability analysis runs. It is recommended to choose a concurrency level that ensures each analysis run has at least the --reach-analysis-memory-limit amount of memory available. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM.', + }, reachDisableAnalytics: { type: 'boolean', default: false, description: 'Disable reachability analytics sharing with Socket. Also disables caching-based optimizations.', }, + reachDisableAnalysisSplitting: { + type: 'boolean', + default: false, + description: + 'Limits Coana to at most 1 reachability analysis run per workspace.', + }, reachEcosystems: { type: 'string', isMultiple: true,