Skip to content

Commit 5d4dbf8

Browse files
committed
feat(codeql_qdriver): recognize result bqrs path according to the pack a query belongs to
1 parent 6f00de0 commit 5d4dbf8

1 file changed

Lines changed: 45 additions & 10 deletions

File tree

cmd/codeql_qdriver/main.go

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"bufio"
5+
"bytes"
56
"flag"
67
"fmt"
78
"log"
@@ -103,7 +104,7 @@ func buildGroupExternalArgs(queries []config.Query, extroot string) []string {
103104
//
104105
// Results are placed at <dbPath>/results/<queryPack>/<queryPathNoExt>.bqrs.
105106
// Decoded output goes to <dbPath>/results/<queryPack>/<queryPathNoExt>.<tgtFmt>.
106-
func runQueriesOnDB(cfg *config.Artifact, db config.DB, queryRoot string, queries []config.Query, tgtFmt string) {
107+
func runQueriesOnDB(cfg *config.Artifact, db config.DB, packName, queryRoot string, queries []config.Query, tgtFmt string) {
107108
// --- Phase 1: run-queries ---
108109
extArgs := buildGroupExternalArgs(queries, db.ExtDir())
109110

@@ -140,8 +141,8 @@ func runQueriesOnDB(cfg *config.Artifact, db config.DB, queryRoot string, querie
140141
utils.MkdirAll(decodeLogDir)
141142

142143
for _, query := range queries {
143-
bqrsPath := filepath.Join(db.Path(), "results/lslightly/qlstat", query.PathNoExt()+".bqrs")
144-
csvPath := filepath.Join(db.Path(), "results/lslightly/qlstat", query.PathNoExt()+"."+tgtFmt)
144+
bqrsPath := filepath.Join(db.Path(), "results", packName, query.PathNoExt()+".bqrs")
145+
csvPath := filepath.Join(db.Path(), "results", packName, query.PathNoExt()+"."+tgtFmt)
145146

146147
decOut, decErr := utils.CreateOutAndErr(filepath.Join(decodeLogDir, query.Name()))
147148
cmd := exec.Command("codeql", "bqrs", "decode",
@@ -166,6 +167,7 @@ dump stdout/stderr for ${db} in ${config.OutResultRoot}/${qScriptNameNoExt}/log/
166167
*/
167168
func queriesExec(cfg *config.Artifact, grp config.QueryGroup, queryRoot string, tgtFmt string) {
168169
dbs := cfg.ConvStrSliceToDBSlice(grp.QueryDBs)
170+
packName := resolvePackName(grp)
169171

170172
// Create Query objects for all queries in the group
171173
queries := make([]config.Query, len(grp.Queries))
@@ -180,7 +182,7 @@ func queriesExec(cfg *config.Artifact, grp config.QueryGroup, queryRoot string,
180182
wg.Add(1)
181183
go func(db config.DB) {
182184
defer wg.Done()
183-
runQueriesOnDB(cfg, db, queryRoot, queries, tgtFmt)
185+
runQueriesOnDB(cfg, db, packName, queryRoot, queries, tgtFmt)
184186
bar.Describe(fmt.Sprintf("db: %-20s %d queries", db.Name, len(queries)))
185187
bar.Add(1)
186188
}(db)
@@ -201,7 +203,7 @@ func checkDecodeTargetFmt(tgtFmt string) bool {
201203
}
202204

203205
/*
204-
codeql bqrs decode --format=${tgtFmt} ${dbPath}/results/lslightly/qlstat/${queryPathNoExt}.bqrs --output=${dbPath}/results/lslightly/qlstat/${queryPathNoExt}.${tgtFmt}
206+
codeql bqrs decode --format=${tgtFmt} ${dbPath}/results/${queryPack}/${queryPathNoExt}.bqrs --output=${dbPath}/results/${queryPack}/${queryPathNoExt}.${tgtFmt}
205207
*/
206208
func decodeResults(cfg *config.Artifact, tgtFmt string) {
207209
checkDecodeTargetFmt(tgtFmt)
@@ -210,12 +212,14 @@ func decodeResults(cfg *config.Artifact, tgtFmt string) {
210212
dbs := cfg.ConvStrSliceToDBSlice(grp.QueryDBs)
211213
queries := grp.Queries
212214

215+
packName := resolvePackName(grp)
216+
213217
bar := progressbar.Default(int64(len(queries) * len(dbs)))
214218
for _, qScript := range queries {
215219
query := config.CreateQuery(qScript, grp.Externals, grp.ExternalFiles, grp.ResolvedExternalRoot())
216220
for _, db := range dbs {
217-
bqrsPath := filepath.Join(db.Path(), "results/lslightly/qlstat", query.PathNoExt()+".bqrs")
218-
csvPath := filepath.Join(db.Path(), "results/lslightly/qlstat", query.PathNoExt()+"."+tgtFmt)
221+
bqrsPath := filepath.Join(db.Path(), "results", packName, query.PathNoExt()+".bqrs")
222+
csvPath := filepath.Join(db.Path(), "results", packName, query.PathNoExt()+"."+tgtFmt)
219223

220224
decodeLogDir := filepath.Join(cfg.PassLogDir("decode"), db.Name)
221225
utils.MkdirAll(decodeLogDir)
@@ -242,19 +246,50 @@ func decodeResults(cfg *config.Artifact, tgtFmt string) {
242246

243247
// -- CSV collection ------------------------------------------------------
244248

249+
// resolvePackName resolves the CodeQL pack name for a query group.
250+
// "std" or empty QueryRoot → built-in pack "lslightly/qlstat".
251+
// Otherwise runs "codeql resolve queries" on the first query to get the pack name.
252+
// Only one .ql file per group is needed — same QueryRoot → same qlpack.
253+
func resolvePackName(grp config.QueryGroup) string {
254+
if grp.QueryRoot == "" || grp.QueryRoot == "std" {
255+
return "lslightly/qlstat"
256+
}
257+
if len(grp.Queries) == 0 {
258+
return "lslightly/qlstat"
259+
}
260+
qPath := filepath.Join(grp.ResolvedQueryRoot(), grp.Queries[0])
261+
var errBuf bytes.Buffer
262+
cmd := exec.Command("codeql", "resolve", "queries", qPath)
263+
cmd.Stderr = &errBuf
264+
err := cmd.Run()
265+
if err != nil {
266+
log.Fatalf("Failed to resolve pack for query %s: %v\nOutput: %s", qPath, err, errBuf.String())
267+
}
268+
// Parse: "Recording pack reference <pack-name> at <path>"
269+
line := strings.TrimSpace(errBuf.String())
270+
prefix := "Recording pack reference "
271+
rest := strings.TrimPrefix(line, prefix)
272+
before, _, found := strings.Cut(rest, " at ")
273+
if !found {
274+
log.Fatalf("Unexpected codeql resolve output format for %s: %s", qPath, rest)
275+
}
276+
return before
277+
}
278+
245279
func collectCSVs(cfg *config.Artifact) {
246280
for grpi, grp := range cfg.QueryGrps {
281+
packName := resolvePackName(grp)
247282
bar := progressbar.Default(int64(len(grp.Queries)))
248283
for _, qScript := range grp.Queries {
249284
query := config.CreateQuery(qScript, grp.Externals, grp.ExternalFiles, grp.ResolvedExternalRoot())
250285
bar.Describe(fmt.Sprintf("Grp %d: Collecting for "+query.PathNoExt(), grpi))
251-
collectCSVsForQuery(cfg, query, grp)
286+
collectCSVsForQuery(cfg, query, grp, packName)
252287
bar.Add(1)
253288
}
254289
}
255290
}
256291

257-
func collectCSVsForQuery(cfg *config.Artifact, query config.Query, grp config.QueryGroup) {
292+
func collectCSVsForQuery(cfg *config.Artifact, query config.Query, grp config.QueryGroup, packName string) {
258293
qResultCSV := query.DirPath(cfg.ResultRoot) + ".csv"
259294

260295
outFile := utils.CreateFile(qResultCSV)
@@ -269,7 +304,7 @@ func collectCSVsForQuery(cfg *config.Artifact, query config.Query, grp config.Qu
269304

270305
var wg sync.WaitGroup
271306
for _, db := range dbs {
272-
csvPath := filepath.Join(db.Path(), "results/lslightly/qlstat", query.PathNoExt()+".csv")
307+
csvPath := filepath.Join(db.Path(), "results", packName, query.PathNoExt()+".csv")
273308

274309
// Check if the csv file exists
275310
if _, err := os.Stat(csvPath); os.IsNotExist(err) {

0 commit comments

Comments
 (0)