Extract getQlPackLanguage function
This commit is contained in:
Родитель
c14fa63321
Коммит
e81f1a1fde
|
@ -0,0 +1,30 @@
|
|||
import { load } from "js-yaml";
|
||||
import { readFile } from "fs-extra";
|
||||
import { QlPackFile } from "../packaging/qlpack-file";
|
||||
import { QueryLanguage } from "./query-language";
|
||||
|
||||
/**
|
||||
* @param qlpackPath The path to the `qlpack.yml` or `codeql-pack.yml` file.
|
||||
* @return the language of the given qlpack file, or undefined if the file is
|
||||
* not a valid qlpack file or does not contain exactly one language.
|
||||
*/
|
||||
export async function getQlPackLanguage(
|
||||
qlpackPath: string,
|
||||
): Promise<QueryLanguage | undefined> {
|
||||
const qlPack = load(await readFile(qlpackPath, "utf8")) as
|
||||
| QlPackFile
|
||||
| undefined;
|
||||
const dependencies = qlPack?.dependencies;
|
||||
if (!dependencies || typeof dependencies !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
const matchingLanguages = Object.values(QueryLanguage).filter(
|
||||
(language) => `codeql/${language}-all` in dependencies,
|
||||
);
|
||||
if (matchingLanguages.length !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return matchingLanguages[0];
|
||||
}
|
|
@ -28,7 +28,7 @@ import {
|
|||
isCodespacesTemplate,
|
||||
setQlPackLocation,
|
||||
} from "../config";
|
||||
import { lstat, pathExists, readFile } from "fs-extra";
|
||||
import { lstat, pathExists } from "fs-extra";
|
||||
import { askForLanguage } from "../codeql-cli/query-language";
|
||||
import { showInformationMessageWithAction } from "../common/vscode/dialog";
|
||||
import { redactableError } from "../common/errors";
|
||||
|
@ -36,8 +36,7 @@ import { App } from "../common/app";
|
|||
import { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
|
||||
import { containsPath, pathsEqual } from "../common/files";
|
||||
import { getQlPackPath } from "../common/ql";
|
||||
import { load } from "js-yaml";
|
||||
import { QlPackFile } from "../packaging/qlpack-file";
|
||||
import { getQlPackLanguage } from "../common/qlpack-language";
|
||||
|
||||
type QueryLanguagesToDatabaseMap = Record<string, string>;
|
||||
|
||||
|
@ -253,24 +252,12 @@ export class SkeletonQueryWizard {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const qlPack = load(await readFile(qlPackPath, "utf8")) as
|
||||
| QlPackFile
|
||||
| undefined;
|
||||
const dependencies = qlPack?.dependencies;
|
||||
if (!dependencies || typeof dependencies !== "object") {
|
||||
return;
|
||||
const language = await getQlPackLanguage(qlPackPath);
|
||||
if (language) {
|
||||
this.qlPackStoragePath = matchingQueryPackPath;
|
||||
}
|
||||
|
||||
const matchingLanguages = Object.values(QueryLanguage).filter(
|
||||
(language) => `codeql/${language}-all` in dependencies,
|
||||
);
|
||||
if (matchingLanguages.length !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
this.qlPackStoragePath = matchingQueryPackPath;
|
||||
|
||||
return matchingLanguages[0];
|
||||
return language;
|
||||
}
|
||||
|
||||
private async chooseLanguage() {
|
||||
|
|
|
@ -4,9 +4,7 @@ import { QueryLanguage } from "../common/query-language";
|
|||
import { FALLBACK_QLPACK_FILENAME, QLPACK_FILENAMES } from "../common/ql";
|
||||
import { FilePathDiscovery } from "../common/vscode/file-path-discovery";
|
||||
import { containsPath } from "../common/files";
|
||||
import { load } from "js-yaml";
|
||||
import { readFile } from "fs-extra";
|
||||
import { QlPackFile } from "../packaging/qlpack-file";
|
||||
import { getQlPackLanguage } from "../common/qlpack-language";
|
||||
|
||||
interface QueryPack {
|
||||
path: string;
|
||||
|
@ -71,32 +69,13 @@ export class QueryPackDiscovery extends FilePathDiscovery<QueryPack> {
|
|||
protected async getDataForPath(path: string): Promise<QueryPack> {
|
||||
let language: QueryLanguage | undefined;
|
||||
try {
|
||||
language = await this.determinePackLanguage(path);
|
||||
language = await getQlPackLanguage(path);
|
||||
} catch (e) {
|
||||
language = undefined;
|
||||
}
|
||||
return { path, language };
|
||||
}
|
||||
|
||||
private async determinePackLanguage(
|
||||
path: string,
|
||||
): Promise<QueryLanguage | undefined> {
|
||||
const qlPack = load(await readFile(path, "utf8")) as QlPackFile | undefined;
|
||||
const dependencies = qlPack?.dependencies;
|
||||
if (!dependencies || typeof dependencies !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
const matchingLanguages = Object.values(QueryLanguage).filter(
|
||||
(language) => `codeql/${language}-all` in dependencies,
|
||||
);
|
||||
if (matchingLanguages.length !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return matchingLanguages[0];
|
||||
}
|
||||
|
||||
protected pathIsRelevant(path: string): boolean {
|
||||
return QLPACK_FILENAMES.includes(basename(path));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
import { join } from "path";
|
||||
import { dirSync } from "tmp-promise";
|
||||
import { DirResult } from "tmp";
|
||||
import { outputFile } from "fs-extra";
|
||||
import { dump } from "js-yaml";
|
||||
import { QueryLanguage } from "../../../src/common/query-language";
|
||||
import { getQlPackLanguage } from "../../../src/common/qlpack-language";
|
||||
|
||||
describe("getQlPackLanguage", () => {
|
||||
let tmpDir: DirResult;
|
||||
let qlpackPath: string;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = dirSync({
|
||||
prefix: "queries_",
|
||||
keep: false,
|
||||
unsafeCleanup: true,
|
||||
});
|
||||
|
||||
qlpackPath = join(tmpDir.name, "qlpack.yml");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
tmpDir.removeCallback();
|
||||
});
|
||||
|
||||
it.each(Object.values(QueryLanguage))(
|
||||
"should find a single language %s",
|
||||
async (language) => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
dependencies: {
|
||||
[`codeql/${language}-all`]: "^0.7.0",
|
||||
"my-custom-pack/test": "${workspace}",
|
||||
},
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(language);
|
||||
},
|
||||
);
|
||||
|
||||
it("should find nothing when there is no dependencies key", async () => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should find nothing when the dependencies are empty", async () => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
dependencies: {},
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should find nothing when dependencies is a scalar", async () => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
dependencies: "codeql/java-all",
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should find nothing when dependencies is an array", async () => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
dependencies: ["codeql/java-all"],
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should find nothing when there are no matching dependencies", async () => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
dependencies: {
|
||||
"codeql/java-queries": "*",
|
||||
"github/my-test-query-pack": "*",
|
||||
},
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should find nothing when there are multiple matching dependencies", async () => {
|
||||
await writeYAML(qlpackPath, {
|
||||
name: "test",
|
||||
dependencies: {
|
||||
"codeql/java-all": "*",
|
||||
"codeql/csharp-all": "*",
|
||||
},
|
||||
});
|
||||
|
||||
const result = await getQlPackLanguage(qlpackPath);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should throw when the file does not exist", async () => {
|
||||
await expect(getQlPackLanguage(qlpackPath)).rejects.toBeDefined();
|
||||
});
|
||||
|
||||
it("should throw when reading a directory", async () => {
|
||||
await expect(getQlPackLanguage(tmpDir.name)).rejects.toBeDefined();
|
||||
});
|
||||
|
||||
it("should throw when the file is invalid YAML", async () => {
|
||||
await outputFile(qlpackPath, `name: test\n foo: bar`);
|
||||
|
||||
await expect(getQlPackLanguage(tmpDir.name)).rejects.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
async function writeYAML(path: string, yaml: unknown): Promise<void> {
|
||||
await outputFile(path, dump(yaml), "utf-8");
|
||||
}
|
Загрузка…
Ссылка в новой задаче