Skip to content

Commit 489eabd

Browse files
committed
feat(fix): add --ecosystems flag and rename --limit to --pr-limit
Ported from v1.x commit 39a114d (#960) - Add --ecosystems flag to limit fix analysis to specific package ecosystems - Rename --limit to --prLimit for clarity (only affects CI/PR mode) - In local mode, process all discovered/provided IDs without limit - Update types, handlers, and tests to use prLimit and ecosystems - Add ecosystem validation with getEcosystemChoicesForMeow() Based on PR #960
1 parent 0cc03a9 commit 489eabd

File tree

5 files changed

+54
-17
lines changed

5 files changed

+54
-17
lines changed

packages/cli/src/commands/fix/cmd-fix.mts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import path from 'node:path'
22

33
import terminalLink from 'terminal-link'
44

5-
import { arrayUnique, joinOr } from '@socketsecurity/lib/arrays'
5+
import { arrayUnique, joinAnd, joinOr } from '@socketsecurity/lib/arrays'
66
import { getDefaultLogger } from '@socketsecurity/lib/logger'
77

88
import { handleFix } from './handle-fix.mts'
99
import { DRY_RUN_NOT_SAVING, FLAG_ID } from '../../constants/cli.mts'
1010
import { ERROR_UNABLE_RESOLVE_ORG } from '../../constants/errors.mts'
1111
import { commonFlags, outputFlags } from '../../flags.mts'
12+
import { getEcosystemChoicesForMeow } from '../../utils/ecosystem/types.mts'
1213
import { meowOrExit } from '../../utils/cli/with-subcommands.mjs'
1314
import {
1415
getFlagApiRequirementsOutput,
@@ -20,6 +21,7 @@ import { RangeStyles } from '../../utils/semver.mts'
2021
import { checkCommandInput } from '../../utils/validation/check-input.mts'
2122
import { getDefaultOrgSlug } from '../ci/fetch-default-org-slug.mts'
2223

24+
import type { PURL_Type } from '../../utils/ecosystem/types.mts'
2325
import type { MeowFlag, MeowFlags } from '../../flags.mts'
2426
import type {
2527
CliCommandConfig,
@@ -81,6 +83,13 @@ const generalFlags: MeowFlags = {
8183
description:
8284
'Process all discovered vulnerabilities in local mode. Cannot be used with --id.',
8385
},
86+
ecosystems: {
87+
type: 'string',
88+
default: [],
89+
description:
90+
'Limit fix analysis to specific ecosystems. Can be provided as comma separated values or as multiple flags. Defaults to all ecosystems.',
91+
isMultiple: true,
92+
},
8493
id: {
8594
type: 'string',
8695
default: [],
@@ -100,10 +109,10 @@ const generalFlags: MeowFlags = {
100109
Can be provided as comma separated values or as multiple flags. Cannot be used with --all.`,
101110
isMultiple: true,
102111
},
103-
limit: {
112+
prLimit: {
104113
type: 'number',
105114
default: DEFAULT_LIMIT,
106-
description: `The number of fixes to attempt at a time (default ${DEFAULT_LIMIT})`,
115+
description: `Maximum number of pull requests to create in CI mode (default ${DEFAULT_LIMIT}). Has no effect in local mode.`,
107116
},
108117
rangeStyle: {
109118
type: 'string',
@@ -267,16 +276,17 @@ async function run(
267276
all,
268277
applyFixes,
269278
autopilot,
279+
ecosystems,
270280
exclude,
271281
include,
272282
json,
273-
limit,
274283
majorUpdates,
275284
markdown,
276285
maxSatisfying,
277286
minimumReleaseAge,
278287
outputFile,
279288
prCheck,
289+
prLimit,
280290
rangeStyle,
281291
showAffectedDirectDependencies,
282292
// We patched in this feature with `npx custompatch meow` at
@@ -286,17 +296,18 @@ async function run(
286296
all: boolean
287297
applyFixes: boolean
288298
autopilot: boolean
299+
ecosystems: string[]
289300
exclude: string[]
290301
include: string[]
291302
json: boolean
292-
limit: number
293303
majorUpdates: boolean
294304
markdown: boolean
295305
maxSatisfying: boolean
296306
minSatisfying: boolean
297307
minimumReleaseAge: string
298308
outputFile: string
299309
prCheck: boolean
310+
prLimit: number
300311
rangeStyle: RangeStyle
301312
showAffectedDirectDependencies: boolean
302313
unknownFlags?: string[]
@@ -311,6 +322,23 @@ async function run(
311322

312323
const outputKind = getOutputKind(json, markdown)
313324

325+
// Process comma-separated values for ecosystems flag.
326+
const ecosystemsRaw = cmdFlagValueToArray(ecosystems)
327+
328+
// Validate ecosystem values early, before dry-run check.
329+
const validatedEcosystems: PURL_Type[] = []
330+
const validEcosystemChoices = getEcosystemChoicesForMeow()
331+
for (const ecosystem of ecosystemsRaw) {
332+
if (!validEcosystemChoices.includes(ecosystem)) {
333+
logger.fail(
334+
`Invalid ecosystem: "${ecosystem}". Valid values are: ${joinAnd(validEcosystemChoices)}`,
335+
)
336+
process.exitCode = 1
337+
return
338+
}
339+
validatedEcosystems.push(ecosystem as PURL_Type)
340+
}
341+
314342
const ghsas = arrayUnique([
315343
...cmdFlagValueToArray(cli.flags['id']),
316344
...cmdFlagValueToArray(cli.flags['ghsa']),
@@ -373,16 +401,17 @@ async function run(
373401
autopilot,
374402
cwd,
375403
disableMajorUpdates,
404+
ecosystems: validatedEcosystems,
376405
exclude: excludePatterns,
377406
ghsas,
378407
include: includePatterns,
379-
limit,
380408
minimumReleaseAge,
381409
minSatisfying,
382410
orgSlug,
383411
outputFile,
384412
outputKind,
385413
prCheck,
414+
prLimit,
386415
rangeStyle,
387416
showAffectedDirectDependencies,
388417
spinner,

packages/cli/src/commands/fix/coana-fix.mts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,15 @@ export async function coanaFix(
7676
autopilot,
7777
cwd,
7878
disableMajorUpdates,
79+
ecosystems,
7980
exclude,
8081
ghsas,
8182
include,
82-
limit,
8383
minimumReleaseAge,
8484
orgSlug,
8585
outputFile,
8686
outputKind,
87+
prLimit,
8788
showAffectedDirectDependencies,
8889
spinner,
8990
} = fixConfig
@@ -178,7 +179,8 @@ export async function coanaFix(
178179
}
179180
}
180181

181-
const ids = shouldDiscoverGhsaIds ? ['all'] : ghsas.slice(0, limit)
182+
// In local mode, process all discovered/provided IDs (no limit).
183+
const ids = shouldDiscoverGhsaIds ? ['all'] : ghsas
182184
if (!ids.length) {
183185
spinner?.stop()
184186
return { ok: true, data: { fixed: false } }
@@ -241,8 +243,8 @@ export async function coanaFix(
241243
}
242244
}
243245

244-
// Adjust limit based on open Socket Fix PRs.
245-
let adjustedLimit = limit
246+
// Adjust PR limit based on open Socket Fix PRs.
247+
let adjustedLimit = prLimit
246248
if (shouldOpenPrs && fixEnv.repoInfo) {
247249
try {
248250
const openPrs = await getSocketFixPrs(
@@ -252,10 +254,10 @@ export async function coanaFix(
252254
)
253255
const openPrCount = openPrs.length
254256
// Reduce limit by number of open PRs to avoid creating too many.
255-
adjustedLimit = Math.max(0, limit - openPrCount)
257+
adjustedLimit = Math.max(0, prLimit - openPrCount)
256258
if (openPrCount > 0) {
257259
debug(
258-
`limit: adjusted from ${limit} to ${adjustedLimit} (${openPrCount} open Socket Fix ${pluralize('PR', { count: openPrCount })}`,
260+
`prLimit: adjusted from ${prLimit} to ${adjustedLimit} (${openPrCount} open Socket Fix ${pluralize('PR', { count: openPrCount })}`,
259261
)
260262
}
261263
} catch (e) {

packages/cli/src/commands/fix/handle-fix.mts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,17 @@ export async function handleFix({
108108
autopilot,
109109
cwd,
110110
disableMajorUpdates,
111+
ecosystems,
111112
exclude,
112113
ghsas,
113114
include,
114-
limit,
115115
minSatisfying,
116116
minimumReleaseAge,
117117
orgSlug,
118118
outputFile,
119119
outputKind,
120120
prCheck,
121+
prLimit,
121122
rangeStyle,
122123
showAffectedDirectDependencies,
123124
spinner,
@@ -130,15 +131,16 @@ export async function handleFix({
130131
autopilot,
131132
cwd,
132133
disableMajorUpdates,
134+
ecosystems,
133135
exclude,
134136
ghsas,
135137
include,
136-
limit,
137138
minSatisfying,
138139
minimumReleaseAge,
139140
outputFile,
140141
outputKind,
141142
prCheck,
143+
prLimit,
142144
rangeStyle,
143145
showAffectedDirectDependencies,
144146
unknownFlags,
@@ -151,17 +153,18 @@ export async function handleFix({
151153
autopilot,
152154
cwd,
153155
disableMajorUpdates,
156+
ecosystems,
154157
exclude,
155158
// Convert mixed CVE/GHSA/PURL inputs to GHSA IDs only.
156159
ghsas: await convertIdsToGhsas(ghsas),
157160
include,
158-
limit,
159161
minimumReleaseAge,
160162
minSatisfying,
161163
orgSlug,
162164
outputFile,
163165
outputKind,
164166
prCheck,
167+
prLimit,
165168
rangeStyle,
166169
showAffectedDirectDependencies,
167170
spinner,

packages/cli/src/commands/fix/types.mts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { PURL_Type } from '../../utils/ecosystem/types.mts'
12
import type { OutputKind } from '../../types.mts'
23
import type { RangeStyle } from '../../utils/semver.mts'
34
import type { Spinner } from '@socketsecurity/lib/spinner'
@@ -8,16 +9,17 @@ export type FixConfig = {
89
autopilot: boolean
910
cwd: string
1011
disableMajorUpdates: boolean
12+
ecosystems: PURL_Type[]
1113
exclude: string[]
1214
ghsas: string[]
1315
include: string[]
14-
limit: number
1516
minimumReleaseAge: string
1617
minSatisfying: boolean
1718
orgSlug: string
1819
outputFile: string
1920
outputKind: OutputKind
2021
prCheck: boolean
22+
prLimit: number
2123
rangeStyle: RangeStyle
2224
showAffectedDirectDependencies: boolean
2325
spinner: Spinner | undefined

packages/cli/test/unit/commands/fix/handle-fix-limit.test.mts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,17 @@ describe('socket fix --limit behavior verification', () => {
128128
autopilot: false,
129129
cwd: '/test/cwd',
130130
disableMajorUpdates: false,
131+
ecosystems: [],
131132
exclude: [],
132133
ghsas: [],
133134
include: [],
134-
limit: 10,
135135
minSatisfying: false,
136136
minimumReleaseAge: '',
137137
orgSlug: 'test-org',
138138
outputFile: '',
139139
outputKind: 'text',
140140
prCheck: true,
141+
prLimit: 10,
141142
rangeStyle: 'preserve',
142143
showAffectedDirectDependencies: false,
143144
spinner: undefined,

0 commit comments

Comments
 (0)