@@ -5,14 +5,14 @@ import * as fs from 'fs-extra';
55
66import { Credentials } from '../authentication' ;
77import { CodeQLCliServer } from '../cli' ;
8- import { ProgressCallback } from '../commandRunner' ;
8+ import { ProgressCallback , UserCancellationException } from '../commandRunner' ;
99import { createTimestampFile , showAndLogErrorMessage , showAndLogInformationMessage , showInformationMessageWithAction } from '../helpers' ;
1010import { Logger } from '../logging' ;
1111import { runRemoteQuery } from './run-remote-query' ;
1212import { RemoteQueriesInterfaceManager } from './remote-queries-interface' ;
1313import { RemoteQuery } from './remote-query' ;
1414import { RemoteQueriesMonitor } from './remote-queries-monitor' ;
15- import { getRemoteQueryIndex } from './gh-actions-api-client' ;
15+ import { createGist , getRemoteQueryIndex } from './gh-actions-api-client' ;
1616import { RemoteQueryResultIndex } from './remote-query-result-index' ;
1717import { RemoteQueryResult } from './remote-query-result' ;
1818import { DownloadLink } from './download-link' ;
@@ -23,6 +23,7 @@ import { QueryHistoryManager } from '../query-history';
2323import { QueryStatus } from '../query-status' ;
2424import { DisposableObject } from '../pure/disposable-object' ;
2525import { QueryHistoryInfo } from '../query-results' ;
26+ import { generateMarkdown } from './remote-queries-markdown-generation' ;
2627
2728const autoDownloadMaxSize = 300 * 1024 ;
2829const autoDownloadMaxCount = 100 ;
@@ -38,7 +39,7 @@ export class RemoteQueriesManager extends DisposableObject {
3839 private readonly cliServer : CodeQLCliServer ,
3940 private readonly qhm : QueryHistoryManager ,
4041 private readonly storagePath : string ,
41- logger : Logger ,
42+ private readonly logger : Logger ,
4243 ) {
4344 super ( ) ;
4445 this . analysesResultsManager = new AnalysesResultsManager ( ctx , cliServer , storagePath , logger ) ;
@@ -301,4 +302,59 @@ export class RemoteQueriesManager extends DisposableObject {
301302 queryItem . status = QueryStatus . Failed ;
302303 }
303304 }
305+
306+ public async exportVariantAnalysisResults ( ) : Promise < void > {
307+ const queryId = this . interfaceManager . getCurrentQueryId ( ) ;
308+ const queryHistoryItem = this . qhm . getCurrentQueryHistoryItem ( ) ;
309+
310+ if ( ! queryId || ! queryHistoryItem || ! queryHistoryItem . completed || queryHistoryItem . t !== 'remote' ) {
311+ throw new Error ( 'No variant analysis results currently open. To open results, click an item in the query history view.' ) ;
312+ }
313+
314+ void this . logger . log ( `Exporting variant analysis results for query: ${ queryId } ` ) ;
315+ const query = queryHistoryItem . remoteQuery ;
316+ const analysesResults = this . analysesResultsManager . getAnalysesResults ( queryId ) ;
317+
318+ const credentials = await Credentials . initialize ( this . ctx ) ;
319+
320+ const gistOption = {
321+ label : '$(ports-open-browser-icon) Create Gist (GitHub)' ,
322+ } ;
323+ const localMarkdownOption = {
324+ label : '$(markdown) Save as markdown' ,
325+ } ;
326+
327+ // User selects export format in quick pick
328+ const exportFormat = await window . showQuickPick (
329+ [ gistOption , localMarkdownOption ] ,
330+ {
331+ placeHolder : 'Select export format' ,
332+ canPickMany : false ,
333+ ignoreFocusOut : true ,
334+ }
335+ ) ;
336+
337+ if ( ! exportFormat || ! exportFormat . label ) {
338+ throw new UserCancellationException ( 'No export format selected' , true ) ;
339+ }
340+
341+ if ( exportFormat === gistOption ) {
342+ const description = 'CodeQL Variant Analysis Results' ;
343+
344+ const markdownFiles = generateMarkdown ( query , analysesResults , 'gist' ) ;
345+
346+ // Convert markdownFiles to the appropriate format for uploading to gist
347+ const gistFiles = markdownFiles . reduce ( ( acc , cur ) => {
348+ acc [ `${ cur . fileName } .md` ] = { content : cur . content . join ( '\n' ) } ;
349+ return acc ;
350+ } , { } as { [ key : string ] : { content : string } } ) ;
351+
352+ const gistUrl = await createGist ( credentials , description , gistFiles ) ;
353+ void showAndLogInformationMessage ( `Variant analysis results exported to [gist](${ gistUrl } ).` ) ;
354+ } else if ( exportFormat === localMarkdownOption ) {
355+ // TODO: Write function that creates local markdown files
356+ // const markdownFiles = generateMarkdown(query, analysesResults, 'local');
357+ void showAndLogInformationMessage ( 'Local markdown export not yet available' ) ;
358+ }
359+ }
304360}
0 commit comments