Merge branch 'main' into robertbrignull/credentials_in_app
This commit is contained in:
2
.github/actions/create-pr/action.yml
vendored
2
.github/actions/create-pr/action.yml
vendored
@@ -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
|
||||
|
||||
22
.github/workflows/bump-cli.yml
vendored
22
.github/workflows/bump-cli.yml
vendored
@@ -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:
|
||||
|
||||
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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] || "";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -34,7 +34,7 @@ export function mapDbItemToTreeViewItem(dbItem: DbItem): DbTreeViewItem {
|
||||
dbItem.listDescription,
|
||||
);
|
||||
|
||||
case DbItemKind.VariantAnalysisUserDefinedList:
|
||||
case DbItemKind.RemoteUserDefinedList:
|
||||
return createDbTreeViewItemUserDefinedList(
|
||||
dbItem,
|
||||
dbItem.listName,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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";
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
[
|
||||
"v2.12.1",
|
||||
"v2.11.6",
|
||||
"v2.7.6",
|
||||
"v2.8.5",
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
@@ -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": {
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
"repositoryLists": [],
|
||||
"owners": [],
|
||||
"repositories": []
|
||||
},
|
||||
"local": {
|
||||
"lists": [],
|
||||
"databases": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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",
|
||||
});
|
||||
|
||||
@@ -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",
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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([]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
@@ -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");
|
||||
@@ -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");
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
@@ -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" },
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user