@@ -5,7 +5,11 @@ import colors from 'yoctocolors-cjs'
55
66import { logger } from '@socketsecurity/registry/lib/logger'
77
8- import { createFullScan } from './create-full-scan'
8+ import { handleCreateNewScan } from './handle-create-new-scan'
9+ import { suggestOrgSlug } from './suggest-org-slug'
10+ import { suggestRepoSlug } from './suggest-repo-slug'
11+ import { suggestBranchSlug } from './suggest_branch_slug'
12+ import { suggestTarget } from './suggest_target'
913import constants from '../../constants'
1014import { meowOrExit } from '../../utils/meow-with-subcommands'
1115import { getFlagListOutput } from '../../utils/output-formatting'
@@ -142,27 +146,75 @@ async function run(
142146 parentName
143147 } )
144148
145- const [ orgSlug = '' , ...targets ] = cli . input
146-
149+ const { cwd : cwdOverride , dryRun } = cli . flags
147150 const cwd =
148- cli . flags [ 'cwd' ] && cli . flags [ 'cwd' ] !== 'process.cwd()'
149- ? String ( cli . flags [ 'cwd' ] )
151+ cwdOverride && cwdOverride !== 'process.cwd()'
152+ ? String ( cwdOverride )
150153 : process . cwd ( )
154+ let { branch : branchName , repo : repoName } = cli . flags
155+ let [ orgSlug = '' , ...targets ] = cli . input
156+
157+ // We're going to need an api token to suggest data because those suggestions
158+ // must come from data we already know. Don't error on missing api token yet.
159+ // If the api-token is not set, ignore it for the sake of suggestions.
160+ const apiToken = getDefaultToken ( )
161+
162+ // If we updated any inputs then we should print the command line to repeat
163+ // the command without requiring user input, as a suggestion.
164+ let updatedInput = false
165+
166+ if ( ! targets . length && ! dryRun ) {
167+ const received = await suggestTarget ( )
168+ targets = received ?? [ ]
169+ updatedInput = true
170+ }
171+
172+ // If the current cwd is unknown and is used as a repo slug anyways, we will
173+ // first need to register the slug before we can use it.
174+ let repoDefaultBranch = ''
175+ // Only do suggestions with an apiToken and when not in dryRun mode
176+ if ( apiToken && ! dryRun ) {
177+ if ( ! orgSlug ) {
178+ const suggestion = await suggestOrgSlug ( )
179+ if ( suggestion ) orgSlug = suggestion
180+ updatedInput = true
181+ }
182+
183+ // (Don't bother asking for the rest if we didn't get an org slug above)
184+ if ( orgSlug && ! repoName ) {
185+ const suggestion = await suggestRepoSlug ( orgSlug )
186+ if ( suggestion ) {
187+ repoDefaultBranch = suggestion . defaultBranch
188+ repoName = suggestion . slug
189+ }
190+ updatedInput = true
191+ }
151192
152- const { branch : branchName , repo : repoName } = cli . flags
193+ // (Don't bother asking for the rest if we didn't get an org/repo above)
194+ if ( orgSlug && repoName && ! branchName ) {
195+ const suggestion = await suggestBranchSlug ( repoDefaultBranch )
196+ if ( suggestion ) branchName = suggestion
197+ updatedInput = true
198+ }
199+ }
153200
154- const apiToken = getDefaultToken ( ) // This checks if we _can_ suggest anything
201+ if ( updatedInput && repoName && branchName && orgSlug && targets ?. length ) {
202+ logger . error (
203+ 'Note: You can invoke this command next time to skip the interactive questions:'
204+ )
205+ logger . error ( '```' )
206+ logger . error (
207+ ` socket scan create [other flags...] --repo ${ repoName } --branch ${ branchName } ${ orgSlug } ${ targets . join ( ' ' ) } `
208+ )
209+ logger . error ( '```\n' )
210+ }
155211
156- if ( ! apiToken && ( ! orgSlug || ! repoName || ! branchName || ! targets . length ) ) {
157- // Without api token we cannot recover because we can't request more info
158- // from the server, to match and help with the current cwd/git status.
159- //
212+ if ( ! orgSlug || ! repoName || ! branchName || ! targets . length ) {
160213 // Use exit status of 2 to indicate incorrect usage, generally invalid
161214 // options or missing arguments.
162215 // https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
163216 process . exitCode = 2
164- logger . fail (
165- stripIndents `
217+ logger . fail ( stripIndents `
166218 ${ colors . bgRed ( colors . white ( 'Input error' ) ) } : Please provide the required fields:
167219
168220 - Org name as the first argument ${ ! orgSlug ? colors . red ( '(missing!)' ) : colors . green ( '(ok)' ) }
@@ -171,30 +223,26 @@ async function run(
171223
172224 - Branch name using --branch ${ ! branchName ? colors . red ( '(missing!)' ) : colors . green ( '(ok)' ) }
173225
174- - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${ ! targets . length ? '(missing)' : colors . green ( '(ok)' ) }
226+ - At least one TARGET (e.g. \`.\` or \`./package.json\`) ${ ! targets . length ? colors . red ( '(missing)' ) : colors . green ( '(ok)' ) }
175227
176- (Additionally, no API Token was set so we cannot auto-discover these details)
177- `
178- )
228+ ${ ! apiToken ? 'Note: was unable to make suggestions because no API Token was found; this would make the command fail regardless' : '' }
229+ ` )
179230 return
180231 }
181232
182233 // Note exiting earlier to skirt a hidden auth requirement
183- if ( cli . flags [ ' dryRun' ] ) {
234+ if ( dryRun ) {
184235 logger . log ( DRY_RUN_BAIL_TEXT )
185236 return
186237 }
187238
188- await createFullScan ( {
239+ await handleCreateNewScan ( {
189240 branchName : branchName as string ,
190- commitHash : ( cli . flags [ 'commitHash' ] as string ) ?? '' ,
191241 commitMessage : ( cli . flags [ 'commitMessage' ] as string ) ?? '' ,
192- committers : ( cli . flags [ 'committers' ] as string ) ?? '' ,
193242 cwd,
194243 defaultBranch : Boolean ( cli . flags [ 'defaultBranch' ] ) ,
195244 orgSlug,
196245 pendingHead : Boolean ( cli . flags [ 'pendingHead' ] ) ,
197- pullRequest : ( cli . flags [ 'pullRequest' ] as number ) ?? undefined ,
198246 readOnly : Boolean ( cli . flags [ 'readOnly' ] ) ,
199247 repoName : repoName as string ,
200248 targets,
0 commit comments