@@ -413,6 +413,69 @@ export class CodeQLService {
413413 return [ ...new Set ( results ) ] ; // Remove any duplicates just in case
414414 }
415415
416+ public async getPacks ( ) : Promise < string [ ] > {
417+ this . logger . logServiceCall ( "CodeQLService" , "getPacks" , "started" ) ;
418+ var packs : string [ ] = [ ] ;
419+
420+ try {
421+ const config = vscode . workspace . getConfiguration ( "codeql-scanner" ) ;
422+ const codeqlPath = config . get < string > ( "codeqlPath" , "codeql" ) ;
423+
424+ this . logger . info (
425+ "CodeQLService" ,
426+ `Getting installed CodeQL packs using CLI at ${ codeqlPath } `
427+ ) ;
428+
429+ const cmd = `${ codeqlPath } resolve packs --format=json` ;
430+ this . logger . info (
431+ "CodeQLService" ,
432+ `Running command to get installed CodeQL packs: ${ cmd } `
433+ ) ;
434+ const { stdout } = await execAsync ( cmd ) ;
435+
436+ this . logger . info (
437+ "CodeQLService" ,
438+ "Successfully retrieved installed CodeQL packs"
439+ ) ;
440+
441+ const packsInfo = JSON . parse ( stdout ) ;
442+
443+ // Reverse steps
444+ const steps = packsInfo . steps || [ ] ;
445+ for ( const step of steps . reverse ( ) ) {
446+ for ( const scans of step . scans || [ ] ) {
447+ const found = scans . found || { } ;
448+ // For each key, add the pack name to the list
449+ for ( const packName of Object . keys ( found ) ) {
450+ if ( ! packs . includes ( packName ) ) {
451+ packs . push ( packName ) ;
452+
453+ this . logger . debug (
454+ "CodeQLService" ,
455+ `Found CodeQL pack: ${ packName } `
456+ ) ;
457+ }
458+ }
459+ }
460+ }
461+ } catch ( error ) {
462+ this . logger . error ( "CodeQLService" , "Error getting CodeQL packs" , error ) ;
463+ throw new Error (
464+ "Failed to get CodeQL packs. Please check your configuration."
465+ ) ;
466+ }
467+
468+ this . logger . info (
469+ "CodeQLService" ,
470+ `Found ${ packs . length } installed CodeQL packs: ${ packs . join ( ", " ) } `
471+ ) ;
472+
473+ this . logger . logServiceCall ( "CodeQLService" , "getPacks" , "completed" , {
474+ packs : packs ,
475+ } ) ;
476+ return packs ;
477+ }
478+
416479 public async runAnalysis (
417480 progress : vscode . Progress < { increment ?: number ; message ?: string } > ,
418481 cancellationToken : vscode . CancellationToken
@@ -908,7 +971,7 @@ export class CodeQLService {
908971
909972 // Build the query suite argument
910973 // var queries = `codeql/${language}-queries`;
911- var queries = this . findQueryPack ( language ) ;
974+ var queries = await this . findQueryPack ( language ) ;
912975 this . logger . info (
913976 "CodeQLService" ,
914977 `Using query pack: ${ queries } for language: ${ language } `
@@ -957,34 +1020,46 @@ export class CodeQLService {
9571020 }
9581021 }
9591022
960- private findQueryPack ( language : string ) : string | undefined {
961- const codeqlDir = this . getCodeQLDirectory ( ) ;
962- const queryPackPath = path . join ( codeqlDir , "packages" ) ;
1023+ private async findQueryPack ( language : string ) : Promise < string | undefined > {
1024+ try {
1025+ // Get all installed packs using the getPacks method
1026+ const installedPacks = await this . getPacks ( ) ;
9631027
964- // List all directories in the packages folder
965- if ( ! fs . existsSync ( queryPackPath ) ) {
966- this . logger . warn (
1028+ this . logger . info (
9671029 "CodeQLService" ,
968- `Query pack directory does not exist: ${ queryPackPath } `
1030+ `Looking for ${ language } query pack among ${ installedPacks . length } installed packs `
9691031 ) ;
970- return undefined ;
971- }
9721032
973- const orgDirs = fs . readdirSync ( queryPackPath , { withFileTypes : true } ) ;
974- for ( const orgDir of orgDirs ) {
975- const orgPath = path . join ( queryPackPath , orgDir . name ) ;
976- // codeql
977- if ( ! orgDir . isDirectory ( ) ) {
978- continue ;
979- }
1033+ // Look for language-specific query pack first
1034+ const queryPack = installedPacks . find (
1035+ ( pack ) =>
1036+ pack . endsWith ( `/${ language } -queries` ) || // Match org/language-queries format
1037+ pack === `${ language } -queries` // Direct match for language-queries
1038+ ) ;
9801039
981- for ( const packDir of fs . readdirSync ( orgPath , { withFileTypes : true } ) ) {
982- if ( packDir . isDirectory ( ) && packDir . name === `${ language } -queries` ) {
983- return `${ orgDir . name } /${ packDir . name } ` ;
984- }
1040+ if ( queryPack ) {
1041+ this . logger . info (
1042+ "CodeQLService" ,
1043+ `Found query pack for ${ language } : ${ queryPack } `
1044+ ) ;
1045+ return queryPack ;
9851046 }
1047+
1048+ // Look for the default codeql pack if no specific pack is found
1049+ const defaultPack = `codeql/${ language } -queries` ;
1050+ this . logger . info (
1051+ "CodeQLService" ,
1052+ `No specific query pack found for ${ language } , using default: ${ defaultPack } `
1053+ ) ;
1054+ return defaultPack ; // Fallback to default pack
1055+ } catch ( error ) {
1056+ this . logger . error (
1057+ "CodeQLService" ,
1058+ `Error finding query pack for ${ language } ` ,
1059+ error
1060+ ) ;
1061+ return `codeql/${ language } -queries` ; // Fallback to default pack on error
9861062 }
987- return `codeql/${ language } -queries` ; // Fallback to default pack
9881063 }
9891064
9901065 private parseSARIFResults (
0 commit comments