@@ -21,6 +21,7 @@ import { detectManifestActions } from '../manifest/detect-manifest-actions.mts'
2121import { generateAutoManifest } from '../manifest/generate_auto_manifest.mts'
2222
2323import type { CResult , OutputKind } from '../../types.mts'
24+ import type { Spinner } from '@socketsecurity/registry/lib/spinner'
2425
2526export async function handleCreateNewScan ( {
2627 autoManifest,
@@ -117,23 +118,31 @@ export async function handleCreateNewScan({
117118 let scanPaths : string [ ] = packagePaths
118119 let tier1ReachabilityScanId : string | undefined
119120
120- // If reachability is enabled, perform reachability analysis
121+ // If reachability is enabled, perform reachability analysis.
121122 if ( reach ) {
122- const reachResult = await performReachabilityAnalysis ( {
123- packagePaths,
124- orgSlug,
125- cwd,
126- repoName,
127- branchName,
128- outputKind,
129- interactive,
130- } )
123+ logger . error ( '' )
124+ logger . info ( 'Starting reachability analysis...' )
125+
126+ const reachResult = await performReachabilityAnalysis (
127+ {
128+ packagePaths,
129+ orgSlug,
130+ cwd,
131+ repoName,
132+ branchName,
133+ outputKind,
134+ interactive,
135+ } ,
136+ { spinner } ,
137+ )
131138
132139 if ( ! reachResult . ok ) {
133140 await outputCreateNewScan ( reachResult , outputKind , interactive )
134141 return
135142 }
136143
144+ logger . success ( 'Reachability analysis completed successfully' )
145+
137146 scanPaths = reachResult . data ?. scanPaths || [ ]
138147 tier1ReachabilityScanId = reachResult . data ?. tier1ReachabilityScanId
139148 }
@@ -158,15 +167,15 @@ export async function handleCreateNewScan({
158167 )
159168
160169 if (
161- fullScanCResult . ok &&
162170 reach &&
163171 tier1ReachabilityScanId &&
172+ fullScanCResult . ok &&
164173 fullScanCResult . data ?. id
165174 ) {
166- await finalizeTier1Scan ( tier1ReachabilityScanId , fullScanCResult . data ? .id )
175+ await finalizeTier1Scan ( tier1ReachabilityScanId , fullScanCResult . data . id )
167176 }
168177
169- if ( fullScanCResult . ok && report ) {
178+ if ( report && fullScanCResult . ok ) {
170179 if ( fullScanCResult . data ?. id ) {
171180 await handleScanReport ( {
172181 filePath : '-' ,
@@ -195,67 +204,88 @@ export async function handleCreateNewScan({
195204 }
196205}
197206
198- async function performReachabilityAnalysis ( {
199- branchName,
200- cwd,
201- orgSlug,
202- packagePaths,
203- repoName,
204- } : {
207+ type ReachabilityAnalysisConfig = {
205208 packagePaths : string [ ]
206209 orgSlug : string
207210 cwd : string
208211 repoName : string
209212 branchName : string
210213 outputKind : OutputKind
211214 interactive : boolean
212- } ) : Promise <
213- CResult < { scanPaths ?: string [ ] ; tier1ReachabilityScanId : string | undefined } >
214- > {
215- logger . info ( 'Starting reachability analysis...' )
216-
217- packagePaths = packagePaths . filter (
218- p =>
219- /* Exclude DOT_SOCKET_DOT_FACTS_JSON from previous runs */ ! p . includes (
220- constants . DOT_SOCKET_DOT_FACTS_JSON ,
221- ) ,
222- )
215+ }
223216
224- // Lazily access constants.spinner.
225- const { spinner } = constants
217+ type ReachabilityAnalysisOptions = {
218+ spinner ?: Spinner | undefined
219+ }
220+
221+ type ReachabilityAnalysisResult = {
222+ scanPaths : string [ ]
223+ tier1ReachabilityScanId : string | undefined
224+ }
225+
226+ async function performReachabilityAnalysis (
227+ {
228+ branchName,
229+ cwd,
230+ orgSlug,
231+ packagePaths,
232+ repoName,
233+ } : ReachabilityAnalysisConfig ,
234+ options ?: ReachabilityAnalysisOptions | undefined ,
235+ ) : Promise < CResult < ReachabilityAnalysisResult > > {
236+ const { spinner } = {
237+ __proto__ : null ,
238+ ...options ,
239+ } as ReachabilityAnalysisOptions
226240
227241 // Setup SDK for uploading manifests
228242 const sockSdkCResult = await setupSdk ( )
229243 if ( ! sockSdkCResult . ok ) {
230244 return sockSdkCResult
231245 }
246+
232247 const sockSdk = sockSdkCResult . data
233248
249+ const wasSpinning = spinner ?. isSpinning ?? false
250+
234251 // Upload manifests to get tar hash
235- spinner . start ( 'Uploading manifests for reachability analysis...' )
252+ spinner ?. start ( 'Uploading manifests for reachability analysis...' )
253+
254+ // Exclude DOT_SOCKET_DOT_FACTS_JSON from previous runs.
255+ const filteredPackagePaths = packagePaths . filter (
256+ p => ! p . endsWith ( constants . DOT_SOCKET_DOT_FACTS_JSON ) ,
257+ )
236258 const uploadCResult = await handleApiCall (
237- sockSdk . uploadManifestFiles ( orgSlug , packagePaths ) ,
238- { desc : 'upload manifests' } ,
259+ sockSdk . uploadManifestFiles ( orgSlug , filteredPackagePaths ) ,
260+ {
261+ desc : 'upload manifests' ,
262+ spinner,
263+ } ,
239264 )
240- spinner . stop ( )
241-
242265 if ( ! uploadCResult . ok ) {
266+ if ( ! wasSpinning ) {
267+ spinner ?. stop ( )
268+ }
243269 return uploadCResult
244270 }
245271
246272 const tarHash = ( uploadCResult . data as { tarHash ?: string } ) ?. tarHash
247273 if ( ! tarHash ) {
274+ if ( ! wasSpinning ) {
275+ spinner ?. stop ( )
276+ }
248277 return {
249278 ok : false ,
250279 message : 'Failed to get manifest tar hash' ,
251280 cause : 'Server did not return a tar hash for the uploaded manifests' ,
252281 }
253282 }
254283
255- logger . success ( `Manifests uploaded successfully. Tar hash: ${ tarHash } ` )
284+ spinner ?. success ( `Manifests uploaded successfully. Tar hash: ${ tarHash } ` )
285+
286+ // Run Coana with the manifests tar hash.
287+ spinner ?. info ( 'Running reachability analysis with Coana...' )
256288
257- // Run Coana with the manifests tar hash
258- logger . info ( 'Running reachability analysis with Coana...' )
259289 const coanaResult = await spawnCoana (
260290 [
261291 'run' ,
@@ -275,18 +305,17 @@ async function performReachabilityAnalysis({
275305 ...process . env ,
276306 SOCKET_REPO_NAME : repoName ,
277307 SOCKET_BRANCH_NAME : branchName ,
278- SOCKET_CLI_VERSION : constants . ENV . INLINED_SOCKET_CLI_VERSION ,
279308 } ,
280309 } ,
281310 )
282311
312+ if ( ! wasSpinning ) {
313+ spinner ?. stop ( )
314+ }
283315 if ( ! coanaResult . ok ) {
284316 return coanaResult
285317 }
286-
287- logger . success ( 'Reachability analysis completed successfully' )
288-
289- // Use the DOT_SOCKET_DOT_FACTS_JSON file for the scan
318+ // Use the DOT_SOCKET_DOT_FACTS_JSON file for the scan.
290319 return {
291320 ok : true ,
292321 data : {
0 commit comments