11import { CodeQLCliServer , SourceInfo } from "../codeql-cli/cli" ;
2- import { QueryRunner } from "../query-server" ;
2+ import { CoreCompletedQuery , QueryRunner } from "../query-server" ;
33import { DatabaseItem } from "../databases/local-databases" ;
44import { ProgressCallback } from "../common/vscode/progress" ;
55import * as Sarif from "sarif" ;
66import { qlpackOfDatabase , resolveQueries } from "../local-queries" ;
7- import { extLogger } from "../common/logging/vscode" ;
87import { Mode } from "./shared/mode" ;
9- import { QlPacksForLanguage } from "../databases/qlpack" ;
10- import { createLockFileForStandardQuery } from "../local-queries/standard-queries" ;
11- import { CancellationToken , CancellationTokenSource } from "vscode" ;
128import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders" ;
13- import { showAndLogExceptionWithTelemetry , TeeLogger } from "../common/logging" ;
14- import { QueryResultType } from "../query-server/new-messages" ;
15- import { telemetryListener } from "../common/vscode/telemetry" ;
16- import { redactableError } from "../common/errors" ;
179import { interpretResultsSarif } from "../query-results" ;
1810import { join } from "path" ;
1911import { assertNever } from "../common/helpers-pure" ;
2012import { dir } from "tmp-promise" ;
2113import { writeFile , outputFile } from "fs-extra" ;
2214import { dump as dumpYaml } from "js-yaml" ;
2315import { MethodSignature } from "./external-api-usage" ;
24-
25- type AutoModelQueryOptions = {
26- queryTag : string ;
27- mode : Mode ;
28- cliServer : CodeQLCliServer ;
29- queryRunner : QueryRunner ;
30- databaseItem : DatabaseItem ;
31- qlpack : QlPacksForLanguage ;
32- sourceInfo : SourceInfo | undefined ;
33- additionalPacks : string [ ] ;
34- extensionPacks : string [ ] ;
35- queryStorageDir : string ;
36-
37- progress : ProgressCallback ;
38- token : CancellationToken ;
39- } ;
16+ import { runQuery } from "../local-queries/run-query" ;
17+ import { QueryMetadata } from "../common/interface-types" ;
18+ import { CancellationTokenSource } from "vscode" ;
4019
4120function modeTag ( mode : Mode ) : string {
4221 switch ( mode ) {
@@ -49,108 +28,6 @@ function modeTag(mode: Mode): string {
4928 }
5029}
5130
52- async function runAutoModelQuery ( {
53- queryTag,
54- mode,
55- cliServer,
56- queryRunner,
57- databaseItem,
58- qlpack,
59- sourceInfo,
60- additionalPacks,
61- extensionPacks,
62- queryStorageDir,
63- progress,
64- token,
65- } : AutoModelQueryOptions ) : Promise < Sarif . Log | undefined > {
66- // First, resolve the query that we want to run.
67- // All queries are tagged like this:
68- // internal extract automodel <mode> <queryTag>
69- // Example: internal extract automodel framework-mode candidates
70- const queries = await resolveQueries (
71- cliServer ,
72- qlpack ,
73- `Extract automodel ${ queryTag } ` ,
74- {
75- kind : "problem" ,
76- "tags contain all" : [ "automodel" , modeTag ( mode ) , ...queryTag . split ( " " ) ] ,
77- } ,
78- ) ;
79- if ( queries . length > 1 ) {
80- throw new Error (
81- `Found multiple auto model queries for ${ mode } ${ queryTag } . Can't continue` ,
82- ) ;
83- }
84- if ( queries . length === 0 ) {
85- throw new Error (
86- `Did not found any auto model queries for ${ mode } ${ queryTag } . Can't continue` ,
87- ) ;
88- }
89-
90- const queryPath = queries [ 0 ] ;
91- const { cleanup : cleanupLockFile } = await createLockFileForStandardQuery (
92- cliServer ,
93- queryPath ,
94- ) ;
95-
96- // Get metadata for the query. This is required to interpret the results. We already know the kind is problem
97- // (because of the constraint in resolveQueries), so we don't need any more checks on the metadata.
98- const metadata = await cliServer . resolveMetadata ( queryPath ) ;
99-
100- const queryRun = queryRunner . createQueryRun (
101- databaseItem . databaseUri . fsPath ,
102- {
103- queryPath,
104- quickEvalPosition : undefined ,
105- quickEvalCountOnly : false ,
106- } ,
107- false ,
108- additionalPacks ,
109- extensionPacks ,
110- queryStorageDir ,
111- undefined ,
112- undefined ,
113- ) ;
114-
115- const completedQuery = await queryRun . evaluate (
116- progress ,
117- token ,
118- new TeeLogger ( queryRunner . logger , queryRun . outputDir . logPath ) ,
119- ) ;
120-
121- await cleanupLockFile ?.( ) ;
122-
123- if ( completedQuery . resultType !== QueryResultType . SUCCESS ) {
124- void showAndLogExceptionWithTelemetry (
125- extLogger ,
126- telemetryListener ,
127- redactableError `Auto-model query ${ queryTag } failed: ${
128- completedQuery . message ?? "No message"
129- } `,
130- ) ;
131- return ;
132- }
133-
134- const interpretedResultsPath = join (
135- queryStorageDir ,
136- `interpreted-results-${ queryTag . replaceAll ( " " , "-" ) } -${ queryRun . id } .sarif` ,
137- ) ;
138-
139- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- We only need the actual SARIF data, not the extra fields added by SarifInterpretationData
140- const { t, sortState, ...sarif } = await interpretResultsSarif (
141- cliServer ,
142- metadata ,
143- {
144- resultsPath : completedQuery . outputDir . bqrsPath ,
145- interpretedResultsPath,
146- } ,
147- sourceInfo ,
148- [ "--sarif-add-snippets" ] ,
149- ) ;
150-
151- return sarif ;
152- }
153-
15431type AutoModelQueriesOptions = {
15532 mode : Mode ;
15633 candidateMethods : MethodSignature [ ] ;
@@ -177,22 +54,13 @@ export async function runAutoModelQueries({
17754 progress,
17855 cancellationTokenSource,
17956} : AutoModelQueriesOptions ) : Promise < AutoModelQueriesResult | undefined > {
180- const qlpack = await qlpackOfDatabase ( cliServer , databaseItem ) ;
181-
182- // CodeQL needs to have access to the database to be able to retrieve the
183- // snippets from it. The source location prefix is used to determine the
184- // base path of the database.
185- const sourceLocationPrefix = await databaseItem . getSourceLocationPrefix (
57+ // First, resolve the query that we want to run.
58+ const queryPath = await resolveAutomodelQuery (
18659 cliServer ,
60+ databaseItem ,
61+ "candidates" ,
62+ mode ,
18763 ) ;
188- const sourceArchiveUri = databaseItem . sourceArchive ;
189- const sourceInfo =
190- sourceArchiveUri === undefined
191- ? undefined
192- : {
193- sourceArchive : sourceArchiveUri . fsPath ,
194- sourceLocationPrefix,
195- } ;
19664
19765 // Generate a pack containing the candidate filters
19866 const filterPackDir = await generateCandidateFilterPack (
@@ -205,30 +73,89 @@ export async function runAutoModelQueries({
20573 await cliServer . resolveQlpacks ( additionalPacks , true ) ,
20674 ) ;
20775
208- const candidates = await runAutoModelQuery ( {
209- mode,
210- queryTag : "candidates" ,
76+ // Run the actual query
77+ const completedQuery = await runQuery ( {
21178 cliServer,
21279 queryRunner,
21380 databaseItem,
214- qlpack ,
215- sourceInfo ,
81+ queryPath ,
82+ queryStorageDir ,
21683 additionalPacks,
21784 extensionPacks,
218- queryStorageDir,
21985 progress,
22086 token : cancellationTokenSource . token ,
22187 } ) ;
22288
223- if ( ! candidates ) {
89+ if ( ! completedQuery ) {
22490 return undefined ;
22591 }
22692
93+ // Get metadata for the query. This is required to interpret the results. We already know the kind is problem
94+ // (because of the constraint in resolveQueries), so we don't need any more checks on the metadata.
95+ const metadata = await cliServer . resolveMetadata ( queryPath ) ;
96+
97+ // CodeQL needs to have access to the database to be able to retrieve the
98+ // snippets from it. The source location prefix is used to determine the
99+ // base path of the database.
100+ const sourceLocationPrefix = await databaseItem . getSourceLocationPrefix (
101+ cliServer ,
102+ ) ;
103+ const sourceArchiveUri = databaseItem . sourceArchive ;
104+ const sourceInfo =
105+ sourceArchiveUri === undefined
106+ ? undefined
107+ : {
108+ sourceArchive : sourceArchiveUri . fsPath ,
109+ sourceLocationPrefix,
110+ } ;
111+
112+ const candidates = await interpretAutomodelResults (
113+ cliServer ,
114+ completedQuery ,
115+ metadata ,
116+ sourceInfo ,
117+ ) ;
118+
227119 return {
228120 candidates,
229121 } ;
230122}
231123
124+ async function resolveAutomodelQuery (
125+ cliServer : CodeQLCliServer ,
126+ databaseItem : DatabaseItem ,
127+ queryTag : string ,
128+ mode : Mode ,
129+ ) : Promise < string > {
130+ const qlpack = await qlpackOfDatabase ( cliServer , databaseItem ) ;
131+
132+ // First, resolve the query that we want to run.
133+ // All queries are tagged like this:
134+ // internal extract automodel <mode> <queryTag>
135+ // Example: internal extract automodel framework-mode candidates
136+ const queries = await resolveQueries (
137+ cliServer ,
138+ qlpack ,
139+ `Extract automodel ${ queryTag } ` ,
140+ {
141+ kind : "problem" ,
142+ "tags contain all" : [ "automodel" , modeTag ( mode ) , ...queryTag . split ( " " ) ] ,
143+ } ,
144+ ) ;
145+ if ( queries . length > 1 ) {
146+ throw new Error (
147+ `Found multiple auto model queries for ${ mode } ${ queryTag } . Can't continue` ,
148+ ) ;
149+ }
150+ if ( queries . length === 0 ) {
151+ throw new Error (
152+ `Did not found any auto model queries for ${ mode } ${ queryTag } . Can't continue` ,
153+ ) ;
154+ }
155+
156+ return queries [ 0 ] ;
157+ }
158+
232159/**
233160 * generateCandidateFilterPack will create a temporary extension pack.
234161 * This pack will contain a filter that will restrict the automodel queries
@@ -284,3 +211,28 @@ export async function generateCandidateFilterPack(
284211
285212 return packDir ;
286213}
214+
215+ async function interpretAutomodelResults (
216+ cliServer : CodeQLCliServer ,
217+ completedQuery : CoreCompletedQuery ,
218+ metadata : QueryMetadata ,
219+ sourceInfo : SourceInfo | undefined ,
220+ ) : Promise < Sarif . Log > {
221+ const interpretedResultsPath = join (
222+ completedQuery . outputDir . querySaveDir ,
223+ "results.sarif" ,
224+ ) ;
225+
226+ const { ...sarif } = await interpretResultsSarif (
227+ cliServer ,
228+ metadata ,
229+ {
230+ resultsPath : completedQuery . outputDir . bqrsPath ,
231+ interpretedResultsPath,
232+ } ,
233+ sourceInfo ,
234+ [ "--sarif-add-snippets" ] ,
235+ ) ;
236+
237+ return sarif ;
238+ }
0 commit comments