Skip to content

Commit 407825e

Browse files
authored
Merge pull request #3021 from github/koesie10/external-api-to-model-editor
Rename external API methods/files/errors to model editor
2 parents 325cc05 + f5d8677 commit 407825e

File tree

7 files changed

+550
-552
lines changed

7 files changed

+550
-552
lines changed

extensions/ql-vscode/src/model-editor/external-api-usage-queries.ts

Lines changed: 0 additions & 189 deletions
This file was deleted.

extensions/ql-vscode/src/model-editor/model-editor-module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { isQueryLanguage } from "../common/query-language";
1515
import { DisposableObject } from "../common/disposable-object";
1616
import { MethodsUsagePanel } from "./methods-usage/methods-usage-panel";
1717
import { Method, Usage } from "./method";
18-
import { setUpPack } from "./model-editor-queries";
18+
import { setUpPack } from "./model-editor-queries-setup";
1919
import { MethodModelingPanel } from "./method-modeling/method-modeling-panel";
2020
import { ModelingStore } from "./modeling-store";
2121
import { showResolvableLocation } from "../databases/local-databases/locations";
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { join } from "path";
2+
import { QueryLanguage } from "../common/query-language";
3+
import { writeFile } from "fs-extra";
4+
import { dump } from "js-yaml";
5+
import { prepareModelEditorQueries } from "./model-editor-queries";
6+
import { CodeQLCliServer } from "../codeql-cli/cli";
7+
import { ModelConfig } from "../config";
8+
import { Mode } from "./shared/mode";
9+
import { resolveQueriesFromPacks } from "../local-queries";
10+
import { modeTag } from "./mode-tag";
11+
12+
export const syntheticQueryPackName = "codeql/model-editor-queries";
13+
14+
/**
15+
* setUpPack sets up a directory to use for the data extension editor queries if required.
16+
*
17+
* There are two cases (example language is Java):
18+
* - In case the queries are present in the codeql/java-queries, we don't need to write our own queries
19+
* to disk. We still need to create a synthetic query pack so we can pass the queryDir to the query
20+
* resolver without caring about whether the queries are present in the pack or not.
21+
* - In case the queries are not present in the codeql/java-queries, we need to write our own queries
22+
* to disk. We will create a synthetic query pack and install its dependencies so it is fully independent
23+
* and we can simply pass it through when resolving the queries.
24+
*
25+
* These steps together ensure that later steps of the process don't need to keep track of whether the queries
26+
* are present in codeql/java-queries or in our own query pack. They just need to resolve the query.
27+
*
28+
* @param cliServer The CodeQL CLI server to use.
29+
* @param queryDir The directory to set up.
30+
* @param language The language to use for the queries.
31+
* @param modelConfig The model config to use.
32+
* @returns true if the setup was successful, false otherwise.
33+
*/
34+
export async function setUpPack(
35+
cliServer: CodeQLCliServer,
36+
queryDir: string,
37+
language: QueryLanguage,
38+
modelConfig: ModelConfig,
39+
): Promise<boolean> {
40+
// Download the required query packs
41+
await cliServer.packDownload([`codeql/${language}-queries`]);
42+
43+
// We'll only check if the application mode query exists in the pack and assume that if it does,
44+
// the framework mode query will also exist.
45+
const applicationModeQuery = await resolveEndpointsQuery(
46+
cliServer,
47+
language,
48+
Mode.Application,
49+
[],
50+
[],
51+
);
52+
53+
if (applicationModeQuery) {
54+
// Set up a synthetic pack so CodeQL doesn't crash later when we try
55+
// to resolve a query within this directory
56+
const syntheticQueryPack = {
57+
name: syntheticQueryPackName,
58+
version: "0.0.0",
59+
dependencies: {},
60+
};
61+
62+
const qlpackFile = join(queryDir, "codeql-pack.yml");
63+
await writeFile(qlpackFile, dump(syntheticQueryPack), "utf8");
64+
} else {
65+
// If we can't resolve the query, we need to write them to desk ourselves.
66+
const externalApiQuerySuccess = await prepareModelEditorQueries(
67+
queryDir,
68+
language,
69+
);
70+
if (!externalApiQuerySuccess) {
71+
return false;
72+
}
73+
74+
// Set up a synthetic pack so that the query can be resolved later.
75+
const syntheticQueryPack = {
76+
name: syntheticQueryPackName,
77+
version: "0.0.0",
78+
dependencies: {
79+
[`codeql/${language}-all`]: "*",
80+
},
81+
};
82+
83+
const qlpackFile = join(queryDir, "codeql-pack.yml");
84+
await writeFile(qlpackFile, dump(syntheticQueryPack), "utf8");
85+
await cliServer.packInstall(queryDir);
86+
}
87+
88+
// Download any other required packs
89+
if (language === "java" && modelConfig.llmGeneration) {
90+
await cliServer.packDownload([`codeql/${language}-automodel-queries`]);
91+
}
92+
93+
return true;
94+
}
95+
96+
/**
97+
* Resolve the query path to the model editor endpoints query. All queries are tagged like this:
98+
* modeleditor endpoints <mode>
99+
* Example: modeleditor endpoints framework-mode
100+
*
101+
* @param cliServer The CodeQL CLI server to use.
102+
* @param language The language of the query pack to use.
103+
* @param mode The mode to resolve the query for.
104+
* @param additionalPackNames Additional pack names to search.
105+
* @param additionalPackPaths Additional pack paths to search.
106+
*/
107+
export async function resolveEndpointsQuery(
108+
cliServer: CodeQLCliServer,
109+
language: string,
110+
mode: Mode,
111+
additionalPackNames: string[] = [],
112+
additionalPackPaths: string[] = [],
113+
): Promise<string | undefined> {
114+
const packsToSearch = [`codeql/${language}-queries`, ...additionalPackNames];
115+
116+
// First, resolve the query that we want to run.
117+
// All queries are tagged like this:
118+
// internal extract automodel <mode> <queryTag>
119+
// Example: internal extract automodel framework-mode candidates
120+
const queries = await resolveQueriesFromPacks(
121+
cliServer,
122+
packsToSearch,
123+
{
124+
kind: "table",
125+
"tags contain all": ["modeleditor", "endpoints", modeTag(mode)],
126+
},
127+
additionalPackPaths,
128+
);
129+
if (queries.length > 1) {
130+
throw new Error(
131+
`Found multiple endpoints queries for ${mode}. Can't continue`,
132+
);
133+
}
134+
135+
if (queries.length === 0) {
136+
return undefined;
137+
}
138+
139+
return queries[0];
140+
}

0 commit comments

Comments
 (0)