@@ -5,7 +5,11 @@ import colors from 'yoctocolors-cjs'
5
5
6
6
import { logger } from '@socketsecurity/registry/lib/logger'
7
7
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'
9
13
import constants from '../../constants'
10
14
import { meowOrExit } from '../../utils/meow-with-subcommands'
11
15
import { getFlagListOutput } from '../../utils/output-formatting'
@@ -142,27 +146,75 @@ async function run(
142
146
parentName
143
147
} )
144
148
145
- const [ orgSlug = '' , ...targets ] = cli . input
146
-
149
+ const { cwd : cwdOverride , dryRun } = cli . flags
147
150
const cwd =
148
- cli . flags [ 'cwd' ] && cli . flags [ 'cwd' ] !== 'process.cwd()'
149
- ? String ( cli . flags [ 'cwd' ] )
151
+ cwdOverride && cwdOverride !== 'process.cwd()'
152
+ ? String ( cwdOverride )
150
153
: 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
+ }
151
192
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
+ }
153
200
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
+ }
155
211
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 ) {
160
213
// Use exit status of 2 to indicate incorrect usage, generally invalid
161
214
// options or missing arguments.
162
215
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
163
216
process . exitCode = 2
164
- logger . fail (
165
- stripIndents `
217
+ logger . fail ( stripIndents `
166
218
${ colors . bgRed ( colors . white ( 'Input error' ) ) } : Please provide the required fields:
167
219
168
220
- Org name as the first argument ${ ! orgSlug ? colors . red ( '(missing!)' ) : colors . green ( '(ok)' ) }
@@ -171,30 +223,26 @@ async function run(
171
223
172
224
- Branch name using --branch ${ ! branchName ? colors . red ( '(missing!)' ) : colors . green ( '(ok)' ) }
173
225
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)' ) }
175
227
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
+ ` )
179
230
return
180
231
}
181
232
182
233
// Note exiting earlier to skirt a hidden auth requirement
183
- if ( cli . flags [ ' dryRun' ] ) {
234
+ if ( dryRun ) {
184
235
logger . log ( DRY_RUN_BAIL_TEXT )
185
236
return
186
237
}
187
238
188
- await createFullScan ( {
239
+ await handleCreateNewScan ( {
189
240
branchName : branchName as string ,
190
- commitHash : ( cli . flags [ 'commitHash' ] as string ) ?? '' ,
191
241
commitMessage : ( cli . flags [ 'commitMessage' ] as string ) ?? '' ,
192
- committers : ( cli . flags [ 'committers' ] as string ) ?? '' ,
193
242
cwd,
194
243
defaultBranch : Boolean ( cli . flags [ 'defaultBranch' ] ) ,
195
244
orgSlug,
196
245
pendingHead : Boolean ( cli . flags [ 'pendingHead' ] ) ,
197
- pullRequest : ( cli . flags [ 'pullRequest' ] as number ) ?? undefined ,
198
246
readOnly : Boolean ( cli . flags [ 'readOnly' ] ) ,
199
247
repoName : repoName as string ,
200
248
targets,
0 commit comments