Skip to content

Commit b6deb8e

Browse files
authored
Merge pull request #2744 from github/starcke/general-setup
Move pack setup out of fetch queries.
2 parents 7b78fc1 + 74a12b9 commit b6deb8e

5 files changed

Lines changed: 140 additions & 108 deletions

File tree

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

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,16 @@ import { join } from "path";
99
import { App } from "../common/app";
1010
import { withProgress } from "../common/vscode/progress";
1111
import { pickExtensionPack } from "./extension-pack-picker";
12-
import {
13-
showAndLogErrorMessage,
14-
showAndLogExceptionWithTelemetry,
15-
} from "../common/logging";
12+
import { showAndLogErrorMessage } from "../common/logging";
1613
import { dir } from "tmp-promise";
17-
import { fetchExternalApiQueries } from "./queries";
18-
import { telemetryListener } from "../common/vscode/telemetry";
19-
import { redactableError } from "../common/errors";
20-
import { extLogger } from "../common/logging/vscode";
14+
2115
import { isQueryLanguage } from "../common/query-language";
22-
import { setUpPack } from "./external-api-usage-queries";
2316
import { DisposableObject } from "../common/disposable-object";
2417
import { ModelDetailsPanel } from "./methods-usage/methods-usage-panel";
2518
import { Mode } from "./shared/mode";
2619
import { showResolvableLocation } from "../databases/local-databases/locations";
2720
import { Usage } from "./external-api-usage";
21+
import { setUpPack } from "./data-extensions-editor-queries";
2822

2923
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
3024

@@ -138,19 +132,12 @@ export class DataExtensionsEditorModule extends DisposableObject {
138132
return;
139133
}
140134

141-
const query = fetchExternalApiQueries[language];
142-
if (!query) {
143-
void showAndLogExceptionWithTelemetry(
144-
extLogger,
145-
telemetryListener,
146-
redactableError`No external API usage query found for language ${language}`,
147-
);
148-
return;
149-
}
150-
151135
// Create new temporary directory for query files and pack dependencies
152136
const queryDir = (await dir({ unsafeCleanup: true })).path;
153-
await setUpPack(queryDir, query, language);
137+
const success = await setUpPack(queryDir, language);
138+
if (!success) {
139+
return;
140+
}
154141
await this.cliServer.packInstall(queryDir);
155142

156143
const view = new DataExtensionsEditorView(
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 { prepareExternalApiQuery } from "./external-api-usage-queries";
6+
7+
/**
8+
* setUpPack sets up a directory to use for the data extension editor queries.
9+
* @param queryDir The directory to set up.
10+
* @param language The language to use for the queries.
11+
* @returns true if the setup was successful, false otherwise.
12+
*/
13+
export async function setUpPack(
14+
queryDir: string,
15+
language: QueryLanguage,
16+
): Promise<boolean> {
17+
// Create the external API query
18+
const externalApiQuerySuccess = await prepareExternalApiQuery(
19+
queryDir,
20+
language,
21+
);
22+
if (!externalApiQuerySuccess) {
23+
return false;
24+
}
25+
26+
// Set up a synthetic query pack to resolve dependencies.
27+
const syntheticQueryPack = {
28+
name: "codeql/external-api-usage",
29+
version: "0.0.0",
30+
dependencies: {
31+
[`codeql/${language}-all`]: "*",
32+
},
33+
};
34+
35+
const qlpackFile = join(queryDir, "codeql-pack.yml");
36+
await writeFile(qlpackFile, dump(syntheticQueryPack), "utf8");
37+
return true;
38+
}

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

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ import { telemetryListener } from "../common/vscode/telemetry";
1212
import { join } from "path";
1313
import { Mode } from "./shared/mode";
1414
import { writeFile } from "fs-extra";
15-
import { Query } from "./queries/query";
1615
import { QueryLanguage } from "../common/query-language";
17-
import { dump } from "js-yaml";
16+
import { fetchExternalApiQueries } from "./queries";
1817

1918
type RunQueryOptions = {
2019
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">;
@@ -27,36 +26,34 @@ type RunQueryOptions = {
2726
token: CancellationToken;
2827
};
2928

30-
export async function setUpPack(
29+
export async function prepareExternalApiQuery(
3130
queryDir: string,
32-
query: Query,
3331
language: QueryLanguage,
34-
) {
35-
Object.values(Mode).map(async (mode) => {
36-
const queryFile = join(
37-
queryDir,
38-
`FetchExternalApis${mode.charAt(0).toUpperCase() + mode.slice(1)}Mode.ql`,
32+
): Promise<boolean> {
33+
// Resolve the query that we want to run.
34+
const query = fetchExternalApiQueries[language];
35+
if (!query) {
36+
void showAndLogExceptionWithTelemetry(
37+
extLogger,
38+
telemetryListener,
39+
redactableError`No external API usage query found for language ${language}`,
3940
);
41+
return false;
42+
}
43+
// Create the query file.
44+
Object.values(Mode).map(async (mode) => {
45+
const queryFile = join(queryDir, queryNameFromMode(mode));
4046
await writeFile(queryFile, query[`${mode}ModeQuery`], "utf8");
4147
});
4248

49+
// Create any dependencies
4350
if (query.dependencies) {
4451
for (const [filename, contents] of Object.entries(query.dependencies)) {
4552
const dependencyFile = join(queryDir, filename);
4653
await writeFile(dependencyFile, contents, "utf8");
4754
}
4855
}
49-
50-
const syntheticQueryPack = {
51-
name: "codeql/external-api-usage",
52-
version: "0.0.0",
53-
dependencies: {
54-
[`codeql/${language}-all`]: "*",
55-
},
56-
};
57-
58-
const qlpackFile = join(queryDir, "codeql-pack.yml");
59-
await writeFile(qlpackFile, dump(syntheticQueryPack), "utf8");
56+
return true;
6057
}
6158

6259
export async function runQuery(
@@ -145,3 +142,9 @@ export async function readQueryResults({
145142

146143
return cliServer.bqrsDecode(bqrsPath, resultSet.name);
147144
}
145+
146+
function queryNameFromMode(mode: Mode): string {
147+
return `FetchExternalApis${
148+
mode.charAt(0).toUpperCase() + mode.slice(1)
149+
}Mode.ql`;
150+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { readFile, readFileSync, readdir } from "fs-extra";
2+
import { join } from "path";
3+
import { load } from "js-yaml";
4+
import { setUpPack } from "../../../../src/data-extensions-editor/data-extensions-editor-queries";
5+
import { dirSync } from "tmp-promise";
6+
import { fetchExternalApiQueries } from "../../../../src/data-extensions-editor/queries";
7+
import { QueryLanguage } from "../../../../src/common/query-language";
8+
import { Mode } from "../../../../src/data-extensions-editor/shared/mode";
9+
10+
describe("setUpPack", () => {
11+
const languages = Object.keys(fetchExternalApiQueries).flatMap((lang) => {
12+
const queryDir = dirSync({ unsafeCleanup: true }).name;
13+
const query = fetchExternalApiQueries[lang as QueryLanguage];
14+
if (!query) {
15+
return [];
16+
}
17+
18+
return { language: lang as QueryLanguage, queryDir, query };
19+
});
20+
21+
test.each(languages)(
22+
"should create files for $language",
23+
async ({ language, queryDir, query }) => {
24+
await setUpPack(queryDir, language);
25+
26+
const queryFiles = await readdir(queryDir);
27+
expect(queryFiles.sort()).toEqual(
28+
[
29+
"codeql-pack.yml",
30+
"FetchExternalApisApplicationMode.ql",
31+
"FetchExternalApisFrameworkMode.ql",
32+
"AutomodelVsCode.qll",
33+
].sort(),
34+
);
35+
36+
const suiteFileContents = await readFile(
37+
join(queryDir, "codeql-pack.yml"),
38+
"utf8",
39+
);
40+
const suiteYaml = load(suiteFileContents);
41+
expect(suiteYaml).toEqual({
42+
name: "codeql/external-api-usage",
43+
version: "0.0.0",
44+
dependencies: {
45+
[`codeql/${language}-all`]: "*",
46+
},
47+
});
48+
49+
Object.values(Mode).forEach((mode) => {
50+
expect(
51+
readFileSync(
52+
join(
53+
queryDir,
54+
`FetchExternalApis${
55+
mode.charAt(0).toUpperCase() + mode.slice(1)
56+
}Mode.ql`,
57+
),
58+
"utf8",
59+
),
60+
).toEqual(query[`${mode}ModeQuery`]);
61+
});
62+
63+
for (const [filename, contents] of Object.entries(
64+
query.dependencies ?? {},
65+
)) {
66+
expect(await readFile(join(queryDir, filename), "utf8")).toEqual(
67+
contents,
68+
);
69+
}
70+
},
71+
);
72+
});

extensions/ql-vscode/test/vscode-tests/no-workspace/data-extensions-editor/external-api-usage-query.test.ts

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
readQueryResults,
33
runQuery,
4-
setUpPack,
54
} from "../../../../src/data-extensions-editor/external-api-usage-queries";
65
import { createMockLogger } from "../../../__mocks__/loggerMock";
76
import { DatabaseKind } from "../../../../src/databases/local-databases";
@@ -14,75 +13,8 @@ import { showAndLogExceptionWithTelemetry } from "../../../../src/common/logging
1413
import { QueryLanguage } from "../../../../src/common/query-language";
1514
import { mockedUri } from "../../utils/mocking.helpers";
1615
import { Mode } from "../../../../src/data-extensions-editor/shared/mode";
17-
import { readFile, readFileSync, readdir } from "fs-extra";
18-
import { join } from "path";
19-
import { load } from "js-yaml";
2016

2117
describe("external api usage query", () => {
22-
describe("setUpPack", () => {
23-
const languages = Object.keys(fetchExternalApiQueries).flatMap((lang) => {
24-
const queryDir = dirSync({ unsafeCleanup: true }).name;
25-
const query = fetchExternalApiQueries[lang as QueryLanguage];
26-
if (!query) {
27-
return [];
28-
}
29-
30-
return { language: lang as QueryLanguage, queryDir, query };
31-
});
32-
33-
test.each(languages)(
34-
"should create files for $language",
35-
async ({ language, queryDir, query }) => {
36-
await setUpPack(queryDir, query, language);
37-
38-
const queryFiles = await readdir(queryDir);
39-
expect(queryFiles.sort()).toEqual(
40-
[
41-
"codeql-pack.yml",
42-
"FetchExternalApisApplicationMode.ql",
43-
"FetchExternalApisFrameworkMode.ql",
44-
"AutomodelVsCode.qll",
45-
].sort(),
46-
);
47-
48-
const suiteFileContents = await readFile(
49-
join(queryDir, "codeql-pack.yml"),
50-
"utf8",
51-
);
52-
const suiteYaml = load(suiteFileContents);
53-
expect(suiteYaml).toEqual({
54-
name: "codeql/external-api-usage",
55-
version: "0.0.0",
56-
dependencies: {
57-
[`codeql/${language}-all`]: "*",
58-
},
59-
});
60-
61-
Object.values(Mode).forEach((mode) => {
62-
expect(
63-
readFileSync(
64-
join(
65-
queryDir,
66-
`FetchExternalApis${
67-
mode.charAt(0).toUpperCase() + mode.slice(1)
68-
}Mode.ql`,
69-
),
70-
"utf8",
71-
),
72-
).toEqual(query[`${mode}ModeQuery`]);
73-
});
74-
75-
for (const [filename, contents] of Object.entries(
76-
query.dependencies ?? {},
77-
)) {
78-
expect(await readFile(join(queryDir, filename), "utf8")).toEqual(
79-
contents,
80-
);
81-
}
82-
},
83-
);
84-
});
85-
8618
describe("runQuery", () => {
8719
const language = Object.keys(fetchExternalApiQueries)[
8820
Math.floor(Math.random() * Object.keys(fetchExternalApiQueries).length)

0 commit comments

Comments
 (0)