Skip to content

Commit bc0fd8b

Browse files
committed
feat(manifest): configure facts options in the setup wizard
`socket manifest setup` now reflects Socket facts as the default for the gradle and sbt generators and lets you configure the facts-only options it previously couldn't: --include-configs, --exclude-configs, and --ignore-unresolved. These are prompted only when facts generation is selected (not --pom), and the sbt pom output questions (stdout/outfile) now only appear when pom is chosen. Refreshes the stale "generate pom.xml (default)" wording left over from the facts-by-default switch.
1 parent 20a4efb commit bc0fd8b

1 file changed

Lines changed: 103 additions & 10 deletions

File tree

src/commands/manifest/setup-manifest-config.mts

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,24 @@ export async function setupManifestConfig(
6161
{
6262
name: 'Gradle'.padEnd(30, ' '),
6363
value: 'gradle',
64-
description: 'Generate pom.xml files through gradle',
64+
description: 'Generate a Socket facts file or pom.xml through gradle',
6565
},
6666
{
6767
name: 'Kotlin (gradle)'.padEnd(30, ' '),
6868
value: 'gradle',
69-
description: 'Generate pom.xml files (for Kotlin) through gradle',
69+
description:
70+
'Generate a Socket facts file or pom.xml (for Kotlin) through gradle',
7071
},
7172
{
7273
name: 'Scala (gradle)'.padEnd(30, ' '),
7374
value: 'gradle',
74-
description: 'Generate pom.xml files (for Scala) through gradle',
75+
description:
76+
'Generate a Socket facts file or pom.xml (for Scala) through gradle',
7577
},
7678
{
7779
name: 'Scala (sbt)'.padEnd(30, ' '),
7880
value: 'sbt',
79-
description: 'Generate pom.xml files through sbt',
81+
description: 'Generate a Socket facts file or pom.xml through sbt',
8082
},
8183
]
8284

@@ -292,6 +294,15 @@ async function setupGradle(
292294
delete config.facts
293295
}
294296

297+
// The config filters and --ignore-unresolved only apply to facts generation
298+
// (the default); skip them when pom generation (--pom) is selected.
299+
if (config.facts !== false) {
300+
const factsOptions = await setupFactsOptions(config)
301+
if (!factsOptions.ok || factsOptions.data.canceled) {
302+
return factsOptions
303+
}
304+
}
305+
295306
const verbose = await askForVerboseFlag(config.verbose)
296307
if (verbose === undefined) {
297308
return canceledByUser()
@@ -341,9 +352,10 @@ async function setupSbt(
341352
delete config.facts
342353
}
343354

344-
// --facts emits a .socket.facts.json instead of pom.xml files, so the pom
345-
// output questions (stdout/outfile) don't apply when it is enabled.
346-
if (config.facts !== true) {
355+
// Socket facts is the default. The pom output questions (stdout/outfile)
356+
// only apply when pom generation (--pom) is explicitly selected; otherwise
357+
// ask the facts-only options.
358+
if (config.facts === false) {
347359
const stdout = await askForStdout(config.stdout)
348360
if (stdout === undefined) {
349361
return canceledByUser()
@@ -370,6 +382,11 @@ async function setupSbt(
370382
}
371383
}
372384
}
385+
} else {
386+
const factsOptions = await setupFactsOptions(config)
387+
if (!factsOptions.ok || factsOptions.data.canceled) {
388+
return factsOptions
389+
}
373390
}
374391

375392
const verbose = await askForVerboseFlag(config.verbose)
@@ -504,21 +521,48 @@ async function askForVerboseFlag(
504521

505522
async function askForFactsFlag(
506523
current: boolean | undefined,
524+
): Promise<string | undefined> {
525+
return await select({
526+
message: '(--facts / --pom) Which manifest should this generate?',
527+
choices: [
528+
{
529+
name: 'Socket facts (default)',
530+
value: 'yes',
531+
description:
532+
'Generate a .socket.facts.json file describing the resolved dependency graph',
533+
},
534+
{
535+
name: 'pom.xml',
536+
value: 'no',
537+
description: 'Generate pom.xml manifest files instead (the --pom path)',
538+
},
539+
{
540+
name: '(leave default)',
541+
value: '',
542+
description: 'Do not store a setting; uses the default (Socket facts)',
543+
},
544+
],
545+
default: current === true ? 'yes' : current === false ? 'no' : '',
546+
})
547+
}
548+
549+
async function askForIgnoreUnresolvedFlag(
550+
current: boolean | undefined,
507551
): Promise<string | undefined> {
508552
return await select({
509553
message:
510-
'(--facts) Emit a Socket facts JSON file instead of generating pom.xml?',
554+
'(--ignore-unresolved) Warn on unresolved dependencies instead of failing?',
511555
choices: [
512556
{
513557
name: 'no',
514558
value: 'no',
515-
description: 'Generate pom.xml files (default behavior)',
559+
description: 'Fail the run when a declared dependency cannot resolve',
516560
},
517561
{
518562
name: 'yes',
519563
value: 'yes',
520564
description:
521-
'Generate a .socket.facts.json file describing the resolved dependency graph',
565+
'Warn and continue; unresolved dependencies are omitted from the facts file',
522566
},
523567
{
524568
name: '(leave default)',
@@ -530,6 +574,55 @@ async function askForFactsFlag(
530574
})
531575
}
532576

577+
// Prompts for the facts-only options shared by gradle and sbt: the config
578+
// include/exclude filters and --ignore-unresolved. Mutates `config` in place.
579+
async function setupFactsOptions(config: {
580+
excludeConfigs?: string | undefined
581+
ignoreUnresolved?: boolean | undefined
582+
includeConfigs?: string | undefined
583+
}): Promise<CResult<{ canceled: boolean }>> {
584+
const includeConfigs = await input({
585+
message:
586+
'(--include-configs) Comma-separated config-name globs to resolve (blank = all configurations)',
587+
default: config.includeConfigs || '',
588+
required: false,
589+
})
590+
if (includeConfigs === undefined) {
591+
return canceledByUser()
592+
} else if (includeConfigs) {
593+
config.includeConfigs = includeConfigs
594+
} else {
595+
delete config.includeConfigs
596+
}
597+
598+
const excludeConfigs = await input({
599+
message:
600+
'(--exclude-configs) Comma-separated config-name globs to skip (blank = none)',
601+
default: config.excludeConfigs || '',
602+
required: false,
603+
})
604+
if (excludeConfigs === undefined) {
605+
return canceledByUser()
606+
} else if (excludeConfigs) {
607+
config.excludeConfigs = excludeConfigs
608+
} else {
609+
delete config.excludeConfigs
610+
}
611+
612+
const ignoreUnresolved = await askForIgnoreUnresolvedFlag(
613+
config.ignoreUnresolved,
614+
)
615+
if (ignoreUnresolved === undefined) {
616+
return canceledByUser()
617+
} else if (ignoreUnresolved === 'yes' || ignoreUnresolved === 'no') {
618+
config.ignoreUnresolved = ignoreUnresolved === 'yes'
619+
} else {
620+
delete config.ignoreUnresolved
621+
}
622+
623+
return notCanceled()
624+
}
625+
533626
function canceledByUser(): CResult<{ canceled: boolean }> {
534627
logger.log('')
535628
logger.info('User canceled')

0 commit comments

Comments
 (0)