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 { App } from "../common/app";
|
||||||
import { withProgress } from "../common/vscode/progress";
|
import { withProgress } from "../common/vscode/progress";
|
||||||
import { pickExtensionPack } from "./extension-pack-picker";
|
import { pickExtensionPack } from "./extension-pack-picker";
|
||||||
import {
|
import { showAndLogErrorMessage } from "../common/logging";
|
||||||
showAndLogErrorMessage,
|
|
||||||
showAndLogExceptionWithTelemetry,
|
|
||||||
} from "../common/logging";
|
|
||||||
import { dir } from "tmp-promise";
|
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 { isQueryLanguage } from "../common/query-language";
|
||||||
import { setUpPack } from "./external-api-usage-queries";
|
|
||||||
import { DisposableObject } from "../common/disposable-object";
|
import { DisposableObject } from "../common/disposable-object";
|
||||||
import { ModelDetailsPanel } from "./methods-usage/methods-usage-panel";
|
import { ModelDetailsPanel } from "./methods-usage/methods-usage-panel";
|
||||||
import { Mode } from "./shared/mode";
|
import { Mode } from "./shared/mode";
|
||||||
import { showResolvableLocation } from "../databases/local-databases/locations";
|
import { showResolvableLocation } from "../databases/local-databases/locations";
|
||||||
import { Usage } from "./external-api-usage";
|
import { Usage } from "./external-api-usage";
|
||||||
|
import { setUpPack } from "./data-extensions-editor-queries";
|
||||||
|
|
||||||
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
|
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
|
||||||
|
|
||||||
@@ -138,19 +132,12 @@ export class DataExtensionsEditorModule extends DisposableObject {
|
|||||||
return;
|
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
|
// Create new temporary directory for query files and pack dependencies
|
||||||
const queryDir = (await dir({ unsafeCleanup: true })).path;
|
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);
|
await this.cliServer.packInstall(queryDir);
|
||||||
|
|
||||||
const view = new DataExtensionsEditorView(
|
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 { join } from "path";
|
||||||
import { Mode } from "./shared/mode";
|
import { Mode } from "./shared/mode";
|
||||||
import { writeFile } from "fs-extra";
|
import { writeFile } from "fs-extra";
|
||||||
import { Query } from "./queries/query";
|
|
||||||
import { QueryLanguage } from "../common/query-language";
|
import { QueryLanguage } from "../common/query-language";
|
||||||
import { dump } from "js-yaml";
|
import { fetchExternalApiQueries } from "./queries";
|
||||||
|
|
||||||
type RunQueryOptions = {
|
type RunQueryOptions = {
|
||||||
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">;
|
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">;
|
||||||
@@ -27,36 +26,34 @@ type RunQueryOptions = {
|
|||||||
token: CancellationToken;
|
token: CancellationToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function setUpPack(
|
export async function prepareExternalApiQuery(
|
||||||
queryDir: string,
|
queryDir: string,
|
||||||
query: Query,
|
|
||||||
language: QueryLanguage,
|
language: QueryLanguage,
|
||||||
) {
|
): Promise<boolean> {
|
||||||
Object.values(Mode).map(async (mode) => {
|
// Resolve the query that we want to run.
|
||||||
const queryFile = join(
|
const query = fetchExternalApiQueries[language];
|
||||||
queryDir,
|
if (!query) {
|
||||||
`FetchExternalApis${mode.charAt(0).toUpperCase() + mode.slice(1)}Mode.ql`,
|
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");
|
await writeFile(queryFile, query[`${mode}ModeQuery`], "utf8");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create any dependencies
|
||||||
if (query.dependencies) {
|
if (query.dependencies) {
|
||||||
for (const [filename, contents] of Object.entries(query.dependencies)) {
|
for (const [filename, contents] of Object.entries(query.dependencies)) {
|
||||||
const dependencyFile = join(queryDir, filename);
|
const dependencyFile = join(queryDir, filename);
|
||||||
await writeFile(dependencyFile, contents, "utf8");
|
await writeFile(dependencyFile, contents, "utf8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runQuery(
|
export async function runQuery(
|
||||||
@@ -145,3 +142,9 @@ export async function readQueryResults({
|
|||||||
|
|
||||||
return cliServer.bqrsDecode(bqrsPath, resultSet.name);
|
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 {
|
import {
|
||||||
readQueryResults,
|
readQueryResults,
|
||||||
runQuery,
|
runQuery,
|
||||||
setUpPack,
|
|
||||||
} from "../../../../src/data-extensions-editor/external-api-usage-queries";
|
} from "../../../../src/data-extensions-editor/external-api-usage-queries";
|
||||||
import { createMockLogger } from "../../../__mocks__/loggerMock";
|
import { createMockLogger } from "../../../__mocks__/loggerMock";
|
||||||
import { DatabaseKind } from "../../../../src/databases/local-databases";
|
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 { QueryLanguage } from "../../../../src/common/query-language";
|
||||||
import { mockedUri } from "../../utils/mocking.helpers";
|
import { mockedUri } from "../../utils/mocking.helpers";
|
||||||
import { Mode } from "../../../../src/data-extensions-editor/shared/mode";
|
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("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", () => {
|
describe("runQuery", () => {
|
||||||
const language = Object.keys(fetchExternalApiQueries)[
|
const language = Object.keys(fetchExternalApiQueries)[
|
||||||
Math.floor(Math.random() * Object.keys(fetchExternalApiQueries).length)
|
Math.floor(Math.random() * Object.keys(fetchExternalApiQueries).length)
|
||||||
|
|||||||
Reference in New Issue
Block a user