@@ -87,6 +87,7 @@ import type { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
8787import { RequestError } from "@octokit/request-error" ;
8888import { handleRequestError } from "./custom-errors" ;
8989import { createMultiSelectionCommand } from "../common/vscode/selection-commands" ;
90+ import { askForLanguage } from "../codeql-cli/query-language" ;
9091
9192const maxRetryCount = 3 ;
9293
@@ -214,7 +215,83 @@ export class VariantAnalysisManager
214215 }
215216
216217 private async runVariantAnalysisFromPublishedPack ( ) : Promise < void > {
217- throw new Error ( "Command not yet implemented" ) ;
218+ return withProgress ( async ( progress , token ) => {
219+ progress ( {
220+ maxStep : 8 ,
221+ step : 0 ,
222+ message : "Determining query language" ,
223+ } ) ;
224+
225+ const language = await askForLanguage ( this . cliServer ) ;
226+
227+ progress ( {
228+ maxStep : 8 ,
229+ step : 1 ,
230+ message : "Downloading query pack" ,
231+ } ) ;
232+
233+ const packName = `codeql/${ language } -queries` ;
234+ const packDownloadResult = await this . cliServer . packDownload ( [ packName ] ) ;
235+ const downloadedPack = packDownloadResult . packs [ 0 ] ;
236+
237+ const packDir = join (
238+ packDownloadResult . packDir ,
239+ downloadedPack . name ,
240+ downloadedPack . version ,
241+ ) ;
242+
243+ progress ( {
244+ maxStep : 8 ,
245+ step : 2 ,
246+ message : "Resolving queries in pack" ,
247+ } ) ;
248+
249+ const suitePath = join (
250+ packDir ,
251+ "codeql-suites" ,
252+ `${ language } -code-scanning.qls` ,
253+ ) ;
254+ const resolvedQueries = await this . cliServer . resolveQueries ( suitePath ) ;
255+
256+ const problemQueries =
257+ await this . filterToOnlyProblemQueries ( resolvedQueries ) ;
258+
259+ if ( problemQueries . length === 0 ) {
260+ void this . app . logger . showErrorMessage (
261+ `Unable to trigger variant analysis. No problem queries found in published query pack: ${ packName } .` ,
262+ ) ;
263+ return ;
264+ }
265+
266+ await this . runVariantAnalysis (
267+ problemQueries . map ( ( q ) => Uri . file ( q ) ) ,
268+ ( p ) =>
269+ progress ( {
270+ ...p ,
271+ maxStep : p . maxStep + 3 ,
272+ step : p . step + 3 ,
273+ } ) ,
274+ token ,
275+ ) ;
276+ } ) ;
277+ }
278+
279+ private async filterToOnlyProblemQueries (
280+ queries : string [ ] ,
281+ ) : Promise < string [ ] > {
282+ const problemQueries : string [ ] = [ ] ;
283+ for ( const query of queries ) {
284+ const queryMetadata = await this . cliServer . resolveMetadata ( query ) ;
285+ if (
286+ queryMetadata . kind === "problem" ||
287+ queryMetadata . kind === "path-problem"
288+ ) {
289+ problemQueries . push ( query ) ;
290+ } else {
291+ void this . app . logger . log ( `Skipping non-problem query ${ query } ` ) ;
292+ }
293+ }
294+ return problemQueries ;
218295 }
219296
220297 private async runVariantAnalysisCommand ( uri : Uri ) : Promise < void > {
0 commit comments