From c42ac464c26b29c3909039a61d572e681cf1774f Mon Sep 17 00:00:00 2001 From: Oskar Haarklou Veileborg Date: Fri, 4 Sep 2026 09:00:05 +0200 Subject: [PATCH 1/2] refactor(scan): require a manifests tar hash for reachability analysis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit performReachabilityAnalysis guarded its manifest upload on `uploadManifests && orgSlug && packagePaths`, all three of which were optional. Falling through that guard left tarHash undefined, which dropped both --manifests-tar-hash and --run-without-docker from the Coana invocation — a silent switch to Docker mode with locally resolved manifests rather than an error. No caller actually did this, but nothing in the type stopped a new one from doing it. Make orgSlug and packagePaths required, drop the uploadManifests option, and flatten the upload into straight-line code so tarHash is a definite string by the time the args are built. A hash-less upload response still fails hard at the parse boundary. --- src/commands/scan/handle-scan-reach.mts | 1 - .../scan/perform-reachability-analysis.mts | 107 +++++++++-------- .../perform-reachability-analysis.test.mts | 108 ++++++++++++++++-- 3 files changed, 150 insertions(+), 66 deletions(-) diff --git a/src/commands/scan/handle-scan-reach.mts b/src/commands/scan/handle-scan-reach.mts index 65ca09355..5e534e16b 100644 --- a/src/commands/scan/handle-scan-reach.mts +++ b/src/commands/scan/handle-scan-reach.mts @@ -137,7 +137,6 @@ async function runScanReach( resolvedPathsSidecar, spinner, target: targets[0]!, - uploadManifests: true, }) spinner.stop() diff --git a/src/commands/scan/perform-reachability-analysis.mts b/src/commands/scan/perform-reachability-analysis.mts index 72017e5e6..36bcc265b 100644 --- a/src/commands/scan/perform-reachability-analysis.mts +++ b/src/commands/scan/perform-reachability-analysis.mts @@ -49,10 +49,12 @@ export type ReachabilityOptions = { export type ReachabilityAnalysisOptions = { branchName?: string | undefined cwd?: string | undefined - orgSlug?: string | undefined + // Required: the manifest upload they drive produces the tar hash Coana needs + // to run without Docker. + orgSlug: string outputKind?: OutputKind | undefined outputPath?: string | undefined - packagePaths?: string[] | undefined + packagePaths: string[] reachabilityOptions: ReachabilityOptions // Resolved-paths sidecar from the auto-manifest run; passed to coana so it // reuses these paths instead of re-resolving the build. @@ -60,7 +62,6 @@ export type ReachabilityAnalysisOptions = { repoName?: string | undefined spinner?: Spinner | undefined target: string - uploadManifests?: boolean | undefined } export type ReachabilityAnalysisResult = { @@ -69,7 +70,7 @@ export type ReachabilityAnalysisResult = { } export async function performReachabilityAnalysis( - options?: ReachabilityAnalysisOptions | undefined, + options: ReachabilityAnalysisOptions, ): Promise> { const { branchName, @@ -83,7 +84,6 @@ export async function performReachabilityAnalysis( resolvedPathsSidecar, spinner, target, - uploadManifests = true, } = { __proto__: null, ...options } as ReachabilityAnalysisOptions // Determine the analysis target - make it relative to cwd if absolute. @@ -125,61 +125,58 @@ export async function performReachabilityAnalysis( const wasSpinning = !!spinner?.isSpinning - let tarHash: string | undefined - - if (uploadManifests && orgSlug && packagePaths) { - // Setup SDK for uploading manifests - const sockSdkCResult = await setupSdk() - if (!sockSdkCResult.ok) { - return sockSdkCResult - } - - const sockSdk = sockSdkCResult.data - - spinner?.start('Uploading manifests for reachability analysis...') + // Setup SDK for uploading manifests + const sockSdkCResult = await setupSdk() + if (!sockSdkCResult.ok) { + return sockSdkCResult + } - // Ensure uploaded manifest files are relative to analysis target as coana resolves SBOM manifest files relative to this path - // NOTE: previously stripped any `.socket.facts.json` from packagePaths - // here to avoid uploading leftover post-reachability output. With the - // producer flow (`socket manifest gradle --facts`) those files are - // legitimate INPUT to compute-artifacts, so we now upload them. Stale - // facts files are cleaned up downstream — see the post-success - // deletion in handle-create-new-scan.mts. - const uploadCResult = await handleApiCall( - sockSdk.uploadManifestFiles(orgSlug, packagePaths, { - pathsRelativeTo: path.resolve(cwd, analysisTarget), - }), - { - description: 'upload manifests', - spinner, - }, - ) + const sockSdk = sockSdkCResult.data + + spinner?.start('Uploading manifests for reachability analysis...') + + // Ensure uploaded manifest files are relative to analysis target as coana resolves SBOM manifest files relative to this path + // NOTE: previously stripped any `.socket.facts.json` from packagePaths + // here to avoid uploading leftover post-reachability output. With the + // producer flow (`socket manifest gradle --facts`) those files are + // legitimate INPUT to compute-artifacts, so we now upload them. Stale + // facts files are cleaned up downstream — see the post-success + // deletion in handle-create-new-scan.mts. + const uploadCResult = await handleApiCall( + sockSdk.uploadManifestFiles(orgSlug, packagePaths, { + pathsRelativeTo: path.resolve(cwd, analysisTarget), + }), + { + description: 'upload manifests', + spinner, + }, + ) - spinner?.stop() + spinner?.stop() - if (!uploadCResult.ok) { - if (wasSpinning) { - spinner.start() - } - return uploadCResult + if (!uploadCResult.ok) { + if (wasSpinning) { + spinner.start() } + return uploadCResult + } - tarHash = (uploadCResult.data as { tarHash?: string })?.tarHash - if (!tarHash) { - if (wasSpinning) { - spinner.start() - } - return { - ok: false, - message: 'Failed to get manifest tar hash', - cause: 'Server did not return a tar hash for the uploaded manifests', - } + const tarHash = (uploadCResult.data as { tarHash?: string } | undefined) + ?.tarHash + if (!tarHash) { + if (wasSpinning) { + spinner.start() + } + return { + ok: false, + message: 'Failed to get manifest tar hash', + cause: 'Server did not return a tar hash for the uploaded manifests', } - - spinner?.start() - spinner?.success(`Manifests uploaded successfully. Tar hash: ${tarHash}`) } + spinner?.start() + spinner?.success(`Manifests uploaded successfully. Tar hash: ${tarHash}`) + spinner?.start() spinner?.infoAndStop('Running reachability analysis with Coana...') @@ -248,9 +245,9 @@ export async function performReachabilityAnalysis( ...(reachabilityOptions.reachEnableAnalysisSplitting ? [] : ['--disable-analysis-splitting']), - ...(tarHash - ? ['--run-without-docker', '--manifests-tar-hash', tarHash] - : []), + '--run-without-docker', + '--manifests-tar-hash', + tarHash, // Empty reachEcosystems implies scanning all ecosystems. ...(reachabilityOptions.reachEcosystems.length ? ['--purl-types', ...reachabilityOptions.reachEcosystems] diff --git a/src/commands/scan/perform-reachability-analysis.test.mts b/src/commands/scan/perform-reachability-analysis.test.mts index 0d456f0a0..de5f146ef 100644 --- a/src/commands/scan/perform-reachability-analysis.test.mts +++ b/src/commands/scan/perform-reachability-analysis.test.mts @@ -6,6 +6,8 @@ * `--cwd ` flag), the full application reachability scan id must be read from the * facts file Coana actually wrote at `/.socket.facts.json`, not from a * relative path resolved against `process.cwd()`. + * - Coana is never spawned without `--manifests-tar-hash`; a missing hash is a + * hard failure rather than a silent fall back to Docker mode. * * Related Files: * - perform-reachability-analysis.mts (implementation) @@ -22,12 +24,31 @@ import { performReachabilityAnalysis } from './perform-reachability-analysis.mts import type { ReachabilityOptions } from './perform-reachability-analysis.mts' -const { mockFetchOrganization, mockHasEnterpriseOrgPlan, mockSpawnCoanaDlx } = - vi.hoisted(() => ({ - mockFetchOrganization: vi.fn(), - mockHasEnterpriseOrgPlan: vi.fn(), - mockSpawnCoanaDlx: vi.fn(), - })) +// The manifest upload is mandatory, so every call below runs through it and +// gets this tar hash back. +const TEST_ORG_SLUG = 'test-org' +const TEST_PACKAGE_PATHS = ['package.json'] +const TEST_TAR_HASH = 'test-tar-hash' + +const { + mockFetchOrganization, + mockHandleApiCall, + mockHasEnterpriseOrgPlan, + mockSetupSdk, + mockSpawnCoanaDlx, +} = vi.hoisted(() => ({ + mockFetchOrganization: vi.fn(), + mockHandleApiCall: vi.fn(async () => ({ + ok: true, + data: { tarHash: 'test-tar-hash' }, + })), + mockHasEnterpriseOrgPlan: vi.fn(), + mockSetupSdk: vi.fn(async () => ({ + ok: true, + data: { uploadManifestFiles: vi.fn() }, + })), + mockSpawnCoanaDlx: vi.fn(), +})) vi.mock('../organization/fetch-organization-list.mts', () => ({ fetchOrganization: mockFetchOrganization, @@ -41,14 +62,13 @@ vi.mock('../../utils/dlx.mts', () => ({ spawnCoanaDlx: mockSpawnCoanaDlx, })) -// Stubbed to keep the heavy SDK / API import chains out of the test; the -// happy path below skips the manifest-upload branch entirely. +// Stubbed to keep the heavy SDK / API import chains out of the test. vi.mock('../../utils/sdk.mts', () => ({ - setupSdk: vi.fn(), + setupSdk: mockSetupSdk, })) vi.mock('../../utils/api.mts', () => ({ - handleApiCall: vi.fn(), + handleApiCall: mockHandleApiCall, })) vi.mock('../../utils/terminal-link.mts', () => ({ @@ -130,6 +150,8 @@ describe('performReachabilityAnalysis facts-file resolution', () => { const result = await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: makeReachabilityOptions(), target: scanCwd, }) @@ -156,6 +178,8 @@ describe('performReachabilityAnalysis facts-file resolution', () => { const result = await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: makeReachabilityOptions(), target: scanCwd, }) @@ -165,6 +189,54 @@ describe('performReachabilityAnalysis facts-file resolution', () => { }) }) +describe('performReachabilityAnalysis manifests tar hash', () => { + let scanCwd: string + + beforeEach(() => { + vi.clearAllMocks() + mockFetchOrganization.mockResolvedValue({ + ok: true, + data: { organizations: {} }, + }) + mockHasEnterpriseOrgPlan.mockReturnValue(true) + mockSpawnCoanaDlx.mockResolvedValue({ ok: true, data: '' }) + scanCwd = mkdtempSync(path.join(tmpdir(), 'socket-reatar-')) + }) + + afterEach(() => { + rmSync(scanCwd, { force: true, recursive: true }) + }) + + it('always passes the uploaded tar hash and --run-without-docker to Coana', async () => { + await performReachabilityAnalysis({ + cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, + reachabilityOptions: makeReachabilityOptions(), + target: scanCwd, + }) + + const args = mockSpawnCoanaDlx.mock.calls[0]![0] as string[] + expect(args).toContain('--run-without-docker') + expect(args[args.indexOf('--manifests-tar-hash') + 1]).toBe(TEST_TAR_HASH) + }) + + it('fails without spawning Coana when the upload returns no tar hash', async () => { + mockHandleApiCall.mockResolvedValueOnce({ ok: true, data: {} } as never) + + const result = await performReachabilityAnalysis({ + cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, + reachabilityOptions: makeReachabilityOptions(), + target: scanCwd, + }) + + expect(result.ok).toBe(false) + expect(mockSpawnCoanaDlx).not.toHaveBeenCalled() + }) +}) + describe('performReachabilityAnalysis timeout/memory forwarding', () => { let scanCwd: string @@ -188,6 +260,8 @@ describe('performReachabilityAnalysis timeout/memory forwarding', () => { ): Promise { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: { ...makeReachabilityOptions(), ...overrides }, target: scanCwd, }) @@ -252,6 +326,8 @@ describe('performReachabilityAnalysis --maven-use-only-socket-facts gating', () await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: { ...makeReachabilityOptions(), dynamicSbomInference: true, @@ -269,6 +345,8 @@ describe('performReachabilityAnalysis --maven-use-only-socket-facts gating', () it('passes --maven-use-only-socket-facts alongside --compute-artifacts-sidecar when dynamicSbomInference is on and a sidecar was generated', async () => { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: { ...makeReachabilityOptions(), dynamicSbomInference: true, @@ -290,6 +368,8 @@ describe('performReachabilityAnalysis --maven-use-only-socket-facts gating', () it('never passes --maven-use-only-socket-facts when dynamicSbomInference is off, even if a sidecar happens to be present', async () => { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: { ...makeReachabilityOptions(), dynamicSbomInference: false, @@ -334,7 +414,9 @@ describe('performReachabilityAnalysis stdio routing by output kind', () => { it('inherits stdio in text output mode', async () => { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, outputKind: 'text', + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: makeReachabilityOptions(), target: scanCwd, }) @@ -347,6 +429,8 @@ describe('performReachabilityAnalysis stdio routing by output kind', () => { it('defaults to inheriting stdio when no output kind is given', async () => { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: makeReachabilityOptions(), target: scanCwd, }) @@ -359,7 +443,9 @@ describe('performReachabilityAnalysis stdio routing by output kind', () => { it('redirects Coana stdout to stderr (fd 2) in json output mode', async () => { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, outputKind: 'json', + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: makeReachabilityOptions(), target: scanCwd, }) @@ -372,7 +458,9 @@ describe('performReachabilityAnalysis stdio routing by output kind', () => { it('redirects Coana stdout to stderr (fd 2) in markdown output mode', async () => { await performReachabilityAnalysis({ cwd: scanCwd, + orgSlug: TEST_ORG_SLUG, outputKind: 'markdown', + packagePaths: TEST_PACKAGE_PATHS, reachabilityOptions: makeReachabilityOptions(), target: scanCwd, }) From b89640cbbf656af84c2095210567988d8d690a98 Mon Sep 17 00:00:00 2001 From: Oskar Haarklou Veileborg Date: Fri, 4 Sep 2026 10:01:42 +0200 Subject: [PATCH 2/2] refactor(scan): stop forwarding --lazy-mode to the reachability analysis Coana no longer supports --lazy-mode, so the CLI must not pass it. The hidden --reach-lazy-mode flag stays accepted and is swallowed, matching how --reach-disable-analysis-splitting was retired, so existing invocations keep working. The hand-maintained exclusion in the "any boolean reach flag implies --reach" check becomes a set of deprecated no-op flag names, so passing --reach-lazy-mode on its own no longer trips the requires---reach error. --- src/commands/ci/handle-ci.mts | 1 - src/commands/scan/cmd-scan-create.mts | 15 ++++++++++----- src/commands/scan/cmd-scan-reach.mts | 3 +-- src/commands/scan/create-scan-from-github.mts | 1 - src/commands/scan/exclude-paths.test.mts | 1 - src/commands/scan/handle-create-new-scan.test.mts | 6 ------ src/commands/scan/handle-scan-reach.test.mts | 8 -------- .../scan/perform-reachability-analysis.mts | 2 -- .../scan/perform-reachability-analysis.test.mts | 1 - src/commands/scan/reachability-flags.mts | 3 ++- 10 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/commands/ci/handle-ci.mts b/src/commands/ci/handle-ci.mts index 36b3e25f4..00876b186 100644 --- a/src/commands/ci/handle-ci.mts +++ b/src/commands/ci/handle-ci.mts @@ -81,7 +81,6 @@ export async function handleCi(autoManifest: boolean): Promise { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, diff --git a/src/commands/scan/cmd-scan-create.mts b/src/commands/scan/cmd-scan-create.mts index 3ef29df8b..96ad57de5 100644 --- a/src/commands/scan/cmd-scan-create.mts +++ b/src/commands/scan/cmd-scan-create.mts @@ -49,6 +49,13 @@ import type { export const CMD_NAME = 'create' +// Accepted for backwards compatibility but forwarded nowhere, so passing one +// must not imply --reach. +const DEPRECATED_NO_OP_REACH_FLAGS = new Set([ + 'reachDisableAnalysisSplitting', + 'reachLazyMode', +]) + const description = 'Create a new Socket scan and report' const hidden = false @@ -270,7 +277,7 @@ async function run( reachDisableAnalytics, reachDisableExternalToolChecks, reachEnableAnalysisSplitting, - reachLazyMode, + reachLazyMode: _reachLazyMode, reachRetainFactsFile, reachSkipCache, reachUseOnlyPregeneratedSboms, @@ -518,12 +525,11 @@ async function run( // Compare every boolean reach flag against its declared default so newly // added flags require --reach automatically instead of relying on a - // hand-maintained list. The deprecated no-op - // --reach-disable-analysis-splitting is excluded on purpose. + // hand-maintained list. Deprecated no-ops are excluded on purpose. const isUsingAnyBooleanReachFlag = Object.entries(reachabilityFlags).some( ([name, flag]) => flag.type === 'boolean' && - name !== 'reachDisableAnalysisSplitting' && + !DEPRECATED_NO_OP_REACH_FLAGS.has(name) && cli.flags[name] !== flag.default, ) @@ -656,7 +662,6 @@ async function run( reachEcosystems, reachEnableAnalysisSplitting: Boolean(reachEnableAnalysisSplitting), reachExcludePaths, - reachLazyMode: Boolean(reachLazyMode), reachRetainFactsFile: Boolean(reachRetainFactsFile), reachSkipCache: Boolean(reachSkipCache), reachUseOnlyPregeneratedSboms: Boolean(reachUseOnlyPregeneratedSboms), diff --git a/src/commands/scan/cmd-scan-reach.mts b/src/commands/scan/cmd-scan-reach.mts index 52d0936a9..d022aa728 100644 --- a/src/commands/scan/cmd-scan-reach.mts +++ b/src/commands/scan/cmd-scan-reach.mts @@ -152,7 +152,7 @@ async function run( reachDisableAnalytics, reachDisableExternalToolChecks, reachEnableAnalysisSplitting, - reachLazyMode, + reachLazyMode: _reachLazyMode, reachRetainFactsFile, reachSkipCache, reachUseOnlyPregeneratedSboms, @@ -302,7 +302,6 @@ async function run( reachEcosystems, reachEnableAnalysisSplitting: Boolean(reachEnableAnalysisSplitting), reachExcludePaths, - reachLazyMode: Boolean(reachLazyMode), reachRetainFactsFile: Boolean(reachRetainFactsFile), reachSkipCache: Boolean(reachSkipCache), reachUseOnlyPregeneratedSboms: Boolean(reachUseOnlyPregeneratedSboms), diff --git a/src/commands/scan/create-scan-from-github.mts b/src/commands/scan/create-scan-from-github.mts index accb37b3f..6b96de30c 100644 --- a/src/commands/scan/create-scan-from-github.mts +++ b/src/commands/scan/create-scan-from-github.mts @@ -339,7 +339,6 @@ async function scanOneRepo( reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, diff --git a/src/commands/scan/exclude-paths.test.mts b/src/commands/scan/exclude-paths.test.mts index 586527107..e36118644 100644 --- a/src/commands/scan/exclude-paths.test.mts +++ b/src/commands/scan/exclude-paths.test.mts @@ -30,7 +30,6 @@ function makeReachOptions( reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, diff --git a/src/commands/scan/handle-create-new-scan.test.mts b/src/commands/scan/handle-create-new-scan.test.mts index fb47a65be..1ca27db9e 100644 --- a/src/commands/scan/handle-create-new-scan.test.mts +++ b/src/commands/scan/handle-create-new-scan.test.mts @@ -108,7 +108,6 @@ function createConfig( reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -409,7 +408,6 @@ describe('handleCreateNewScan excludePaths', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: ['dist'], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -473,7 +471,6 @@ describe('handleCreateNewScan excludePaths', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: ['node_modules'], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -543,7 +540,6 @@ describe('handleCreateNewScan excludePaths', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -603,7 +599,6 @@ describe('handleCreateNewScan excludePaths', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: ['node_modules'], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -663,7 +658,6 @@ describe('handleCreateNewScan excludePaths', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, diff --git a/src/commands/scan/handle-scan-reach.test.mts b/src/commands/scan/handle-scan-reach.test.mts index 023f570e3..dc9a6d142 100644 --- a/src/commands/scan/handle-scan-reach.test.mts +++ b/src/commands/scan/handle-scan-reach.test.mts @@ -133,7 +133,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: ['node_modules'], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -186,7 +185,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: ['node_modules'], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -249,7 +247,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: ['node_modules'], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -298,7 +295,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -351,7 +347,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -389,7 +384,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -440,7 +434,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, @@ -494,7 +487,6 @@ describe('handleScanReach', () => { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, diff --git a/src/commands/scan/perform-reachability-analysis.mts b/src/commands/scan/perform-reachability-analysis.mts index 36bcc265b..3314e1bc9 100644 --- a/src/commands/scan/perform-reachability-analysis.mts +++ b/src/commands/scan/perform-reachability-analysis.mts @@ -39,7 +39,6 @@ export type ReachabilityOptions = { reachEcosystems: PURL_Type[] reachEnableAnalysisSplitting: boolean reachExcludePaths: string[] - reachLazyMode: boolean reachRetainFactsFile: boolean reachSkipCache: boolean reachUseOnlyPregeneratedSboms: boolean @@ -260,7 +259,6 @@ export async function performReachabilityAnalysis( ...(reachabilityOptions.dynamicSbomInference ? ['--maven-use-only-socket-facts'] : []), - ...(reachabilityOptions.reachLazyMode ? ['--lazy-mode'] : []), ...(reachabilityOptions.reachSkipCache ? ['--skip-cache-usage'] : []), ...(reachabilityOptions.reachUseOnlyPregeneratedSboms ? ['--use-only-pregenerated-sboms'] diff --git a/src/commands/scan/perform-reachability-analysis.test.mts b/src/commands/scan/perform-reachability-analysis.test.mts index de5f146ef..bf24a6dbc 100644 --- a/src/commands/scan/perform-reachability-analysis.test.mts +++ b/src/commands/scan/perform-reachability-analysis.test.mts @@ -111,7 +111,6 @@ function makeReachabilityOptions(): ReachabilityOptions { reachEcosystems: [], reachEnableAnalysisSplitting: false, reachExcludePaths: [], - reachLazyMode: false, reachRetainFactsFile: false, reachSkipCache: false, reachUseOnlyPregeneratedSboms: false, diff --git a/src/commands/scan/reachability-flags.mts b/src/commands/scan/reachability-flags.mts index 74768588b..f57c26390 100644 --- a/src/commands/scan/reachability-flags.mts +++ b/src/commands/scan/reachability-flags.mts @@ -107,8 +107,9 @@ export const reachabilityFlags: MeowFlags = { reachLazyMode: { type: 'boolean', default: false, - description: 'Enable lazy mode for reachability analysis.', hidden: true, + description: + 'Deprecated: lazy mode is no longer supported. This flag is a no-op.', }, reachRetainFactsFile: { type: 'boolean',