Skip to content

Commit 61fc79a

Browse files
mtorpjdalton
authored andcommitted
Various fixes for handling of target paths. (#933)
1 parent eba18f7 commit 61fc79a

25 files changed

+4914
-1821
lines changed

CHANGELOG.md

Lines changed: 249 additions & 92 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 271 additions & 216 deletions
Large diffs are not rendered by default.

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

Lines changed: 40 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,43 @@
1-
import { existsSync, promises as fs } from 'node:fs'
21
import path from 'node:path'
32

4-
import { joinAnd } from '@socketsecurity/lib/arrays'
5-
import { getDefaultLogger } from '@socketsecurity/lib/logger'
3+
import { joinAnd } from '@socketsecurity/registry/lib/arrays'
4+
import { logger } from '@socketsecurity/registry/lib/logger'
65

76
import { handleCreateNewScan } from './handle-create-new-scan.mts'
87
import { outputCreateNewScan } from './output-create-new-scan.mts'
98
import { reachabilityFlags } from './reachability-flags.mts'
109
import { suggestOrgSlug } from './suggest-org-slug.mts'
1110
import { suggestTarget } from './suggest_target.mts'
12-
import { DRY_RUN_BAILING_NOW } from '../../constants/cli.mts'
13-
import { REQUIREMENTS_TXT, SOCKET_JSON } from '../../constants/paths.mts'
14-
import { REPORT_LEVEL_ERROR } from '../../constants/reporting.mjs'
11+
import { validateReachabilityTarget } from './validate-reachability-target.mts'
12+
import constants, { REQUIREMENTS_TXT, SOCKET_JSON } from '../../constants.mts'
1513
import { commonFlags, outputFlags } from '../../flags.mts'
16-
import { meowOrExit } from '../../utils/cli/with-subcommands.mjs'
17-
import { getEcosystemChoicesForMeow } from '../../utils/ecosystem/types.mjs'
14+
import { checkCommandInput } from '../../utils/check-input.mts'
15+
import { cmdFlagValueToArray } from '../../utils/cmd.mts'
16+
import { determineOrgSlug } from '../../utils/determine-org-slug.mts'
17+
import { getEcosystemChoicesForMeow } from '../../utils/ecosystem.mts'
18+
import { getOutputKind } from '../../utils/get-output-kind.mts'
1819
import {
1920
detectDefaultBranch,
2021
getRepoName,
2122
gitBranch,
22-
} from '../../utils/git/operations.mjs'
23+
} from '../../utils/git.mts'
24+
import { meowOrExit } from '../../utils/meow-with-subcommands.mts'
2325
import {
2426
getFlagApiRequirementsOutput,
2527
getFlagListOutput,
26-
} from '../../utils/output/formatting.mts'
27-
import { getOutputKind } from '../../utils/output/mode.mjs'
28-
import { cmdFlagValueToArray } from '../../utils/process/cmd.mts'
29-
import { readOrDefaultSocketJsonUp } from '../../utils/socket/json.mts'
30-
import { determineOrgSlug } from '../../utils/socket/org-slug.mjs'
31-
import { hasDefaultApiToken } from '../../utils/socket/sdk.mjs'
32-
import { socketDashboardLink } from '../../utils/terminal/link.mts'
33-
import { checkCommandInput } from '../../utils/validation/check-input.mts'
28+
} from '../../utils/output-formatting.mts'
29+
import { hasDefaultApiToken } from '../../utils/sdk.mts'
30+
import { readOrDefaultSocketJsonUp } from '../../utils/socket-json.mts'
31+
import { socketDashboardLink } from '../../utils/terminal-link.mts'
3432
import { detectManifestActions } from '../manifest/detect-manifest-actions.mts'
3533

3634
import type { REPORT_LEVEL } from './types.mts'
3735
import type { MeowFlags } from '../../flags.mts'
36+
import type { PURL_Type } from '../../utils/ecosystem.mts'
3837
import type {
3938
CliCommandConfig,
4039
CliCommandContext,
41-
} from '../../utils/cli/with-subcommands.mjs'
42-
import type { PURL_Type } from '../../utils/ecosystem/types.mjs'
43-
const logger = getDefaultLogger()
40+
} from '../../utils/meow-with-subcommands.mts'
4441

4542
export const CMD_NAME = 'create'
4643

@@ -132,8 +129,8 @@ const generalFlags: MeowFlags = {
132129
},
133130
reportLevel: {
134131
type: 'string',
135-
default: REPORT_LEVEL_ERROR,
136-
description: `Which policy level alerts should be reported (default '${REPORT_LEVEL_ERROR}')`,
132+
default: constants.REPORT_LEVEL_ERROR,
133+
description: `Which policy level alerts should be reported (default '${constants.REPORT_LEVEL_ERROR}')`,
137134
},
138135
setAsAlertsPage: {
139136
type: 'boolean',
@@ -170,7 +167,7 @@ async function run(
170167
...generalFlags,
171168
...reachabilityFlags,
172169
},
173-
// Note: Could document socket.yml's "projectIgnorePaths" setting in help text.
170+
// TODO: Your project's "socket.yml" file's "projectIgnorePaths".
174171
help: command => `
175172
Usage
176173
$ ${command} [options] [TARGET...]
@@ -246,14 +243,12 @@ async function run(
246243
reachDebug,
247244
reachDisableAnalysisSplitting,
248245
reachDisableAnalytics,
249-
reachMinSeverity,
250246
reachSkipCache,
251-
reachUseUnreachableFromPrecomputation,
252247
readOnly,
253248
reportLevel,
254249
setAsAlertsPage: pendingHeadFlag,
255250
tmp,
256-
} = cli.flags as unknown as {
251+
} = cli.flags as {
257252
cwd: string
258253
commitHash: string
259254
commitMessage: string
@@ -270,15 +265,13 @@ async function run(
270265
tmp: boolean
271266
// Reachability flags.
272267
reach: boolean
273-
reachAnalysisMemoryLimit: number
274268
reachAnalysisTimeout: number
269+
reachAnalysisMemoryLimit: number
275270
reachConcurrency: number
276271
reachDebug: boolean
277272
reachDisableAnalytics: boolean
278273
reachDisableAnalysisSplitting: boolean
279-
reachMinSeverity: string
280274
reachSkipCache: boolean
281-
reachUseUnreachableFromPrecomputation: boolean
282275
}
283276

284277
// Validate ecosystem values.
@@ -294,25 +287,14 @@ async function run(
294287
reachEcosystems.push(ecosystem as PURL_Type)
295288
}
296289

297-
// Validate severity value if provided.
298-
const validSeverities = ['info', 'low', 'moderate', 'high', 'critical']
299-
if (
300-
reachMinSeverity &&
301-
!validSeverities.includes(reachMinSeverity.toLowerCase())
302-
) {
303-
throw new Error(
304-
`Invalid severity: "${reachMinSeverity}". Valid values are: ${joinAnd(validSeverities)}`,
305-
)
306-
}
307-
308290
const dryRun = !!cli.flags['dryRun']
309291

310292
let {
311293
autoManifest,
312294
branch: branchName,
313295
repo: repoName,
314296
report,
315-
} = cli.flags as unknown as {
297+
} = cli.flags as {
316298
autoManifest?: boolean | undefined
317299
branch: string
318300
repo: string
@@ -375,7 +357,7 @@ async function run(
375357
let updatedInput = false
376358

377359
// Accept zero or more paths. Default to cwd() if none given.
378-
let targets: string[] = cli.input ? [...cli.input] : [cwd]
360+
let targets = cli.input || [cwd]
379361

380362
if (!targets.length && !dryRun && interactive) {
381363
targets = await suggestTarget()
@@ -431,7 +413,7 @@ async function run(
431413
)
432414
logger.error('```')
433415
logger.error(
434-
` socket scan create [other flags] ${orgSlug} ${targets.join(' ')}`,
416+
` socket scan create [other flags...] ${orgSlug} ${targets.join(' ')}`,
435417
)
436418
logger.error('```')
437419
logger.error('')
@@ -473,30 +455,14 @@ async function run(
473455
reachDisableAnalysisSplitting
474456

475457
// Validate target constraints when --reach is enabled.
476-
let reachTargetValid = true
477-
let reachTargetIsDirectory = false
478-
let reachTargetExists = false
479-
let reachTargetInsideCwd = false
480-
481-
if (reach) {
482-
// Resolve target path to absolute for validation.
483-
const targetPath = path.isAbsolute(targets[0]!)
484-
? targets[0]!
485-
: path.resolve(cwd, targets[0]!)
486-
487-
// Check if target is inside cwd.
488-
const relativePath = path.relative(cwd, targetPath)
489-
reachTargetInsideCwd =
490-
!relativePath.startsWith('..') && !path.isAbsolute(relativePath)
491-
492-
reachTargetExists = existsSync(targetPath)
493-
if (reachTargetExists) {
494-
const targetStat = await fs.stat(targetPath)
495-
reachTargetIsDirectory = targetStat.isDirectory()
496-
}
497-
498-
reachTargetValid = targets.length === 1
499-
}
458+
const reachTargetValidation = reach
459+
? await validateReachabilityTarget(targets, cwd)
460+
: {
461+
isDirectory: false,
462+
isInsideCwd: false,
463+
isValid: true,
464+
targetExists: false,
465+
}
500466

501467
const wasValidInput = checkCommandInput(
502468
outputKind,
@@ -543,27 +509,27 @@ async function run(
543509
},
544510
{
545511
nook: true,
546-
test: !reach || reachTargetValid,
512+
test: !reach || reachTargetValidation.isValid,
547513
message:
548514
'Reachability analysis requires exactly one target directory when --reach is enabled',
549515
fail: 'provide exactly one directory path',
550516
},
551517
{
552518
nook: true,
553-
test: !reach || reachTargetIsDirectory,
519+
test: !reach || reachTargetValidation.isDirectory,
554520
message:
555521
'Reachability analysis target must be a directory when --reach is enabled',
556522
fail: 'provide a directory path, not a file',
557523
},
558524
{
559525
nook: true,
560-
test: !reach || reachTargetExists,
526+
test: !reach || reachTargetValidation.targetExists,
561527
message: 'Target directory must exist when --reach is enabled',
562528
fail: 'provide an existing directory path',
563529
},
564530
{
565531
nook: true,
566-
test: !reach || reachTargetInsideCwd,
532+
test: !reach || reachTargetValidation.isInsideCwd,
567533
message:
568534
'Target directory must be inside the current working directory when --reach is enabled',
569535
fail: 'provide a path inside the working directory',
@@ -574,7 +540,7 @@ async function run(
574540
}
575541

576542
if (dryRun) {
577-
logger.log(DRY_RUN_BAILING_NOW)
543+
logger.log(constants.DRY_RUN_BAILING_NOW)
578544
return
579545
}
580546

@@ -593,19 +559,15 @@ async function run(
593559
pullRequest: Number(pullRequest),
594560
reach: {
595561
runReachabilityAnalysis: Boolean(reach),
596-
reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit),
562+
reachDisableAnalytics: Boolean(reachDisableAnalytics),
597563
reachAnalysisTimeout: Number(reachAnalysisTimeout),
564+
reachAnalysisMemoryLimit: Number(reachAnalysisMemoryLimit),
598565
reachConcurrency: Number(reachConcurrency),
599566
reachDebug: Boolean(reachDebug),
600-
reachDisableAnalytics: Boolean(reachDisableAnalytics),
601567
reachDisableAnalysisSplitting: Boolean(reachDisableAnalysisSplitting),
602568
reachEcosystems,
603569
reachExcludePaths,
604-
reachMinSeverity,
605570
reachSkipCache: Boolean(reachSkipCache),
606-
reachUseUnreachableFromPrecomputation: Boolean(
607-
reachUseUnreachableFromPrecomputation,
608-
),
609571
},
610572
readOnly: Boolean(readOnly),
611573
repoName,

0 commit comments

Comments
 (0)