Skip to content

Commit 0d661e4

Browse files
committed
feat: Add getPacks method to retrieve installed CodeQL packs and update findQueryPack to use async
1 parent fa20c2d commit 0d661e4

File tree

1 file changed

+97
-22
lines changed

1 file changed

+97
-22
lines changed

src/services/codeqlService.ts

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)