Skip to content

Commit 0fbb1b0

Browse files
committed
refactor(scan): drop local reach unit validation, defer to Coana
Coana (@coana-tech/cli) is now the sole validator/parser of the --reach-analysis-timeout and --reach-analysis-memory-limit values, matching the Python CLI. Removes the local grammar mirror (isValid* regex fast-fail) that had already drifted from Coana twice (unit case-sensitivity, and a whitespace gap where Coana trims but the mirror did not). An invalid unit now surfaces as Coana's error instead of a fast local one. Kept the non-validation helpers, which Coana does not model: isOmittedReachValue (empty/zero -> omit the flag so Coana applies its default) and reachMemoryLimitToMb (unit-agnostic default-equivalence for the "requires --reach" guard). The raw string is still forwarded to Coana verbatim.
1 parent 3b82942 commit 0fbb1b0

5 files changed

Lines changed: 18 additions & 116 deletions

File tree

src/commands/scan/cmd-scan-create.mts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ import { handleCreateNewScan } from './handle-create-new-scan.mts'
99
import { outputCreateNewScan } from './output-create-new-scan.mts'
1010
import { excludePathsFlag, reachabilityFlags } from './reachability-flags.mts'
1111
import {
12-
REACH_ANALYSIS_MEMORY_LIMIT_HELP,
13-
REACH_ANALYSIS_TIMEOUT_HELP,
1412
isOmittedReachValue,
15-
isValidReachAnalysisMemoryLimit,
16-
isValidReachAnalysisTimeout,
1713
reachMemoryLimitToMb,
1814
} from './reachability-units.mts'
1915
import { suggestOrgSlug } from './suggest-org-slug.mts'
@@ -587,18 +583,6 @@ async function run(
587583
message: 'Reachability analysis flags require --reach to be enabled',
588584
fail: 'add --reach flag to use --reach-* options',
589585
},
590-
{
591-
nook: true,
592-
test: !reach || isValidReachAnalysisTimeout(reachAnalysisTimeout),
593-
message: `The --reach-analysis-timeout must be ${REACH_ANALYSIS_TIMEOUT_HELP}`,
594-
fail: `invalid value "${reachAnalysisTimeout}"`,
595-
},
596-
{
597-
nook: true,
598-
test: !reach || isValidReachAnalysisMemoryLimit(reachAnalysisMemoryLimit),
599-
message: `The --reach-analysis-memory-limit must be ${REACH_ANALYSIS_MEMORY_LIMIT_HELP}`,
600-
fail: `invalid value "${reachAnalysisMemoryLimit}"`,
601-
},
602586
{
603587
nook: true,
604588
test: !reach || reachTargetValidation.isValid,

src/commands/scan/cmd-scan-reach.mts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ import { logger } from '@socketsecurity/registry/lib/logger'
66
import { assertValidExcludePaths } from './exclude-paths.mts'
77
import { handleScanReach } from './handle-scan-reach.mts'
88
import { excludePathsFlag, reachabilityFlags } from './reachability-flags.mts'
9-
import {
10-
REACH_ANALYSIS_MEMORY_LIMIT_HELP,
11-
REACH_ANALYSIS_TIMEOUT_HELP,
12-
isValidReachAnalysisMemoryLimit,
13-
isValidReachAnalysisTimeout,
14-
} from './reachability-units.mts'
159
import { suggestTarget } from './suggest_target.mts'
1610
import { validateReachabilityTarget } from './validate-reachability-target.mts'
1711
import constants from '../../constants.mts'
@@ -265,18 +259,6 @@ async function run(
265259
message: 'Target directory must be inside the current working directory',
266260
fail: 'provide a path inside the working directory',
267261
},
268-
{
269-
nook: true,
270-
test: isValidReachAnalysisTimeout(reachAnalysisTimeout),
271-
message: `The --reach-analysis-timeout must be ${REACH_ANALYSIS_TIMEOUT_HELP}`,
272-
fail: `invalid value "${reachAnalysisTimeout}"`,
273-
},
274-
{
275-
nook: true,
276-
test: isValidReachAnalysisMemoryLimit(reachAnalysisMemoryLimit),
277-
message: `The --reach-analysis-memory-limit must be ${REACH_ANALYSIS_MEMORY_LIMIT_HELP}`,
278-
fail: `invalid value "${reachAnalysisMemoryLimit}"`,
279-
},
280262
)
281263
if (!wasValidInput) {
282264
return

src/commands/scan/cmd-scan-reach.test.mts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,14 +1050,12 @@ describe('socket scan reach', async () => {
10501050
FLAG_CONFIG,
10511051
'{"apiToken":"fake-token"}',
10521052
],
1053-
'should show clear error for invalid memory limit',
1053+
'should forward an unrecognized memory value to Coana without locally rejecting it',
10541054
async cmd => {
10551055
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
10561056
const output = stdout + stderr
1057-
expect(output).toContain(
1058-
'The --reach-analysis-memory-limit must be a whole number optionally followed by MB or GB',
1059-
)
1060-
expect(code).not.toBe(0)
1057+
expect(output).toContain('[DryRun]: Bailing now')
1058+
expect(code).toBe(0)
10611059
},
10621060
)
10631061

@@ -1073,14 +1071,12 @@ describe('socket scan reach', async () => {
10731071
FLAG_CONFIG,
10741072
'{"apiToken":"fake-token"}',
10751073
],
1076-
'should show clear error for unsupported memory unit',
1074+
'should forward an unsupported memory unit to Coana without locally rejecting it',
10771075
async cmd => {
10781076
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
10791077
const output = stdout + stderr
1080-
expect(output).toContain(
1081-
'The --reach-analysis-memory-limit must be a whole number optionally followed by MB or GB',
1082-
)
1083-
expect(code).not.toBe(0)
1078+
expect(output).toContain('[DryRun]: Bailing now')
1079+
expect(code).toBe(0)
10841080
},
10851081
)
10861082

@@ -1096,14 +1092,12 @@ describe('socket scan reach', async () => {
10961092
FLAG_CONFIG,
10971093
'{"apiToken":"fake-token"}',
10981094
],
1099-
'should show clear error for invalid timeout value',
1095+
'should forward an unrecognized timeout value to Coana without locally rejecting it',
11001096
async cmd => {
11011097
const { code, stderr, stdout } = await spawnSocketCli(binCliPath, cmd)
11021098
const output = stdout + stderr
1103-
expect(output).toContain(
1104-
'The --reach-analysis-timeout must be a whole number optionally followed by s, m or h',
1105-
)
1106-
expect(code).not.toBe(0)
1099+
expect(output).toContain('[DryRun]: Bailing now')
1100+
expect(code).toBe(0)
11071101
},
11081102
)
11091103

src/commands/scan/reachability-units.mts

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,8 @@
1-
// Thin local mirror of the reachability unit grammar. Coana (@coana-tech/cli)
2-
// is the canonical parser for these values; the Socket CLI forwards the raw
3-
// string through verbatim and only performs this lightweight check so obvious
4-
// mistakes fail fast before the Coana binary is spawned. Keep the patterns and
5-
// help text in sync with Coana's grammar.
6-
7-
// --reach-analysis-timeout: a whole number optionally followed by s, m or h.
8-
// Units are case-insensitive (matching Coana). A bare number is treated as
9-
// seconds (back-compat, no longer documented).
10-
const REACH_ANALYSIS_TIMEOUT_PATTERN = /^\d+(?:s|m|h)?$/i
11-
12-
// --reach-analysis-memory-limit: a whole number optionally followed by MB or GB.
13-
// Units are case-insensitive (matching Coana). A bare number is treated as MB
14-
// (back-compat, no longer documented).
15-
const REACH_ANALYSIS_MEMORY_LIMIT_PATTERN = /^\d+(?:mb|gb)?$/i
16-
17-
export const REACH_ANALYSIS_MEMORY_LIMIT_HELP =
18-
'a whole number optionally followed by MB or GB (e.g. 512MB, 8GB)'
19-
20-
export const REACH_ANALYSIS_TIMEOUT_HELP =
21-
'a whole number optionally followed by s, m or h (e.g. 90s, 10m, 1h)'
1+
// Helpers for the reachability unit values. Coana (@coana-tech/cli) is the sole
2+
// validator/parser of these values; the Socket CLI forwards the raw string
3+
// through verbatim. These helpers do NOT validate grammar (that would duplicate
4+
// Coana's and drift): they only handle the meow-default sentinel and detect
5+
// whether a value differs from the default, neither of which Coana models.
226

237
// A zero-magnitude or empty value (e.g. "", "0", "0s", "0gb") means "use the
248
// default": the flag is omitted when forwarding and Coana applies its own
@@ -29,18 +13,12 @@ export function isOmittedReachValue(value: string): boolean {
2913
return !match || Number(match[0]) === 0
3014
}
3115

32-
export function isValidReachAnalysisMemoryLimit(value: string): boolean {
33-
return value === '' || REACH_ANALYSIS_MEMORY_LIMIT_PATTERN.test(value)
34-
}
35-
36-
export function isValidReachAnalysisTimeout(value: string): boolean {
37-
return value === '' || REACH_ANALYSIS_TIMEOUT_PATTERN.test(value)
38-
}
39-
4016
// Resolve a memory-limit value to its magnitude in MB (the unit Coana uses), or
4117
// null when the value is omitted/zero (Coana then applies its own default).
42-
// Lets callers compare a value against the default regardless of how the unit
43-
// is written: 8192, 8192MB and 8GB all resolve to 8192.
18+
// Used only to compare a value against the default regardless of how the unit
19+
// is written: 8192, 8192MB and 8GB all resolve to 8192. This is default
20+
// detection, not validation, so an unrecognized value resolves to null and is
21+
// simply treated as "not a non-default value".
4422
export function reachMemoryLimitToMb(value: string): number | null {
4523
if (isOmittedReachValue(value)) {
4624
return null

src/commands/scan/reachability-units.test.mts

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,9 @@ import { describe, expect, it } from 'vitest'
22

33
import {
44
isOmittedReachValue,
5-
isValidReachAnalysisMemoryLimit,
6-
isValidReachAnalysisTimeout,
75
reachMemoryLimitToMb,
86
} from './reachability-units.mts'
97

10-
describe('isValidReachAnalysisTimeout', () => {
11-
// Units are case-insensitive, matching Coana.
12-
it.each(['', '0', '90', '90s', '10m', '1h', '600', '10M', '1H', '30S'])(
13-
'accepts %j',
14-
value => {
15-
expect(isValidReachAnalysisTimeout(value)).toBe(true)
16-
},
17-
)
18-
19-
it.each(['90ms', '1.5h', '10 m', 'm', '-1', 'invalid', '10mb'])(
20-
'rejects %j',
21-
value => {
22-
expect(isValidReachAnalysisTimeout(value)).toBe(false)
23-
},
24-
)
25-
})
26-
27-
describe('isValidReachAnalysisMemoryLimit', () => {
28-
// Units are case-insensitive, matching Coana.
29-
it.each(['', '0', '8192', '512MB', '512mb', '8GB', '8gb', '8Gb'])(
30-
'accepts %j',
31-
value => {
32-
expect(isValidReachAnalysisMemoryLimit(value)).toBe(true)
33-
},
34-
)
35-
36-
it.each(['512kb', '1TB', '1.5GB', '8 GB', 'GB', '-1', 'invalid'])(
37-
'rejects %j',
38-
value => {
39-
expect(isValidReachAnalysisMemoryLimit(value)).toBe(false)
40-
},
41-
)
42-
})
43-
448
describe('isOmittedReachValue', () => {
459
// Empty or any zero-magnitude value means "use the default" (flag omitted).
4610
it.each(['', '0', '00', '0s', '0m', '0h', '0mb', '0gb'])(

0 commit comments

Comments
 (0)