Merge branch 'main' into robertbrignull/credentials_in_app

This commit is contained in:
Robert
2023-01-25 10:15:29 +00:00
85 changed files with 844 additions and 1524 deletions

View File

@@ -75,7 +75,7 @@ runs:
echo "Found existing open PR: $PR_NUMBERS"
exit 0
fi
gh pr create --head "$HEAD_BRANCH" --base "$BASE_BRANCH" --title "$TITLE" --body "$BODY" --assignee ${{ github.actor }}
gh pr create --head "$HEAD_BRANCH" --base "$BASE_BRANCH" --title "$TITLE" --body "$BODY" --assignee ${{ github.actor }} --draft
if [[ $? -ne 0 ]]; then
echo "Failed to create new PR."
exit 1

View File

@@ -1,6 +1,20 @@
name: Bump CLI version
on:
workflow_dispatch:
inputs:
option:
description: "Option"
required: true
default: 'replace'
type: choice
options:
- prepend
- replace
version:
description: |
The version to prepend to the supported versions file. This should be in the form: `vA.B.C`.
required: false
type: string
pull_request:
branches: [main]
paths:
@@ -23,10 +37,18 @@ jobs:
with:
fetch-depth: 1
- name: Bump CLI
if: ${{ inputs.option == 'replace' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
scripts/replace-cli-version.sh
- name: Prepend another version
if: ${{ inputs.option == 'prepend' }}
run: |
cat extensions/ql-vscode/supported_cli_versions.json | jq '. |= ["${{ inputs.version }}"] + .' > supported_cli_versions_temp.json
mv supported_cli_versions_temp.json extensions/ql-vscode/supported_cli_versions.json
echo "LATEST_VERSION=${{ inputs.version }}" >> $GITHUB_ENV
echo "PREVIOUS_VERSION=`jq -r '.[1]' extensions/ql-vscode/supported_cli_versions.json`" >> $GITHUB_ENV
- name: Commit, Push and Open a PR
uses: ./.github/actions/create-pr
with:

View File

@@ -191,7 +191,7 @@ jobs:
uses: actions/checkout@v3
- name: Set the variables
id: set-variables
run: echo "cli-versions=$(cat ./supported_cli_versions.json | jq -rc)" >> $GITHUB_OUTPUT
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:

View File

@@ -2,5 +2,9 @@
node_modules/
out/
# This file gets written by an actions workflow.
# Don't try to format it.
supported_cli_versions.json
# Include the Storybook config
!.storybook

View File

@@ -3,6 +3,7 @@
## [UNRELEASED]
- Renamed command "CodeQL: Run Query" to "CodeQL: Run Query on Selected Dababase".
- Remove support for CodeQL CLI versions older than 2.7.6. [#1788](https://github.com/github/vscode-codeql/pull/1788)
## 1.7.7 - 13 December 2022

View File

@@ -48,120 +48,14 @@
},
"required": ["repositoryLists", "owners", "repositories"],
"additionalProperties": false
},
"local": {
"type": "object",
"properties": {
"lists": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"databases": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"dateAdded": {
"type": "number"
},
"language": {
"type": "string",
"minLength": 1
},
"storagePath": {
"type": "string",
"minLength": 1
}
},
"required": [
"name",
"dateAdded",
"language",
"storagePath"
],
"additionalProperties": false
}
}
},
"required": ["name", "databases"],
"additionalProperties": false
}
},
"databases": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"dateAdded": {
"type": "number"
},
"language": {
"type": "string",
"minLength": 1
},
"storagePath": {
"type": "string",
"minLength": 1
}
},
"required": ["name", "dateAdded", "language", "storagePath"],
"additionalProperties": false
}
}
},
"required": ["lists", "databases"],
"additionalProperties": false
}
},
"required": ["variantAnalysis", "local"],
"required": ["variantAnalysis"],
"additionalProperties": false
},
"selected": {
"type": "object",
"oneOf": [
{
"properties": {
"kind": {
"type": "string",
"enum": ["localUserDefinedList"]
},
"listName": {
"type": "string",
"minLength": 1
}
},
"required": ["kind", "listName"],
"additionalProperties": false
},
{
"properties": {
"kind": {
"type": "string",
"enum": ["localDatabase"]
},
"databaseName": {
"type": "string"
},
"listName": {
"type": "string",
"minLength": 1
}
},
"required": ["kind", "databaseName"],
"additionalProperties": false
},
{
"properties": {
"kind": {

View File

@@ -798,19 +798,23 @@
"view/item/context": [
{
"command": "codeQLVariantAnalysisRepositories.removeItemContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeRemoved/"
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeRemoved/",
"group": "2_qlContextMenu@3"
},
{
"command": "codeQLVariantAnalysisRepositories.setSelectedItemContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeSelected/"
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeSelected/",
"group": "1_qlContextMenu@1"
},
{
"command": "codeQLVariantAnalysisRepositories.renameItemContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeRenamed/"
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeRenamed/",
"group": "2_qlContextMenu@2"
},
{
"command": "codeQLVariantAnalysisRepositories.openOnGitHubContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeOpenedOnGitHub/"
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeOpenedOnGitHub/",
"group": "2_qlContextMenu@1"
},
{
"command": "codeQLDatabases.setCurrentDatabase",
@@ -839,7 +843,7 @@
},
{
"command": "codeQLVariantAnalysisRepositories.setSelectedItem",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeSelected/",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeSelected/ && false",
"group": "inline"
},
{
@@ -1318,7 +1322,7 @@
},
{
"view": "codeQLQueryHistory",
"contents": "Run the 'CodeQL: Run Query on Selected Database' command on a QL query.\n[Run Query](command:codeQL.runQuery)"
"contents": "You have no query history items at the moment.\n\nSelect a database to run a CodeQL query and get your first results."
},
{
"view": "codeQLDatabases",

View File

@@ -1124,10 +1124,7 @@ export class CodeQLCliServer implements Disposable {
];
if (targetDbScheme) {
args.push("--target-dbscheme", targetDbScheme);
if (
allowDowngradesIfPossible &&
(await this.cliConstraints.supportsDowngrades())
) {
if (allowDowngradesIfPossible) {
args.push("--allow-downgrades");
}
}
@@ -1209,10 +1206,8 @@ export class CodeQLCliServer implements Disposable {
if (searchPath !== undefined) {
args.push("--search-path", join(...searchPath));
}
if (await this.cliConstraints.supportsAllowLibraryPacksInResolveQueries()) {
// All of our usage of `codeql resolve queries` needs to handle library packs.
args.push("--allow-library-packs");
}
// All of our usage of `codeql resolve queries` needs to handle library packs.
args.push("--allow-library-packs");
args.push(suite);
return this.runJsonCodeQlCliCommand<string[]>(
["resolve", "queries"],
@@ -1299,12 +1294,9 @@ export class CodeQLCliServer implements Disposable {
}
async generateDil(qloFile: string, outFile: string): Promise<void> {
const extraArgs = (await this.cliConstraints.supportsDecompileDil())
? ["--kind", "dil", "-o", outFile, qloFile]
: ["-o", outFile, qloFile];
await this.runCodeQlCliCommand(
["query", "decompile"],
extraArgs,
["--kind", "dil", "-o", outFile, qloFile],
"Generating DIL",
);
}
@@ -1582,56 +1574,6 @@ export function shouldDebugCliServer() {
}
export class CliVersionConstraint {
/**
* CLI version where --kind=DIL was introduced
*/
public static CLI_VERSION_WITH_DECOMPILE_KIND_DIL = new SemVer("2.3.0");
/**
* CLI version where languages are exposed during a `codeql resolve database` command.
*/
public static CLI_VERSION_WITH_LANGUAGE = new SemVer("2.4.1");
public static CLI_VERSION_WITH_NONDESTURCTIVE_UPGRADES = new SemVer("2.4.2");
/**
* CLI version where `codeql resolve upgrades` supports
* the `--allow-downgrades` flag
*/
public static CLI_VERSION_WITH_DOWNGRADES = new SemVer("2.4.4");
/**
* CLI version where the `codeql resolve qlref` command is available.
*/
public static CLI_VERSION_WITH_RESOLVE_QLREF = new SemVer("2.5.1");
/**
* CLI version where database registration was introduced
*/
public static CLI_VERSION_WITH_DB_REGISTRATION = new SemVer("2.4.1");
/**
* CLI version where the `--allow-library-packs` option to `codeql resolve queries` was
* introduced.
*/
public static CLI_VERSION_WITH_ALLOW_LIBRARY_PACKS_IN_RESOLVE_QUERIES =
new SemVer("2.6.1");
/**
* CLI version where the `database unbundle` subcommand was introduced.
*/
public static CLI_VERSION_WITH_DATABASE_UNBUNDLE = new SemVer("2.6.0");
/**
* CLI version where the `--no-precompile` option for pack creation was introduced.
*/
public static CLI_VERSION_WITH_NO_PRECOMPILE = new SemVer("2.7.1");
/**
* CLI version where remote queries (variant analysis) are supported.
*/
public static CLI_VERSION_REMOTE_QUERIES = new SemVer("2.6.3");
/**
* CLI version where building QLX packs for remote queries is supported.
* (The options were _accepted_ by a few earlier versions, but only from
@@ -1639,11 +1581,6 @@ export class CliVersionConstraint {
*/
public static CLI_VERSION_QLX_REMOTE = new SemVer("2.11.3");
/**
* CLI version where the `resolve ml-models` subcommand was introduced.
*/
public static CLI_VERSION_WITH_RESOLVE_ML_MODELS = new SemVer("2.7.3");
/**
* CLI version where the `resolve ml-models` subcommand was enhanced to work with packaging.
*/
@@ -1651,16 +1588,6 @@ export class CliVersionConstraint {
"2.10.0",
);
/**
* CLI version where the `--old-eval-stats` option to the query server was introduced.
*/
public static CLI_VERSION_WITH_OLD_EVAL_STATS = new SemVer("2.7.4");
/**
* CLI version where packaging was introduced.
*/
public static CLI_VERSION_WITH_PACKAGING = new SemVer("2.6.0");
/**
* CLI version where the `--evaluator-log` and related options to the query server were introduced,
* on a per-query server basis.
@@ -1701,94 +1628,16 @@ export class CliVersionConstraint {
return (await this.cli.getVersion()).compare(v) >= 0;
}
public async supportsDecompileDil() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DECOMPILE_KIND_DIL,
);
}
public async supportsLanguageName() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_LANGUAGE,
);
}
public async supportsNonDestructiveUpgrades() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_NONDESTURCTIVE_UPGRADES,
);
}
public async supportsDowngrades() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DOWNGRADES,
);
}
public async supportsResolveQlref() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_QLREF,
);
}
public async supportsAllowLibraryPacksInResolveQueries() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_ALLOW_LIBRARY_PACKS_IN_RESOLVE_QUERIES,
);
}
async supportsDatabaseRegistration() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DB_REGISTRATION,
);
}
async supportsDatabaseUnbundle() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DATABASE_UNBUNDLE,
);
}
async supportsNoPrecompile() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_NO_PRECOMPILE,
);
}
async supportsRemoteQueries() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES,
);
}
async supportsQlxRemote() {
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_QLX_REMOTE);
}
async supportsResolveMlModels() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_ML_MODELS,
);
}
async supportsPreciseResolveMlModels() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_PRECISE_RESOLVE_ML_MODELS,
);
}
async supportsOldEvalStats() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_OLD_EVAL_STATS,
);
}
async supportsPackaging() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_PACKAGING,
);
}
async supportsStructuredEvalLog() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_STRUCTURED_EVAL_LOG,

View File

@@ -8,7 +8,7 @@ import {
} from "vscode";
import { showAndLogErrorMessage, showAndLogWarningMessage } from "./helpers";
import { extLogger } from "./common";
import { getErrorMessage, getErrorStack } from "./pure/helpers-pure";
import { asError, getErrorMessage, getErrorStack } from "./pure/helpers-pure";
import { telemetryListener } from "./telemetry";
export class UserCancellationException extends Error {
@@ -126,7 +126,7 @@ export function commandRunner(
return await task(...args);
} catch (e) {
const errorMessage = `${getErrorMessage(e) || e} (${commandId})`;
error = e instanceof Error ? e : new Error(errorMessage);
error = asError(e);
const errorStack = getErrorStack(e);
if (e instanceof UserCancellationException) {
// User has cancelled this action manually
@@ -179,7 +179,7 @@ export function commandRunnerWithProgress<R>(
return await withProgress(progressOptionsWithDefaults, task, ...args);
} catch (e) {
const errorMessage = `${getErrorMessage(e) || e} (${commandId})`;
error = e instanceof Error ? e : new Error(errorMessage);
error = asError(e);
const errorStack = getErrorStack(e);
if (e instanceof UserCancellationException) {
// User has cancelled this action manually

View File

@@ -17,7 +17,7 @@ import {
import resultsDiff from "./resultsDiff";
import { CompletedLocalQueryInfo } from "../query-results";
import { assertNever, getErrorMessage } from "../pure/helpers-pure";
import { HistoryItemLabelProvider } from "../history-item-label-provider";
import { HistoryItemLabelProvider } from "../query-history/history-item-label-provider";
import { AbstractWebview, WebviewPanelConfig } from "../abstract-webview";
import { telemetryListener } from "../telemetry";

View File

@@ -74,39 +74,12 @@ export async function resolveQueries(
qlpacks: QlPacksForLanguage,
keyType: KeyType,
): Promise<string[]> {
const cliCanHandleLibraryPack =
await cli.cliConstraints.supportsAllowLibraryPacksInResolveQueries();
const packsToSearch: string[] = [];
let blameCli: boolean;
if (cliCanHandleLibraryPack) {
// The CLI can handle both library packs and query packs, so search both packs in order.
packsToSearch.push(qlpacks.dbschemePack);
if (qlpacks.queryPack !== undefined) {
packsToSearch.push(qlpacks.queryPack);
}
// If we don't find the query, it's because it's not there, not because the CLI was unable to
// search the pack.
blameCli = false;
} else {
// Older CLIs can't handle `codeql resolve queries` with a suite that references a library pack.
if (qlpacks.dbschemePackIsLibraryPack) {
if (qlpacks.queryPack !== undefined) {
// Just search the query pack, because some older library/query releases still had the
// contextual queries in the query pack.
packsToSearch.push(qlpacks.queryPack);
}
// If we don't find it, it's because the CLI was unable to search the library pack that
// actually contains the query. Blame any failure on the CLI, not the packs.
blameCli = true;
} else {
// We have an old CLI, but the dbscheme pack is old enough that it's still a unified pack with
// both libraries and queries. Just search that pack.
packsToSearch.push(qlpacks.dbschemePack);
// Any CLI should be able to search the single query pack, so if we don't find it, it's
// because the language doesn't support it.
blameCli = false;
}
// The CLI can handle both library packs and query packs, so search both packs in order.
packsToSearch.push(qlpacks.dbschemePack);
if (qlpacks.queryPack !== undefined) {
packsToSearch.push(qlpacks.queryPack);
}
const queries = await resolveQueriesFromPacks(cli, packsToSearch, keyType);
@@ -115,15 +88,11 @@ export async function resolveQueries(
}
// No queries found. Determine the correct error message for the various scenarios.
const errorMessage = blameCli
? `Your current version of the CodeQL CLI, '${
(await cli.getVersion()).version
}', \
is unable to use contextual queries from recent versions of the standard CodeQL libraries. \
Please upgrade to the latest version of the CodeQL CLI.`
: `No ${nameOfKeyType(keyType)} queries (tagged "${tagOfKeyType(
keyType,
)}") could be found in the current library path. \
const errorMessage = `No ${nameOfKeyType(
keyType,
)} queries (tagged "${tagOfKeyType(
keyType,
)}") could be found in the current library path. \
Try upgrading the CodeQL libraries. If that doesn't work, then ${nameOfKeyType(
keyType,
)} queries are not yet available \

View File

@@ -321,7 +321,7 @@ async function readAndUnzip(
step: 9,
message: `Unzipping into ${basename(unzipPath)}`,
});
if (cli && (await cli.cliConstraints.supportsDatabaseUnbundle())) {
if (cli) {
// Use the `database unbundle` command if the installed cli version supports it
await cli.databaseUnbundle(zipFile, unzipPath);
} else {

View File

@@ -19,7 +19,7 @@ import {
} from "./archive-filesystem-provider";
import { DisposableObject } from "./pure/disposable-object";
import { Logger, extLogger } from "./common";
import { getErrorMessage } from "./pure/helpers-pure";
import { asError, getErrorMessage } from "./pure/helpers-pure";
import { QueryRunner } from "./queryRunner";
import { pathsEqual } from "./pure/files";
@@ -370,7 +370,7 @@ export class DatabaseItemImpl implements DatabaseItem {
this._error = undefined;
} catch (e) {
this._contents = undefined;
this._error = e instanceof Error ? e : new Error(String(e));
this._error = asError(e);
throw e;
}
} finally {
@@ -990,12 +990,6 @@ export class DatabaseManager extends DisposableObject {
}
private async getPrimaryLanguage(dbPath: string) {
if (!(await this.cli.cliConstraints.supportsLanguageName())) {
// return undefined so that we recalculate on restart until the cli is at a version that
// supports this feature. This recalculation is cheap since we avoid calling into the cli
// unless we know it can return the langauges property.
return undefined;
}
const dbInfo = await this.cli.resolveDatabase(dbPath);
return dbInfo.languages?.[0] || "";
}

View File

@@ -1,8 +1,10 @@
import { pathExists, outputJSON, readJSON, readJSONSync } from "fs-extra";
import { join } from "path";
import {
clearLocalDbConfig,
cloneDbConfig,
DbConfig,
initializeLocalDbConfig,
removeLocalDb,
removeLocalList,
removeRemoteList,
@@ -26,7 +28,7 @@ import { ValueResult } from "../../common/value-result";
import {
LocalDatabaseDbItem,
LocalListDbItem,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
DbItem,
DbItemKind,
} from "../db-item";
@@ -113,7 +115,7 @@ export class DbConfigStore extends DisposableObject {
case DbItemKind.LocalList:
config = removeLocalList(this.config, dbItem.listName);
break;
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
config = removeRemoteList(this.config, dbItem.listName);
break;
case DbItemKind.LocalDatabase:
@@ -246,7 +248,7 @@ export class DbConfigStore extends DisposableObject {
}
public async renameRemoteList(
currentDbItem: VariantAnalysisUserDefinedListDbItem,
currentDbItem: RemoteUserDefinedListDbItem,
newName: string,
) {
if (!this.config) {
@@ -349,6 +351,7 @@ export class DbConfigStore extends DisposableObject {
}
private async writeConfig(config: DbConfig): Promise<void> {
clearLocalDbConfig(config);
await outputJSON(this.configPath, config, {
spaces: 2,
});
@@ -380,6 +383,7 @@ export class DbConfigStore extends DisposableObject {
}
if (newConfig) {
initializeLocalDbConfig(newConfig);
this.configErrors = this.configValidator.validate(newConfig);
}
@@ -414,6 +418,7 @@ export class DbConfigStore extends DisposableObject {
}
if (newConfig) {
initializeLocalDbConfig(newConfig);
this.configErrors = this.configValidator.validate(newConfig);
}

View File

@@ -1,7 +1,7 @@
import { readJsonSync } from "fs-extra";
import { resolve } from "path";
import Ajv from "ajv";
import { DbConfig } from "./db-config";
import { clearLocalDbConfig, DbConfig } from "./db-config";
import { findDuplicateStrings } from "../../text-utils";
import {
DbConfigValidationError,
@@ -18,6 +18,9 @@ export class DbConfigValidator {
public validate(dbConfig: DbConfig): DbConfigValidationError[] {
const ajv = new Ajv({ allErrors: true });
const localDbs = clearLocalDbConfig(dbConfig);
ajv.validate(this.schema, dbConfig);
if (ajv.errors) {
@@ -27,6 +30,13 @@ export class DbConfigValidator {
}));
}
// Add any local db config back so that we have a config
// object that respects its type and validation can happen
// as normal.
if (localDbs) {
dbConfig.databases.local = localDbs;
}
return [
...this.validateDbListNames(dbConfig),
...this.validateDbNames(dbConfig),

View File

@@ -325,6 +325,38 @@ export function removeRemoteOwner(
return config;
}
/**
* Removes local db config from a db config object, if one is set.
* We do this because we don't want to expose this feature to users
* yet (since it's only partially implemented), but we also don't want
* to remove all the code we've already implemented.
* @param config The config object to change.
* @returns Any removed local db config.
*/
export function clearLocalDbConfig(
config: DbConfig,
): LocalDbConfig | undefined {
let localDbs = undefined;
if (config && config.databases && config.databases.local) {
localDbs = config.databases.local;
delete (config.databases as any).local;
}
return localDbs;
}
/**
* Initializes the local db config, if the config object contains
* database configuration.
* @param config The config object to change.
*/
export function initializeLocalDbConfig(config: DbConfig): void {
if (config.databases) {
config.databases.local = { lists: [], databases: [] };
}
}
function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
switch (selected.kind) {
case SelectedDbItemKind.LocalUserDefinedList:

View File

@@ -4,7 +4,7 @@ export type ExpandedDbItem =
| RootLocalExpandedDbItem
| LocalUserDefinedListExpandedDbItem
| RootRemoteExpandedDbItem
| VariantAnalysisUserDefinedListExpandedDbItem;
| RemoteUserDefinedListExpandedDbItem;
export enum ExpandedDbItemKind {
RootLocal = "rootLocal",
@@ -26,7 +26,7 @@ export interface RootRemoteExpandedDbItem {
kind: ExpandedDbItemKind.RootRemote;
}
export interface VariantAnalysisUserDefinedListExpandedDbItem {
export interface RemoteUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.RemoteUserDefinedList;
listName: string;
}
@@ -89,7 +89,7 @@ function mapDbItemToExpandedDbItem(dbItem: DbItem): ExpandedDbItem {
};
case DbItemKind.RootRemote:
return { kind: ExpandedDbItemKind.RootRemote };
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
return {
kind: ExpandedDbItemKind.RemoteUserDefinedList,
listName: dbItem.listName,
@@ -113,7 +113,7 @@ function isDbItemEqualToExpandedDbItem(
);
case DbItemKind.RootRemote:
return expandedDbItem.kind === ExpandedDbItemKind.RootRemote;
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
return (
expandedDbItem.kind === ExpandedDbItemKind.RemoteUserDefinedList &&
expandedDbItem.listName === dbItem.listName

View File

@@ -6,7 +6,7 @@ export function getDbItemName(dbItem: DbItem): string | undefined {
case DbItemKind.RootRemote:
return undefined;
case DbItemKind.LocalList:
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
case DbItemKind.RemoteSystemDefinedList:
return dbItem.listName;
case DbItemKind.RemoteOwner:

View File

@@ -33,7 +33,7 @@ function extractSelected(
}
}
break;
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
for (const repo of dbItem.repos) {
if (repo.selected) {
return repo;
@@ -59,7 +59,7 @@ export function mapDbItemToSelectedDbItem(
listName: dbItem.listName,
};
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
return {
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
listName: dbItem.listName,

View File

@@ -6,7 +6,7 @@ export enum DbItemKind {
LocalDatabase = "LocalDatabase",
RootRemote = "RootRemote",
RemoteSystemDefinedList = "RemoteSystemDefinedList",
VariantAnalysisUserDefinedList = "VariantAnalysisUserDefinedList",
RemoteUserDefinedList = "RemoteUserDefinedList",
RemoteOwner = "RemoteOwner",
RemoteRepo = "RemoteRepo",
}
@@ -14,7 +14,7 @@ export enum DbItemKind {
export const remoteDbKinds = [
DbItemKind.RootRemote,
DbItemKind.RemoteSystemDefinedList,
DbItemKind.VariantAnalysisUserDefinedList,
DbItemKind.RemoteUserDefinedList,
DbItemKind.RemoteOwner,
DbItemKind.RemoteRepo,
];
@@ -70,7 +70,7 @@ export type DbItem =
export type RemoteDbItem =
| RemoteSystemDefinedListDbItem
| VariantAnalysisUserDefinedListDbItem
| RemoteUserDefinedListDbItem
| RemoteOwnerDbItem
| RemoteRepoDbItem;
@@ -82,8 +82,8 @@ export interface RemoteSystemDefinedListDbItem {
listDescription: string;
}
export interface VariantAnalysisUserDefinedListDbItem {
kind: DbItemKind.VariantAnalysisUserDefinedList;
export interface RemoteUserDefinedListDbItem {
kind: DbItemKind.RemoteUserDefinedList;
expanded: boolean;
selected: boolean;
listName: string;
@@ -109,10 +109,10 @@ export function isRemoteSystemDefinedListDbItem(
return dbItem.kind === DbItemKind.RemoteSystemDefinedList;
}
export function isVariantAnalysisUserDefinedListDbItem(
export function isRemoteUserDefinedListDbItem(
dbItem: DbItem,
): dbItem is VariantAnalysisUserDefinedListDbItem {
return dbItem.kind === DbItemKind.VariantAnalysisUserDefinedList;
): dbItem is RemoteUserDefinedListDbItem {
return dbItem.kind === DbItemKind.RemoteUserDefinedList;
}
export function isRemoteOwnerDbItem(
@@ -145,7 +145,7 @@ const SelectableDbItemKinds = [
DbItemKind.LocalList,
DbItemKind.LocalDatabase,
DbItemKind.RemoteSystemDefinedList,
DbItemKind.VariantAnalysisUserDefinedList,
DbItemKind.RemoteUserDefinedList,
DbItemKind.RemoteOwner,
DbItemKind.RemoteRepo,
];
@@ -165,7 +165,7 @@ export function flattenDbItems(dbItems: DbItem[]): DbItem[] {
case DbItemKind.RootRemote:
allItems.push(...flattenDbItems(dbItem.children));
break;
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
allItems.push(...dbItem.repos);
break;
case DbItemKind.LocalDatabase:

View File

@@ -8,7 +8,7 @@ import {
DbListKind,
LocalDatabaseDbItem,
LocalListDbItem,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
} from "./db-item";
import {
updateExpandedItem,
@@ -20,7 +20,7 @@ import {
getSelectedDbItem,
mapDbItemToSelectedDbItem,
} from "./db-item-selection";
import { createLocalTree, createRemoteTree } from "./db-tree-creator";
import { createRemoteTree } from "./db-tree-creator";
import { DbConfigValidationError } from "./db-validation-errors";
export class DbManager {
@@ -58,10 +58,8 @@ export class DbManager {
const expandedItems = this.getExpandedItems();
return ValueResult.ok([
createRemoteTree(configResult.value, expandedItems),
createLocalTree(configResult.value, expandedItems),
]);
const remoteTree = createRemoteTree(configResult.value, expandedItems);
return ValueResult.ok(remoteTree.children);
}
public getConfigPath(): string {
@@ -123,14 +121,12 @@ export class DbManager {
}
public async renameList(
currentDbItem: LocalListDbItem | VariantAnalysisUserDefinedListDbItem,
currentDbItem: LocalListDbItem | RemoteUserDefinedListDbItem,
newName: string,
): Promise<void> {
if (currentDbItem.kind === DbItemKind.LocalList) {
await this.dbConfigStore.renameLocalList(currentDbItem, newName);
} else if (
currentDbItem.kind === DbItemKind.VariantAnalysisUserDefinedList
) {
} else if (currentDbItem.kind === DbItemKind.RemoteUserDefinedList) {
await this.dbConfigStore.renameRemoteList(currentDbItem, newName);
}

View File

@@ -12,7 +12,7 @@ import {
RemoteOwnerDbItem,
RemoteRepoDbItem,
RemoteSystemDefinedListDbItem,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
RootLocalDbItem,
RootRemoteDbItem,
} from "./db-item";
@@ -102,7 +102,7 @@ function createVariantAnalysisUserDefinedList(
list: RemoteRepositoryList,
dbConfig: DbConfig,
expandedItems: ExpandedDbItem[],
): VariantAnalysisUserDefinedListDbItem {
): RemoteUserDefinedListDbItem {
const selected =
dbConfig.selected &&
dbConfig.selected.kind ===
@@ -116,7 +116,7 @@ function createVariantAnalysisUserDefinedList(
);
return {
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
listName: list.name,
repos: list.repositories.map((r) => createRepoItem(r, dbConfig, list.name)),
selected: !!selected,

View File

@@ -34,7 +34,7 @@ export function mapDbItemToTreeViewItem(dbItem: DbItem): DbTreeViewItem {
dbItem.listDescription,
);
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
return createDbTreeViewItemUserDefinedList(
dbItem,
dbItem.listName,

View File

@@ -22,8 +22,7 @@ import {
DbListKind,
LocalDatabaseDbItem,
LocalListDbItem,
remoteDbKinds,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
} from "../db-item";
import { getDbItemName } from "../db-item-naming";
import { DbManager } from "../db-manager";
@@ -124,7 +123,7 @@ export class DbPanel extends DisposableObject {
private async addNewRemoteDatabase(): Promise<void> {
const highlightedItem = await this.getHighlightedDbItem();
if (highlightedItem?.kind === DbItemKind.VariantAnalysisUserDefinedList) {
if (highlightedItem?.kind === DbItemKind.RemoteUserDefinedList) {
await this.addNewRemoteRepo(highlightedItem.listName);
} else if (
highlightedItem?.kind === DbItemKind.RemoteRepo &&
@@ -219,7 +218,7 @@ export class DbPanel extends DisposableObject {
}
private async addNewList(): Promise<void> {
const listKind = await this.getAddNewListKind();
const listKind = DbListKind.Remote;
const listName = await window.showInputBox({
prompt: "Enter a name for the new list",
@@ -237,47 +236,6 @@ export class DbPanel extends DisposableObject {
await this.dbManager.addNewList(listKind, listName);
}
private async getAddNewListKind(): Promise<DbListKind> {
const highlightedItem = await this.getHighlightedDbItem();
if (highlightedItem) {
return remoteDbKinds.includes(highlightedItem.kind)
? DbListKind.Remote
: DbListKind.Local;
} else {
const quickPickItems = [
{
label: "$(cloud) Variant Analysis",
detail: "Add a repository from GitHub",
alwaysShow: true,
kind: DbListKind.Remote,
},
{
label: "$(database) Local",
detail: "Import a database from the cloud or a local file",
alwaysShow: true,
kind: DbListKind.Local,
},
];
const selectedOption = await window.showQuickPick<AddListQuickPickItem>(
quickPickItems,
{
title: "Add a new database",
ignoreFocusOut: true,
},
);
if (!selectedOption) {
// We don't need to display a warning pop-up in this case, since the user just escaped out of the operation.
// We set 'true' to make this a silent exception.
throw new UserCancellationException(
"No database list kind selected",
true,
);
}
return selectedOption.kind;
}
}
private async setSelectedItem(treeViewItem: DbTreeViewItem): Promise<void> {
if (treeViewItem.dbItem === undefined) {
throw new Error(
@@ -313,7 +271,7 @@ export class DbPanel extends DisposableObject {
case DbItemKind.LocalDatabase:
await this.renameLocalDatabaseItem(dbItem, newName);
break;
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
await this.renameVariantAnalysisUserDefinedListItem(dbItem, newName);
break;
default:
@@ -354,7 +312,7 @@ export class DbPanel extends DisposableObject {
}
private async renameVariantAnalysisUserDefinedListItem(
dbItem: VariantAnalysisUserDefinedListDbItem,
dbItem: RemoteUserDefinedListDbItem,
newName: string,
): Promise<void> {
if (dbItem.listName === newName) {

View File

@@ -27,7 +27,7 @@ export function getDbItemActions(dbItem: DbItem): DbTreeViewItemAction[] {
const dbItemKindsThatCanBeRemoved = [
DbItemKind.LocalList,
DbItemKind.VariantAnalysisUserDefinedList,
DbItemKind.RemoteUserDefinedList,
DbItemKind.LocalDatabase,
DbItemKind.RemoteRepo,
DbItemKind.RemoteOwner,
@@ -35,7 +35,7 @@ const dbItemKindsThatCanBeRemoved = [
const dbItemKindsThatCanBeRenamed = [
DbItemKind.LocalList,
DbItemKind.VariantAnalysisUserDefinedList,
DbItemKind.RemoteUserDefinedList,
DbItemKind.LocalDatabase,
];

View File

@@ -7,7 +7,7 @@ import {
RemoteOwnerDbItem,
RemoteRepoDbItem,
RemoteSystemDefinedListDbItem,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
RootLocalDbItem,
RootRemoteDbItem,
} from "../db-item";
@@ -97,7 +97,7 @@ export function createDbTreeViewItemSystemDefinedList(
}
export function createDbTreeViewItemUserDefinedList(
dbItem: LocalListDbItem | VariantAnalysisUserDefinedListDbItem,
dbItem: LocalListDbItem | RemoteUserDefinedListDbItem,
listName: string,
children: DbTreeViewItem[],
): DbTreeViewItem {

View File

@@ -33,7 +33,7 @@ import {
zipArchiveScheme,
} from "./archive-filesystem-provider";
import QuickEvalCodeLensProvider from "./quickEvalCodeLensProvider";
import { CodeQLCliServer, CliVersionConstraint } from "./cli";
import { CodeQLCliServer } from "./cli";
import {
CliConfigListener,
DistributionConfigListener,
@@ -83,7 +83,7 @@ import {
ProgressReporter,
queryServerLogger,
} from "./common";
import { QueryHistoryManager } from "./query-history";
import { QueryHistoryManager } from "./query-history/query-history";
import { CompletedLocalQueryInfo, LocalQueryInfo } from "./query-results";
import { QueryServerClient as LegacyQueryServerClient } from "./legacy-query-server/queryserver-client";
import { QueryServerClient } from "./query-server/queryserver-client";
@@ -109,7 +109,7 @@ import {
handleDownloadPacks,
handleInstallPackDependencies,
} from "./packaging";
import { HistoryItemLabelProvider } from "./history-item-label-provider";
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
import {
exportRemoteQueryResults,
exportSelectedRemoteQueryResults,
@@ -824,17 +824,9 @@ async function activateWithInstalledDistribution(
const path =
selectedQuery?.fsPath || window.activeTextEditor?.document.uri.fsPath;
if (qs !== undefined && path) {
if (await cliServer.cliConstraints.supportsResolveQlref()) {
const resolved = await cliServer.resolveQlref(path);
const uri = Uri.file(resolved.resolvedPath);
await window.showTextDocument(uri, { preview: false });
} else {
void showAndLogErrorMessage(
"Jumping from a .qlref file to the .ql file it references is not " +
"supported with the CLI version you are running.\n" +
`Please upgrade your CLI to version ${CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_QLREF} or later to use this feature.`,
);
}
const resolved = await cliServer.resolveQlref(path);
const uri = Uri.file(resolved.resolvedPath);
await window.showTextDocument(uri, { preview: false });
}
}
@@ -1018,19 +1010,6 @@ async function activateWithInstalledDistribution(
});
}
if (
queryUris.length > 1 &&
!(await cliServer.cliConstraints.supportsNonDestructiveUpgrades())
) {
// Try to upgrade the current database before running any queries
// so that the user isn't confronted with multiple upgrade
// requests for each query to run.
// Only do it if running multiple queries since this check is
// performed on each query run anyway.
// Don't do this with non destructive upgrades as the user won't see anything anyway.
await databaseUI.tryUpgradeCurrentDatabase(progress, token);
}
wrappedProgress({
maxStep: queryUris.length,
step: queryUris.length - queriesRemaining,

View File

@@ -540,7 +540,6 @@ export class CachedOperation<U> {
* `cli.CodeQLCliServer.resolveDatabase` and use the first entry in the
* `languages` property.
*
* @see cli.CliVersionConstraint.supportsLanguageName
* @see cli.CodeQLCliServer.resolveDatabase
*/
export const dbSchemeToLanguage = {

View File

@@ -64,7 +64,7 @@ import {
} from "./pure/bqrs-cli-types";
import { AbstractWebview, WebviewPanelConfig } from "./abstract-webview";
import { PAGE_SIZE } from "./config";
import { HistoryItemLabelProvider } from "./history-item-label-provider";
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
import { telemetryListener } from "./telemetry";
/**

View File

@@ -74,10 +74,7 @@ export class LegacyQueryRunner extends QueryRunner {
token: CancellationToken,
dbItem: DatabaseItem,
): Promise<void> {
if (
dbItem.contents &&
(await this.qs.cliServer.cliConstraints.supportsDatabaseRegistration())
) {
if (dbItem.contents) {
const databases: Dataset[] = [
{
dbDir: dbItem.contents.datasetUri.fsPath,
@@ -97,10 +94,7 @@ export class LegacyQueryRunner extends QueryRunner {
token: CancellationToken,
dbItem: DatabaseItem,
): Promise<void> {
if (
dbItem.contents &&
(await this.qs.cliServer.cliConstraints.supportsDatabaseRegistration())
) {
if (dbItem.contents) {
const databases: Dataset[] = [
{
dbDir: dbItem.contents.datasetUri.fsPath,

View File

@@ -141,14 +141,9 @@ export class QueryServerClient extends DisposableObject {
args.push(this.config.cacheSize.toString());
}
if (await this.cliServer.cliConstraints.supportsDatabaseRegistration()) {
args.push("--require-db-registration");
}
args.push("--require-db-registration");
if (
(await this.cliServer.cliConstraints.supportsOldEvalStats()) &&
!(await this.cliServer.cliConstraints.supportsPerQueryEvalLog())
) {
if (!(await this.cliServer.cliConstraints.supportsPerQueryEvalLog())) {
args.push("--old-eval-stats");
}

View File

@@ -1,5 +1,3 @@
import { createHash } from "crypto";
import { readFile } from "fs-extra";
import * as tmp from "tmp-promise";
import { basename, join } from "path";
import { CancellationToken, Uri } from "vscode";
@@ -21,10 +19,7 @@ import * as messages from "../pure/legacy-messages";
import { InitialQueryInfo, LocalQueryInfo } from "../query-results";
import * as qsClient from "./queryserver-client";
import { getErrorMessage } from "../pure/helpers-pure";
import {
compileDatabaseUpgradeSequence,
upgradeDatabaseExplicit,
} from "./upgrades";
import { compileDatabaseUpgradeSequence } from "./upgrades";
import { QueryEvaluationInfo, QueryWithResults } from "../run-queries-shared";
/**
@@ -233,57 +228,6 @@ export async function clearCacheInDatabase(
return qs.sendRequest(messages.clearCache, params, token, progress);
}
/**
* Compare the dbscheme implied by the query `query` and that of the current database.
* - If they are compatible, do nothing.
* - If they are incompatible but the database can be upgraded, suggest that upgrade.
* - If they are incompatible and the database cannot be upgraded, throw an error.
*/
async function checkDbschemeCompatibility(
cliServer: cli.CodeQLCliServer,
qs: qsClient.QueryServerClient,
query: QueryInProgress,
qlProgram: messages.QlProgram,
dbItem: DatabaseItem,
progress: ProgressCallback,
token: CancellationToken,
): Promise<void> {
const searchPath = getOnDiskWorkspaceFolders();
if (dbItem.contents?.dbSchemeUri !== undefined) {
const { finalDbscheme } = await cliServer.resolveUpgrades(
dbItem.contents.dbSchemeUri.fsPath,
searchPath,
false,
);
const hash = async function (filename: string): Promise<string> {
return createHash("sha256")
.update(await readFile(filename))
.digest("hex");
};
// At this point, we have learned about three dbschemes:
// the dbscheme of the actual database we're querying.
const dbschemeOfDb = await hash(dbItem.contents.dbSchemeUri.fsPath);
// the dbscheme of the query we're running, including the library we've resolved it to use.
const dbschemeOfLib = await hash(query.queryDbscheme);
// the database we're able to upgrade to
const upgradableTo = await hash(finalDbscheme);
if (upgradableTo != dbschemeOfLib) {
reportNoUpgradePath(qlProgram, query);
}
if (upgradableTo == dbschemeOfLib && dbschemeOfDb != dbschemeOfLib) {
// Try to upgrade the database
await upgradeDatabaseExplicit(qs, dbItem, progress, token);
}
}
}
function reportNoUpgradePath(
qlProgram: messages.QlProgram,
query: QueryInProgress,
@@ -309,11 +253,8 @@ async function compileNonDestructiveUpgrade(
throw new Error("Database is invalid, and cannot be upgraded.");
}
// When packaging is used, dependencies may exist outside of the workspace and they are always on the resolved search path.
// When packaging is not used, all dependencies are in the workspace.
const upgradesPath = (await qs.cliServer.cliConstraints.supportsPackaging())
? qlProgram.libraryPath
: getOnDiskWorkspaceFolders();
// Dependencies may exist outside of the workspace and they are always on the resolved search path.
const upgradesPath = qlProgram.libraryPath;
const { scripts, matchesTarget } = await qs.cliServer.resolveUpgrades(
dbItem.contents.dbSchemeUri.fsPath,
@@ -409,33 +350,27 @@ export async function compileAndRunQueryAgainstDatabase(
const metadata = await tryGetQueryMetadata(cliServer, qlProgram.queryPath);
let availableMlModels: cli.MlModelInfo[] = [];
if (!(await cliServer.cliConstraints.supportsResolveMlModels())) {
void extLogger.log(
"Resolving ML models is unsupported by this version of the CLI. Running the query without any ML models.",
);
} else {
try {
availableMlModels = (
await cliServer.resolveMlModels(
diskWorkspaceFolders,
initialInfo.queryPath,
)
).models;
if (availableMlModels.length) {
void extLogger.log(
`Found available ML models at the following paths: ${availableMlModels
.map((x) => `'${x.path}'`)
.join(", ")}.`,
);
} else {
void extLogger.log("Did not find any available ML models.");
}
} catch (e) {
const message =
`Couldn't resolve available ML models for ${qlProgram.queryPath}. Running the ` +
`query without any ML models: ${e}.`;
void showAndLogErrorMessage(message);
try {
availableMlModels = (
await cliServer.resolveMlModels(
diskWorkspaceFolders,
initialInfo.queryPath,
)
).models;
if (availableMlModels.length) {
void extLogger.log(
`Found available ML models at the following paths: ${availableMlModels
.map((x) => `'${x.path}'`)
.join(", ")}.`,
);
} else {
void extLogger.log("Did not find any available ML models.");
}
} catch (e) {
const message =
`Couldn't resolve available ML models for ${qlProgram.queryPath}. Running the ` +
`query without any ML models: ${e}.`;
void showAndLogErrorMessage(message);
}
const hasMetadataFile = await dbItem.hasMetadataFile();
@@ -452,29 +387,16 @@ export async function compileAndRunQueryAgainstDatabase(
let upgradeDir: tmp.DirectoryResult | undefined;
try {
let upgradeQlo;
if (await cliServer.cliConstraints.supportsNonDestructiveUpgrades()) {
upgradeDir = await tmp.dir({ dir: upgradesTmpDir, unsafeCleanup: true });
upgradeQlo = await compileNonDestructiveUpgrade(
qs,
upgradeDir,
query,
qlProgram,
dbItem,
progress,
token,
);
} else {
await checkDbschemeCompatibility(
cliServer,
qs,
query,
qlProgram,
dbItem,
progress,
token,
);
}
upgradeDir = await tmp.dir({ dir: upgradesTmpDir, unsafeCleanup: true });
const upgradeQlo = await compileNonDestructiveUpgrade(
qs,
upgradeDir,
query,
qlProgram,
dbItem,
progress,
token,
);
let errors;
try {
errors = await query.compile(qs, qlProgram, progress, token);

View File

@@ -37,11 +37,6 @@ export async function compileDatabaseUpgradeSequence(
) {
throw new Error("Database is invalid, and cannot be upgraded.");
}
if (!(await qs.cliServer.cliConstraints.supportsNonDestructiveUpgrades())) {
throw new Error(
"The version of codeql is too old to run non-destructive upgrades.",
);
}
// If possible just compile the upgrade sequence
return await qs.sendRequest(
messages.compileUpgradeSequence,

View File

@@ -1,7 +1,7 @@
import { Diagnostic, DiagnosticSeverity, languages, Range, Uri } from "vscode";
import { DisposableObject } from "../pure/disposable-object";
import { QueryHistoryManager } from "../query-history";
import { QueryHistoryInfo } from "../query-history-info";
import { QueryHistoryManager } from "../query-history/query-history";
import { QueryHistoryInfo } from "../query-history/query-history-info";
import {
EvaluationLogProblemReporter,
EvaluationLogScannerSet,

View File

@@ -1,4 +1,4 @@
import { CliVersionConstraint, CodeQLCliServer } from "./cli";
import { CodeQLCliServer } from "./cli";
import {
getOnDiskWorkspaceFolders,
showAndLogErrorMessage,
@@ -30,11 +30,6 @@ export async function handleDownloadPacks(
cliServer: CodeQLCliServer,
progress: ProgressCallback,
): Promise<void> {
if (!(await cliServer.cliConstraints.supportsPackaging())) {
throw new Error(
`Packaging commands are not supported by this version of CodeQL. Please upgrade to v${CliVersionConstraint.CLI_VERSION_WITH_PACKAGING} or later.`,
);
}
progress({
message: "Choose packs to download",
step: 1,
@@ -92,11 +87,6 @@ export async function handleInstallPackDependencies(
cliServer: CodeQLCliServer,
progress: ProgressCallback,
): Promise<void> {
if (!(await cliServer.cliConstraints.supportsPackaging())) {
throw new Error(
`Packaging commands are not supported by this version of CodeQL. Please upgrade to v${CliVersionConstraint.CLI_VERSION_WITH_PACKAGING} or later.`,
);
}
progress({
message: "Choose packs to install dependencies for",
step: 1,

View File

@@ -46,14 +46,14 @@ export const REPO_REGEX = /^[a-zA-Z0-9-_\.]+\/[a-zA-Z0-9-_\.]+$/;
*/
export const OWNER_REGEX = /^[a-zA-Z0-9-_\.]+$/;
export function getErrorMessage(e: any) {
export function getErrorMessage(e: unknown) {
return e instanceof Error ? e.message : String(e);
}
export function getErrorStack(e: any) {
export function getErrorStack(e: unknown) {
return e instanceof Error ? e.stack ?? "" : "";
}
export function asError(e: any): Error {
export function asError(e: unknown): Error {
return e instanceof Error ? e : new Error(String(e));
}

View File

@@ -1,17 +1,17 @@
import { env } from "vscode";
import { basename } from "path";
import { QueryHistoryConfig } from "./config";
import { LocalQueryInfo } from "./query-results";
import { QueryHistoryConfig } from "../config";
import { LocalQueryInfo } from "../query-results";
import {
buildRepoLabel,
getRawQueryName,
QueryHistoryInfo,
} from "./query-history-info";
import { RemoteQueryHistoryItem } from "./remote-queries/remote-query-history-item";
import { VariantAnalysisHistoryItem } from "./remote-queries/variant-analysis-history-item";
import { assertNever } from "./pure/helpers-pure";
import { pluralize } from "./pure/word";
import { humanizeQueryStatus } from "./query-status";
import { RemoteQueryHistoryItem } from "../remote-queries/remote-query-history-item";
import { VariantAnalysisHistoryItem } from "./variant-analysis-history-item";
import { assertNever } from "../pure/helpers-pure";
import { pluralize } from "../pure/word";
import { humanizeQueryStatus } from "../query-status";
interface InterpolateReplacements {
t: string; // Start time

View File

@@ -1,12 +1,12 @@
import { RemoteQueryHistoryItem } from "./remote-queries/remote-query-history-item";
import { VariantAnalysisHistoryItem } from "./remote-queries/variant-analysis-history-item";
import { LocalQueryInfo } from "./query-results";
import { assertNever } from "./pure/helpers-pure";
import { pluralize } from "./pure/word";
import { RemoteQueryHistoryItem } from "../remote-queries/remote-query-history-item";
import { VariantAnalysisHistoryItem } from "./variant-analysis-history-item";
import { LocalQueryInfo } from "../query-results";
import { assertNever } from "../pure/helpers-pure";
import { pluralize } from "../pure/word";
import {
hasRepoScanCompleted,
getActionsWorkflowRunUrl as getVariantAnalysisActionsWorkflowRunUrl,
} from "./remote-queries/shared/variant-analysis";
} from "../remote-queries/shared/variant-analysis";
export type QueryHistoryInfo =
| LocalQueryInfo

View File

@@ -2,7 +2,7 @@ import { pathExists, readdir, stat, remove, readFile } from "fs-extra";
import { EOL } from "os";
import { join } from "path";
import { Disposable, ExtensionContext } from "vscode";
import { extLogger } from "./common";
import { extLogger } from "../common";
import { QueryHistoryManager } from "./query-history";
const LAST_SCRUB_TIME_KEY = "lastScrubTime";

View File

@@ -17,58 +17,58 @@ import {
window,
workspace,
} from "vscode";
import { QueryHistoryConfig } from "./config";
import { QueryHistoryConfig } from "../config";
import {
showAndLogErrorMessage,
showAndLogInformationMessage,
showAndLogWarningMessage,
showBinaryChoiceDialog,
showInformationMessageWithAction,
} from "./helpers";
import { extLogger } from "./common";
} from "../helpers";
import { extLogger } from "../common";
import { URLSearchParams } from "url";
import { DisposableObject } from "./pure/disposable-object";
import { commandRunner } from "./commandRunner";
import { ONE_HOUR_IN_MS, TWO_HOURS_IN_MS } from "./pure/time";
import { DisposableObject } from "../pure/disposable-object";
import { commandRunner } from "../commandRunner";
import { ONE_HOUR_IN_MS, TWO_HOURS_IN_MS } from "../pure/time";
import {
assertNever,
getErrorMessage,
getErrorStack,
} from "./pure/helpers-pure";
import { CompletedLocalQueryInfo, LocalQueryInfo } from "./query-results";
} from "../pure/helpers-pure";
import { CompletedLocalQueryInfo, LocalQueryInfo } from "../query-results";
import {
getActionsWorkflowRunUrl,
getQueryId,
getQueryText,
QueryHistoryInfo,
} from "./query-history-info";
import { DatabaseManager } from "./databases";
import { DatabaseManager } from "../databases";
import { registerQueryHistoryScrubber } from "./query-history-scrubber";
import {
QueryStatus,
variantAnalysisStatusToQueryStatus,
} from "./query-status";
} from "../query-status";
import {
deserializeQueryHistory,
serializeQueryHistory,
} from "./query-serialization";
} from "../query-serialization";
import { pathExists } from "fs-extra";
import { CliVersionConstraint } from "./cli";
import { CliVersionConstraint } from "../cli";
import { HistoryItemLabelProvider } from "./history-item-label-provider";
import { cancelRemoteQuery } from "./remote-queries/gh-api/gh-actions-api-client";
import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager";
import { RemoteQueryHistoryItem } from "./remote-queries/remote-query-history-item";
import { ResultsView } from "./interface";
import { WebviewReveal } from "./interface-utils";
import { EvalLogViewer } from "./eval-log-viewer";
import EvalLogTreeBuilder from "./eval-log-tree-builder";
import { EvalLogData, parseViewerData } from "./pure/log-summary-parser";
import { QueryWithResults } from "./run-queries-shared";
import { QueryRunner } from "./queryRunner";
import { VariantAnalysisManager } from "./remote-queries/variant-analysis-manager";
import { VariantAnalysisHistoryItem } from "./remote-queries/variant-analysis-history-item";
import { getTotalResultCount } from "./remote-queries/shared/variant-analysis";
import { App } from "./common/app";
import { cancelRemoteQuery } from "../remote-queries/gh-api/gh-actions-api-client";
import { RemoteQueriesManager } from "../remote-queries/remote-queries-manager";
import { RemoteQueryHistoryItem } from "../remote-queries/remote-query-history-item";
import { ResultsView } from "../interface";
import { WebviewReveal } from "../interface-utils";
import { EvalLogViewer } from "../eval-log-viewer";
import EvalLogTreeBuilder from "../eval-log-tree-builder";
import { EvalLogData, parseViewerData } from "../pure/log-summary-parser";
import { QueryWithResults } from "../run-queries-shared";
import { QueryRunner } from "../queryRunner";
import { VariantAnalysisManager } from "../remote-queries/variant-analysis-manager";
import { VariantAnalysisHistoryItem } from "./variant-analysis-history-item";
import { getTotalResultCount } from "../remote-queries/shared/variant-analysis";
import { App } from "../common/app";
/**
* query-history.ts
@@ -1701,6 +1701,7 @@ the file in the file explorer and dragging it into the workspace.`,
throw new Error("No other queries available to compare with.");
}
const choice = await window.showQuickPick(comparableQueryLabels);
return choice?.query;
}

View File

@@ -1,5 +1,5 @@
import { QueryStatus } from "../query-status";
import { VariantAnalysis } from "./shared/variant-analysis";
import { VariantAnalysis } from "../remote-queries/shared/variant-analysis";
/**
* Information about a variant analysis.

View File

@@ -8,7 +8,7 @@ import {
getErrorStack,
} from "./pure/helpers-pure";
import { CompletedQueryInfo, LocalQueryInfo } from "./query-results";
import { QueryHistoryInfo } from "./query-history-info";
import { QueryHistoryInfo } from "./query-history/query-history-info";
import { QueryStatus } from "./query-status";
import { QueryEvaluationInfo } from "./run-queries-shared";
import { QueryResultType } from "./pure/legacy-messages";

View File

@@ -84,10 +84,7 @@ export class NewQueryRunner extends QueryRunner {
token: CancellationToken,
dbItem: DatabaseItem,
): Promise<void> {
if (
dbItem.contents &&
(await this.qs.cliServer.cliConstraints.supportsDatabaseRegistration())
) {
if (dbItem.contents) {
const databases: string[] = [dbItem.databaseUri.fsPath];
await this.qs.sendRequest(
deregisterDatabases,
@@ -102,10 +99,7 @@ export class NewQueryRunner extends QueryRunner {
token: CancellationToken,
dbItem: DatabaseItem,
): Promise<void> {
if (
dbItem.contents &&
(await this.qs.cliServer.cliConstraints.supportsDatabaseRegistration())
) {
if (dbItem.contents) {
const databases: string[] = [dbItem.databaseUri.fsPath];
await this.qs.sendRequest(
registerDatabases,
@@ -129,7 +123,7 @@ export class NewQueryRunner extends QueryRunner {
const noItem = { title: "No", isCloseAffordance: true };
const dialogOptions: vscode.MessageItem[] = [yesItem, noItem];
const message = `Should the database ${dbItem.databaseUri.fsPath} be destructively upgraded?\n\nThis should not be necessary to run queries
const message = `Should the database ${dbItem.databaseUri.fsPath} be destructively upgraded?\n\nThis should not be necessary to run queries
as we will non-destructively update it anyway.`;
const chosenItem = await vscode.window.showInformationMessage(
message,

View File

@@ -12,7 +12,7 @@ import {
import { ProgressCallback, UserCancellationException } from "../commandRunner";
import { showInformationMessageWithAction } from "../helpers";
import { extLogger } from "../common";
import { QueryHistoryManager } from "../query-history";
import { QueryHistoryManager } from "../query-history/query-history";
import { createGist } from "./gh-api/gh-api-client";
import { RemoteQueriesManager } from "./remote-queries-manager";
import {

View File

@@ -28,7 +28,7 @@ import {
} from "./shared/remote-query-result";
import { showAndLogWarningMessage } from "../helpers";
import { URLSearchParams } from "url";
import { SHOW_QUERY_TEXT_MSG } from "../query-history";
import { SHOW_QUERY_TEXT_MSG } from "../query-history/query-history";
import { AnalysesResultsManager } from "./analyses-results-manager";
import { AnalysisResults } from "./shared/analysis-result";
import { humanizeUnit } from "../pure/time";

View File

@@ -46,7 +46,7 @@ export async function getRepositorySelection(
);
case DbItemKind.RemoteSystemDefinedList:
return { repositoryLists: [selectedDbItem.listName] };
case DbItemKind.VariantAnalysisUserDefinedList:
case DbItemKind.RemoteUserDefinedList:
if (selectedDbItem.repos.length === 0) {
throw new UserCancellationException(
"The selected repository list is empty. Please add repositories to it before running a variant analysis.",

View File

@@ -137,7 +137,7 @@ async function generateQueryPack(
"--no-default-compilation-cache",
`--compilation-cache=${ccache}`,
];
} else if (await cliServer.cliConstraints.supportsNoPrecompile()) {
} else {
precompilationOpts = ["--no-precompile"];
}
@@ -227,12 +227,6 @@ export async function prepareRemoteQueryRun(
token: CancellationToken,
dbManager?: DbManager, // the dbManager is only needed when variantAnalysisReposPanel is enabled
): Promise<PreparedRemoteQuery> {
if (!(await cliServer.cliConstraints.supportsRemoteQueries())) {
throw new Error(
`Variant analysis is not supported by this version of CodeQL. Please upgrade to v${cli.CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES} or later.`,
);
}
if (!uri?.fsPath.endsWith(".ql")) {
throw new UserCancellationException("Not a CodeQL query file.");
}

View File

@@ -1,7 +1,7 @@
import { TextDocumentContentProvider, Uri } from "vscode";
import { URLSearchParams } from "url";
import { showAndLogWarningMessage } from "../helpers";
import { SHOW_QUERY_TEXT_MSG } from "../query-history";
import { SHOW_QUERY_TEXT_MSG } from "../query-history/query-history";
import { VariantAnalysisManager } from "./variant-analysis-manager";
export const createVariantAnalysisContentProvider = (

View File

@@ -33,7 +33,7 @@ import { DatabaseManager } from "./databases";
import { DecodedBqrsChunk } from "./pure/bqrs-cli-types";
import { extLogger, Logger } from "./common";
import { generateSummarySymbolsFile } from "./log-insights/summary-parser";
import { asError } from "./pure/helpers-pure";
import { getErrorMessage } from "./pure/helpers-pure";
/**
* run-queries.ts
@@ -270,9 +270,10 @@ export class QueryEvaluationInfo {
);
return this.evalLogSummaryPath;
} catch (e) {
const err = asError(e);
void showAndLogWarningMessage(
`Failed to generate human-readable structured evaluator log summary. Reason: ${err.message}`,
`Failed to generate human-readable structured evaluator log summary. Reason: ${getErrorMessage(
e,
)}`,
);
return undefined;
}

View File

@@ -1,4 +1,5 @@
[
"v2.12.1",
"v2.11.6",
"v2.7.6",
"v2.8.5",

View File

@@ -8,7 +8,7 @@ import {
RemoteOwnerDbItem,
RemoteRepoDbItem,
RemoteSystemDefinedListDbItem,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
RootLocalDbItem,
RootRemoteDbItem,
} from "../../src/databases/db-item";
@@ -79,7 +79,7 @@ export function createRemoteSystemDefinedListDbItem({
};
}
export function createVariantAnalysisUserDefinedListDbItem({
export function createRemoteUserDefinedListDbItem({
expanded = false,
selected = false,
listName = `list${faker.datatype.number()}`,
@@ -93,9 +93,9 @@ export function createVariantAnalysisUserDefinedListDbItem({
expanded?: boolean;
selected?: boolean;
repos?: RemoteRepoDbItem[];
} = {}): VariantAnalysisUserDefinedListDbItem {
} = {}): RemoteUserDefinedListDbItem {
return {
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
expanded,
selected,
listName,

View File

@@ -1,7 +1,7 @@
import { VariantAnalysisHistoryItem } from "../../../src/remote-queries/variant-analysis-history-item";
import { VariantAnalysisHistoryItem } from "../../../src/query-history/variant-analysis-history-item";
import { QueryStatus } from "../../../src/query-status";
import { VariantAnalysisStatus } from "../../../src/remote-queries/shared/variant-analysis";
import { createMockVariantAnalysis } from "./shared/variant-analysis";
import { createMockVariantAnalysis } from "../remote-queries/shared/variant-analysis";
export function createMockVariantAnalysisHistoryItem({
historyItemStatus = QueryStatus.InProgress,

View File

@@ -9,40 +9,6 @@
],
"owners": [],
"repositories": ["owner/repo1", "owner/repo2", "owner/repo3"]
},
"local": {
"lists": [
{
"name": "localList1",
"databases": [
{
"name": "foo/bar",
"dateAdded": 1668096745193,
"language": "go",
"storagePath": "/path/to/database/"
}
]
},
{
"name": "localList2",
"databases": [
{
"name": "foo/baz",
"dateAdded": 1668096760848,
"language": "javascript",
"storagePath": "/path/to/database/"
}
]
}
],
"databases": [
{
"name": "example-db",
"dateAdded": 1668096927267,
"language": "ruby",
"storagePath": "/path/to/database/"
}
]
}
},
"selected": {

View File

@@ -4,10 +4,6 @@
"repositoryLists": [],
"owners": [],
"repositories": []
},
"local": {
"lists": [],
"databases": []
}
}
}

View File

@@ -16,7 +16,7 @@ import {
createLocalListDbItem,
createRemoteOwnerDbItem,
createRemoteRepoDbItem,
createVariantAnalysisUserDefinedListDbItem,
createRemoteUserDefinedListDbItem,
} from "../../../factories/db-item-factories";
import { createMockApp } from "../../../__mocks__/appMock";
@@ -82,25 +82,6 @@ describe("db config store", () => {
"owner/repo2",
"owner/repo3",
]);
expect(config.databases.local.lists).toHaveLength(2);
expect(config.databases.local.lists[0]).toEqual({
name: "localList1",
databases: [
{
name: "foo/bar",
dateAdded: 1668096745193,
language: "go",
storagePath: "/path/to/database/",
},
],
});
expect(config.databases.local.databases).toHaveLength(1);
expect(config.databases.local.databases[0]).toEqual({
name: "example-db",
dateAdded: 1668096927267,
language: "ruby",
storagePath: "/path/to/database/",
});
expect(config.selected).toEqual({
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
listName: "repoList1",
@@ -272,7 +253,7 @@ describe("db config store", () => {
configStore.dispose();
});
it("should add a local list", async () => {
it.skip("should add a local list", async () => {
// Initial set up
const dbConfig = createDbConfig();
@@ -348,7 +329,7 @@ describe("db config store", () => {
const configStore = await initializeConfig(dbConfig, configPath, app);
// Rename
const currentDbItem = createVariantAnalysisUserDefinedListDbItem({
const currentDbItem = createRemoteUserDefinedListDbItem({
listName: "list1",
});
await configStore.renameRemoteList(currentDbItem, "listRenamed");
@@ -370,7 +351,7 @@ describe("db config store", () => {
configStore.dispose();
});
it("should allow renaming a local list", async () => {
it.skip("should allow renaming a local list", async () => {
// Initial set up
const dbConfig = createDbConfig({
localLists: [
@@ -413,7 +394,7 @@ describe("db config store", () => {
configStore.dispose();
});
it("should allow renaming of a local db", async () => {
it.skip("should allow renaming of a local db", async () => {
// Initial set up
const dbConfig = createDbConfig({
localLists: [
@@ -477,7 +458,7 @@ describe("db config store", () => {
const configStore = await initializeConfig(dbConfig, configPath, app);
// Rename
const currentDbItem = createVariantAnalysisUserDefinedListDbItem({
const currentDbItem = createRemoteUserDefinedListDbItem({
listName: "list1",
});
await expect(
@@ -555,7 +536,7 @@ describe("db config store", () => {
const configStore = await initializeConfig(dbConfig, configPath, app);
// Remove
const currentDbItem = createVariantAnalysisUserDefinedListDbItem({
const currentDbItem = createRemoteUserDefinedListDbItem({
listName: "list1",
});
await configStore.removeDbItem(currentDbItem);
@@ -723,7 +704,7 @@ describe("db config store", () => {
configStore.dispose();
});
it("should return true if a local db and local list exists", async () => {
it.skip("should return true if a local db and local list exists", async () => {
// Initial set up
const dbConfig = createDbConfig({
localLists: [
@@ -772,8 +753,11 @@ describe("db config store", () => {
configPath: string,
app: App,
): Promise<DbConfigStore> {
if (dbConfig && dbConfig.databases && dbConfig.databases.local) {
delete (dbConfig.databases as any).local;
}
// const config = clearLocalDbs(dbConfig);
await writeJSON(configPath, dbConfig);
const configStore = new DbConfigStore(app, false);
await configStore.initialize();

View File

@@ -31,18 +31,14 @@ describe("db config validation", () => {
const validationOutput = configValidator.validate(dbConfig);
expect(validationOutput).toHaveLength(3);
expect(validationOutput).toHaveLength(2);
expect(validationOutput[0]).toEqual({
kind: DbConfigValidationErrorKind.InvalidConfig,
message: "/databases must have required property 'local'",
});
expect(validationOutput[1]).toEqual({
kind: DbConfigValidationErrorKind.InvalidConfig,
message:
"/databases/variantAnalysis must have required property 'owners'",
});
expect(validationOutput[2]).toEqual({
expect(validationOutput[1]).toEqual({
kind: DbConfigValidationErrorKind.InvalidConfig,
message: "/databases/variantAnalysis must NOT have additional properties",
});

View File

@@ -7,7 +7,7 @@ import {
} from "../../../src/databases/db-item-expansion";
import {
createLocalListDbItem,
createVariantAnalysisUserDefinedListDbItem,
createRemoteUserDefinedListDbItem,
createRootLocalDbItem,
createRootRemoteDbItem,
} from "../../factories/db-item-factories";
@@ -25,7 +25,7 @@ describe("db item expansion", () => {
},
];
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName: "list2",
});
@@ -45,7 +45,7 @@ describe("db item expansion", () => {
});
it("should add an expanded item to an empty list", () => {
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName: "list2",
});
@@ -70,7 +70,7 @@ describe("db item expansion", () => {
},
];
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName: "list1",
});
@@ -126,7 +126,7 @@ describe("db item expansion", () => {
},
];
const currentDbItem = createVariantAnalysisUserDefinedListDbItem({
const currentDbItem = createRemoteUserDefinedListDbItem({
listName: "list1",
});
@@ -184,7 +184,7 @@ describe("db item expansion", () => {
const dbItems = [
createRootRemoteDbItem({
children: [
createVariantAnalysisUserDefinedListDbItem({
createRemoteUserDefinedListDbItem({
listName: "list2",
}),
],

View File

@@ -5,7 +5,7 @@ import {
createRemoteOwnerDbItem,
createRemoteRepoDbItem,
createRemoteSystemDefinedListDbItem,
createVariantAnalysisUserDefinedListDbItem,
createRemoteUserDefinedListDbItem,
createRootLocalDbItem,
createRootRemoteDbItem,
} from "../../factories/db-item-factories";
@@ -37,7 +37,7 @@ describe("db item naming", () => {
});
it("return list name for remote user defined list db item", () => {
const dbItem = createVariantAnalysisUserDefinedListDbItem();
const dbItem = createRemoteUserDefinedListDbItem();
const name = getDbItemName(dbItem);

View File

@@ -6,7 +6,7 @@ import {
createRemoteOwnerDbItem,
createRemoteRepoDbItem,
createRemoteSystemDefinedListDbItem,
createVariantAnalysisUserDefinedListDbItem,
createRemoteUserDefinedListDbItem,
createRootLocalDbItem,
createRootRemoteDbItem,
} from "../../factories/db-item-factories";
@@ -18,7 +18,7 @@ describe("db item selection", () => {
children: [
createRemoteSystemDefinedListDbItem(),
createRemoteOwnerDbItem(),
createVariantAnalysisUserDefinedListDbItem(),
createRemoteUserDefinedListDbItem(),
],
}),
createRootLocalDbItem({
@@ -67,7 +67,7 @@ describe("db item selection", () => {
children: [
createRemoteSystemDefinedListDbItem(),
createRemoteOwnerDbItem(),
createVariantAnalysisUserDefinedListDbItem({
createRemoteUserDefinedListDbItem({
listName: "my list",
selected: true,
repos: [
@@ -80,7 +80,7 @@ describe("db item selection", () => {
];
expect(getSelectedDbItem(dbItems)).toEqual({
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
expanded: false,
listName: "my list",
repos: [
@@ -105,7 +105,7 @@ describe("db item selection", () => {
children: [
createRemoteSystemDefinedListDbItem(),
createRemoteOwnerDbItem(),
createVariantAnalysisUserDefinedListDbItem(),
createRemoteUserDefinedListDbItem(),
],
}),
createRemoteSystemDefinedListDbItem({
@@ -131,7 +131,7 @@ describe("db item selection", () => {
children: [
createRemoteSystemDefinedListDbItem(),
createRemoteOwnerDbItem(),
createVariantAnalysisUserDefinedListDbItem({
createRemoteUserDefinedListDbItem({
repos: [],
selected: true,
listName: "list84",
@@ -141,7 +141,7 @@ describe("db item selection", () => {
];
expect(getSelectedDbItem(dbItems)).toEqual({
expanded: false,
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
listName: "list84",
repos: [],
selected: true,

View File

@@ -9,7 +9,7 @@ import {
createRemoteOwnerDbItem,
createRemoteRepoDbItem,
createRemoteSystemDefinedListDbItem,
createVariantAnalysisUserDefinedListDbItem,
createRemoteUserDefinedListDbItem,
createRootLocalDbItem,
createRootRemoteDbItem,
} from "../../factories/db-item-factories";
@@ -22,14 +22,14 @@ describe("DbItem", () => {
children: [
createRemoteSystemDefinedListDbItem({ listName: "top10" }),
createRemoteSystemDefinedListDbItem({ listName: "top100" }),
createVariantAnalysisUserDefinedListDbItem({
createRemoteUserDefinedListDbItem({
listName: "remote-list1",
repos: [
createRemoteRepoDbItem({ repoFullName: "owner1/repo1" }),
createRemoteRepoDbItem({ repoFullName: "owner1/repo2" }),
],
}),
createVariantAnalysisUserDefinedListDbItem({
createRemoteUserDefinedListDbItem({
listName: "remote-list2",
repos: [
createRemoteRepoDbItem({ repoFullName: "owner2/repo1" }),
@@ -82,7 +82,7 @@ describe("DbItem", () => {
expect(
items.find(
(item) =>
item.kind === DbItemKind.VariantAnalysisUserDefinedList &&
item.kind === DbItemKind.RemoteUserDefinedList &&
item.listName === name,
),
).toBeDefined();

View File

@@ -7,29 +7,30 @@ import {
} from "../../../src/databases/config/db-config";
import { DbConfigStore } from "../../../src/databases/config/db-config-store";
import {
DbListKind,
flattenDbItems,
isLocalDatabaseDbItem,
isLocalListDbItem,
isRemoteOwnerDbItem,
isRemoteRepoDbItem,
isVariantAnalysisUserDefinedListDbItem,
isRemoteUserDefinedListDbItem,
LocalDatabaseDbItem,
LocalListDbItem,
RemoteOwnerDbItem,
RemoteRepoDbItem,
VariantAnalysisUserDefinedListDbItem,
RemoteUserDefinedListDbItem,
} from "../../../src/databases/db-item";
import {
ExpandedDbItem,
ExpandedDbItemKind,
VariantAnalysisUserDefinedListExpandedDbItem,
RemoteUserDefinedListExpandedDbItem,
} from "../../../src/databases/db-item-expansion";
import { DbManager } from "../../../src/databases/db-manager";
import {
createDbConfig,
createLocalDbConfigItem,
} from "../../factories/db-config-factories";
import { createVariantAnalysisUserDefinedListDbItem } from "../../factories/db-item-factories";
import { createRemoteUserDefinedListDbItem } from "../../factories/db-item-factories";
import { createMockApp } from "../../__mocks__/appMock";
// Note: Although these are "unit tests" (i.e. not integrating with VS Code), they do
@@ -67,6 +68,189 @@ describe("db manager", () => {
dbConfigStore.dispose();
});
describe("adding items", () => {
describe("adding a remote repo", () => {
it("should add a new remote repo", async () => {
const dbConfig: DbConfig = createDbConfig({
remoteRepos: ["owner1/repo1"],
});
await saveDbConfig(dbConfig);
await dbManager.addNewRemoteRepo("owner2/repo2");
const dbConfigFileContents = await readDbConfigDirectly();
expect(
dbConfigFileContents.databases.variantAnalysis.repositories.length,
).toBe(2);
expect(
dbConfigFileContents.databases.variantAnalysis.repositories[1],
).toEqual("owner2/repo2");
});
it("should add a new remote repo to a user defined list", async () => {
const dbConfig: DbConfig = createDbConfig({
remoteLists: [
{
name: "my-list-1",
repositories: ["owner1/repo1"],
},
],
});
await saveDbConfig(dbConfig);
await dbManager.addNewRemoteRepo("owner2/repo2", "my-list-1");
const dbConfigFileContents = await readDbConfigDirectly();
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists.length,
).toBe(1);
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists[0],
).toEqual({
name: "my-list-1",
repositories: ["owner1/repo1", "owner2/repo2"],
});
});
it("should not allow adding a new remote db with empty name", async () => {
const dbConfig = createDbConfig();
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteRepo("")).rejects.toThrow(
new Error("Repository name cannot be empty"),
);
});
it("should not allow adding a remote db with duplicate name", async () => {
const dbConfig = createDbConfig({
remoteRepos: ["owner1/repo1"],
});
await saveDbConfig(dbConfig);
await expect(
dbManager.addNewRemoteRepo("owner1/repo1"),
).rejects.toThrow(
new Error(
"A variant analysis repository with the name 'owner1/repo1' already exists",
),
);
});
});
describe("adding a list", () => {
it("should add a new remote list", async () => {
const dbConfig: DbConfig = createDbConfig({
remoteLists: [
{
name: "my-list-1",
repositories: ["owner1/repo1", "owner1/repo2"],
},
],
selected: {
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
listName: "my-list-1",
},
});
await saveDbConfig(dbConfig);
await dbManager.addNewList(DbListKind.Remote, "my-list-2");
const dbConfigFileContents = await readDbConfigDirectly();
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists.length,
).toBe(2);
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists[1],
).toEqual({
name: "my-list-2",
repositories: [],
});
});
it.skip("should add a new local list", async () => {
const dbConfig: DbConfig = createDbConfig({
localLists: [
{
name: "my-list-1",
databases: [],
},
],
});
await saveDbConfig(dbConfig);
await dbManager.addNewList(DbListKind.Local, "my-list-2");
const dbConfigFileContents = await readDbConfigDirectly();
expect(dbConfigFileContents.databases.local.lists.length).toBe(2);
expect(dbConfigFileContents.databases.local.lists[1]).toEqual({
name: "my-list-2",
databases: [],
});
});
it("should not allow adding a new list with empty name", async () => {
const dbConfig = createDbConfig();
await saveDbConfig(dbConfig);
await expect(
dbManager.addNewList(DbListKind.Remote, ""),
).rejects.toThrow(new Error("List name cannot be empty"));
});
it("should not allow adding a list with duplicate name", async () => {
const dbConfig = createDbConfig({
remoteLists: [
{
name: "my-list-1",
repositories: ["owner1/repo1", "owner1/repo2"],
},
],
});
await saveDbConfig(dbConfig);
await expect(
dbManager.addNewList(DbListKind.Remote, "my-list-1"),
).rejects.toThrow(
new Error(
"A variant analysis list with the name 'my-list-1' already exists",
),
);
});
});
});
describe("adding an owner", () => {
it("should not allow adding a new remote owner with empty name", async () => {
const dbConfig = createDbConfig();
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteOwner("")).rejects.toThrow(
new Error("Owner name cannot be empty"),
);
});
it("should not allow adding a remote owner with duplicate name", async () => {
const dbConfig = createDbConfig({
remoteOwners: ["owner1"],
});
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteOwner("owner1")).rejects.toThrow(
new Error("An owner with the name 'owner1' already exists"),
);
});
});
describe("renaming items", () => {
const remoteList = {
name: "my-list-1",
@@ -86,8 +270,7 @@ describe("db manager", () => {
await saveDbConfig(dbConfig);
const remoteListDbItems =
getVariantAnalysisUserDefinedListDbItems("my-list-1");
const remoteListDbItems = getRemoteUserDefinedListDbItems("my-list-1");
expect(remoteListDbItems.length).toEqual(1);
await dbManager.renameList(remoteListDbItems[0], "my-list-2");
@@ -102,17 +285,9 @@ describe("db manager", () => {
name: "my-list-2",
repositories: ["owner1/repo1", "owner1/repo2"],
});
// Check that the local list has not been renamed
const localLists = dbConfigFileContents.databases.local.lists;
expect(localLists.length).toBe(1);
expect(localLists[0]).toEqual({
name: "my-list-1",
databases: [localDb],
});
});
it("should rename local db list", async () => {
it.skip("should rename local db list", async () => {
const dbConfig = createDbConfig({
remoteLists: [remoteList],
localLists: [localList],
@@ -145,7 +320,7 @@ describe("db manager", () => {
});
});
it("should rename local db outside a list", async () => {
it.skip("should rename local db outside a list", async () => {
const dbConfig = createDbConfig({
localLists: [localList],
localDbs: [localDb],
@@ -174,7 +349,7 @@ describe("db manager", () => {
});
});
it("should rename local db inside a list", async () => {
it.skip("should rename local db inside a list", async () => {
const dbConfig = createDbConfig({
localLists: [localList],
localDbs: [localDb],
@@ -230,8 +405,7 @@ describe("db manager", () => {
it("should remove remote user-defined list", async () => {
await saveDbConfig(dbConfig);
const remoteListDbItems =
getVariantAnalysisUserDefinedListDbItems("my-list-1");
const remoteListDbItems = getRemoteUserDefinedListDbItems("my-list-1");
expect(remoteListDbItems.length).toEqual(1);
await dbManager.removeDbItem(remoteListDbItems[0]);
@@ -245,10 +419,6 @@ describe("db manager", () => {
repositories: [remoteRepo1, remoteRepo2],
owners: [remoteOwner],
},
local: {
lists: [localList],
databases: [localDb],
},
},
});
});
@@ -270,10 +440,6 @@ describe("db manager", () => {
repositories: [remoteRepo2],
owners: [remoteOwner],
},
local: {
lists: [localList],
databases: [localDb],
},
},
selected: {
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
@@ -299,10 +465,6 @@ describe("db manager", () => {
repositories: [remoteRepo1, remoteRepo2],
owners: [],
},
local: {
lists: [localList],
databases: [localDb],
},
},
selected: {
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
@@ -311,7 +473,7 @@ describe("db manager", () => {
});
});
it("should remove local db list", async () => {
it.skip("should remove local db list", async () => {
await saveDbConfig(dbConfig);
const localListDbItems = getLocalListDbItems("my-list-1");
@@ -340,7 +502,7 @@ describe("db manager", () => {
});
});
it("should remove local database", async () => {
it.skip("should remove local database", async () => {
await saveDbConfig(dbConfig);
const localDbItems = getLocalDatabaseDbItems("db1");
@@ -381,7 +543,7 @@ describe("db manager", () => {
await saveDbConfig(dbConfig);
// Add item to expanded state
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName,
});
@@ -392,7 +554,7 @@ describe("db manager", () => {
expect(expandedItems?.length).toEqual(1);
const expandedItem =
expandedItems![0] as VariantAnalysisUserDefinedListExpandedDbItem;
expandedItems![0] as RemoteUserDefinedListExpandedDbItem;
expect(expandedItem.listName).toEqual(listName);
});
@@ -409,7 +571,7 @@ describe("db manager", () => {
]);
// Remove item from expanded state
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName,
});
@@ -440,7 +602,7 @@ describe("db manager", () => {
]);
// Rename item
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName,
});
@@ -451,7 +613,7 @@ describe("db manager", () => {
expect(expandedItems?.length).toEqual(1);
const expandedItem =
expandedItems![0] as VariantAnalysisUserDefinedListExpandedDbItem;
expandedItems![0] as RemoteUserDefinedListExpandedDbItem;
expect(expandedItem.listName).toEqual("new-list-name");
});
@@ -477,7 +639,7 @@ describe("db manager", () => {
]);
// Trigger adding an item that is not in the config
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
listName,
});
@@ -488,7 +650,7 @@ describe("db manager", () => {
expect(expandedItems?.length).toEqual(1);
const expandedItem =
expandedItems![0] as VariantAnalysisUserDefinedListExpandedDbItem;
expandedItems![0] as RemoteUserDefinedListExpandedDbItem;
expect(expandedItem.listName).toEqual("my-list-4");
});
});
@@ -558,13 +720,13 @@ describe("db manager", () => {
return ownerDbItems;
}
function getVariantAnalysisUserDefinedListDbItems(
function getRemoteUserDefinedListDbItems(
listName: string,
): VariantAnalysisUserDefinedListDbItem[] {
): RemoteUserDefinedListDbItem[] {
const dbItemsResult = dbManager.getDbItems();
const dbItems = flattenDbItems(dbItemsResult.value);
const listDbItems = dbItems
.filter(isVariantAnalysisUserDefinedListDbItem)
.filter(isRemoteUserDefinedListDbItem)
.filter((i) => i.listName === listName);
return listDbItems;

View File

@@ -6,7 +6,7 @@ import {
DbItemKind,
isRemoteOwnerDbItem,
isRemoteRepoDbItem,
isVariantAnalysisUserDefinedListDbItem,
isRemoteUserDefinedListDbItem,
} from "../../../src/databases/db-item";
import {
ExpandedDbItem,
@@ -71,12 +71,12 @@ describe("db tree creator", () => {
expect(dbTreeRoot).toBeTruthy();
expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote);
const repositoryListNodes = dbTreeRoot.children.filter(
isVariantAnalysisUserDefinedListDbItem,
isRemoteUserDefinedListDbItem,
);
expect(repositoryListNodes.length).toBe(2);
expect(repositoryListNodes[0]).toEqual({
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
selected: false,
expanded: false,
listName: dbConfig.databases.variantAnalysis.repositoryLists[0].name,
@@ -92,7 +92,7 @@ describe("db tree creator", () => {
),
});
expect(repositoryListNodes[1]).toEqual({
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
selected: false,
expanded: false,
listName: dbConfig.databases.variantAnalysis.repositoryLists[1].name,
@@ -182,7 +182,7 @@ describe("db tree creator", () => {
expect(dbTreeRoot).toBeTruthy();
expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote);
const repositoryListNodes = dbTreeRoot.children.filter(
(child) => child.kind === DbItemKind.VariantAnalysisUserDefinedList,
(child) => child.kind === DbItemKind.RemoteUserDefinedList,
);
expect(repositoryListNodes.length).toBe(1);
@@ -252,7 +252,7 @@ describe("db tree creator", () => {
expect(dbTreeRoot).toBeTruthy();
const listNodes = dbTreeRoot.children.filter(
isVariantAnalysisUserDefinedListDbItem,
isRemoteUserDefinedListDbItem,
);
expect(listNodes.length).toBe(1);
@@ -304,7 +304,7 @@ describe("db tree creator", () => {
expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote);
expect(dbTreeRoot.expanded).toBe(true);
const repositoryListNodes = dbTreeRoot.children.filter(
isVariantAnalysisUserDefinedListDbItem,
isRemoteUserDefinedListDbItem,
);
expect(repositoryListNodes.length).toBe(1);

View File

@@ -8,7 +8,7 @@ import {
createRemoteOwnerDbItem,
createRemoteRepoDbItem,
createRemoteSystemDefinedListDbItem,
createVariantAnalysisUserDefinedListDbItem,
createRemoteUserDefinedListDbItem,
createRootLocalDbItem,
createRootRemoteDbItem,
} from "../../../factories/db-item-factories";
@@ -63,7 +63,7 @@ describe("getDbItemActions", () => {
});
it("should set canBeSelected, canBeRemoved and canBeRenamed for remote user defined db list", () => {
const dbItem = createVariantAnalysisUserDefinedListDbItem();
const dbItem = createRemoteUserDefinedListDbItem();
const actions = getDbItemActions(dbItem);
@@ -71,7 +71,7 @@ describe("getDbItemActions", () => {
});
it("should not set canBeSelected for remote user defined db list that is already selected", () => {
const dbItem = createVariantAnalysisUserDefinedListDbItem({
const dbItem = createRemoteUserDefinedListDbItem({
selected: true,
});
@@ -135,7 +135,7 @@ describe("getGitHubUrl", () => {
it("should return undefined for other remote db items", () => {
const dbItem0 = createRootRemoteDbItem();
const dbItem1 = createRemoteSystemDefinedListDbItem();
const dbItem2 = createVariantAnalysisUserDefinedListDbItem();
const dbItem2 = createRemoteUserDefinedListDbItem();
const actualUrl0 = getGitHubUrl(dbItem0);
const actualUrl1 = getGitHubUrl(dbItem1);

View File

@@ -35,9 +35,6 @@ describe("Db panel UI commands", () => {
it("should add new remote db list", async () => {
// Add db list
jest.spyOn(window, "showQuickPick").mockResolvedValue({
kind: DbListKind.Remote,
} as AddListQuickPickItem);
jest.spyOn(window, "showInputBox").mockResolvedValue("my-list-1");
await commands.executeCommand(
"codeQLVariantAnalysisRepositories.addNewList",
@@ -55,7 +52,7 @@ describe("Db panel UI commands", () => {
);
});
it("should add new local db list", async () => {
it.skip("should add new local db list", async () => {
// Add db list
jest.spyOn(window, "showQuickPick").mockResolvedValue({
kind: DbListKind.Local,

View File

@@ -154,16 +154,14 @@ describeWithCodeQL()("using the legacy query server", () => {
const parsedResults = new Checkpoint<void>();
it("should register the database if necessary", async () => {
if (await cliServer.cliConstraints.supportsDatabaseRegistration()) {
await qs.sendRequest(
messages.registerDatabases,
{ databases: [db] },
token,
(() => {
/**/
}) as any,
);
}
await qs.sendRequest(
messages.registerDatabases,
{ databases: [db] },
token,
(() => {
/**/
}) as any,
);
});
it(`should be able to compile query ${queryName}`, async () => {

View File

@@ -6,6 +6,7 @@ import {
codeQlLauncherName,
} from "../../src/pure/distribution";
import fetch from "node-fetch";
import supportedCliVersions from "../../supported_cli_versions.json";
/**
* This module ensures that the proper CLI is available for tests of the extension.
@@ -36,9 +37,9 @@ import fetch from "node-fetch";
const _1MB = 1024 * 1024;
const _10MB = _1MB * 10;
// CLI version to test. Hard code the latest as default. And be sure
// to update the env if it is not otherwise set.
const CLI_VERSION = process.env.CLI_VERSION || "v2.11.6";
// CLI version to test. Use the latest supported version by default.
// And be sure to update the env if it is not otherwise set.
const CLI_VERSION = process.env.CLI_VERSION || supportedCliVersions[0];
process.env.CLI_VERSION = CLI_VERSION;
// Base dir where CLIs will be downloaded into

View File

@@ -33,7 +33,6 @@ describe("databases", () => {
let updateSpy: jest.Mock<Promise<void>, []>;
let registerSpy: jest.Mock<Promise<void>, []>;
let deregisterSpy: jest.Mock<Promise<void>, []>;
let supportsLanguageNameSpy: jest.Mock<Promise<boolean>, []>;
let resolveDatabaseSpy: jest.Mock<Promise<DbInfo>, []>;
let dir: tmp.DirResult;
@@ -44,7 +43,6 @@ describe("databases", () => {
updateSpy = jest.fn(() => Promise.resolve(undefined));
registerSpy = jest.fn(() => Promise.resolve(undefined));
deregisterSpy = jest.fn(() => Promise.resolve(undefined));
supportsLanguageNameSpy = jest.fn(() => Promise.resolve(true));
resolveDatabaseSpy = jest.fn(() => Promise.resolve({} as DbInfo));
databaseManager = new DatabaseManager(
@@ -65,10 +63,6 @@ describe("databases", () => {
},
} as unknown as QueryRunner,
{
cliConstraints: {
supportsLanguageName: supportsLanguageNameSpy,
supportsDatabaseRegistration: () => true,
},
resolveDatabase: resolveDatabaseSpy,
} as unknown as CodeQLCliServer,
{
@@ -384,15 +378,7 @@ describe("databases", () => {
});
});
it("should not support the primary language", async () => {
supportsLanguageNameSpy.mockResolvedValue(false);
const result = await (databaseManager as any).getPrimaryLanguage("hucairz");
expect(result).toBeUndefined();
});
it("should get the primary language", async () => {
supportsLanguageNameSpy.mockResolvedValue(true);
resolveDatabaseSpy.mockResolvedValue({
languages: ["python"],
} as unknown as DbInfo);
@@ -401,7 +387,6 @@ describe("databases", () => {
});
it("should handle missing the primary language", async () => {
supportsLanguageNameSpy.mockResolvedValue(true);
resolveDatabaseSpy.mockResolvedValue({
languages: [],
} as unknown as DbInfo);

View File

@@ -48,7 +48,7 @@ describe("db panel rendering nodes", () => {
await remove(workspaceStoragePath);
});
it("should render default local and remote nodes when the config is empty", async () => {
it("should render default remote nodes when the config is empty", async () => {
const dbConfig: DbConfig = createDbConfig();
await saveDbConfig(dbConfig);
@@ -57,37 +57,11 @@ describe("db panel rendering nodes", () => {
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
expect(items.length).toBe(2);
expect(items.length).toBe(3);
const remoteRootNode = items[0];
expect(remoteRootNode.dbItem).toBeTruthy();
expect(remoteRootNode.dbItem?.kind).toBe(DbItemKind.RootRemote);
expect(remoteRootNode.label).toBe("remote");
expect(remoteRootNode.tooltip).toBe("Remote databases");
expect(remoteRootNode.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(remoteRootNode.children).toBeTruthy();
expect(remoteRootNode.children.length).toBe(3);
const systemDefinedListItems = remoteRootNode.children.filter(
(item) => item.dbItem?.kind === DbItemKind.RemoteSystemDefinedList,
);
expect(systemDefinedListItems.length).toBe(3);
checkRemoteSystemDefinedListItem(systemDefinedListItems[0], 10);
checkRemoteSystemDefinedListItem(systemDefinedListItems[1], 100);
checkRemoteSystemDefinedListItem(systemDefinedListItems[2], 1000);
const localRootNode = items[1];
expect(localRootNode.dbItem).toBeTruthy();
expect(localRootNode.dbItem?.kind).toBe(DbItemKind.RootLocal);
expect(localRootNode.label).toBe("local");
expect(localRootNode.tooltip).toBe("Local databases");
expect(localRootNode.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(localRootNode.children).toBeTruthy();
expect(localRootNode.children.length).toBe(0);
checkRemoteSystemDefinedListItem(items[0], 10);
checkRemoteSystemDefinedListItem(items[1], 100);
checkRemoteSystemDefinedListItem(items[2], 1000);
});
it("should render remote repository list nodes", async () => {
@@ -107,26 +81,15 @@ describe("db panel rendering nodes", () => {
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
expect(items.length).toBe(2);
const remoteRootNode = items[0];
expect(remoteRootNode.dbItem).toBeTruthy();
expect(remoteRootNode.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(remoteRootNode.children).toBeTruthy();
expect(remoteRootNode.children.length).toBe(5);
const systemDefinedListItems = remoteRootNode.children.filter(
const systemDefinedListItems = dbTreeItems!.filter(
(item) => item.dbItem?.kind === DbItemKind.RemoteSystemDefinedList,
);
expect(systemDefinedListItems.length).toBe(3);
const userDefinedListItems = remoteRootNode.children.filter(
(item) => item.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList,
const userDefinedListItems = dbTreeItems!.filter(
(item) => item.dbItem?.kind === DbItemKind.RemoteUserDefinedList,
);
expect(userDefinedListItems.length).toBe(2);
checkUserDefinedListItem(userDefinedListItems[0], "my-list-1", [
@@ -148,20 +111,10 @@ describe("db panel rendering nodes", () => {
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
expect(items.length).toBe(2);
expect(dbTreeItems?.length).toBe(5);
const remoteRootNode = items[0];
expect(remoteRootNode.dbItem).toBeTruthy();
expect(remoteRootNode.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(remoteRootNode.children).toBeTruthy();
expect(remoteRootNode.children.length).toBe(5);
const ownerListItems = remoteRootNode.children.filter(
const ownerListItems = dbTreeItems!.filter(
(item) => item.dbItem?.kind === DbItemKind.RemoteOwner,
);
expect(ownerListItems.length).toBe(2);
@@ -177,20 +130,10 @@ describe("db panel rendering nodes", () => {
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
expect(items.length).toBe(2);
expect(dbTreeItems!.length).toBe(5);
const remoteRootNode = items[0];
expect(remoteRootNode.dbItem).toBeTruthy();
expect(remoteRootNode.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(remoteRootNode.children).toBeTruthy();
expect(remoteRootNode.children.length).toBe(5);
const repoItems = remoteRootNode.children.filter(
const repoItems = dbTreeItems!.filter(
(item) => item.dbItem?.kind === DbItemKind.RemoteRepo,
);
expect(repoItems.length).toBe(2);
@@ -198,7 +141,7 @@ describe("db panel rendering nodes", () => {
checkRemoteRepoItem(repoItems[1], "owner1/repo2");
});
it("should render local list nodes", async () => {
it.skip("should render local list nodes", async () => {
const dbConfig: DbConfig = createDbConfig({
localLists: [
{
@@ -235,20 +178,21 @@ describe("db panel rendering nodes", () => {
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
expect(items.length).toBe(2);
const localRootNode = items[1];
expect(localRootNode.dbItem).toBeTruthy();
expect(localRootNode.collapsibleState).toBe(
const localRootNode = dbTreeItems?.find(
(i) => i.dbItem?.kind === DbItemKind.RootLocal,
);
expect(localRootNode).toBeTruthy();
expect(localRootNode!.dbItem).toBeTruthy();
expect(localRootNode!.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(localRootNode.children).toBeTruthy();
expect(localRootNode.children.length).toBe(2);
expect(localRootNode!.children).toBeTruthy();
expect(localRootNode!.children.length).toBe(2);
const localListItems = localRootNode.children.filter(
const localListItems = localRootNode!.children.filter(
(item) => item.dbItem?.kind === DbItemKind.LocalList,
);
expect(localListItems.length).toBe(2);
@@ -282,7 +226,7 @@ describe("db panel rendering nodes", () => {
]);
});
it("should render local database nodes", async () => {
it.skip("should render local database nodes", async () => {
const dbConfig: DbConfig = createDbConfig({
localDbs: [
{
@@ -305,18 +249,19 @@ describe("db panel rendering nodes", () => {
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
expect(items.length).toBe(2);
const localRootNode = dbTreeItems?.find(
(i) => i.dbItem?.kind === DbItemKind.RootLocal,
);
expect(localRootNode).toBeTruthy();
const localRootNode = items[1];
expect(localRootNode.dbItem).toBeTruthy();
expect(localRootNode.collapsibleState).toBe(
expect(localRootNode!.dbItem).toBeTruthy();
expect(localRootNode!.collapsibleState).toBe(
TreeItemCollapsibleState.Collapsed,
);
expect(localRootNode.children).toBeTruthy();
expect(localRootNode.children.length).toBe(2);
expect(localRootNode!.children).toBeTruthy();
expect(localRootNode!.children.length).toBe(2);
const localDatabaseItems = localRootNode.children.filter(
const localDatabaseItems = localRootNode!.children.filter(
(item) => item.dbItem?.kind === DbItemKind.LocalDatabase,
);
expect(localDatabaseItems.length).toBe(2);

View File

@@ -5,7 +5,6 @@ import { DbConfig } from "../../../../src/databases/config/db-config";
import { DbManager } from "../../../../src/databases/db-manager";
import { DbConfigStore } from "../../../../src/databases/config/db-config-store";
import { DbTreeDataProvider } from "../../../../src/databases/ui/db-tree-data-provider";
import { DbListKind } from "../../../../src/databases/db-item";
import { DbTreeViewItem } from "../../../../src/databases/ui/db-tree-view-item";
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
import { createMockExtensionContext } from "../../../factories/extension-context";
@@ -104,85 +103,6 @@ describe("db panel", () => {
});
});
describe("name validation", () => {
it("should not allow adding a new list with empty name", async () => {
const dbConfig = createDbConfig();
await saveDbConfig(dbConfig);
await expect(dbManager.addNewList(DbListKind.Remote, "")).rejects.toThrow(
new Error("List name cannot be empty"),
);
});
it("should not allow adding a list with duplicate name", async () => {
const dbConfig = createDbConfig({
remoteLists: [
{
name: "my-list-1",
repositories: ["owner1/repo1", "owner1/repo2"],
},
],
});
await saveDbConfig(dbConfig);
await expect(
dbManager.addNewList(DbListKind.Remote, "my-list-1"),
).rejects.toThrow(
new Error(
"A variant analysis list with the name 'my-list-1' already exists",
),
);
});
it("should not allow adding a new remote db with empty name", async () => {
const dbConfig = createDbConfig();
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteRepo("")).rejects.toThrow(
new Error("Repository name cannot be empty"),
);
});
it("should not allow adding a remote db with duplicate name", async () => {
const dbConfig = createDbConfig({
remoteRepos: ["owner1/repo1"],
});
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteRepo("owner1/repo1")).rejects.toThrow(
new Error(
"A variant analysis repository with the name 'owner1/repo1' already exists",
),
);
});
it("should not allow adding a new remote owner with empty name", async () => {
const dbConfig = createDbConfig();
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteOwner("")).rejects.toThrow(
new Error("Owner name cannot be empty"),
);
});
it("should not allow adding a remote owner with duplicate name", async () => {
const dbConfig = createDbConfig({
remoteOwners: ["owner1"],
});
await saveDbConfig(dbConfig);
await expect(dbManager.addNewRemoteOwner("owner1")).rejects.toThrow(
new Error("An owner with the name 'owner1' already exists"),
);
});
});
async function saveDbConfig(dbConfig: DbConfig): Promise<void> {
await writeJson(dbConfigFilePath, dbConfig);

View File

@@ -22,9 +22,6 @@ describe("queryResolver", () => {
const mockCli = {
resolveQueriesInSuite: jest.fn(),
cliConstraints: {
supportsAllowLibraryPacksInResolveQueries: jest.fn(),
},
};
beforeEach(() => {
@@ -40,10 +37,6 @@ describe("queryResolver", () => {
jest.spyOn(helpers, "getOnDiskWorkspaceFolders").mockReturnValue([]);
jest.spyOn(helpers, "showAndLogErrorMessage").mockResolvedValue(undefined);
mockCli.cliConstraints.supportsAllowLibraryPacksInResolveQueries.mockReturnValue(
true,
);
});
describe("resolveQueries", () => {
@@ -75,42 +68,6 @@ describe("queryResolver", () => {
]);
});
it("should resolve a query from the queries pack if this is an old CLI", async () => {
// pretend this is an older CLI
mockCli.cliConstraints.supportsAllowLibraryPacksInResolveQueries.mockReturnValue(
false,
);
mockCli.resolveQueriesInSuite.mockReturnValue(["a", "b"]);
const result = await resolveQueries(
mockCli as unknown as CodeQLCliServer,
{
dbschemePackIsLibraryPack: true,
dbschemePack: "my-qlpack",
queryPack: "my-qlpack2",
},
KeyType.DefinitionQuery,
);
expect(result).toEqual(["a", "b"]);
expect(mockCli.resolveQueriesInSuite).toHaveBeenCalledWith(
expect.stringMatching(/\.qls$/),
[],
);
const fileName = mockCli.resolveQueriesInSuite.mock.calls[0][0];
expect(load(await fs.readFile(fileName, "utf-8"))).toEqual([
{
from: "my-qlpack2",
queries: ".",
include: {
kind: "definitions",
"tags contain": "ide-contextual-queries/local-definitions",
},
},
]);
});
it("should throw an error when there are no queries found", async () => {
mockCli.resolveQueriesInSuite.mockReturnValue([]);

View File

@@ -1,241 +0,0 @@
import { join } from "path";
import { ensureDir, readJSON, remove, writeJson } from "fs-extra";
import {
DbConfig,
SelectedDbItemKind,
} from "../../../../src/databases/config/db-config";
import { DbManager } from "../../../../src/databases/db-manager";
import { DbConfigStore } from "../../../../src/databases/config/db-config-store";
import { DbTreeDataProvider } from "../../../../src/databases/ui/db-tree-data-provider";
import { DbItemKind, DbListKind } from "../../../../src/databases/db-item";
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
import { createMockExtensionContext } from "../../../factories/extension-context";
import { createDbConfig } from "../../../factories/db-config-factories";
describe("db panel add items", () => {
const workspaceStoragePath = join(__dirname, "test-workspace-storage");
const globalStoragePath = join(__dirname, "test-global-storage");
const extensionPath = join(__dirname, "../../../../");
const dbConfigFilePath = join(
workspaceStoragePath,
DbConfigStore.databaseConfigFileName,
);
let dbTreeDataProvider: DbTreeDataProvider;
let dbManager: DbManager;
let dbConfigStore: DbConfigStore;
beforeAll(async () => {
const extensionContext = createMockExtensionContext({
extensionPath,
globalStoragePath,
workspaceStoragePath,
});
await ensureDir(workspaceStoragePath);
const app = new ExtensionApp(extensionContext);
dbConfigStore = new DbConfigStore(app, false);
dbManager = new DbManager(app, dbConfigStore);
});
beforeEach(async () => {
await ensureDir(workspaceStoragePath);
});
afterEach(async () => {
await remove(workspaceStoragePath);
});
describe("addNewRemoteRepo", () => {
it("should add a new remote repo", async () => {
const dbConfig: DbConfig = createDbConfig({
remoteRepos: ["owner1/repo1"],
});
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
const remoteRootNode = items[0];
const remoteRepos = remoteRootNode.children.filter(
(c) => c.dbItem?.kind === DbItemKind.RemoteRepo,
);
const repo1 = remoteRootNode.children.find(
(c) =>
c.dbItem?.kind === DbItemKind.RemoteRepo &&
c.dbItem?.repoFullName === "owner1/repo1",
);
expect(remoteRepos.length).toBe(1);
expect(remoteRepos[0]).toBe(repo1);
await dbManager.addNewRemoteRepo("owner2/repo2");
const dbConfigFileContents = await readDbConfigDirectly();
expect(
dbConfigFileContents.databases.variantAnalysis.repositories.length,
).toBe(2);
expect(
dbConfigFileContents.databases.variantAnalysis.repositories[1],
).toEqual("owner2/repo2");
});
it("should add a new remote repo to a user defined list", async () => {
const dbConfig: DbConfig = createDbConfig({
remoteLists: [
{
name: "my-list-1",
repositories: ["owner1/repo1"],
},
],
});
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
const remoteRootNode = items[0];
const remoteUserDefinedLists = remoteRootNode.children.filter(
(c) => c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList,
);
const list1 = remoteRootNode.children.find(
(c) =>
c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList &&
c.dbItem?.listName === "my-list-1",
);
expect(remoteUserDefinedLists.length).toBe(1);
expect(remoteUserDefinedLists[0]).toBe(list1);
await dbManager.addNewRemoteRepo("owner2/repo2", "my-list-1");
// Read the workspace databases JSON file directly to check that the new repo has been added.
// We can't use the dbConfigStore's `read` function here because it depends on the file watcher
// picking up changes, and we don't control the timing of that.
const dbConfigFileContents = await readJSON(dbConfigFilePath);
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists.length,
).toBe(1);
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists[0],
).toEqual({
name: "my-list-1",
repositories: ["owner1/repo1", "owner2/repo2"],
});
});
});
describe("addNewList", () => {
it("should add a new remote list", async () => {
const dbConfig: DbConfig = createDbConfig({
remoteLists: [
{
name: "my-list-1",
repositories: ["owner1/repo1", "owner1/repo2"],
},
],
selected: {
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
listName: "my-list-1",
},
});
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
const remoteRootNode = items[0];
const remoteUserDefinedLists = remoteRootNode.children.filter(
(c) => c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList,
);
const list1 = remoteRootNode.children.find(
(c) =>
c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList &&
c.dbItem?.listName === "my-list-1",
);
expect(remoteUserDefinedLists.length).toBe(1);
expect(remoteUserDefinedLists[0]).toBe(list1);
await dbManager.addNewList(DbListKind.Remote, "my-list-2");
const dbConfigFileContents = await readDbConfigDirectly();
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists.length,
).toBe(2);
expect(
dbConfigFileContents.databases.variantAnalysis.repositoryLists[1],
).toEqual({
name: "my-list-2",
repositories: [],
});
});
it("should throw error when adding a new list to a local node", async () => {
const dbConfig: DbConfig = createDbConfig({
localLists: [
{
name: "my-list-1",
databases: [],
},
],
});
await saveDbConfig(dbConfig);
const dbTreeItems = await dbTreeDataProvider.getChildren();
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
const localRootNode = items[1];
const localUserDefinedLists = localRootNode.children.filter(
(c) => c.dbItem?.kind === DbItemKind.LocalList,
);
const list1 = localRootNode.children.find(
(c) =>
c.dbItem?.kind === DbItemKind.LocalList &&
c.dbItem?.listName === "my-list-1",
);
expect(localUserDefinedLists.length).toBe(1);
expect(localUserDefinedLists[0]).toBe(list1);
await dbManager.addNewList(DbListKind.Local, "my-list-2");
const dbConfigFileContents = await readDbConfigDirectly();
expect(dbConfigFileContents.databases.local.lists.length).toBe(2);
expect(dbConfigFileContents.databases.local.lists[1]).toEqual({
name: "my-list-2",
databases: [],
});
});
});
async function saveDbConfig(dbConfig: DbConfig): Promise<void> {
await writeJson(dbConfigFilePath, dbConfig);
// Ideally we would just initialise the db config store at the start
// of each test and then rely on the file watcher to update the config.
// However, this requires adding sleep to the tests to allow for the
// file watcher to catch up, so we instead initialise the config store here.
await dbConfigStore.initialize();
dbTreeDataProvider = new DbTreeDataProvider(dbManager);
}
async function readDbConfigDirectly(): Promise<DbConfig> {
// Read the workspace databases JSON file directly to check that the new list has been added.
// We can't use the dbConfigStore's `read` function here because it depends on the file watcher
// picking up changes, and we don't control the timing of that.
return (await readJSON(dbConfigFilePath)) as DbConfig;
}
});

View File

@@ -75,18 +75,14 @@ describe("db panel selection", () => {
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
const remoteRootNode = items[0];
expect(remoteRootNode.dbItem).toBeTruthy();
expect(remoteRootNode.dbItem?.kind).toEqual(DbItemKind.RootRemote);
const list1 = remoteRootNode.children.find(
const list1 = items.find(
(c) =>
c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList &&
c.dbItem?.kind === DbItemKind.RemoteUserDefinedList &&
c.dbItem?.listName === "my-list-1",
);
const list2 = remoteRootNode.children.find(
const list2 = items.find(
(c) =>
c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList &&
c.dbItem?.kind === DbItemKind.RemoteUserDefinedList &&
c.dbItem?.listName === "my-list-2",
);
@@ -123,13 +119,9 @@ describe("db panel selection", () => {
expect(dbTreeItems).toBeTruthy();
const items = dbTreeItems!;
const remoteRootNode = items[0];
expect(remoteRootNode.dbItem).toBeTruthy();
expect(remoteRootNode.dbItem?.kind).toEqual(DbItemKind.RootRemote);
const list2 = remoteRootNode.children.find(
const list2 = items.find(
(c) =>
c.dbItem?.kind === DbItemKind.VariantAnalysisUserDefinedList &&
c.dbItem?.kind === DbItemKind.RemoteUserDefinedList &&
c.dbItem?.listName === "my-list-2",
);
expect(list2).toBeTruthy();
@@ -150,7 +142,7 @@ describe("db panel selection", () => {
expect(repo2Node).toBeTruthy();
expect(isTreeViewItemSelectable(repo2Node!)).toBeTruthy();
for (const item of remoteRootNode.children) {
for (const item of items) {
expect(isTreeViewItemSelectable(item)).toBeTruthy();
}
});

View File

@@ -1,9 +1,9 @@
import { env } from "vscode";
import { QueryHistoryConfig } from "../../../src/config";
import { HistoryItemLabelProvider } from "../../../src/history-item-label-provider";
import { createMockLocalQueryInfo } from "../../factories/local-queries/local-query-history-item";
import { createMockRemoteQueryHistoryItem } from "../../factories/remote-queries/remote-query-history-item";
import { QueryStatus } from "../../../src/query-status";
import { QueryHistoryConfig } from "../../../../src/config";
import { HistoryItemLabelProvider } from "../../../../src/query-history/history-item-label-provider";
import { createMockLocalQueryInfo } from "../../../factories/query-history/local-query-history-item";
import { createMockRemoteQueryHistoryItem } from "../../../factories/query-history/remote-query-history-item";
import { QueryStatus } from "../../../../src/query-status";
describe("HistoryItemLabelProvider", () => {
let labelProvider: HistoryItemLabelProvider;

View File

@@ -1,20 +1,20 @@
import { QueryStatus } from "../../../src/query-status";
import { QueryStatus } from "../../../../src/query-status";
import {
buildRepoLabel,
getActionsWorkflowRunUrl,
getQueryId,
getQueryText,
getRawQueryName,
} from "../../../src/query-history-info";
import { VariantAnalysisHistoryItem } from "../../../src/remote-queries/variant-analysis-history-item";
import { createMockVariantAnalysis } from "../../factories/remote-queries/shared/variant-analysis";
import { createMockScannedRepos } from "../../factories/remote-queries/shared/scanned-repositories";
import { createMockLocalQueryInfo } from "../../factories/local-queries/local-query-history-item";
import { createMockRemoteQueryHistoryItem } from "../../factories/remote-queries/remote-query-history-item";
} from "../../../../src/query-history/query-history-info";
import { VariantAnalysisHistoryItem } from "../../../../src/query-history/variant-analysis-history-item";
import { createMockVariantAnalysis } from "../../../factories/remote-queries/shared/variant-analysis";
import { createMockScannedRepos } from "../../../factories/remote-queries/shared/scanned-repositories";
import { createMockLocalQueryInfo } from "../../../factories/query-history/local-query-history-item";
import { createMockRemoteQueryHistoryItem } from "../../../factories/query-history/remote-query-history-item";
import {
VariantAnalysisRepoStatus,
VariantAnalysisStatus,
} from "../../../src/remote-queries/shared/variant-analysis";
} from "../../../../src/remote-queries/shared/variant-analysis";
describe("Query history info", () => {
const date = new Date("2022-01-01T00:00:00.000Z");

View File

@@ -2,52 +2,50 @@ import { readdirSync, mkdirSync, writeFileSync } from "fs-extra";
import { join } from "path";
import * as vscode from "vscode";
import { extLogger } from "../../../src/common";
import { registerQueryHistoryScrubber } from "../../../src/query-history-scrubber";
import { extLogger } from "../../../../src/common";
import { registerQueryHistoryScrubber } from "../../../../src/query-history/query-history-scrubber";
import {
HistoryTreeDataProvider,
QueryHistoryManager,
SortOrder,
} from "../../../src/query-history";
} from "../../../../src/query-history/query-history";
import {
QueryHistoryConfig,
QueryHistoryConfigListener,
} from "../../../src/config";
import { LocalQueryInfo } from "../../../src/query-results";
import { DatabaseManager } from "../../../src/databases";
} from "../../../../src/config";
import { LocalQueryInfo } from "../../../../src/query-results";
import { DatabaseManager } from "../../../../src/databases";
import { dirSync } from "tmp-promise";
import {
ONE_DAY_IN_MS,
ONE_HOUR_IN_MS,
THREE_HOURS_IN_MS,
TWO_HOURS_IN_MS,
} from "../../../src/pure/time";
import { tmpDir } from "../../../src/helpers";
import { HistoryItemLabelProvider } from "../../../src/history-item-label-provider";
import { RemoteQueriesManager } from "../../../src/remote-queries/remote-queries-manager";
import { ResultsView } from "../../../src/interface";
import { EvalLogViewer } from "../../../src/eval-log-viewer";
import { QueryRunner } from "../../../src/queryRunner";
import { VariantAnalysisManager } from "../../../src/remote-queries/variant-analysis-manager";
import { QueryHistoryInfo } from "../../../src/query-history-info";
} from "../../../../src/pure/time";
import { tmpDir } from "../../../../src/helpers";
import { HistoryItemLabelProvider } from "../../../../src/query-history/history-item-label-provider";
import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager";
import { ResultsView } from "../../../../src/interface";
import { EvalLogViewer } from "../../../../src/eval-log-viewer";
import { QueryRunner } from "../../../../src/queryRunner";
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager";
import { QueryHistoryInfo } from "../../../../src/query-history/query-history-info";
import {
createMockLocalQueryInfo,
createMockQueryWithResults,
} from "../../factories/local-queries/local-query-history-item";
import { createMockRemoteQueryHistoryItem } from "../../factories/remote-queries/remote-query-history-item";
import { RemoteQueryHistoryItem } from "../../../src/remote-queries/remote-query-history-item";
import { shuffleHistoryItems } from "../utils/query-history-helpers";
import { createMockVariantAnalysisHistoryItem } from "../../factories/remote-queries/variant-analysis-history-item";
import { VariantAnalysisHistoryItem } from "../../../src/remote-queries/variant-analysis-history-item";
import { QueryStatus } from "../../../src/query-status";
import { VariantAnalysisStatus } from "../../../src/remote-queries/shared/variant-analysis";
import * as ghActionsApiClient from "../../../src/remote-queries/gh-api/gh-actions-api-client";
} from "../../../factories/query-history/local-query-history-item";
import { createMockRemoteQueryHistoryItem } from "../../../factories/query-history/remote-query-history-item";
import { RemoteQueryHistoryItem } from "../../../../src/remote-queries/remote-query-history-item";
import { shuffleHistoryItems } from "../../utils/query-history-helpers";
import { createMockVariantAnalysisHistoryItem } from "../../../factories/query-history/variant-analysis-history-item";
import { VariantAnalysisHistoryItem } from "../../../../src/query-history/variant-analysis-history-item";
import { QueryStatus } from "../../../../src/query-status";
import { VariantAnalysisStatus } from "../../../../src/remote-queries/shared/variant-analysis";
import * as ghActionsApiClient from "../../../../src/remote-queries/gh-api/gh-actions-api-client";
import { QuickPickItem, TextEditor } from "vscode";
import { WebviewReveal } from "../../../src/interface-utils";
import * as helpers from "../../../src/helpers";
import { testCredentialsWithStub } from "../../factories/authentication";
import { createMockApp } from "../../__mocks__/appMock";
import { Credentials } from "../../../src/common/authentication";
import { WebviewReveal } from "../../../../src/interface-utils";
import * as helpers from "../../../../src/helpers";
import { testCredentialsWithStub } from "../../../factories/authentication";
describe("query-history", () => {
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");

View File

@@ -20,12 +20,12 @@ import {
import { QueryHistoryConfig } from "../../../../src/config";
import { DatabaseManager } from "../../../../src/databases";
import { tmpDir, walkDirectory } from "../../../../src/helpers";
import { QueryHistoryManager } from "../../../../src/query-history";
import { QueryHistoryManager } from "../../../../src/query-history/query-history";
import { AnalysesResultsManager } from "../../../../src/remote-queries/analyses-results-manager";
import { RemoteQueryResult } from "../../../../src/remote-queries/shared/remote-query-result";
import { DisposableBucket } from "../../disposable-bucket";
import { testDisposeHandler } from "../../test-dispose-handler";
import { HistoryItemLabelProvider } from "../../../../src/history-item-label-provider";
import { HistoryItemLabelProvider } from "../../../../src/query-history/history-item-label-provider";
import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager";
import { ResultsView } from "../../../../src/interface";
import { EvalLogViewer } from "../../../../src/eval-log-viewer";

View File

@@ -12,10 +12,10 @@ import { commands, ExtensionContext, Uri } from "vscode";
import { QueryHistoryConfig } from "../../../../src/config";
import { DatabaseManager } from "../../../../src/databases";
import { tmpDir, walkDirectory } from "../../../../src/helpers";
import { QueryHistoryManager } from "../../../../src/query-history";
import { QueryHistoryManager } from "../../../../src/query-history/query-history";
import { DisposableBucket } from "../../disposable-bucket";
import { testDisposeHandler } from "../../test-dispose-handler";
import { HistoryItemLabelProvider } from "../../../../src/history-item-label-provider";
import { HistoryItemLabelProvider } from "../../../../src/query-history/history-item-label-provider";
import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager";
import { ResultsView } from "../../../../src/interface";
import { EvalLogViewer } from "../../../../src/eval-log-viewer";

View File

@@ -21,10 +21,6 @@ import {
import { CodeQLCliServer, SourceInfo } from "../../../src/cli";
import { CancellationTokenSource, Uri } from "vscode";
import { tmpDir } from "../../../src/helpers";
import {
deserializeQueryHistory,
serializeQueryHistory,
} from "../../../src/query-serialization";
import {
formatLegacyMessage,
QueryInProgress,
@@ -438,117 +434,6 @@ describe("query-results", () => {
);
});
describe("serialize and deserialize", () => {
let infoSuccessRaw: LocalQueryInfo;
let infoSuccessInterpreted: LocalQueryInfo;
let infoEarlyFailure: LocalQueryInfo;
let infoLateFailure: LocalQueryInfo;
let infoInprogress: LocalQueryInfo;
let allHistory: LocalQueryInfo[];
beforeEach(() => {
infoSuccessRaw = createMockFullQueryInfo(
"a",
createMockQueryWithResults(
`${queryPath}-a`,
false,
false,
"/a/b/c/a",
false,
),
);
infoSuccessInterpreted = createMockFullQueryInfo(
"b",
createMockQueryWithResults(
`${queryPath}-b`,
true,
true,
"/a/b/c/b",
false,
),
);
infoEarlyFailure = createMockFullQueryInfo("c", undefined, true);
infoLateFailure = createMockFullQueryInfo(
"d",
createMockQueryWithResults(
`${queryPath}-c`,
false,
false,
"/a/b/c/d",
false,
),
);
infoInprogress = createMockFullQueryInfo("e");
allHistory = [
infoSuccessRaw,
infoSuccessInterpreted,
infoEarlyFailure,
infoLateFailure,
infoInprogress,
];
});
it("should serialize and deserialize query history", async () => {
// the expected results only contains the history with completed queries
const expectedHistory = [
infoSuccessRaw,
infoSuccessInterpreted,
infoLateFailure,
];
const allHistoryPath = join(tmpDir.name, "workspace-query-history.json");
// serialize and deserialize
await serializeQueryHistory(allHistory, allHistoryPath);
const allHistoryActual = await deserializeQueryHistory(allHistoryPath);
// the dispose methods will be different. Ignore them.
allHistoryActual.forEach((info) => {
if (info.t === "local" && info.completedQuery) {
const completedQuery = info.completedQuery;
(completedQuery as any).dispose = undefined;
// these fields should be missing on the deserialized value
// but they are undefined on the original value
if (!("logFileLocation" in completedQuery)) {
(completedQuery as any).logFileLocation = undefined;
}
const query = completedQuery.query;
if (!("quickEvalPosition" in query)) {
(query as any).quickEvalPosition = undefined;
}
}
});
expectedHistory.forEach((info) => {
if (info.completedQuery) {
(info.completedQuery as any).dispose = undefined;
}
});
// make the diffs somewhat sane by comparing each element directly
for (let i = 0; i < allHistoryActual.length; i++) {
expect(allHistoryActual[i]).toEqual(expectedHistory[i]);
}
expect(allHistoryActual.length).toEqual(expectedHistory.length);
});
it("should handle an invalid query history version", async () => {
const badPath = join(tmpDir.name, "bad-query-history.json");
writeFileSync(
badPath,
JSON.stringify({
version: 3,
queries: allHistory,
}),
"utf8",
);
const allHistoryActual = await deserializeQueryHistory(badPath);
// version number is invalid. Should return an empty array.
expect(allHistoryActual).toEqual([]);
});
});
function safeDel(file: string) {
try {
unlinkSync(file);

View File

@@ -0,0 +1,233 @@
import {
deserializeQueryHistory,
serializeQueryHistory,
} from "../../../src/query-serialization";
import { join } from "path";
import { writeFileSync, mkdirpSync } from "fs-extra";
import { LocalQueryInfo, InitialQueryInfo } from "../../../src/query-results";
import { QueryWithResults } from "../../../src/run-queries-shared";
import { DatabaseInfo } from "../../../src/pure/interface-types";
import { CancellationTokenSource, Uri } from "vscode";
import { tmpDir } from "../../../src/helpers";
import { QueryResultType } from "../../../src/pure/legacy-messages";
import { QueryInProgress } from "../../../src/legacy-query-server/run-queries";
import { RemoteQueryHistoryItem } from "../../../src/remote-queries/remote-query-history-item";
import { VariantAnalysisHistoryItem } from "../../../src/query-history/variant-analysis-history-item";
import { QueryHistoryInfo } from "../../../src/query-history/query-history-info";
import { createMockRemoteQueryHistoryItem } from "../../factories/query-history/remote-query-history-item";
import { createMockVariantAnalysisHistoryItem } from "../../factories/query-history/variant-analysis-history-item";
describe("serialize and deserialize", () => {
let infoSuccessRaw: LocalQueryInfo;
let infoSuccessInterpreted: LocalQueryInfo;
let infoEarlyFailure: LocalQueryInfo;
let infoLateFailure: LocalQueryInfo;
let infoInProgress: LocalQueryInfo;
let remoteQuery1: RemoteQueryHistoryItem;
let remoteQuery2: RemoteQueryHistoryItem;
let variantAnalysis1: VariantAnalysisHistoryItem;
let variantAnalysis2: VariantAnalysisHistoryItem;
let allHistory: QueryHistoryInfo[];
let queryPath: string;
let cnt = 0;
beforeEach(() => {
queryPath = join(Uri.file(tmpDir.name).fsPath, `query-${cnt++}`);
infoSuccessRaw = createMockFullQueryInfo(
"a",
createMockQueryWithResults(
`${queryPath}-a`,
false,
false,
"/a/b/c/a",
false,
),
);
infoSuccessInterpreted = createMockFullQueryInfo(
"b",
createMockQueryWithResults(
`${queryPath}-b`,
true,
true,
"/a/b/c/b",
false,
),
);
infoEarlyFailure = createMockFullQueryInfo("c", undefined, true);
infoLateFailure = createMockFullQueryInfo(
"d",
createMockQueryWithResults(
`${queryPath}-c`,
false,
false,
"/a/b/c/d",
false,
),
);
infoInProgress = createMockFullQueryInfo("e");
remoteQuery1 = createMockRemoteQueryHistoryItem({});
remoteQuery2 = createMockRemoteQueryHistoryItem({});
variantAnalysis1 = createMockVariantAnalysisHistoryItem({});
variantAnalysis2 = createMockVariantAnalysisHistoryItem({});
allHistory = [
infoSuccessRaw,
infoSuccessInterpreted,
infoEarlyFailure,
infoLateFailure,
infoInProgress,
remoteQuery1,
remoteQuery2,
variantAnalysis1,
variantAnalysis2,
];
});
it("should serialize and deserialize query history", async () => {
// the expected results only contains the history with completed queries
const expectedHistory = [
infoSuccessRaw,
infoSuccessInterpreted,
infoLateFailure,
remoteQuery1,
remoteQuery2,
variantAnalysis1,
variantAnalysis2,
];
const allHistoryPath = join(tmpDir.name, "workspace-query-history.json");
// serialize and deserialize
await serializeQueryHistory(allHistory, allHistoryPath);
const allHistoryActual = await deserializeQueryHistory(allHistoryPath);
// the dispose methods will be different. Ignore them.
allHistoryActual.forEach((info) => {
if (info.t === "local" && info.completedQuery) {
const completedQuery = info.completedQuery;
(completedQuery as any).dispose = undefined;
// these fields should be missing on the deserialized value
// but they are undefined on the original value
if (!("logFileLocation" in completedQuery)) {
(completedQuery as any).logFileLocation = undefined;
}
const query = completedQuery.query;
if (!("quickEvalPosition" in query)) {
(query as any).quickEvalPosition = undefined;
}
}
});
expectedHistory.forEach((info) => {
if (info.t == "local" && info.completedQuery) {
(info.completedQuery as any).dispose = undefined;
}
});
// make the diffs somewhat sane by comparing each element directly
for (let i = 0; i < allHistoryActual.length; i++) {
expect(allHistoryActual[i]).toEqual(expectedHistory[i]);
}
expect(allHistoryActual.length).toEqual(expectedHistory.length);
});
it("should handle an invalid query history version", async () => {
const badPath = join(tmpDir.name, "bad-query-history.json");
writeFileSync(
badPath,
JSON.stringify({
version: 3,
queries: allHistory,
}),
"utf8",
);
const allHistoryActual = await deserializeQueryHistory(badPath);
// version number is invalid. Should return an empty array.
expect(allHistoryActual).toEqual([]);
});
function createMockFullQueryInfo(
dbName = "a",
queryWithResults?: QueryWithResults,
isFail = false,
): LocalQueryInfo {
const fqi = new LocalQueryInfo(
{
databaseInfo: {
name: dbName,
databaseUri: Uri.parse(`/a/b/c/${dbName}`).fsPath,
} as unknown as DatabaseInfo,
start: new Date(),
queryPath: "path/to/hucairz",
queryText: "some query",
isQuickQuery: false,
isQuickEval: false,
id: `some-id-${dbName}`,
} as InitialQueryInfo,
{
dispose: () => {
/**/
},
} as CancellationTokenSource,
);
if (queryWithResults) {
fqi.completeThisQuery(queryWithResults);
}
if (isFail) {
fqi.failureReason = "failure reason";
}
return fqi;
}
function createMockQueryWithResults(
queryPath: string,
didRunSuccessfully = true,
hasInterpretedResults = true,
dbPath = "/a/b/c",
includeSpies = true,
): QueryWithResults {
// pretend that the results path exists
const resultsPath = join(queryPath, "results.bqrs");
mkdirpSync(queryPath);
writeFileSync(resultsPath, "", "utf8");
const query = new QueryInProgress(
queryPath,
Uri.file(dbPath).fsPath,
true,
"queryDbscheme",
undefined,
{
name: "vwx",
},
);
const result: QueryWithResults = {
query: query.queryEvalInfo,
successful: didRunSuccessfully,
message: "foo",
dispose: jest.fn(),
result: {
evaluationTime: 1,
queryId: 0,
runId: 0,
resultType: QueryResultType.SUCCESS,
},
};
if (includeSpies) {
(query as any).hasInterpretedResults = () =>
Promise.resolve(hasInterpretedResults);
}
return result;
}
});

View File

@@ -42,7 +42,7 @@ describe("repository selection", () => {
it("should log an error when an empty remote user defined list is selected", async () => {
const dbManager = setUpDbManager({
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
repos: [] as RemoteRepoDbItem[],
} as DbItem);
@@ -66,7 +66,7 @@ describe("repository selection", () => {
it("should return correct selection when remote user defined list is selected", async () => {
const dbManager = setUpDbManager({
kind: DbItemKind.VariantAnalysisUserDefinedList,
kind: DbItemKind.RemoteUserDefinedList,
repos: [
{ repoFullName: "owner1/repo1" },
{ repoFullName: "owner1/repo2" },

View File

@@ -222,11 +222,7 @@ describe("run-queries", () => {
describe("register", () => {
it("should register", async () => {
const qs = createMockQueryServerClient({
cliConstraints: {
supportsDatabaseRegistration: () => true,
},
} as any);
const qs = createMockQueryServerClient();
const runner = new LegacyQueryRunner(qs);
const mockProgress = "progress-monitor";
const mockCancel = "cancel-token";
@@ -261,11 +257,7 @@ describe("run-queries", () => {
});
it("should deregister", async () => {
const qs = createMockQueryServerClient({
cliConstraints: {
supportsDatabaseRegistration: () => true,
},
} as any);
const qs = createMockQueryServerClient();
const runner = new LegacyQueryRunner(qs);
const mockProgress = "progress-monitor";
const mockCancel = "cancel-token";
@@ -298,54 +290,6 @@ describe("run-queries", () => {
mockProgress,
);
});
it("should not register if unsupported", async () => {
const qs = createMockQueryServerClient({
cliConstraints: {
supportsDatabaseRegistration: () => false,
},
} as any);
const runner = new LegacyQueryRunner(qs);
const mockProgress = "progress-monitor";
const mockCancel = "cancel-token";
const datasetUri = Uri.file("dataset-uri");
const dbItem: DatabaseItem = {
contents: {
datasetUri,
},
} as any;
await runner.registerDatabase(
mockProgress as any,
mockCancel as any,
dbItem,
);
expect(qs.sendRequest).not.toHaveBeenCalled();
});
it("should not deregister if unsupported", async () => {
const qs = createMockQueryServerClient({
cliConstraints: {
supportsDatabaseRegistration: () => false,
},
} as any);
const runner = new LegacyQueryRunner(qs);
const mockProgress = "progress-monitor";
const mockCancel = "cancel-token";
const datasetUri = Uri.file("dataset-uri");
const dbItem: DatabaseItem = {
contents: {
datasetUri,
},
} as any;
await runner.registerDatabase(
mockProgress as any,
mockCancel as any,
dbItem,
);
expect(qs.sendRequest).not.toBeCalled();
});
});
let queryNum = 0;

View File

@@ -1,4 +1,4 @@
import { QueryHistoryInfo } from "../../../src/query-history-info";
import { QueryHistoryInfo } from "../../../src/query-history/query-history-info";
export function shuffleHistoryItems(history: QueryHistoryInfo[]) {
return history.sort(() => Math.random() - 0.5);

View File

@@ -9,5 +9,4 @@ PREVIOUS_VERSION=$(echo $VERSIONS | awk '{ print $2 }')
echo "LATEST_VERSION=$LATEST_VERSION" >> $GITHUB_ENV
echo "PREVIOUS_VERSION=$PREVIOUS_VERSION" >> $GITHUB_ENV
sed -i "s/$PREVIOUS_VERSION/$LATEST_VERSION/g" supported_cli_versions.json
sed -i "s/$PREVIOUS_VERSION/$LATEST_VERSION/g" extensions/ql-vscode/test/vscode-tests/ensureCli.ts
sed -i "s/$PREVIOUS_VERSION/$LATEST_VERSION/g" extensions/ql-vscode/supported_cli_versions.json