Merge branch 'main' into robertbrignull/use_app_commands_3

This commit is contained in:
Robert
2023-03-24 11:41:16 +00:00
29 changed files with 1149 additions and 375 deletions

View File

@@ -199,6 +199,7 @@ jobs:
run: echo "cli-versions=$(cat ./extensions/ql-vscode/supported_cli_versions.json | jq -rc)" >> $GITHUB_OUTPUT
outputs:
cli-versions: ${{ steps.set-variables.outputs.cli-versions }}
cli-test:
name: CLI Test
runs-on: ${{ matrix.os }}

File diff suppressed because it is too large Load Diff

View File

@@ -1441,12 +1441,11 @@
"classnames": "~2.2.6",
"d3": "^7.6.1",
"d3-graphviz": "^5.0.2",
"fs-extra": "^10.0.1",
"glob-promise": "^6.0.2",
"fs-extra": "^11.1.1",
"immutable": "^4.0.0",
"js-yaml": "^4.1.0",
"minimist": "~1.2.6",
"msw": "^0.49.0",
"msw": "^1.2.0",
"nanoid": "^3.2.0",
"node-fetch": "~2.6.7",
"p-queue": "^6.0.0",
@@ -1492,8 +1491,7 @@
"@types/d3": "^7.4.0",
"@types/d3-graphviz": "^2.6.6",
"@types/del": "^4.0.0",
"@types/fs-extra": "^9.0.6",
"@types/glob": "^7.1.1",
"@types/fs-extra": "^11.0.1",
"@types/google-protobuf": "^3.2.7",
"@types/gulp": "^4.0.9",
"@types/gulp-replace": "^1.1.0",
@@ -1539,7 +1537,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-storybook": "^0.6.4",
"file-loader": "^6.2.0",
"glob": "^7.1.4",
"glob": "^9.3.2",
"gulp": "^4.0.2",
"gulp-esbuild": "^0.10.5",
"gulp-replace": "^1.1.3",
@@ -1573,8 +1571,5 @@
"prettier --write",
"eslint --fix"
]
},
"resolutions": {
"glob-parent": "6.0.0"
}
}

View File

@@ -289,7 +289,7 @@ const MIN_VERSION = "1.67.0";
*/
export async function activate(
ctx: ExtensionContext,
): Promise<CodeQLExtensionInterface | Record<string, never>> {
): Promise<CodeQLExtensionInterface | undefined> {
void extLogger.log(`Starting ${extensionId} extension`);
if (extension === undefined) {
throw new Error(`Can't find extension ${extensionId}`);
@@ -379,9 +379,11 @@ export async function activate(
},
);
variantAnalysisViewSerializer.onExtensionLoaded(
codeQlExtension.variantAnalysisManager,
);
if (codeQlExtension !== undefined) {
variantAnalysisViewSerializer.onExtensionLoaded(
codeQlExtension.variantAnalysisManager,
);
}
return codeQlExtension;
}
@@ -571,7 +573,7 @@ async function installOrUpdateThenTryActivate(
distributionManager: DistributionManager,
distributionConfigListener: DistributionConfigListener,
config: DistributionUpdateConfig,
): Promise<CodeQLExtensionInterface | Record<string, never>> {
): Promise<CodeQLExtensionInterface | undefined> {
await installOrUpdateDistribution(ctx, app, distributionManager, config);
try {
@@ -585,20 +587,19 @@ async function installOrUpdateThenTryActivate(
// Display the warnings even if the extension has already activated.
const distributionResult =
await getDistributionDisplayingDistributionWarnings(distributionManager);
let extensionInterface: CodeQLExtensionInterface | Record<string, never> = {};
if (
!beganMainExtensionActivation &&
distributionResult.kind !== FindDistributionResultKind.NoDistribution
) {
extensionInterface = await activateWithInstalledDistribution(
return await activateWithInstalledDistribution(
ctx,
app,
distributionManager,
distributionConfigListener,
);
} else if (
distributionResult.kind === FindDistributionResultKind.NoDistribution
) {
}
if (distributionResult.kind === FindDistributionResultKind.NoDistribution) {
registerErrorStubs([checkForUpdatesCommand], (command) => async () => {
const installActionName = "Install CodeQL CLI";
const chosenAction = await showAndLogErrorMessage(
@@ -622,7 +623,7 @@ async function installOrUpdateThenTryActivate(
}
});
}
return extensionInterface;
return undefined;
}
const PACK_GLOBS = [

View File

@@ -6,7 +6,7 @@ import {
writeFile,
opendir,
} from "fs-extra";
import { promise as glob } from "glob-promise";
import { glob } from "glob";
import { load } from "js-yaml";
import { join, basename } from "path";
import { dirSync } from "tmp-promise";
@@ -515,7 +515,9 @@ export async function getQlPackForDbscheme(
export async function getPrimaryDbscheme(
datasetFolder: string,
): Promise<string> {
const dbschemes = await glob(join(datasetFolder, "*.dbscheme"));
const dbschemes = await glob("*.dbscheme", {
cwd: datasetFolder,
});
if (dbschemes.length < 1) {
throw new Error(

View File

@@ -33,7 +33,7 @@ import { redactableError } from "../pure/errors";
export class QueryInProgress {
public queryEvalInfo: QueryEvaluationInfo;
/**
* Note that in the {@link deserializeQueryHistory} method, we create a QueryEvaluationInfo instance
* Note that in the {@link readQueryHistoryFromFile} method, we create a QueryEvaluationInfo instance
* by explicitly setting the prototype in order to avoid calling this constructor.
*/
constructor(

View File

@@ -1,5 +1,5 @@
import { pathExists, stat, remove } from "fs-extra";
import { promise as glob } from "glob-promise";
import { glob } from "glob";
import { join, basename, resolve, relative, dirname, extname } from "path";
import * as vscode from "vscode";
import * as cli from "./cli";

View File

@@ -1,6 +1,6 @@
import { join, resolve } from "path";
import { pathExists } from "fs-extra";
import { setupServer, SetupServerApi } from "msw/node";
import { setupServer, SetupServer } from "msw/node";
import { DisposableObject } from "../pure/disposable-object";
@@ -14,7 +14,7 @@ import { getDirectoryNamesInsidePath } from "../pure/files";
export class MockGitHubApiServer extends DisposableObject {
private _isListening: boolean;
private readonly server: SetupServerApi;
private readonly server: SetupServer;
private readonly recorder: Recorder;
constructor() {

View File

@@ -2,7 +2,7 @@ import { ensureDir, writeFile } from "fs-extra";
import { join } from "path";
import { MockedRequest } from "msw";
import { SetupServerApi } from "msw/node";
import { SetupServer } from "msw/node";
import { IsomorphicResponse } from "@mswjs/interceptors";
import { Headers } from "headers-polyfill";
@@ -22,7 +22,7 @@ export class Recorder extends DisposableObject {
private _isRecording = false;
constructor(private readonly server: SetupServerApi) {
constructor(private readonly server: SetupServer) {
super();
this.onRequestStart = this.onRequestStart.bind(this);
this.onResponseBypass = this.onResponseBypass.bind(this);
@@ -88,13 +88,18 @@ export class Recorder extends DisposableObject {
const bodyFileName = `${i}-${writtenRequest.request.kind}.body.${extension}`;
const bodyFilePath = join(scenarioDirectory, bodyFileName);
await writeFile(bodyFilePath, writtenRequest.response.body);
let bodyFileLink = undefined;
if (writtenRequest.response.body) {
await writeFile(bodyFilePath, writtenRequest.response.body || "");
bodyFileLink = `file:${bodyFileName}`;
}
writtenRequest = {
...writtenRequest,
response: {
...writtenRequest.response,
body: `file:${bodyFileName}`,
body: bodyFileLink,
},
};
}

View File

@@ -40,8 +40,8 @@ import {
variantAnalysisStatusToQueryStatus,
} from "../query-status";
import {
deserializeQueryHistory,
serializeQueryHistory,
readQueryHistoryFromFile,
writeQueryHistoryToFile,
} from "./store/query-history-store";
import { pathExists } from "fs-extra";
import { CliVersionConstraint } from "../cli";
@@ -379,7 +379,7 @@ export class QueryHistoryManager extends DisposableObject {
void extLogger.log(
`Reading cached query history from '${this.queryMetadataStorageLocation}'.`,
);
const history = await deserializeQueryHistory(
const history = await readQueryHistoryFromFile(
this.queryMetadataStorageLocation,
);
this.treeDataProvider.allHistory = history;
@@ -395,7 +395,7 @@ export class QueryHistoryManager extends DisposableObject {
}
async writeQueryHistory(): Promise<void> {
await serializeQueryHistory(
await writeQueryHistoryToFile(
this.treeDataProvider.allHistory,
this.queryMetadataStorageLocation,
);

View File

@@ -14,7 +14,7 @@ import { QueryEvaluationInfo } from "../../run-queries-shared";
import { QueryResultType } from "../../pure/legacy-messages";
import { redactableError } from "../../pure/errors";
export async function deserializeQueryHistory(
export async function readQueryHistoryFromFile(
fsPath: string,
): Promise<QueryHistoryInfo[]> {
try {
@@ -109,7 +109,7 @@ export async function deserializeQueryHistory(
* @param queries the list of queries to save.
* @param fsPath the path to save the queries to.
*/
export async function serializeQueryHistory(
export async function writeQueryHistoryToFile(
queries: QueryHistoryInfo[],
fsPath: string,
): Promise<void> {

View File

@@ -70,7 +70,7 @@ export class CompletedQueryInfo implements QueryWithResults {
interpretedResultsSortState: InterpretedResultsSortState | undefined;
/**
* Note that in the {@link deserializeQueryHistory} method, we create a CompletedQueryInfo instance
* Note that in the {@link readQueryHistoryFromFile} method, we create a CompletedQueryInfo instance
* by explicitly setting the prototype in order to avoid calling this constructor.
*/
constructor(evaluation: QueryWithResults) {
@@ -224,7 +224,7 @@ export class LocalQueryInfo {
public evalLogSummarySymbolsLocation: string | undefined;
/**
* Note that in the {@link deserializeQueryHistory} method, we create a FullQueryInfo instance
* Note that in the {@link readQueryHistoryFromFile} method, we create a FullQueryInfo instance
* by explicitly setting the prototype in order to avoid calling this constructor.
*/
constructor(

View File

@@ -68,7 +68,7 @@ function findQueryEvalLogEndSummaryFile(resultPath: string): string {
export class QueryEvaluationInfo {
/**
* Note that in the {@link deserializeQueryHistory} method, we create a QueryEvaluationInfo instance
* Note that in the {@link readQueryHistoryFromFile} method, we create a QueryEvaluationInfo instance
* by explicitly setting the prototype in order to avoid calling this constructor.
*/
constructor(

View File

@@ -1,6 +1,5 @@
import { commands, extensions, window } from "vscode";
import { commands, window } from "vscode";
import { CodeQLExtensionInterface } from "../../../../src/extension";
import { readJson } from "fs-extra";
import * as path from "path";
import {
@@ -15,19 +14,15 @@ import { DbListKind } from "../../../../src/databases/db-item";
import { createDbTreeViewItemSystemDefinedList } from "../../../../src/databases/ui/db-tree-view-item";
import { createRemoteSystemDefinedListDbItem } from "../../../factories/db-item-factories";
import { DbConfigStore } from "../../../../src/databases/config/db-config-store";
import { getActivatedExtension } from "../../global.helper";
jest.setTimeout(60_000);
describe("Db panel UI commands", () => {
let extension: CodeQLExtensionInterface | Record<string, never>;
let storagePath: string;
beforeEach(async () => {
extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
const extension = await getActivatedExtension();
storagePath =
extension.ctx.storageUri?.fsPath || extension.ctx.globalStorageUri.fsPath;

View File

@@ -1,14 +1,12 @@
import {
commands,
env,
extensions,
TextDocument,
TextEditor,
Uri,
window,
workspace,
} from "vscode";
import { CodeQLExtensionInterface } from "../../../../src/extension";
import { extLogger } from "../../../../src/common";
import * as ghApiClient from "../../../../src/variant-analysis/gh-api/gh-api-client";
import * as ghActionsApiClient from "../../../../src/variant-analysis/gh-api/gh-actions-api-client";
@@ -20,7 +18,7 @@ import { Response } from "node-fetch";
import { VariantAnalysisManager } from "../../../../src/variant-analysis/variant-analysis-manager";
import { CodeQLCliServer } from "../../../../src/cli";
import { storagePath } from "../../global.helper";
import { getActivatedExtension, storagePath } from "../../global.helper";
import { VariantAnalysisResultsManager } from "../../../../src/variant-analysis/variant-analysis-results-manager";
import { createMockVariantAnalysis } from "../../../factories/variant-analysis/shared/variant-analysis";
import * as VariantAnalysisModule from "../../../../src/variant-analysis/shared/variant-analysis";
@@ -67,11 +65,7 @@ describe("Variant Analysis Manager", () => {
scannedRepos,
});
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
const extension = await getActivatedExtension();
const cli = mockedObject<CodeQLCliServer>({});
app = new ExtensionApp(extension.ctx);
const dbManager = new DbManager(app, new DbConfigStore(app));

View File

@@ -1,14 +1,19 @@
import { join } from "path";
import { extensions, CancellationToken, Uri, window } from "vscode";
import { CancellationToken, Uri, window } from "vscode";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { CodeQLCliServer } from "../../../src/cli";
import { DatabaseManager } from "../../../src/local-databases";
import {
importArchiveDatabase,
promptImportInternetDatabase,
} from "../../../src/databaseFetcher";
import { cleanDatabases, dbLoc, DB_URL, storagePath } from "../global.helper";
import {
cleanDatabases,
dbLoc,
DB_URL,
getActivatedExtension,
storagePath,
} from "../global.helper";
import { createMockCommandManager } from "../../__mocks__/commandsMock";
jest.setTimeout(60_000);
@@ -30,18 +35,8 @@ describe("DatabaseFetcher", () => {
jest.spyOn(window, "showErrorMessage").mockResolvedValue(undefined);
jest.spyOn(window, "showInformationMessage").mockResolvedValue(undefined);
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("databaseManager" in extension) {
databaseManager = extension.databaseManager;
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
}
const extension = await getActivatedExtension();
databaseManager = extension.databaseManager;
await cleanDatabases(databaseManager);
});

View File

@@ -1,9 +1,8 @@
import { join } from "path";
import { extensions } from "vscode";
import { CodeQLCliServer } from "../../../src/cli";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { tryGetQueryMetadata } from "../../../src/helpers";
import { getActivatedExtension } from "../global.helper";
// up to 3 minutes per test
jest.setTimeout(3 * 60 * 1000);
@@ -14,18 +13,8 @@ describe("helpers (with CLI)", () => {
let cli: CodeQLCliServer;
beforeEach(async () => {
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("cliServer" in extension) {
cli = extension.cliServer;
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
}
const extension = await getActivatedExtension();
cli = extension.cliServer;
});
it("should get query metadata when available", async () => {

View File

@@ -7,12 +7,11 @@ import * as messages from "../../../src/pure/legacy-messages";
import * as qsClient from "../../../src/legacy-query-server/queryserver-client";
import * as cli from "../../../src/cli";
import { CellValue } from "../../../src/pure/bqrs-cli-types";
import { extensions } from "vscode";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { describeWithCodeQL } from "../cli";
import { QueryServerClient } from "../../../src/legacy-query-server/queryserver-client";
import { extLogger, ProgressReporter } from "../../../src/common";
import { createMockApp } from "../../__mocks__/appMock";
import { getActivatedExtension } from "../global.helper";
const baseDir = join(__dirname, "../../../test/data");
@@ -112,41 +111,30 @@ describeWithCodeQL()("using the legacy query server", () => {
let cliServer: cli.CodeQLCliServer;
beforeAll(async () => {
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("cliServer" in extension) {
cliServer = extension.cliServer;
cliServer.quiet = true;
const extension = await getActivatedExtension();
cliServer = extension.cliServer;
cliServer.quiet = true;
qs = new QueryServerClient(
createMockApp({}),
{
codeQlPath:
(await extension.distributionManager.getCodeQlPathWithoutVersionCheck()) ||
"",
debug: false,
cacheSize: 0,
numThreads: 1,
saveCache: false,
timeoutSecs: 0,
},
cliServer,
{
contextStoragePath: tmpDir.name,
logger: extLogger,
},
(task) =>
task(nullProgressReporter, new CancellationTokenSource().token),
);
await qs.startQueryServer();
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
}
qs = new QueryServerClient(
createMockApp({}),
{
codeQlPath:
(await extension.distributionManager.getCodeQlPathWithoutVersionCheck()) ||
"",
debug: false,
cacheSize: 0,
numThreads: 1,
saveCache: false,
timeoutSecs: 0,
},
cliServer,
{
contextStoragePath: tmpDir.name,
logger: extLogger,
},
(task) => task(nullProgressReporter, new CancellationTokenSource().token),
);
await qs.startQueryServer();
});
for (const queryTestCase of queryTestCases) {

View File

@@ -5,13 +5,17 @@ import * as messages from "../../../src/pure/new-messages";
import * as qsClient from "../../../src/query-server/queryserver-client";
import * as cli from "../../../src/cli";
import { CellValue } from "../../../src/pure/bqrs-cli-types";
import { extensions, Uri } from "vscode";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { Uri } from "vscode";
import { describeWithCodeQL } from "../cli";
import { QueryServerClient } from "../../../src/query-server/queryserver-client";
import { extLogger, ProgressReporter } from "../../../src/common";
import { QueryResultType } from "../../../src/pure/new-messages";
import { cleanDatabases, dbLoc, storagePath } from "../global.helper";
import {
cleanDatabases,
dbLoc,
getActivatedExtension,
storagePath,
} from "../global.helper";
import { importArchiveDatabase } from "../../../src/databaseFetcher";
import { createMockApp } from "../../__mocks__/appMock";
@@ -111,64 +115,53 @@ describeWithCodeQL()("using the new query server", () => {
beforeAll(async () => {
const app = createMockApp({});
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("cliServer" in extension && "databaseManager" in extension) {
cliServer = extension.cliServer;
const extension = await getActivatedExtension();
cliServer = extension.cliServer;
cliServer.quiet = true;
if (!(await cliServer.cliConstraints.supportsNewQueryServerForTests())) {
supportNewQueryServer = false;
}
qs = new QueryServerClient(
app,
{
codeQlPath:
(await extension.distributionManager.getCodeQlPathWithoutVersionCheck()) ||
"",
debug: false,
cacheSize: 0,
numThreads: 1,
saveCache: false,
timeoutSecs: 0,
},
cliServer,
{
contextStoragePath: tmpDir.name,
logger: extLogger,
},
(task) =>
task(nullProgressReporter, new CancellationTokenSource().token),
);
await qs.startQueryServer();
// Unlike the old query sevre the new one wants a database and the empty direcrtory is not valid.
// Add a database, but make sure the database manager is empty first
await cleanDatabases(extension.databaseManager);
const uri = Uri.file(dbLoc);
const maybeDbItem = await importArchiveDatabase(
app.commands,
uri.toString(true),
extension.databaseManager,
storagePath,
() => {
/**ignore progress */
},
token,
);
if (!maybeDbItem) {
throw new Error("Could not import database");
}
db = maybeDbItem.databaseUri.fsPath;
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
cliServer.quiet = true;
if (!(await cliServer.cliConstraints.supportsNewQueryServerForTests())) {
supportNewQueryServer = false;
}
qs = new QueryServerClient(
app,
{
codeQlPath:
(await extension.distributionManager.getCodeQlPathWithoutVersionCheck()) ||
"",
debug: false,
cacheSize: 0,
numThreads: 1,
saveCache: false,
timeoutSecs: 0,
},
cliServer,
{
contextStoragePath: tmpDir.name,
logger: extLogger,
},
(task) => task(nullProgressReporter, new CancellationTokenSource().token),
);
await qs.startQueryServer();
// Unlike the old query sevre the new one wants a database and the empty direcrtory is not valid.
// Add a database, but make sure the database manager is empty first
await cleanDatabases(extension.databaseManager);
const uri = Uri.file(dbLoc);
const maybeDbItem = await importArchiveDatabase(
app.commands,
uri.toString(true),
extension.databaseManager,
storagePath,
() => {
/**ignore progress */
},
token,
);
if (!maybeDbItem) {
throw new Error("Could not import database");
}
db = maybeDbItem.databaseUri.fsPath;
});
for (const queryTestCase of queryTestCases) {

View File

@@ -1,8 +1,7 @@
import { extensions, window } from "vscode";
import { window } from "vscode";
import { join } from "path";
import { CodeQLCliServer } from "../../../src/cli";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { getErrorMessage } from "../../../src/pure/helpers-pure";
import * as helpers from "../../../src/helpers";
@@ -11,6 +10,7 @@ import {
handleInstallPackDependencies,
} from "../../../src/packaging";
import { mockedQuickPickItem } from "../utils/mocking.helpers";
import { getActivatedExtension } from "../global.helper";
// up to 3 minutes per test
jest.setTimeout(3 * 60 * 1000);
@@ -41,18 +41,8 @@ describe("Packaging commands", () => {
.spyOn(helpers, "showAndLogInformationMessage")
.mockResolvedValue(undefined);
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("cliServer" in extension) {
cli = extension.cliServer;
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
}
const extension = await getActivatedExtension();
cli = extension.cliServer;
});
it("should download all core query packs", async () => {

View File

@@ -1,10 +1,4 @@
import {
CancellationToken,
commands,
ExtensionContext,
extensions,
Uri,
} from "vscode";
import { CancellationToken, commands, ExtensionContext, Uri } from "vscode";
import { join, dirname } from "path";
import {
pathExistsSync,
@@ -16,8 +10,12 @@ import {
import { load, dump } from "js-yaml";
import { DatabaseItem, DatabaseManager } from "../../../src/local-databases";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { cleanDatabases, dbLoc, storagePath } from "../global.helper";
import {
cleanDatabases,
dbLoc,
getActivatedExtension,
storagePath,
} from "../global.helper";
import { importArchiveDatabase } from "../../../src/databaseFetcher";
import { CliVersionConstraint, CodeQLCliServer } from "../../../src/cli";
import { describeWithCodeQL } from "../cli";
@@ -48,26 +46,16 @@ describeWithCodeQL()("Queries", () => {
let qlFile: string;
beforeEach(async () => {
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("databaseManager" in extension) {
databaseManager = extension.databaseManager;
cli = extension.cliServer;
qs = extension.qs;
cli.quiet = true;
ctx = extension.ctx;
qlpackFile = `${ctx.storageUri?.fsPath}/quick-queries/qlpack.yml`;
qlpackLockFile = `${ctx.storageUri?.fsPath}/quick-queries/codeql-pack.lock.yml`;
oldQlpackLockFile = `${ctx.storageUri?.fsPath}/quick-queries/qlpack.lock.yml`;
qlFile = `${ctx.storageUri?.fsPath}/quick-queries/quick-query.ql`;
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
}
const extension = await getActivatedExtension();
databaseManager = extension.databaseManager;
cli = extension.cliServer;
qs = extension.qs;
cli.quiet = true;
ctx = extension.ctx;
qlpackFile = `${ctx.storageUri?.fsPath}/quick-queries/qlpack.yml`;
qlpackLockFile = `${ctx.storageUri?.fsPath}/quick-queries/codeql-pack.lock.yml`;
oldQlpackLockFile = `${ctx.storageUri?.fsPath}/quick-queries/qlpack.lock.yml`;
qlFile = `${ctx.storageUri?.fsPath}/quick-queries/quick-query.ql`;
// Ensure we are starting from a clean slate.
safeDel(qlFile);

View File

@@ -1,9 +1,8 @@
import { authentication, extensions, Uri } from "vscode";
import { authentication, Uri } from "vscode";
import { join } from "path";
import { SemVer } from "semver";
import { CodeQLCliServer, QueryInfoByLanguage } from "../../../src/cli";
import { CodeQLExtensionInterface } from "../../../src/extension";
import { itWithCodeQL } from "../cli";
import {
getOnDiskWorkspaceFolders,
@@ -13,6 +12,7 @@ import {
import { resolveQueries } from "../../../src/contextual/queryResolver";
import { KeyType } from "../../../src/contextual/keyType";
import { faker } from "@faker-js/faker";
import { getActivatedExtension } from "../global.helper";
jest.setTimeout(60_000);
@@ -24,19 +24,9 @@ describe("Use cli", () => {
let supportedLanguages: string[];
beforeEach(async () => {
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
if ("cliServer" in extension) {
cli = extension.cliServer;
supportedLanguages = await cli.getSupportedLanguages();
} else {
throw new Error(
"Extension not initialized. Make sure cli is downloaded and installed properly.",
);
}
const extension = await getActivatedExtension();
cli = extension.cliServer;
supportedLanguages = await cli.getSupportedLanguages();
});
if (process.env.CLI_VERSION && process.env.CLI_VERSION !== "nightly") {

View File

@@ -1,11 +1,4 @@
import {
CancellationTokenSource,
commands,
extensions,
Uri,
window,
} from "vscode";
import { CodeQLExtensionInterface } from "../../../../src/extension";
import { CancellationTokenSource, commands, Uri, window } from "vscode";
import { extLogger } from "../../../../src/common";
import { setRemoteControllerRepo } from "../../../../src/config";
import * as ghApiClient from "../../../../src/variant-analysis/gh-api/gh-api-client";
@@ -15,6 +8,7 @@ import { VariantAnalysisManager } from "../../../../src/variant-analysis/variant
import { CliVersionConstraint, CodeQLCliServer } from "../../../../src/cli";
import {
fixWorkspaceReferences,
getActivatedExtension,
restoreWorkspaceReferences,
storagePath,
} from "../../global.helper";
@@ -48,11 +42,7 @@ describe("Variant Analysis Manager", () => {
cancellationTokenSource = new CancellationTokenSource();
const extension = await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
const extension = await getActivatedExtension();
cli = extension.cliServer;
const app = new ExtensionApp(extension.ctx);
const dbManager = new DbManager(app, new DbConfigStore(app));

View File

@@ -3,16 +3,15 @@ import { resolve } from "path";
import {
authentication,
commands,
extensions,
TextDocument,
window,
workspace,
} from "vscode";
import { CodeQLExtensionInterface } from "../../../../src/extension";
import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server";
import { mockedQuickPickItem } from "../../utils/mocking.helpers";
import { setRemoteControllerRepo } from "../../../../src/config";
import { getActivatedExtension } from "../../global.helper";
jest.setTimeout(30_000);
@@ -55,11 +54,7 @@ describe("Variant Analysis Submission Integration", () => {
.spyOn(window, "showErrorMessage")
.mockResolvedValue(undefined);
await extensions
.getExtension<CodeQLExtensionInterface | Record<string, never>>(
"GitHub.vscode-codeql",
)!
.activate();
await getActivatedExtension();
});
describe("Successful scenario", () => {

View File

@@ -1,10 +1,11 @@
import { join } from "path";
import { load, dump } from "js-yaml";
import { realpathSync, readFileSync, writeFileSync } from "fs-extra";
import { commands } from "vscode";
import { commands, extensions } from "vscode";
import { DatabaseManager } from "../../src/local-databases";
import { CodeQLCliServer } from "../../src/cli";
import { removeWorkspaceRefs } from "../../src/variant-analysis/run-remote-query";
import { CodeQLExtensionInterface } from "../../src/extension";
// This file contains helpers shared between tests that work with an activated extension.
@@ -23,6 +24,18 @@ export function setStoragePath(path: string) {
storagePath = path;
}
export async function getActivatedExtension(): Promise<CodeQLExtensionInterface> {
const extension = await extensions
.getExtension<CodeQLExtensionInterface | undefined>("GitHub.vscode-codeql")
?.activate();
if (extension === undefined) {
throw new Error(
"Unable to active CodeQL extension. Make sure cli is downloaded and installed properly.",
);
}
return extension;
}
export async function cleanDatabases(databaseManager: DatabaseManager) {
for (const item of databaseManager.databaseItems) {
await commands.executeCommand("codeQLDatabases.removeDatabase", item);

View File

@@ -1,13 +1,19 @@
import { CUSTOM_CODEQL_PATH_SETTING } from "../../src/config";
import { ConfigurationTarget, env, extensions } from "vscode";
import { ConfigurationTarget, env } from "vscode";
import { beforeEachAction as testConfigBeforeEachAction } from "./test-config";
import * as tmp from "tmp";
import { realpathSync } from "fs-extra";
import { setStoragePath, storagePath } from "./global.helper";
import {
getActivatedExtension,
setStoragePath,
storagePath,
} from "./global.helper";
jest.retryTimes(3, {
logErrorsBeforeRetry: true,
});
if (process.env.CI) {
jest.retryTimes(3, {
logErrorsBeforeRetry: true,
});
}
// create an extension storage location
let removeStorage: tmp.DirResult["removeCallback"] | undefined;
@@ -33,7 +39,7 @@ export async function beforeAllAction() {
removeStorage = dir.removeCallback;
// Activate the extension
await extensions.getExtension("GitHub.vscode-codeql")?.activate();
await getActivatedExtension();
}
export async function beforeEachAction() {

View File

@@ -1,9 +1,11 @@
import { env } from "vscode";
import { beforeEachAction } from "./test-config";
jest.retryTimes(3, {
logErrorsBeforeRetry: true,
});
if (process.env.CI) {
jest.retryTimes(3, {
logErrorsBeforeRetry: true,
});
}
beforeEach(async () => {
jest.spyOn(env, "openExternal").mockResolvedValue(false);

View File

@@ -1,6 +1,6 @@
import {
deserializeQueryHistory,
serializeQueryHistory,
readQueryHistoryFromFile,
writeQueryHistoryToFile,
} from "../../../../../src/query-history/store/query-history-store";
import { join } from "path";
import { writeFileSync, mkdirpSync, writeFile } from "fs-extra";
@@ -19,7 +19,7 @@ import { QueryHistoryInfo } from "../../../../../src/query-history/query-history
import { createMockVariantAnalysisHistoryItem } from "../../../../factories/query-history/variant-analysis-history-item";
import { nanoid } from "nanoid";
describe("serialize and deserialize", () => {
describe("write and read", () => {
let infoSuccessRaw: LocalQueryInfo;
let infoSuccessInterpreted: LocalQueryInfo;
let infoEarlyFailure: LocalQueryInfo;
@@ -93,12 +93,12 @@ describe("serialize and deserialize", () => {
];
});
it("should serialize and deserialize query history", async () => {
it("should write and read query history", async () => {
const allHistoryPath = join(tmpDir.name, "workspace-query-history.json");
// serialize and deserialize
await serializeQueryHistory(allHistory, allHistoryPath);
const allHistoryActual = await deserializeQueryHistory(allHistoryPath);
// write and read
await writeQueryHistoryToFile(allHistory, allHistoryPath);
const allHistoryActual = await readQueryHistoryFromFile(allHistoryPath);
// the dispose methods will be different. Ignore them.
allHistoryActual.forEach((info) => {
@@ -106,7 +106,7 @@ describe("serialize and deserialize", () => {
const completedQuery = info.completedQuery;
(completedQuery as any).dispose = undefined;
// these fields should be missing on the deserialized value
// these fields should be missing on the read value
// but they are undefined on the original value
if (!("logFileLocation" in completedQuery)) {
(completedQuery as any).logFileLocation = undefined;
@@ -181,7 +181,7 @@ describe("serialize and deserialize", () => {
"utf8",
);
const actual = await deserializeQueryHistory(path);
const actual = await readQueryHistoryFromFile(path);
expect(actual.length).toEqual(expectedHistory.length);
});
@@ -196,7 +196,7 @@ describe("serialize and deserialize", () => {
"utf8",
);
const allHistoryActual = await deserializeQueryHistory(badPath);
const allHistoryActual = await readQueryHistoryFromFile(badPath);
// version number is invalid. Should return an empty array.
expect(allHistoryActual).toEqual([]);
});

View File

@@ -1,4 +1,3 @@
import * as fs from "fs-extra";
import { Uri, WorkspaceFolder } from "vscode";
import { QLTestAdapter } from "../../../src/test-adapter";
@@ -19,8 +18,6 @@ jest.mock("fs-extra", () => {
};
});
const mockedFsExtra = jest.mocked(fs);
describe("test-adapter", () => {
let adapter: QLTestAdapter;
let fakeDatabaseManager: DatabaseManager;
@@ -131,8 +128,6 @@ describe("test-adapter", () => {
});
it("should reregister testproj databases around test run", async () => {
mockedFsExtra.access.mockResolvedValue(undefined);
currentDatabaseItem = preTestDatabaseItem;
databaseItems = [preTestDatabaseItem];
await adapter.run(["/path/to/test/dir"]);