@@ -3,14 +3,15 @@ import { ensureDir, writeFile } from "fs-extra";
33
44import {
55 commands ,
6+ CancellationToken ,
67 ExtensionContext ,
78 Uri ,
89 ViewColumn ,
910 window ,
1011 workspace ,
1112} from "vscode" ;
1213import { Credentials } from "../authentication" ;
13- import { UserCancellationException } from "../commandRunner" ;
14+ import { ProgressCallback , UserCancellationException } from "../commandRunner" ;
1415import { showInformationMessageWithAction } from "../helpers" ;
1516import { extLogger } from "../common" ;
1617import { QueryHistoryManager } from "../query-history" ;
@@ -133,6 +134,8 @@ export async function exportRemoteQueryAnalysisResults(
133134 ) ;
134135}
135136
137+ const MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS = 2 ;
138+
136139/**
137140 * Exports the results of the given or currently-selected remote query.
138141 * The user is prompted to select the export format.
@@ -141,7 +144,9 @@ export async function exportVariantAnalysisResults(
141144 ctx : ExtensionContext ,
142145 variantAnalysisManager : VariantAnalysisManager ,
143146 variantAnalysisId : number ,
144- filterSort ?: RepositoriesFilterSortStateWithIds ,
147+ filterSort : RepositoriesFilterSortStateWithIds | undefined ,
148+ progress : ProgressCallback ,
149+ token : CancellationToken ,
145150) : Promise < void > {
146151 const variantAnalysis = await variantAnalysisManager . getVariantAnalysis (
147152 variantAnalysisId ,
@@ -155,6 +160,10 @@ export async function exportVariantAnalysisResults(
155160 ) ;
156161 }
157162
163+ if ( token . isCancellationRequested ) {
164+ throw new UserCancellationException ( "Cancelled" ) ;
165+ }
166+
158167 const repoStates = await variantAnalysisManager . getRepoStates (
159168 variantAnalysisId ,
160169 ) ;
@@ -163,11 +172,21 @@ export async function exportVariantAnalysisResults(
163172 `Exporting variant analysis results for variant analysis with id ${ variantAnalysis . id } ` ,
164173 ) ;
165174
175+ progress ( {
176+ maxStep : MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS ,
177+ step : 0 ,
178+ message : "Determining export format" ,
179+ } ) ;
180+
166181 const exportFormat = await determineExportFormat ( ) ;
167182 if ( ! exportFormat ) {
168183 return ;
169184 }
170185
186+ if ( token . isCancellationRequested ) {
187+ throw new UserCancellationException ( "Cancelled" ) ;
188+ }
189+
171190 async function * getAnalysesResults ( ) : AsyncGenerator <
172191 [ VariantAnalysisScannedRepository , VariantAnalysisScannedRepositoryResult ]
173192 > {
@@ -241,6 +260,8 @@ export async function exportVariantAnalysisResults(
241260 variantAnalysis ,
242261 getAnalysesResults ( ) ,
243262 exportFormat ,
263+ progress ,
264+ token ,
244265 ) ;
245266}
246267
@@ -252,7 +273,19 @@ export async function exportVariantAnalysisAnalysisResults(
252273 [ VariantAnalysisScannedRepository , VariantAnalysisScannedRepositoryResult ]
253274 > ,
254275 exportFormat : "gist" | "local" ,
276+ progress : ProgressCallback ,
277+ token : CancellationToken ,
255278) {
279+ if ( token . isCancellationRequested ) {
280+ throw new UserCancellationException ( "Cancelled" ) ;
281+ }
282+
283+ progress ( {
284+ maxStep : MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS ,
285+ step : 1 ,
286+ message : "Generating Markdown files" ,
287+ } ) ;
288+
256289 const { markdownFiles, summaries } = await generateVariantAnalysisMarkdown (
257290 variantAnalysis ,
258291 analysesResults ,
@@ -269,6 +302,8 @@ export async function exportVariantAnalysisAnalysisResults(
269302 description ,
270303 markdownFiles ,
271304 exportFormat ,
305+ progress ,
306+ token ,
272307 ) ;
273308}
274309
@@ -311,21 +346,44 @@ export async function exportResults(
311346 description : string ,
312347 markdownFiles : MarkdownFile [ ] ,
313348 exportFormat : "gist" | "local" ,
349+ progress ?: ProgressCallback ,
350+ token ?: CancellationToken ,
314351) {
352+ if ( token ?. isCancellationRequested ) {
353+ throw new UserCancellationException ( "Cancelled" ) ;
354+ }
355+
315356 if ( exportFormat === "gist" ) {
316- await exportToGist ( ctx , description , markdownFiles ) ;
357+ await exportToGist ( ctx , description , markdownFiles , progress , token ) ;
317358 } else if ( exportFormat === "local" ) {
318- await exportToLocalMarkdown ( exportedResultsPath , markdownFiles ) ;
359+ await exportToLocalMarkdown (
360+ exportedResultsPath ,
361+ markdownFiles ,
362+ progress ,
363+ token ,
364+ ) ;
319365 }
320366}
321367
322368export async function exportToGist (
323369 ctx : ExtensionContext ,
324370 description : string ,
325371 markdownFiles : MarkdownFile [ ] ,
372+ progress ?: ProgressCallback ,
373+ token ?: CancellationToken ,
326374) {
375+ progress ?.( {
376+ maxStep : MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS ,
377+ step : 2 ,
378+ message : "Creating Gist" ,
379+ } ) ;
380+
327381 const credentials = await Credentials . initialize ( ctx ) ;
328382
383+ if ( token ?. isCancellationRequested ) {
384+ throw new UserCancellationException ( "Cancelled" ) ;
385+ }
386+
329387 // Convert markdownFiles to the appropriate format for uploading to gist
330388 const gistFiles = markdownFiles . reduce ( ( acc , cur ) => {
331389 acc [ `${ cur . fileName } .md` ] = { content : cur . content . join ( "\n" ) } ;
@@ -334,13 +392,17 @@ export async function exportToGist(
334392
335393 const gistUrl = await createGist ( credentials , description , gistFiles ) ;
336394 if ( gistUrl ) {
337- const shouldOpenGist = await showInformationMessageWithAction (
395+ // This needs to use .then to ensure we aren't keeping the progress notification open. We shouldn't await the
396+ // "Open gist" button click.
397+ void showInformationMessageWithAction (
338398 "Variant analysis results exported to gist." ,
339399 "Open gist" ,
340- ) ;
341- if ( shouldOpenGist ) {
342- await commands . executeCommand ( "vscode.open" , Uri . parse ( gistUrl ) ) ;
343- }
400+ ) . then ( ( shouldOpenGist ) => {
401+ if ( ! shouldOpenGist ) {
402+ return ;
403+ }
404+ return commands . executeCommand ( "vscode.open" , Uri . parse ( gistUrl ) ) ;
405+ } ) ;
344406 }
345407}
346408
@@ -386,20 +448,38 @@ const buildVariantAnalysisGistDescription = (
386448async function exportToLocalMarkdown (
387449 exportedResultsPath : string ,
388450 markdownFiles : MarkdownFile [ ] ,
451+ progress ?: ProgressCallback ,
452+ token ?: CancellationToken ,
389453) {
454+ if ( token ?. isCancellationRequested ) {
455+ throw new UserCancellationException ( "Cancelled" ) ;
456+ }
457+
458+ progress ?.( {
459+ maxStep : MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS ,
460+ step : 2 ,
461+ message : "Creating local Markdown files" ,
462+ } ) ;
463+
390464 await ensureDir ( exportedResultsPath ) ;
391465 for ( const markdownFile of markdownFiles ) {
392466 const filePath = join ( exportedResultsPath , `${ markdownFile . fileName } .md` ) ;
393467 await writeFile ( filePath , markdownFile . content . join ( "\n" ) , "utf8" ) ;
394468 }
395- const shouldOpenExportedResults = await showInformationMessageWithAction (
469+
470+ // This needs to use .then to ensure we aren't keeping the progress notification open. We shouldn't await the
471+ // "Open exported results" button click.
472+ void showInformationMessageWithAction (
396473 `Variant analysis results exported to \"${ exportedResultsPath } \".` ,
397474 "Open exported results" ,
398- ) ;
399- if ( shouldOpenExportedResults ) {
475+ ) . then ( async ( shouldOpenExportedResults ) => {
476+ if ( ! shouldOpenExportedResults ) {
477+ return ;
478+ }
479+
400480 const summaryFilePath = join ( exportedResultsPath , "_summary.md" ) ;
401481 const summaryFile = await workspace . openTextDocument ( summaryFilePath ) ;
402482 await window . showTextDocument ( summaryFile , ViewColumn . One ) ;
403483 await commands . executeCommand ( "revealFileInOS" , Uri . file ( summaryFilePath ) ) ;
404- }
484+ } ) ;
405485}
0 commit comments