Merge pull request #2744 from github/starcke/general-setup
Move pack setup out of fetch queries.
This commit is contained in:
@@ -9,22 +9,16 @@ import { join } from "path";
|
||||
import { App } from "../common/app";
|
||||
import { withProgress } from "../common/vscode/progress";
|
||||
import { pickExtensionPack } from "./extension-pack-picker";
|
||||
import {
|
||||
showAndLogErrorMessage,
|
||||
showAndLogExceptionWithTelemetry,
|
||||
} from "../common/logging";
|
||||
import { showAndLogErrorMessage } from "../common/logging";
|
||||
import { dir } from "tmp-promise";
|
||||
import { fetchExternalApiQueries } from "./queries";
|
||||
import { telemetryListener } from "../common/vscode/telemetry";
|
||||
import { redactableError } from "../common/errors";
|
||||
import { extLogger } from "../common/logging/vscode";
|
||||
|
||||
import { isQueryLanguage } from "../common/query-language";
|
||||
import { setUpPack } from "./external-api-usage-queries";
|
||||
import { DisposableObject } from "../common/disposable-object";
|
||||
import { ModelDetailsPanel } from "./methods-usage/methods-usage-panel";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { showResolvableLocation } from "../databases/local-databases/locations";
|
||||
import { Usage } from "./external-api-usage";
|
||||
import { setUpPack } from "./data-extensions-editor-queries";
|
||||
|
||||
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
|
||||
|
||||
@@ -138,19 +132,12 @@ export class DataExtensionsEditorModule extends DisposableObject {
|
||||
return;
|
||||
}
|
||||
|
||||
const query = fetchExternalApiQueries[language];
|
||||
if (!query) {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
extLogger,
|
||||
telemetryListener,
|
||||
redactableError`No external API usage query found for language ${language}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new temporary directory for query files and pack dependencies
|
||||
const queryDir = (await dir({ unsafeCleanup: true })).path;
|
||||
await setUpPack(queryDir, query, language);
|
||||
const success = await setUpPack(queryDir, language);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
await this.cliServer.packInstall(queryDir);
|
||||
|
||||
const view = new DataExtensionsEditorView(
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { join } from "path";
|
||||
import { QueryLanguage } from "../common/query-language";
|
||||
import { writeFile } from "fs-extra";
|
||||
import { dump } from "js-yaml";
|
||||
import { prepareExternalApiQuery } from "./external-api-usage-queries";
|
||||
|
||||
/**
|
||||
* setUpPack sets up a directory to use for the data extension editor queries.
|
||||
* @param queryDir The directory to set up.
|
||||
* @param language The language to use for the queries.
|
||||
* @returns true if the setup was successful, false otherwise.
|
||||
*/
|
||||
export async function setUpPack(
|
||||
queryDir: string,
|
||||
language: QueryLanguage,
|
||||
): Promise<boolean> {
|
||||
// Create the external API query
|
||||
const externalApiQuerySuccess = await prepareExternalApiQuery(
|
||||
queryDir,
|
||||
language,
|
||||
);
|
||||
if (!externalApiQuerySuccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up a synthetic query pack to resolve dependencies.
|
||||
const syntheticQueryPack = {
|
||||
name: "codeql/external-api-usage",
|
||||
version: "0.0.0",
|
||||
dependencies: {
|
||||
[`codeql/${language}-all`]: "*",
|
||||
},
|
||||
};
|
||||
|
||||
const qlpackFile = join(queryDir, "codeql-pack.yml");
|
||||
await writeFile(qlpackFile, dump(syntheticQueryPack), "utf8");
|
||||
return true;
|
||||
}
|
||||
@@ -12,9 +12,8 @@ import { telemetryListener } from "../common/vscode/telemetry";
|
||||
import { join } from "path";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { writeFile } from "fs-extra";
|
||||
import { Query } from "./queries/query";
|
||||
import { QueryLanguage } from "../common/query-language";
|
||||
import { dump } from "js-yaml";
|
||||
import { fetchExternalApiQueries } from "./queries";
|
||||
|
||||
type RunQueryOptions = {
|
||||
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">;
|
||||
@@ -27,36 +26,34 @@ type RunQueryOptions = {
|
||||
token: CancellationToken;
|
||||
};
|
||||
|
||||
export async function setUpPack(
|
||||
export async function prepareExternalApiQuery(
|
||||
queryDir: string,
|
||||
query: Query,
|
||||
language: QueryLanguage,
|
||||
) {
|
||||
Object.values(Mode).map(async (mode) => {
|
||||
const queryFile = join(
|
||||
queryDir,
|
||||
`FetchExternalApis${mode.charAt(0).toUpperCase() + mode.slice(1)}Mode.ql`,
|
||||
): Promise<boolean> {
|
||||
// Resolve the query that we want to run.
|
||||
const query = fetchExternalApiQueries[language];
|
||||
if (!query) {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
extLogger,
|
||||
telemetryListener,
|
||||
redactableError`No external API usage query found for language ${language}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// Create the query file.
|
||||
Object.values(Mode).map(async (mode) => {
|
||||
const queryFile = join(queryDir, queryNameFromMode(mode));
|
||||
await writeFile(queryFile, query[`${mode}ModeQuery`], "utf8");
|
||||
});
|
||||
|
||||
// Create any dependencies
|
||||
if (query.dependencies) {
|
||||
for (const [filename, contents] of Object.entries(query.dependencies)) {
|
||||
const dependencyFile = join(queryDir, filename);
|
||||
await writeFile(dependencyFile, contents, "utf8");
|
||||
}
|
||||
}
|
||||
|
||||
const syntheticQueryPack = {
|
||||
name: "codeql/external-api-usage",
|
||||
version: "0.0.0",
|
||||
dependencies: {
|
||||
[`codeql/${language}-all`]: "*",
|
||||
},
|
||||
};
|
||||
|
||||
const qlpackFile = join(queryDir, "codeql-pack.yml");
|
||||
await writeFile(qlpackFile, dump(syntheticQueryPack), "utf8");
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function runQuery(
|
||||
@@ -145,3 +142,9 @@ export async function readQueryResults({
|
||||
|
||||
return cliServer.bqrsDecode(bqrsPath, resultSet.name);
|
||||
}
|
||||
|
||||
function queryNameFromMode(mode: Mode): string {
|
||||
return `FetchExternalApis${
|
||||
mode.charAt(0).toUpperCase() + mode.slice(1)
|
||||
}Mode.ql`;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { readFile, readFileSync, readdir } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { load } from "js-yaml";
|
||||
import { setUpPack } from "../../../../src/data-extensions-editor/data-extensions-editor-queries";
|
||||
import { dirSync } from "tmp-promise";
|
||||
import { fetchExternalApiQueries } from "../../../../src/data-extensions-editor/queries";
|
||||
import { QueryLanguage } from "../../../../src/common/query-language";
|
||||
import { Mode } from "../../../../src/data-extensions-editor/shared/mode";
|
||||
|
||||
describe("setUpPack", () => {
|
||||
const languages = Object.keys(fetchExternalApiQueries).flatMap((lang) => {
|
||||
const queryDir = dirSync({ unsafeCleanup: true }).name;
|
||||
const query = fetchExternalApiQueries[lang as QueryLanguage];
|
||||
if (!query) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return { language: lang as QueryLanguage, queryDir, query };
|
||||
});
|
||||
|
||||
test.each(languages)(
|
||||
"should create files for $language",
|
||||
async ({ language, queryDir, query }) => {
|
||||
await setUpPack(queryDir, language);
|
||||
|
||||
const queryFiles = await readdir(queryDir);
|
||||
expect(queryFiles.sort()).toEqual(
|
||||
[
|
||||
"codeql-pack.yml",
|
||||
"FetchExternalApisApplicationMode.ql",
|
||||
"FetchExternalApisFrameworkMode.ql",
|
||||
"AutomodelVsCode.qll",
|
||||
].sort(),
|
||||
);
|
||||
|
||||
const suiteFileContents = await readFile(
|
||||
join(queryDir, "codeql-pack.yml"),
|
||||
"utf8",
|
||||
);
|
||||
const suiteYaml = load(suiteFileContents);
|
||||
expect(suiteYaml).toEqual({
|
||||
name: "codeql/external-api-usage",
|
||||
version: "0.0.0",
|
||||
dependencies: {
|
||||
[`codeql/${language}-all`]: "*",
|
||||
},
|
||||
});
|
||||
|
||||
Object.values(Mode).forEach((mode) => {
|
||||
expect(
|
||||
readFileSync(
|
||||
join(
|
||||
queryDir,
|
||||
`FetchExternalApis${
|
||||
mode.charAt(0).toUpperCase() + mode.slice(1)
|
||||
}Mode.ql`,
|
||||
),
|
||||
"utf8",
|
||||
),
|
||||
).toEqual(query[`${mode}ModeQuery`]);
|
||||
});
|
||||
|
||||
for (const [filename, contents] of Object.entries(
|
||||
query.dependencies ?? {},
|
||||
)) {
|
||||
expect(await readFile(join(queryDir, filename), "utf8")).toEqual(
|
||||
contents,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
readQueryResults,
|
||||
runQuery,
|
||||
setUpPack,
|
||||
} from "../../../../src/data-extensions-editor/external-api-usage-queries";
|
||||
import { createMockLogger } from "../../../__mocks__/loggerMock";
|
||||
import { DatabaseKind } from "../../../../src/databases/local-databases";
|
||||
@@ -14,75 +13,8 @@ import { showAndLogExceptionWithTelemetry } from "../../../../src/common/logging
|
||||
import { QueryLanguage } from "../../../../src/common/query-language";
|
||||
import { mockedUri } from "../../utils/mocking.helpers";
|
||||
import { Mode } from "../../../../src/data-extensions-editor/shared/mode";
|
||||
import { readFile, readFileSync, readdir } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { load } from "js-yaml";
|
||||
|
||||
describe("external api usage query", () => {
|
||||
describe("setUpPack", () => {
|
||||
const languages = Object.keys(fetchExternalApiQueries).flatMap((lang) => {
|
||||
const queryDir = dirSync({ unsafeCleanup: true }).name;
|
||||
const query = fetchExternalApiQueries[lang as QueryLanguage];
|
||||
if (!query) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return { language: lang as QueryLanguage, queryDir, query };
|
||||
});
|
||||
|
||||
test.each(languages)(
|
||||
"should create files for $language",
|
||||
async ({ language, queryDir, query }) => {
|
||||
await setUpPack(queryDir, query, language);
|
||||
|
||||
const queryFiles = await readdir(queryDir);
|
||||
expect(queryFiles.sort()).toEqual(
|
||||
[
|
||||
"codeql-pack.yml",
|
||||
"FetchExternalApisApplicationMode.ql",
|
||||
"FetchExternalApisFrameworkMode.ql",
|
||||
"AutomodelVsCode.qll",
|
||||
].sort(),
|
||||
);
|
||||
|
||||
const suiteFileContents = await readFile(
|
||||
join(queryDir, "codeql-pack.yml"),
|
||||
"utf8",
|
||||
);
|
||||
const suiteYaml = load(suiteFileContents);
|
||||
expect(suiteYaml).toEqual({
|
||||
name: "codeql/external-api-usage",
|
||||
version: "0.0.0",
|
||||
dependencies: {
|
||||
[`codeql/${language}-all`]: "*",
|
||||
},
|
||||
});
|
||||
|
||||
Object.values(Mode).forEach((mode) => {
|
||||
expect(
|
||||
readFileSync(
|
||||
join(
|
||||
queryDir,
|
||||
`FetchExternalApis${
|
||||
mode.charAt(0).toUpperCase() + mode.slice(1)
|
||||
}Mode.ql`,
|
||||
),
|
||||
"utf8",
|
||||
),
|
||||
).toEqual(query[`${mode}ModeQuery`]);
|
||||
});
|
||||
|
||||
for (const [filename, contents] of Object.entries(
|
||||
query.dependencies ?? {},
|
||||
)) {
|
||||
expect(await readFile(join(queryDir, filename), "utf8")).toEqual(
|
||||
contents,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("runQuery", () => {
|
||||
const language = Object.keys(fetchExternalApiQueries)[
|
||||
Math.floor(Math.random() * Object.keys(fetchExternalApiQueries).length)
|
||||
|
||||
Reference in New Issue
Block a user