Skip to content

Commit 2122737

Browse files
authored
Merge pull request #2054 from github/koesie10/codeql-pack-yml
Handle `codeql-pack.yml` files everywhere
2 parents c71238c + 752b6a7 commit 2122737

7 files changed

Lines changed: 112 additions & 30 deletions

File tree

extensions/ql-vscode/src/contextual/queryResolver.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { CancellationToken, Uri } from "vscode";
1919
import { ProgressCallback } from "../commandRunner";
2020
import { QueryRunner } from "../queryRunner";
2121
import { redactableError } from "../pure/errors";
22+
import { QLPACK_FILENAMES } from "../pure/ql";
2223

2324
export async function qlpackOfDatabase(
2425
cli: CodeQLCliServer,
@@ -113,7 +114,7 @@ async function resolveContextualQuery(
113114
// Work out the enclosing pack.
114115
const packContents = await cli.packPacklist(query, false);
115116
const packFilePath = packContents.find((p) =>
116-
["codeql-pack.yml", "qlpack.yml"].includes(basename(p)),
117+
QLPACK_FILENAMES.includes(basename(p)),
117118
);
118119
if (packFilePath === undefined) {
119120
// Should not happen; we already resolved this query.

extensions/ql-vscode/src/extension.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,7 @@ async function activateWithInstalledDistribution(
845845
documentSelector: [
846846
{ language: "ql", scheme: "file" },
847847
{ language: "yaml", scheme: "file", pattern: "**/qlpack.yml" },
848+
{ language: "yaml", scheme: "file", pattern: "**/codeql-pack.yml" },
848849
],
849850
synchronize: {
850851
configurationSection: "codeQL",

extensions/ql-vscode/src/helpers.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { extLogger, OutputChannelLogger } from "./common";
2323
import { QueryMetadata } from "./pure/interface-types";
2424
import { telemetryListener } from "./telemetry";
2525
import { RedactableError } from "./pure/errors";
26+
import { getQlPackPath } from "./pure/ql";
2627

2728
// Shared temporary folder for the extension.
2829
export const tmpDir = dirSync({
@@ -387,17 +388,22 @@ async function findDbschemePack(
387388
): Promise<{ name: string; isLibraryPack: boolean }> {
388389
for (const { packDir, packName } of packs) {
389390
if (packDir !== undefined) {
390-
const qlpack = load(
391-
await readFile(join(packDir, "qlpack.yml"), "utf8"),
392-
) as { dbscheme?: string; library?: boolean };
393-
if (
394-
qlpack.dbscheme !== undefined &&
395-
basename(qlpack.dbscheme) === basename(dbschemePath)
396-
) {
397-
return {
398-
name: packName,
399-
isLibraryPack: qlpack.library === true,
391+
const qlpackPath = await getQlPackPath(packDir);
392+
393+
if (qlpackPath !== undefined) {
394+
const qlpack = load(await readFile(qlpackPath, "utf8")) as {
395+
dbscheme?: string;
396+
library?: boolean;
400397
};
398+
if (
399+
qlpack.dbscheme !== undefined &&
400+
basename(qlpack.dbscheme) === basename(dbschemePath)
401+
) {
402+
return {
403+
name: packName,
404+
isLibraryPack: qlpack.library === true,
405+
};
406+
}
401407
}
402408
}
403409
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { join } from "path";
2+
import { pathExists } from "fs-extra";
3+
4+
export const QLPACK_FILENAMES = ["qlpack.yml", "codeql-pack.yml"];
5+
export const FALLBACK_QLPACK_FILENAME = QLPACK_FILENAMES[0];
6+
7+
export async function getQlPackPath(
8+
packRoot: string,
9+
): Promise<string | undefined> {
10+
for (const filename of QLPACK_FILENAMES) {
11+
const path = join(packRoot, filename);
12+
13+
if (await pathExists(path)) {
14+
return path;
15+
}
16+
}
17+
18+
return undefined;
19+
}

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
} from "./helpers";
2020
import { ProgressCallback, UserCancellationException } from "./commandRunner";
2121
import { getErrorMessage } from "./pure/helpers-pure";
22+
import { FALLBACK_QLPACK_FILENAME, getQlPackPath } from "./pure/ql";
2223

2324
const QUICK_QUERIES_DIR_NAME = "quick-queries";
2425
const QUICK_QUERY_QUERY_NAME = "quick-query.ql";
@@ -112,7 +113,7 @@ export async function displayQuickQuery(
112113
const dbscheme = await getPrimaryDbscheme(datasetFolder);
113114
const qlpack = (await getQlPackForDbscheme(cliServer, dbscheme))
114115
.dbschemePack;
115-
const qlPackFile = join(queriesDir, "qlpack.yml");
116+
const qlPackFile = await getQlPackPath(queriesDir);
116117
const qlFile = join(queriesDir, QUICK_QUERY_QUERY_NAME);
117118
const shouldRewrite = await checkShouldRewrite(qlPackFile, qlpack);
118119

@@ -126,7 +127,7 @@ export async function displayQuickQuery(
126127
},
127128
};
128129
await writeFile(
129-
qlPackFile,
130+
qlPackFile ?? join(queriesDir, FALLBACK_QLPACK_FILENAME),
130131
QLPACK_FILE_HEADER + dump(quickQueryQlpackYaml),
131132
"utf8",
132133
);
@@ -158,7 +159,13 @@ export async function displayQuickQuery(
158159
}
159160
}
160161

161-
async function checkShouldRewrite(qlPackFile: string, newDependency: string) {
162+
async function checkShouldRewrite(
163+
qlPackFile: string | undefined,
164+
newDependency: string,
165+
) {
166+
if (!qlPackFile) {
167+
return true;
168+
}
162169
if (!(await pathExists(qlPackFile))) {
163170
return true;
164171
}

extensions/ql-vscode/src/remote-queries/run-remote-query.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { CancellationToken, Uri, window } from "vscode";
22
import { relative, join, sep, dirname, parse, basename } from "path";
33
import { dump, load } from "js-yaml";
4-
import { pathExists, copy, writeFile, readFile, mkdirp } from "fs-extra";
4+
import { copy, writeFile, readFile, mkdirp } from "fs-extra";
55
import { dir, tmpName } from "tmp-promise";
66
import {
77
askForLanguage,
@@ -30,6 +30,11 @@ import {
3030
} from "./repository-selection";
3131
import { Repository } from "./shared/repository";
3232
import { DbManager } from "../databases/db-manager";
33+
import {
34+
getQlPackPath,
35+
FALLBACK_QLPACK_FILENAME,
36+
QLPACK_FILENAMES,
37+
} from "../pure/ql";
3338

3439
export interface QlPack {
3540
name: string;
@@ -67,7 +72,7 @@ async function generateQueryPack(
6772
const targetQueryFileName = join(queryPackDir, packRelativePath);
6873

6974
let language: string | undefined;
70-
if (await getExistingPackFile(originalPackRoot)) {
75+
if (await getQlPackPath(originalPackRoot)) {
7176
// don't include ql files. We only want the queryFile to be copied.
7277
const toCopy = await cliServer.packPacklist(originalPackRoot, false);
7378

@@ -120,7 +125,10 @@ async function generateQueryPack(
120125
},
121126
defaultSuite: generateDefaultSuite(packRelativePath),
122127
};
123-
await writeFile(join(queryPackDir, "qlpack.yml"), dump(syntheticQueryPack));
128+
await writeFile(
129+
join(queryPackDir, FALLBACK_QLPACK_FILENAME),
130+
dump(syntheticQueryPack),
131+
);
124132
}
125133
if (!language) {
126134
throw new UserCancellationException("Could not determine language.");
@@ -163,7 +171,7 @@ async function generateQueryPack(
163171
async function findPackRoot(queryFile: string): Promise<string> {
164172
// recursively find the directory containing qlpack.yml
165173
let dir = dirname(queryFile);
166-
while (!(await getExistingPackFile(dir))) {
174+
while (!(await getQlPackPath(dir))) {
167175
dir = dirname(dir);
168176
if (isFileSystemRoot(dir)) {
169177
// there is no qlpack.yml in this directory or any parent directory.
@@ -175,16 +183,6 @@ async function findPackRoot(queryFile: string): Promise<string> {
175183
return dir;
176184
}
177185

178-
async function getExistingPackFile(dir: string) {
179-
if (await pathExists(join(dir, "qlpack.yml"))) {
180-
return join(dir, "qlpack.yml");
181-
}
182-
if (await pathExists(join(dir, "codeql-pack.yml"))) {
183-
return join(dir, "codeql-pack.yml");
184-
}
185-
return undefined;
186-
}
187-
188186
function isFileSystemRoot(dir: string): boolean {
189187
const pathObj = parse(dir);
190188
return pathObj.root === dir && pathObj.base === "";
@@ -319,12 +317,14 @@ async function fixPackFile(
319317
queryPackDir: string,
320318
packRelativePath: string,
321319
): Promise<void> {
322-
const packPath = await getExistingPackFile(queryPackDir);
320+
const packPath = await getQlPackPath(queryPackDir);
323321

324322
// This should not happen since we create the pack ourselves.
325323
if (!packPath) {
326324
throw new Error(
327-
`Could not find qlpack.yml or codeql-pack.yml file in '${queryPackDir}'`,
325+
`Could not find ${QLPACK_FILENAMES.join(
326+
" or ",
327+
)} file in '${queryPackDir}'`,
328328
);
329329
}
330330
const qlpack = load(await readFile(packPath, "utf8")) as QlPack;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { join } from "path";
2+
import { dirSync } from "tmp-promise";
3+
import { DirResult } from "tmp";
4+
import { writeFile } from "fs-extra";
5+
import { getQlPackPath } from "../../../src/pure/ql";
6+
7+
describe("getQlPackPath", () => {
8+
let tmpDir: DirResult;
9+
10+
beforeEach(() => {
11+
tmpDir = dirSync({
12+
prefix: "queries_",
13+
keep: false,
14+
unsafeCleanup: true,
15+
});
16+
});
17+
18+
afterEach(() => {
19+
tmpDir.removeCallback();
20+
});
21+
22+
it("should find a qlpack.yml when it exists", async () => {
23+
await writeFile(join(tmpDir.name, "qlpack.yml"), "name: test");
24+
25+
const result = await getQlPackPath(tmpDir.name);
26+
expect(result).toEqual(join(tmpDir.name, "qlpack.yml"));
27+
});
28+
29+
it("should find a codeql-pack.yml when it exists", async () => {
30+
await writeFile(join(tmpDir.name, "codeql-pack.yml"), "name: test");
31+
32+
const result = await getQlPackPath(tmpDir.name);
33+
expect(result).toEqual(join(tmpDir.name, "codeql-pack.yml"));
34+
});
35+
36+
it("should find a qlpack.yml when both exist", async () => {
37+
await writeFile(join(tmpDir.name, "qlpack.yml"), "name: test");
38+
await writeFile(join(tmpDir.name, "codeql-pack.yml"), "name: test");
39+
40+
const result = await getQlPackPath(tmpDir.name);
41+
expect(result).toEqual(join(tmpDir.name, "qlpack.yml"));
42+
});
43+
44+
it("should find nothing when it doesn't exist", async () => {
45+
const result = await getQlPackPath(tmpDir.name);
46+
expect(result).toEqual(undefined);
47+
});
48+
});

0 commit comments

Comments
 (0)