@@ -8,6 +8,8 @@ import type { CodeQLCliServer } from "../codeql-cli/cli";
8
8
import { pathExists } from "fs-extra" ;
9
9
import { withProgress , progressUpdate } from "../common/vscode/progress" ;
10
10
import type { ProgressCallback } from "../common/vscode/progress" ;
11
+ import { join , dirname , parse } from "path" ;
12
+ import { tryGetQueryMetadata } from "../codeql-cli/query-metadata" ;
11
13
12
14
/**
13
15
* Generates autofixes for the results of a variant analysis.
@@ -28,6 +30,16 @@ export async function viewAutofixesForVariantAnalysisResults(
28
30
progress ( progressUpdate ( 1 , 4 , `Checking for local autofix installation` ) ) ;
29
31
const localAutofixPath = findLocalAutofix ( ) ;
30
32
33
+ // Get the variant analysis with the given id.
34
+ const variantAnalysis = variantAnalyses . get ( variantAnalysisId ) ;
35
+ if ( ! variantAnalysis ) {
36
+ throw new Error ( `No variant analysis with id: ${ variantAnalysisId } ` ) ;
37
+ }
38
+
39
+ // Generate the query help and output it to the override directory.
40
+ progress ( progressUpdate ( 2 , 4 , `Generating query help override` ) ) ;
41
+ await overrideQueryHelp ( variantAnalysis , cliServer , localAutofixPath ) ;
42
+
31
43
// TODO
32
44
} ,
33
45
{
@@ -53,3 +65,68 @@ function findLocalAutofix(): string {
53
65
}
54
66
return localAutofixPath ;
55
67
}
68
+
69
+ /**
70
+ * Overrides the query help from a given variant analysis
71
+ * at a location within the `localAutofixPath` directory .
72
+ */
73
+ async function overrideQueryHelp (
74
+ variantAnalysis : VariantAnalysis ,
75
+ cliServer : CodeQLCliServer ,
76
+ localAutofixPath : string ,
77
+ ) : Promise < void > {
78
+ // Get path to the query used by the variant analysis.
79
+ const queryFilePath = variantAnalysis . query . filePath ;
80
+ if ( ! ( await pathExists ( queryFilePath ) ) ) {
81
+ throw new Error ( `Query file used by variant analysis not found.` ) ;
82
+ }
83
+ const queryFilePathNoExt = join (
84
+ dirname ( queryFilePath ) ,
85
+ parse ( queryFilePath ) . name ,
86
+ ) ;
87
+
88
+ // Get the path to the query help, which may be either a `.qhelp` or a `.md` file.
89
+ // Note: we assume that the name of the query file is the same as the name of the query help file.
90
+ const queryHelpFilePathQhelp = `${ queryFilePathNoExt } .qhelp` ;
91
+ const queryHelpFilePathMarkdown = `${ queryFilePathNoExt } .md` ;
92
+
93
+ // Set `queryHelpFilePath` to the existing extension type.
94
+ let queryHelpFilePath : string ;
95
+ if ( await pathExists ( queryHelpFilePathQhelp ) ) {
96
+ queryHelpFilePath = queryHelpFilePathQhelp ;
97
+ } else if ( await pathExists ( queryHelpFilePathMarkdown ) ) {
98
+ queryHelpFilePath = queryHelpFilePathMarkdown ;
99
+ } else {
100
+ throw new Error (
101
+ `Could not find query help file at either ${ queryHelpFilePathQhelp } or ${ queryHelpFilePathMarkdown } . Check that the query help file exists and is named correctly.` ,
102
+ ) ;
103
+ }
104
+
105
+ // Get the query metadata.
106
+ const metadata = await tryGetQueryMetadata ( cliServer , queryFilePath ) ;
107
+ if ( ! metadata ) {
108
+ throw new Error ( `Could not get query metadata for ${ queryFilePath } .` ) ;
109
+ }
110
+ // Get the query ID (used for the overridden query help's filename).
111
+ const queryId = metadata . id ;
112
+ if ( ! queryId ) {
113
+ throw new Error ( `Query metadata for ${ queryFilePath } is missing an ID.` ) ;
114
+ }
115
+ // Replace `/` with `-` for use with the overridden query help's filename.
116
+ // Use `replaceAll` since some query IDs have multiple slashes.
117
+ const queryIdWithDash = queryId . replaceAll ( "/" , "-" ) ;
118
+
119
+ // Get the path to the output directory for overriding the query help.
120
+ // Note: the path to this directory may change in the future.
121
+ const queryHelpOverrideDirectory = join (
122
+ localAutofixPath ,
123
+ "prompt-templates" ,
124
+ "qhelps" ,
125
+ `${ queryIdWithDash } .md` ,
126
+ ) ;
127
+
128
+ await cliServer . generateQueryHelp (
129
+ queryHelpFilePath ,
130
+ queryHelpOverrideDirectory ,
131
+ ) ;
132
+ }
0 commit comments