Skip to content

Commit 706c6b8

Browse files
committed
Move qlpacks helpers to separate file
1 parent fe21a21 commit 706c6b8

File tree

6 files changed

+144
-139
lines changed

6 files changed

+144
-139
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { window } from "vscode";
2+
import { glob } from "glob";
3+
import { basename } from "path";
4+
import { load } from "js-yaml";
5+
import { readFile } from "fs-extra";
6+
import { getQlPackPath } from "../pure/ql";
7+
import { CodeQLCliServer, QlpacksInfo } from "../codeql-cli/cli";
8+
import { extLogger } from "../common";
9+
import { getOnDiskWorkspaceFolders } from "../helpers";
10+
11+
export interface QlPacksForLanguage {
12+
/** The name of the pack containing the dbscheme. */
13+
dbschemePack: string;
14+
/** `true` if `dbschemePack` is a library pack. */
15+
dbschemePackIsLibraryPack: boolean;
16+
/**
17+
* The name of the corresponding standard query pack.
18+
* Only defined if `dbschemePack` is a library pack.
19+
*/
20+
queryPack?: string;
21+
}
22+
23+
interface QlPackWithPath {
24+
packName: string;
25+
packDir: string | undefined;
26+
}
27+
28+
async function findDbschemePack(
29+
packs: QlPackWithPath[],
30+
dbschemePath: string,
31+
): Promise<{ name: string; isLibraryPack: boolean }> {
32+
for (const { packDir, packName } of packs) {
33+
if (packDir !== undefined) {
34+
const qlpackPath = await getQlPackPath(packDir);
35+
36+
if (qlpackPath !== undefined) {
37+
const qlpack = load(await readFile(qlpackPath, "utf8")) as {
38+
dbscheme?: string;
39+
library?: boolean;
40+
};
41+
if (
42+
qlpack.dbscheme !== undefined &&
43+
basename(qlpack.dbscheme) === basename(dbschemePath)
44+
) {
45+
return {
46+
name: packName,
47+
isLibraryPack: qlpack.library === true,
48+
};
49+
}
50+
}
51+
}
52+
}
53+
throw new Error(`Could not find qlpack file for dbscheme ${dbschemePath}`);
54+
}
55+
56+
function findStandardQueryPack(
57+
qlpacks: QlpacksInfo,
58+
dbschemePackName: string,
59+
): string | undefined {
60+
const matches = dbschemePackName.match(/^codeql\/(?<language>[a-z]+)-all$/);
61+
if (matches) {
62+
const queryPackName = `codeql/${matches.groups!.language}-queries`;
63+
if (qlpacks[queryPackName] !== undefined) {
64+
return queryPackName;
65+
}
66+
}
67+
68+
// Either the dbscheme pack didn't look like one where the queries might be in the query pack, or
69+
// no query pack was found in the search path. Either is OK.
70+
return undefined;
71+
}
72+
73+
export async function getQlPackForDbscheme(
74+
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">,
75+
dbschemePath: string,
76+
): Promise<QlPacksForLanguage> {
77+
const qlpacks = await cliServer.resolveQlpacks(getOnDiskWorkspaceFolders());
78+
const packs: QlPackWithPath[] = Object.entries(qlpacks).map(
79+
([packName, dirs]) => {
80+
if (dirs.length < 1) {
81+
void extLogger.log(
82+
`In getQlPackFor ${dbschemePath}, qlpack ${packName} has no directories`,
83+
);
84+
return { packName, packDir: undefined };
85+
}
86+
if (dirs.length > 1) {
87+
void extLogger.log(
88+
`In getQlPackFor ${dbschemePath}, qlpack ${packName} has more than one directory; arbitrarily choosing the first`,
89+
);
90+
}
91+
return {
92+
packName,
93+
packDir: dirs[0],
94+
};
95+
},
96+
);
97+
const dbschemePack = await findDbschemePack(packs, dbschemePath);
98+
const queryPack = dbschemePack.isLibraryPack
99+
? findStandardQueryPack(qlpacks, dbschemePack.name)
100+
: undefined;
101+
return {
102+
dbschemePack: dbschemePack.name,
103+
dbschemePackIsLibraryPack: dbschemePack.isLibraryPack,
104+
queryPack,
105+
};
106+
}
107+
108+
export async function getPrimaryDbscheme(
109+
datasetFolder: string,
110+
): Promise<string> {
111+
const dbschemes = await glob("*.dbscheme", {
112+
cwd: datasetFolder,
113+
});
114+
115+
if (dbschemes.length < 1) {
116+
throw new Error(
117+
`Can't find dbscheme for current database in ${datasetFolder}`,
118+
);
119+
}
120+
121+
dbschemes.sort();
122+
const dbscheme = dbschemes[0];
123+
124+
if (dbschemes.length > 1) {
125+
void window.showErrorMessage(
126+
`Found multiple dbschemes in ${datasetFolder} during quick query; arbitrarily choosing the first, ${dbscheme}, to decide what library to use.`,
127+
);
128+
}
129+
return dbscheme;
130+
}

extensions/ql-vscode/src/helpers.ts

Lines changed: 1 addition & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
import {
22
ensureDirSync,
3-
readFile,
43
pathExists,
54
ensureDir,
65
writeFile,
76
opendir,
87
} from "fs-extra";
98
import { glob } from "glob";
10-
import { load } from "js-yaml";
119
import { join, basename, dirname } from "path";
1210
import { dirSync } from "tmp-promise";
1311
import { Uri, window as Window, workspace, env, WorkspaceFolder } from "vscode";
14-
import { CodeQLCliServer, QlpacksInfo } from "./codeql-cli/cli";
12+
import { CodeQLCliServer } from "./codeql-cli/cli";
1513
import { UserCancellationException } from "./common/vscode/progress";
1614
import { extLogger, OutputChannelLogger } from "./common";
1715
import { QueryMetadata } from "./pure/interface-types";
1816
import { telemetryListener } from "./telemetry";
1917
import { RedactableError } from "./pure/errors";
20-
import { getQlPackPath } from "./pure/ql";
2118
import { dbSchemeToLanguage, QueryLanguage } from "./common/query-language";
2219
import { isCodespacesTemplate } from "./config";
2320
import { AppCommandManager } from "./common/commands";
@@ -356,127 +353,6 @@ export async function prepareCodeTour(
356353
}
357354
}
358355

359-
export interface QlPacksForLanguage {
360-
/** The name of the pack containing the dbscheme. */
361-
dbschemePack: string;
362-
/** `true` if `dbschemePack` is a library pack. */
363-
dbschemePackIsLibraryPack: boolean;
364-
/**
365-
* The name of the corresponding standard query pack.
366-
* Only defined if `dbschemePack` is a library pack.
367-
*/
368-
queryPack?: string;
369-
}
370-
371-
interface QlPackWithPath {
372-
packName: string;
373-
packDir: string | undefined;
374-
}
375-
376-
async function findDbschemePack(
377-
packs: QlPackWithPath[],
378-
dbschemePath: string,
379-
): Promise<{ name: string; isLibraryPack: boolean }> {
380-
for (const { packDir, packName } of packs) {
381-
if (packDir !== undefined) {
382-
const qlpackPath = await getQlPackPath(packDir);
383-
384-
if (qlpackPath !== undefined) {
385-
const qlpack = load(await readFile(qlpackPath, "utf8")) as {
386-
dbscheme?: string;
387-
library?: boolean;
388-
};
389-
if (
390-
qlpack.dbscheme !== undefined &&
391-
basename(qlpack.dbscheme) === basename(dbschemePath)
392-
) {
393-
return {
394-
name: packName,
395-
isLibraryPack: qlpack.library === true,
396-
};
397-
}
398-
}
399-
}
400-
}
401-
throw new Error(`Could not find qlpack file for dbscheme ${dbschemePath}`);
402-
}
403-
404-
function findStandardQueryPack(
405-
qlpacks: QlpacksInfo,
406-
dbschemePackName: string,
407-
): string | undefined {
408-
const matches = dbschemePackName.match(/^codeql\/(?<language>[a-z]+)-all$/);
409-
if (matches) {
410-
const queryPackName = `codeql/${matches.groups!.language}-queries`;
411-
if (qlpacks[queryPackName] !== undefined) {
412-
return queryPackName;
413-
}
414-
}
415-
416-
// Either the dbscheme pack didn't look like one where the queries might be in the query pack, or
417-
// no query pack was found in the search path. Either is OK.
418-
return undefined;
419-
}
420-
421-
export async function getQlPackForDbscheme(
422-
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">,
423-
dbschemePath: string,
424-
): Promise<QlPacksForLanguage> {
425-
const qlpacks = await cliServer.resolveQlpacks(getOnDiskWorkspaceFolders());
426-
const packs: QlPackWithPath[] = Object.entries(qlpacks).map(
427-
([packName, dirs]) => {
428-
if (dirs.length < 1) {
429-
void extLogger.log(
430-
`In getQlPackFor ${dbschemePath}, qlpack ${packName} has no directories`,
431-
);
432-
return { packName, packDir: undefined };
433-
}
434-
if (dirs.length > 1) {
435-
void extLogger.log(
436-
`In getQlPackFor ${dbschemePath}, qlpack ${packName} has more than one directory; arbitrarily choosing the first`,
437-
);
438-
}
439-
return {
440-
packName,
441-
packDir: dirs[0],
442-
};
443-
},
444-
);
445-
const dbschemePack = await findDbschemePack(packs, dbschemePath);
446-
const queryPack = dbschemePack.isLibraryPack
447-
? findStandardQueryPack(qlpacks, dbschemePack.name)
448-
: undefined;
449-
return {
450-
dbschemePack: dbschemePack.name,
451-
dbschemePackIsLibraryPack: dbschemePack.isLibraryPack,
452-
queryPack,
453-
};
454-
}
455-
456-
export async function getPrimaryDbscheme(
457-
datasetFolder: string,
458-
): Promise<string> {
459-
const dbschemes = await glob("*.dbscheme", {
460-
cwd: datasetFolder,
461-
});
462-
463-
if (dbschemes.length < 1) {
464-
throw new Error(
465-
`Can't find dbscheme for current database in ${datasetFolder}`,
466-
);
467-
}
468-
469-
dbschemes.sort();
470-
const dbscheme = dbschemes[0];
471-
472-
if (dbschemes.length > 1) {
473-
void Window.showErrorMessage(
474-
`Found multiple dbschemes in ${datasetFolder} during quick query; arbitrarily choosing the first, ${dbscheme}, to decide what library to use.`,
475-
);
476-
}
477-
return dbscheme;
478-
}
479-
480356
/**
481357
* The following functions al heuristically determine metadata about databases.
482358
*/

extensions/ql-vscode/src/language-support/contextual/query-resolver.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { file } from "tmp-promise";
44
import { basename, dirname, resolve } from "path";
55

66
import {
7-
getPrimaryDbscheme,
8-
getQlPackForDbscheme,
97
getOnDiskWorkspaceFolders,
10-
QlPacksForLanguage,
118
showAndLogExceptionWithTelemetry,
129
} from "../../helpers";
10+
import {
11+
getPrimaryDbscheme,
12+
getQlPackForDbscheme,
13+
QlPacksForLanguage,
14+
} from "../../databases/qlpack";
1315
import {
1416
KeyType,
1517
kindOfKeyType,

extensions/ql-vscode/src/local-queries/quick-query.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@ import { CancellationToken, window as Window, workspace, Uri } from "vscode";
55
import { LSPErrorCodes, ResponseError } from "vscode-languageclient";
66
import { CodeQLCliServer } from "../codeql-cli/cli";
77
import { DatabaseUI } from "../databases/local-databases-ui";
8-
import {
9-
getInitialQueryContents,
10-
getPrimaryDbscheme,
11-
getQlPackForDbscheme,
12-
showBinaryChoiceDialog,
13-
} from "../helpers";
8+
import { getInitialQueryContents, showBinaryChoiceDialog } from "../helpers";
9+
import { getPrimaryDbscheme, getQlPackForDbscheme } from "../databases/qlpack";
1410
import {
1511
ProgressCallback,
1612
UserCancellationException,

extensions/ql-vscode/test/vscode-tests/cli-integration/run-cli.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import {
99
import { itWithCodeQL } from "../cli";
1010
import {
1111
getOnDiskWorkspaceFolders,
12-
getQlPackForDbscheme,
1312
languageToDbScheme,
1413
} from "../../../src/helpers";
1514
import { KeyType, resolveQueries } from "../../../src/language-support";
1615
import { faker } from "@faker-js/faker";
1716
import { getActivatedExtension } from "../global.helper";
1817
import { BaseLogger } from "../../../src/common";
18+
import { getQlPackForDbscheme } from "../../../src/databases/qlpack";
1919

2020
/**
2121
* Perform proper integration tests by running the CLI

extensions/ql-vscode/test/vscode-tests/no-workspace/language-support/contextual/query-resolver.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as fs from "fs-extra";
44
import { getErrorMessage } from "../../../../../src/pure/helpers-pure";
55

66
import * as helpers from "../../../../../src/helpers";
7+
import * as qlpack from "../../../../../src/databases/qlpack";
78
import {
89
KeyType,
910
qlpackOfDatabase,
@@ -14,10 +15,10 @@ import { mockDatabaseItem, mockedObject } from "../../../utils/mocking.helpers";
1415

1516
describe("queryResolver", () => {
1617
let getQlPackForDbschemeSpy: jest.SpiedFunction<
17-
typeof helpers.getQlPackForDbscheme
18+
typeof qlpack.getQlPackForDbscheme
1819
>;
1920
let getPrimaryDbschemeSpy: jest.SpiedFunction<
20-
typeof helpers.getPrimaryDbscheme
21+
typeof qlpack.getPrimaryDbscheme
2122
>;
2223

2324
const resolveQueriesInSuite = jest.fn();
@@ -28,13 +29,13 @@ describe("queryResolver", () => {
2829

2930
beforeEach(() => {
3031
getQlPackForDbschemeSpy = jest
31-
.spyOn(helpers, "getQlPackForDbscheme")
32+
.spyOn(qlpack, "getQlPackForDbscheme")
3233
.mockResolvedValue({
3334
dbschemePack: "dbschemePack",
3435
dbschemePackIsLibraryPack: false,
3536
});
3637
getPrimaryDbschemeSpy = jest
37-
.spyOn(helpers, "getPrimaryDbscheme")
38+
.spyOn(qlpack, "getPrimaryDbscheme")
3839
.mockResolvedValue("primaryDbscheme");
3940

4041
jest.spyOn(helpers, "getOnDiskWorkspaceFolders").mockReturnValue([]);

0 commit comments

Comments
 (0)