Merge pull request #2071 from github/koesie10/remove-remote-queries-history-item
Remove remote queries history item
This commit is contained in:
@@ -652,7 +652,6 @@ async function activateWithInstalledDistribution(
|
||||
|
||||
void extLogger.log("Initializing query history.");
|
||||
const qhm = new QueryHistoryManager(
|
||||
app,
|
||||
qs,
|
||||
dbm,
|
||||
localQueryResultsView,
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
getRawQueryName,
|
||||
QueryHistoryInfo,
|
||||
} from "./query-history-info";
|
||||
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";
|
||||
@@ -34,9 +33,6 @@ export class HistoryItemLabelProvider {
|
||||
case "local":
|
||||
replacements = this.getLocalInterpolateReplacements(item);
|
||||
break;
|
||||
case "remote":
|
||||
replacements = this.getRemoteInterpolateReplacements(item);
|
||||
break;
|
||||
case "variant-analysis":
|
||||
replacements = this.getVariantAnalysisInterpolateReplacements(item);
|
||||
break;
|
||||
@@ -92,25 +88,6 @@ export class HistoryItemLabelProvider {
|
||||
};
|
||||
}
|
||||
|
||||
private getRemoteInterpolateReplacements(
|
||||
item: RemoteQueryHistoryItem,
|
||||
): InterpolateReplacements {
|
||||
const resultCount = item.resultCount
|
||||
? `(${pluralize(item.resultCount, "result", "results")})`
|
||||
: "";
|
||||
return {
|
||||
t: new Date(item.remoteQuery.executionStartTime).toLocaleString(
|
||||
env.language,
|
||||
),
|
||||
q: `${item.remoteQuery.queryName} (${item.remoteQuery.language})`,
|
||||
d: buildRepoLabel(item),
|
||||
r: resultCount,
|
||||
s: humanizeQueryStatus(item.status),
|
||||
f: basename(item.remoteQuery.queryFilePath),
|
||||
"%": "%",
|
||||
};
|
||||
}
|
||||
|
||||
private getVariantAnalysisInterpolateReplacements(
|
||||
item: VariantAnalysisHistoryItem,
|
||||
): InterpolateReplacements {
|
||||
|
||||
@@ -236,8 +236,6 @@ export class HistoryTreeDataProvider
|
||||
switch (item.t) {
|
||||
case "local":
|
||||
return item.initialInfo.start.getTime();
|
||||
case "remote":
|
||||
return item.remoteQuery.executionStartTime;
|
||||
case "variant-analysis":
|
||||
return item.variantAnalysis.executionStartTime;
|
||||
default:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
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";
|
||||
@@ -8,17 +7,12 @@ import {
|
||||
getActionsWorkflowRunUrl as getVariantAnalysisActionsWorkflowRunUrl,
|
||||
} from "../remote-queries/shared/variant-analysis";
|
||||
|
||||
export type QueryHistoryInfo =
|
||||
| LocalQueryInfo
|
||||
| RemoteQueryHistoryItem
|
||||
| VariantAnalysisHistoryItem;
|
||||
export type QueryHistoryInfo = LocalQueryInfo | VariantAnalysisHistoryItem;
|
||||
|
||||
export function getRawQueryName(item: QueryHistoryInfo): string {
|
||||
switch (item.t) {
|
||||
case "local":
|
||||
return item.getQueryName();
|
||||
case "remote":
|
||||
return item.remoteQuery.queryName;
|
||||
case "variant-analysis":
|
||||
return item.variantAnalysis.query.name;
|
||||
default:
|
||||
@@ -37,8 +31,6 @@ export function getQueryId(item: QueryHistoryInfo): string {
|
||||
switch (item.t) {
|
||||
case "local":
|
||||
return item.initialInfo.id;
|
||||
case "remote":
|
||||
return item.queryId;
|
||||
case "variant-analysis":
|
||||
return item.variantAnalysis.id.toString();
|
||||
default:
|
||||
@@ -50,8 +42,6 @@ export function getQueryText(item: QueryHistoryInfo): string {
|
||||
switch (item.t) {
|
||||
case "local":
|
||||
return item.initialInfo.queryText;
|
||||
case "remote":
|
||||
return item.remoteQuery.queryText;
|
||||
case "variant-analysis":
|
||||
return item.variantAnalysis.query.text;
|
||||
default:
|
||||
@@ -59,47 +49,23 @@ export function getQueryText(item: QueryHistoryInfo): string {
|
||||
}
|
||||
}
|
||||
|
||||
export function buildRepoLabel(
|
||||
item: RemoteQueryHistoryItem | VariantAnalysisHistoryItem,
|
||||
): string {
|
||||
if (item.t === "remote") {
|
||||
// Return the number of repositories queried if available. Otherwise, use the controller repository name.
|
||||
const repositoryCount = item.remoteQuery.repositoryCount;
|
||||
export function buildRepoLabel(item: VariantAnalysisHistoryItem): string {
|
||||
const totalScannedRepositoryCount =
|
||||
item.variantAnalysis.scannedRepos?.length ?? 0;
|
||||
const completedRepositoryCount =
|
||||
item.variantAnalysis.scannedRepos?.filter((repo) =>
|
||||
hasRepoScanCompleted(repo),
|
||||
).length ?? 0;
|
||||
|
||||
if (repositoryCount) {
|
||||
return pluralize(repositoryCount, "repository", "repositories");
|
||||
}
|
||||
return `${item.remoteQuery.controllerRepository.owner}/${item.remoteQuery.controllerRepository.name}`;
|
||||
} else if (item.t === "variant-analysis") {
|
||||
const totalScannedRepositoryCount =
|
||||
item.variantAnalysis.scannedRepos?.length ?? 0;
|
||||
const completedRepositoryCount =
|
||||
item.variantAnalysis.scannedRepos?.filter((repo) =>
|
||||
hasRepoScanCompleted(repo),
|
||||
).length ?? 0;
|
||||
|
||||
return `${completedRepositoryCount}/${pluralize(
|
||||
totalScannedRepositoryCount,
|
||||
"repository",
|
||||
"repositories",
|
||||
)}`; // e.g. "2/3 repositories"
|
||||
} else {
|
||||
assertNever(item);
|
||||
}
|
||||
return `${completedRepositoryCount}/${pluralize(
|
||||
totalScannedRepositoryCount,
|
||||
"repository",
|
||||
"repositories",
|
||||
)}`; // e.g. "2/3 repositories"
|
||||
}
|
||||
|
||||
export function getActionsWorkflowRunUrl(
|
||||
item: RemoteQueryHistoryItem | VariantAnalysisHistoryItem,
|
||||
item: VariantAnalysisHistoryItem,
|
||||
): string {
|
||||
if (item.t === "remote") {
|
||||
const {
|
||||
actionsWorkflowRunId: workflowRunId,
|
||||
controllerRepository: { owner, name },
|
||||
} = item.remoteQuery;
|
||||
return `https://github.com/${owner}/${name}/actions/runs/${workflowRunId}`;
|
||||
} else if (item.t === "variant-analysis") {
|
||||
return getVariantAnalysisActionsWorkflowRunUrl(item.variantAnalysis);
|
||||
} else {
|
||||
assertNever(item);
|
||||
}
|
||||
return getVariantAnalysisActionsWorkflowRunUrl(item.variantAnalysis);
|
||||
}
|
||||
|
||||
@@ -53,8 +53,6 @@ import {
|
||||
import { pathExists } from "fs-extra";
|
||||
import { CliVersionConstraint } from "../cli";
|
||||
import { HistoryItemLabelProvider } from "./history-item-label-provider";
|
||||
import { cancelRemoteQuery } from "../remote-queries/gh-api/gh-actions-api-client";
|
||||
import { RemoteQueryHistoryItem } from "../remote-queries/remote-query-history-item";
|
||||
import { ResultsView } from "../interface";
|
||||
import { WebviewReveal } from "../interface-utils";
|
||||
import { EvalLogViewer } from "../eval-log-viewer";
|
||||
@@ -65,7 +63,6 @@ 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";
|
||||
import { HistoryTreeDataProvider } from "./history-tree-data-provider";
|
||||
import { redactableError } from "../pure/errors";
|
||||
|
||||
@@ -137,7 +134,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
readonly onDidCompleteQuery = this._onDidCompleteQuery.event;
|
||||
|
||||
constructor(
|
||||
private readonly app: App,
|
||||
private readonly qs: QueryRunner,
|
||||
private readonly dbm: DatabaseManager,
|
||||
private readonly localQueriesResultsView: ResultsView,
|
||||
@@ -525,9 +521,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
case "local":
|
||||
queryPath = finalSingleItem.initialInfo.queryPath;
|
||||
break;
|
||||
case "remote":
|
||||
queryPath = finalSingleItem.remoteQuery.queryFilePath;
|
||||
break;
|
||||
default:
|
||||
assertNever(finalSingleItem);
|
||||
}
|
||||
@@ -553,12 +546,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
return this.treeDataProvider.getCurrent();
|
||||
}
|
||||
|
||||
getRemoteQueryById(queryId: string): RemoteQueryHistoryItem | undefined {
|
||||
return this.treeDataProvider.allHistory.find(
|
||||
(i) => i.t === "remote" && i.queryId === queryId,
|
||||
) as RemoteQueryHistoryItem;
|
||||
}
|
||||
|
||||
async removeDeletedQueries() {
|
||||
await Promise.all(
|
||||
this.treeDataProvider.allHistory.map(async (item) => {
|
||||
@@ -595,8 +582,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
// We need to delete it from disk as well.
|
||||
await item.completedQuery?.query.deleteQuery();
|
||||
}
|
||||
} else if (item.t === "remote") {
|
||||
// Do nothing. TODO: Remove once remote queries are no longer supported.
|
||||
} else if (item.t === "variant-analysis") {
|
||||
await this.removeVariantAnalysis(item);
|
||||
} else {
|
||||
@@ -808,8 +793,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
if (queryHistoryItem.completedQuery) {
|
||||
return queryHistoryItem.completedQuery.query.querySaveDir;
|
||||
}
|
||||
} else if (queryHistoryItem.t === "remote") {
|
||||
return join(this.queryStorageDir, queryHistoryItem.queryId);
|
||||
} else if (queryHistoryItem.t === "variant-analysis") {
|
||||
return this.variantAnalysisManager.getVariantAnalysisStorageLocation(
|
||||
queryHistoryItem.variantAnalysis.id,
|
||||
@@ -840,12 +823,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
"timestamp",
|
||||
);
|
||||
}
|
||||
} else if (finalSingleItem.t === "remote") {
|
||||
externalFilePath = join(
|
||||
this.queryStorageDir,
|
||||
finalSingleItem.queryId,
|
||||
"timestamp",
|
||||
);
|
||||
} else if (finalSingleItem.t === "variant-analysis") {
|
||||
externalFilePath = join(
|
||||
this.variantAnalysisManager.getVariantAnalysisStorageLocation(
|
||||
@@ -1012,11 +989,6 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
if (item.status === QueryStatus.InProgress) {
|
||||
if (item.t === "local") {
|
||||
item.cancel();
|
||||
} else if (item.t === "remote") {
|
||||
void showAndLogInformationMessage(
|
||||
"Cancelling variant analysis. This may take a while.",
|
||||
);
|
||||
await cancelRemoteQuery(this.app.credentials, item.remoteQuery);
|
||||
} else if (item.t === "variant-analysis") {
|
||||
await commands.executeCommand(
|
||||
"codeQL.cancelVariantAnalysis",
|
||||
@@ -1239,10 +1211,8 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remote queries and variant analysis only
|
||||
if (finalSingleItem.t === "remote") {
|
||||
// Do nothing. TODO: Remove this case once remote queries are removed.
|
||||
} else if (finalSingleItem.t === "variant-analysis") {
|
||||
// Variant analysis only
|
||||
if (finalSingleItem.t === "variant-analysis") {
|
||||
await commands.executeCommand(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
finalSingleItem.variantAnalysis.id,
|
||||
@@ -1475,8 +1445,6 @@ the file in the file explorer and dragging it into the workspace.`,
|
||||
WebviewReveal.Forced,
|
||||
false,
|
||||
);
|
||||
} else if (item.t === "remote") {
|
||||
// Do nothing. TODO: Remove when remote queries is no longer supported.
|
||||
} else if (item.t === "variant-analysis") {
|
||||
await this.variantAnalysisManager.showView(item.variantAnalysis.id);
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
} from "./pure/helpers-pure";
|
||||
import { CompletedQueryInfo, LocalQueryInfo } from "./query-results";
|
||||
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";
|
||||
import { redactableError } from "./pure/errors";
|
||||
@@ -33,58 +32,57 @@ export async function deserializeQueryHistory(
|
||||
}
|
||||
|
||||
const queries = obj.queries;
|
||||
const parsedQueries = queries.map((q: QueryHistoryInfo) => {
|
||||
// Need to explicitly set prototype since reading in from JSON will not
|
||||
// do this automatically. Note that we can't call the constructor here since
|
||||
// the constructor invokes extra logic that we don't want to do.
|
||||
if (q.t === "local") {
|
||||
Object.setPrototypeOf(q, LocalQueryInfo.prototype);
|
||||
const parsedQueries = queries
|
||||
// Remove remote queries, which are not supported anymore.
|
||||
.filter((q: QueryHistoryInfo | { t: "remote" }) => q.t !== "remote")
|
||||
.map((q: QueryHistoryInfo) => {
|
||||
// Need to explicitly set prototype since reading in from JSON will not
|
||||
// do this automatically. Note that we can't call the constructor here since
|
||||
// the constructor invokes extra logic that we don't want to do.
|
||||
if (q.t === "local") {
|
||||
Object.setPrototypeOf(q, LocalQueryInfo.prototype);
|
||||
|
||||
// Date instances are serialized as strings. Need to
|
||||
// convert them back to Date instances.
|
||||
(q.initialInfo as any).start = new Date(q.initialInfo.start);
|
||||
if (q.completedQuery) {
|
||||
// Again, need to explicitly set prototypes.
|
||||
Object.setPrototypeOf(q.completedQuery, CompletedQueryInfo.prototype);
|
||||
Object.setPrototypeOf(
|
||||
q.completedQuery.query,
|
||||
QueryEvaluationInfo.prototype,
|
||||
);
|
||||
// deserialized queries do not need to be disposed
|
||||
q.completedQuery.dispose = () => {
|
||||
/**/
|
||||
};
|
||||
// Date instances are serialized as strings. Need to
|
||||
// convert them back to Date instances.
|
||||
(q.initialInfo as any).start = new Date(q.initialInfo.start);
|
||||
if (q.completedQuery) {
|
||||
// Again, need to explicitly set prototypes.
|
||||
Object.setPrototypeOf(
|
||||
q.completedQuery,
|
||||
CompletedQueryInfo.prototype,
|
||||
);
|
||||
Object.setPrototypeOf(
|
||||
q.completedQuery.query,
|
||||
QueryEvaluationInfo.prototype,
|
||||
);
|
||||
// deserialized queries do not need to be disposed
|
||||
q.completedQuery.dispose = () => {
|
||||
/**/
|
||||
};
|
||||
|
||||
// Previously, there was a typo in the completedQuery type. There was a field
|
||||
// `sucessful` and it was renamed to `successful`. We need to handle this case.
|
||||
if ("sucessful" in q.completedQuery) {
|
||||
(q.completedQuery as any).successful = (
|
||||
q.completedQuery as any
|
||||
).sucessful;
|
||||
delete (q.completedQuery as any).sucessful;
|
||||
}
|
||||
// Previously, there was a typo in the completedQuery type. There was a field
|
||||
// `sucessful` and it was renamed to `successful`. We need to handle this case.
|
||||
if ("sucessful" in q.completedQuery) {
|
||||
(q.completedQuery as any).successful = (
|
||||
q.completedQuery as any
|
||||
).sucessful;
|
||||
delete (q.completedQuery as any).sucessful;
|
||||
}
|
||||
|
||||
if (!("successful" in q.completedQuery)) {
|
||||
(q.completedQuery as any).successful =
|
||||
q.completedQuery.result?.resultType === QueryResultType.SUCCESS;
|
||||
if (!("successful" in q.completedQuery)) {
|
||||
(q.completedQuery as any).successful =
|
||||
q.completedQuery.result?.resultType === QueryResultType.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (q.t === "remote") {
|
||||
// A bug was introduced that didn't set the completed flag in query history
|
||||
// items. The following code makes sure that the flag is set in order to
|
||||
// "patch" older query history items.
|
||||
if (q.status === QueryStatus.Completed) {
|
||||
q.completed = true;
|
||||
}
|
||||
}
|
||||
return q;
|
||||
});
|
||||
return q;
|
||||
});
|
||||
|
||||
// filter out queries that have been deleted on disk
|
||||
// most likely another workspace has deleted them because the
|
||||
// queries aged out.
|
||||
return asyncFilter(parsedQueries, async (q) => {
|
||||
if (q.t === "remote" || q.t === "variant-analysis") {
|
||||
if (q.t === "variant-analysis") {
|
||||
// the deserializer doesn't know where the remote queries are stored
|
||||
// so we need to assume here that they exist. Later, we check to
|
||||
// see if they exist on disk.
|
||||
|
||||
@@ -47,9 +47,7 @@ export async function exportSelectedRemoteQueryResults(
|
||||
);
|
||||
}
|
||||
|
||||
if (queryHistoryItem.t === "remote") {
|
||||
// Do nothing. TODO: Remove this branch once we stop supporting remote queries.
|
||||
} else if (queryHistoryItem.t === "variant-analysis") {
|
||||
if (queryHistoryItem.t === "variant-analysis") {
|
||||
return commands.executeCommand(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
queryHistoryItem.variantAnalysis.id,
|
||||
|
||||
@@ -1,33 +1,6 @@
|
||||
import { join } from "path";
|
||||
import { pathExists, writeFile } from "fs-extra";
|
||||
import { Credentials } from "../../common/authentication";
|
||||
import { extLogger } from "../../common";
|
||||
import { createDownloadPath, DownloadLink } from "../download-link";
|
||||
import { RemoteQuery } from "../remote-query";
|
||||
import { unzipFile } from "../../pure/zip";
|
||||
import { VariantAnalysis } from "../shared/variant-analysis";
|
||||
|
||||
export async function cancelRemoteQuery(
|
||||
credentials: Credentials,
|
||||
remoteQuery: RemoteQuery,
|
||||
): Promise<void> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
const {
|
||||
actionsWorkflowRunId,
|
||||
controllerRepository: { owner, name },
|
||||
} = remoteQuery;
|
||||
const response = await octokit.request(
|
||||
`POST /repos/${owner}/${name}/actions/runs/${actionsWorkflowRunId}/cancel`,
|
||||
);
|
||||
if (response.status >= 300) {
|
||||
throw new Error(
|
||||
`Error cancelling variant analysis: ${response.status} ${
|
||||
response?.data?.message || ""
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function cancelVariantAnalysis(
|
||||
credentials: Credentials,
|
||||
variantAnalysis: VariantAnalysis,
|
||||
@@ -48,39 +21,3 @@ export async function cancelVariantAnalysis(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function downloadArtifactFromLink(
|
||||
credentials: Credentials,
|
||||
storagePath: string,
|
||||
downloadLink: DownloadLink,
|
||||
): Promise<string> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
|
||||
const extractedPath = createDownloadPath(storagePath, downloadLink);
|
||||
|
||||
// first check if we already have the artifact
|
||||
if (!(await pathExists(extractedPath))) {
|
||||
// Download the zipped artifact.
|
||||
const response = await octokit.request(
|
||||
`GET ${downloadLink.urlPath}/zip`,
|
||||
{},
|
||||
);
|
||||
|
||||
const zipFilePath = createDownloadPath(storagePath, downloadLink, "zip");
|
||||
|
||||
await unzipBuffer(response.data as ArrayBuffer, zipFilePath, extractedPath);
|
||||
}
|
||||
return join(extractedPath, downloadLink.innerFilePath || "");
|
||||
}
|
||||
|
||||
async function unzipBuffer(
|
||||
data: ArrayBuffer,
|
||||
filePath: string,
|
||||
destinationPath: string,
|
||||
): Promise<void> {
|
||||
void extLogger.log(`Saving file to ${filePath}`);
|
||||
await writeFile(filePath, Buffer.from(data));
|
||||
|
||||
void extLogger.log(`Unzipping file to ${destinationPath}`);
|
||||
await unzipFile(filePath, destinationPath);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { OctokitResponse } from "@octokit/types/dist-types";
|
||||
import { Credentials } from "../../common/authentication";
|
||||
import { RemoteQueriesSubmission } from "../shared/remote-queries";
|
||||
import { VariantAnalysisSubmission } from "../shared/variant-analysis";
|
||||
import {
|
||||
VariantAnalysis,
|
||||
@@ -8,10 +7,6 @@ import {
|
||||
VariantAnalysisSubmissionRequest,
|
||||
} from "./variant-analysis";
|
||||
import { Repository } from "./repository";
|
||||
import {
|
||||
RemoteQueriesResponse,
|
||||
RemoteQueriesSubmissionRequest,
|
||||
} from "./remote-queries";
|
||||
|
||||
export async function submitVariantAnalysis(
|
||||
credentials: Credentials,
|
||||
@@ -116,40 +111,3 @@ export async function createGist(
|
||||
}
|
||||
return response.data.html_url;
|
||||
}
|
||||
|
||||
export async function submitRemoteQueries(
|
||||
credentials: Credentials,
|
||||
submissionDetails: RemoteQueriesSubmission,
|
||||
): Promise<RemoteQueriesResponse> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
|
||||
const {
|
||||
ref,
|
||||
language,
|
||||
repositories,
|
||||
repositoryLists,
|
||||
repositoryOwners,
|
||||
queryPack,
|
||||
controllerRepoId,
|
||||
} = submissionDetails;
|
||||
|
||||
const data: RemoteQueriesSubmissionRequest = {
|
||||
ref,
|
||||
language,
|
||||
repositories,
|
||||
repository_lists: repositoryLists,
|
||||
repository_owners: repositoryOwners,
|
||||
query_pack: queryPack,
|
||||
};
|
||||
|
||||
const response: OctokitResponse<RemoteQueriesResponse> =
|
||||
await octokit.request(
|
||||
"POST /repositories/:controllerRepoId/code-scanning/codeql/queries",
|
||||
{
|
||||
controllerRepoId,
|
||||
data,
|
||||
},
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
export interface RemoteQueriesSubmissionRequest {
|
||||
ref: string;
|
||||
language: string;
|
||||
repositories?: string[];
|
||||
repository_lists?: string[];
|
||||
repository_owners?: string[];
|
||||
query_pack: string;
|
||||
}
|
||||
|
||||
export interface RemoteQueriesResponse {
|
||||
workflow_run_id: number;
|
||||
errors?: {
|
||||
invalid_repositories?: string[];
|
||||
repositories_without_database?: string[];
|
||||
private_repositories?: string[];
|
||||
cutoff_repositories?: string[];
|
||||
cutoff_repositories_count?: number;
|
||||
};
|
||||
repositories_queried: string[];
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { QueryStatus } from "../query-status";
|
||||
import { RemoteQuery } from "./remote-query";
|
||||
|
||||
/**
|
||||
* Information about a remote query.
|
||||
*/
|
||||
export interface RemoteQueryHistoryItem {
|
||||
readonly t: "remote";
|
||||
failureReason?: string;
|
||||
resultCount?: number;
|
||||
status: QueryStatus;
|
||||
completed: boolean;
|
||||
readonly queryId: string;
|
||||
remoteQuery: RemoteQuery;
|
||||
userSpecifiedLabel?: string;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
export interface RemoteQueryResultIndex {
|
||||
artifactsUrlPath: string;
|
||||
successes: RemoteQuerySuccessIndexItem[];
|
||||
failures: RemoteQueryFailureIndexItem[];
|
||||
}
|
||||
|
||||
export interface RemoteQuerySuccessIndexItem {
|
||||
id: string;
|
||||
artifactId: number;
|
||||
nwo: string;
|
||||
sha?: string;
|
||||
resultCount: number;
|
||||
bqrsFileSize: number;
|
||||
sarifFileSize?: number;
|
||||
sourceLocationPrefix: string;
|
||||
}
|
||||
|
||||
export interface RemoteQueryFailureIndexItem {
|
||||
id: string;
|
||||
artifactId: number;
|
||||
nwo: string;
|
||||
error: string;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { DownloadLink } from "./download-link";
|
||||
import { AnalysisFailure } from "./shared/analysis-failure";
|
||||
|
||||
export interface RemoteQueryResult {
|
||||
executionEndTime: number; // Can't use a Date here since it needs to be serialized and desserialized.
|
||||
analysisSummaries: AnalysisSummary[];
|
||||
analysisFailures: AnalysisFailure[];
|
||||
queryId: string;
|
||||
}
|
||||
|
||||
export interface AnalysisSummary {
|
||||
nwo: string;
|
||||
databaseSha: string;
|
||||
resultCount: number;
|
||||
sourceLocationPrefix: string;
|
||||
downloadLink: DownloadLink;
|
||||
fileSizeInBytes: number;
|
||||
starCount?: number;
|
||||
lastUpdated?: number;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { RemoteQuery } from "./remote-query";
|
||||
import { VariantAnalysis } from "./shared/variant-analysis";
|
||||
|
||||
export interface RemoteQuerySubmissionResult {
|
||||
queryDirPath?: string;
|
||||
query?: RemoteQuery;
|
||||
variantAnalysis?: VariantAnalysis;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
export type RemoteQueryWorkflowStatus =
|
||||
| "InProgress"
|
||||
| "CompletedSuccessfully"
|
||||
| "CompletedUnsuccessfully"
|
||||
| "Cancelled";
|
||||
|
||||
export interface RemoteQueryWorkflowResult {
|
||||
status: RemoteQueryWorkflowStatus;
|
||||
error?: string;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Repository as RemoteRepository } from "./repository";
|
||||
|
||||
export interface RemoteQuery {
|
||||
queryName: string;
|
||||
queryFilePath: string;
|
||||
queryText: string;
|
||||
language: string;
|
||||
controllerRepository: RemoteRepository;
|
||||
executionStartTime: number; // Use number here since it needs to be serialized and desserialized.
|
||||
actionsWorkflowRunId: number;
|
||||
repositoryCount: number;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
export interface RemoteQueriesSubmission {
|
||||
ref: string;
|
||||
language: string;
|
||||
repositories?: string[];
|
||||
repositoryLists?: string[];
|
||||
repositoryOwners?: string[];
|
||||
queryPack: string;
|
||||
|
||||
controllerRepoId: number;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { nanoid } from "nanoid";
|
||||
import { RemoteQueryHistoryItem } from "../../../src/remote-queries/remote-query-history-item";
|
||||
import { QueryStatus } from "../../../src/query-status";
|
||||
|
||||
export function createMockRemoteQueryHistoryItem({
|
||||
date = new Date("2022-01-01T00:00:00.000Z"),
|
||||
status = QueryStatus.InProgress,
|
||||
failureReason = undefined,
|
||||
resultCount = undefined,
|
||||
repositoryCount = 0,
|
||||
executionStartTime = date.getTime(),
|
||||
userSpecifiedLabel = undefined,
|
||||
}: {
|
||||
date?: Date;
|
||||
status?: QueryStatus;
|
||||
failureReason?: string;
|
||||
resultCount?: number;
|
||||
repositoryCount?: number;
|
||||
repositories?: string[];
|
||||
executionStartTime?: number;
|
||||
userSpecifiedLabel?: string;
|
||||
}): RemoteQueryHistoryItem {
|
||||
return {
|
||||
t: "remote",
|
||||
failureReason,
|
||||
resultCount,
|
||||
status,
|
||||
completed: false,
|
||||
queryId: nanoid(),
|
||||
remoteQuery: {
|
||||
queryName: "query-name",
|
||||
queryFilePath: "query-file.ql",
|
||||
queryText: "select 1",
|
||||
language: "javascript",
|
||||
controllerRepository: {
|
||||
owner: "github",
|
||||
name: "vscode-codeql-integration-tests",
|
||||
},
|
||||
executionStartTime,
|
||||
actionsWorkflowRunId: 1,
|
||||
repositoryCount,
|
||||
},
|
||||
userSpecifiedLabel,
|
||||
};
|
||||
}
|
||||
@@ -2,15 +2,12 @@ import { env } from "vscode";
|
||||
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;
|
||||
let config: QueryHistoryConfig;
|
||||
const date = new Date("2022-01-01T00:00:00.000Z");
|
||||
const dateStr = date.toLocaleString(env.language);
|
||||
const executionStartTime = date.getTime();
|
||||
const userSpecifiedLabel = "user-specified-name";
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -85,149 +82,4 @@ describe("HistoryItemLabelProvider", () => {
|
||||
expect(labelProvider.getShortLabel(fqi2)).toBe("query-file.ql");
|
||||
});
|
||||
});
|
||||
|
||||
describe("remote queries", () => {
|
||||
it("should interpolate query when user specified", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({ userSpecifiedLabel });
|
||||
|
||||
expect(labelProvider.getLabel(fqi)).toBe(userSpecifiedLabel);
|
||||
|
||||
fqi.userSpecifiedLabel = "%t %q %d %s %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress %`,
|
||||
);
|
||||
|
||||
fqi.userSpecifiedLabel = "%t %q %d %s %%::%t %q %d %s %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress %::${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress %`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should interpolate query when not user-specified", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 16,
|
||||
});
|
||||
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
"xxx query-name (javascript) xxx",
|
||||
);
|
||||
|
||||
config.format = "%t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests completed query-file.ql (16 results) %`,
|
||||
);
|
||||
|
||||
config.format = "%t %q %d %s %f %r %%::%t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests completed query-file.ql (16 results) %::${dateStr} query-name (javascript) github/vscode-codeql-integration-tests completed query-file.ql (16 results) %`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should use number of repositories instead of controller repo if available", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 16,
|
||||
repositoryCount: 2,
|
||||
});
|
||||
|
||||
config.format = "%t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) 2 repositories completed query-file.ql (16 results) %`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should get query short label", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
userSpecifiedLabel,
|
||||
});
|
||||
|
||||
// fall back on user specified if one exists.
|
||||
expect(labelProvider.getShortLabel(fqi)).toBe("user-specified-name");
|
||||
|
||||
// use query name if no user-specified label exists
|
||||
const fqi2 = createMockRemoteQueryHistoryItem({});
|
||||
|
||||
expect(labelProvider.getShortLabel(fqi2)).toBe("query-name");
|
||||
});
|
||||
|
||||
describe("when results are present", () => {
|
||||
it("should display results if there are any", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 16,
|
||||
repositoryCount: 2,
|
||||
});
|
||||
config.format = "%t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) 2 repositories completed query-file.ql (16 results) %`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when results are not present", () => {
|
||||
it("should skip displaying them", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 0,
|
||||
repositoryCount: 2,
|
||||
});
|
||||
config.format = "%t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) 2 repositories completed query-file.ql %`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when extra whitespace is present in the middle of the label", () => {
|
||||
it("should squash it down to a single whitespace", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 0,
|
||||
repositoryCount: 2,
|
||||
});
|
||||
config.format = "%t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) 2 repositories completed query-file.ql %`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when extra whitespace is present at the start of the label", () => {
|
||||
it("should squash it down to a single whitespace", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 0,
|
||||
repositoryCount: 2,
|
||||
});
|
||||
config.format = " %t %q %d %s %f %r %%";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
` ${dateStr} query-name (javascript) 2 repositories completed query-file.ql %`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when extra whitespace is present at the end of the label", () => {
|
||||
it("should squash it down to a single whitespace", () => {
|
||||
const fqi = createMockRemoteQueryHistoryItem({
|
||||
status: QueryStatus.Completed,
|
||||
executionStartTime,
|
||||
resultCount: 0,
|
||||
repositoryCount: 2,
|
||||
});
|
||||
config.format = "%t %q %d %s %f %r %% ";
|
||||
expect(labelProvider.getLabel(fqi)).toBe(
|
||||
`${dateStr} query-name (javascript) 2 repositories completed query-file.ql % `,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,15 +19,11 @@ import {
|
||||
createMockLocalQueryInfo,
|
||||
createMockQueryWithResults,
|
||||
} 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 { Credentials } from "../../../../src/common/authentication";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import {
|
||||
HistoryTreeDataProvider,
|
||||
SortOrder,
|
||||
@@ -46,7 +42,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
let allHistory: QueryHistoryInfo[];
|
||||
let localQueryHistory: LocalQueryInfo[];
|
||||
let remoteQueryHistory: RemoteQueryHistoryItem[];
|
||||
let variantAnalysisHistory: VariantAnalysisHistoryItem[];
|
||||
|
||||
let historyTreeDataProvider: HistoryTreeDataProvider;
|
||||
@@ -102,12 +97,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
// in progress
|
||||
createMockLocalQueryInfo({ resultCount: 0 }),
|
||||
];
|
||||
remoteQueryHistory = [
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.Completed }),
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.Failed }),
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.InProgress }),
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.InProgress }),
|
||||
];
|
||||
variantAnalysisHistory = [
|
||||
createMockVariantAnalysisHistoryItem({
|
||||
historyItemStatus: QueryStatus.Completed,
|
||||
@@ -128,7 +117,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
];
|
||||
allHistory = shuffleHistoryItems([
|
||||
...localQueryHistory,
|
||||
...remoteQueryHistory,
|
||||
...variantAnalysisHistory,
|
||||
]);
|
||||
|
||||
@@ -233,12 +221,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
describe("sorting", () => {
|
||||
const history = [
|
||||
createMockRemoteQueryHistoryItem({
|
||||
userSpecifiedLabel: "a",
|
||||
executionStartTime: 2,
|
||||
resultCount: 24,
|
||||
status: QueryStatus.Completed,
|
||||
}),
|
||||
createMockLocalQueryInfo({
|
||||
userSpecifiedLabel: "b",
|
||||
startTime: new Date(10),
|
||||
@@ -275,12 +257,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
historyItemStatus: QueryStatus.Failed,
|
||||
variantAnalysisStatus: VariantAnalysisStatus.Failed,
|
||||
}),
|
||||
createMockRemoteQueryHistoryItem({
|
||||
userSpecifiedLabel: "h",
|
||||
executionStartTime: 6,
|
||||
resultCount: 5,
|
||||
status: QueryStatus.InProgress,
|
||||
}),
|
||||
];
|
||||
|
||||
let treeDataProvider: HistoryTreeDataProvider;
|
||||
@@ -309,14 +285,12 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
it("should get children for date ascending", async () => {
|
||||
const expected = [
|
||||
history[4],
|
||||
history[2],
|
||||
history[5],
|
||||
history[0],
|
||||
history[3],
|
||||
history[7],
|
||||
history[6],
|
||||
history[1],
|
||||
history[2],
|
||||
history[4],
|
||||
history[3],
|
||||
];
|
||||
treeDataProvider.sortOrder = SortOrder.DateAsc;
|
||||
|
||||
@@ -326,14 +300,12 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
it("should get children for date descending", async () => {
|
||||
const expected = [
|
||||
history[4],
|
||||
history[2],
|
||||
history[5],
|
||||
history[0],
|
||||
history[3],
|
||||
history[7],
|
||||
history[6],
|
||||
history[1],
|
||||
history[2],
|
||||
history[4],
|
||||
history[3],
|
||||
].reverse();
|
||||
|
||||
treeDataProvider.sortOrder = SortOrder.DateDesc;
|
||||
@@ -344,14 +316,12 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
it("should get children for result count ascending", async () => {
|
||||
const expected = [
|
||||
history[7],
|
||||
history[5],
|
||||
history[4],
|
||||
history[1],
|
||||
history[0],
|
||||
history[3],
|
||||
history[6],
|
||||
history[0],
|
||||
history[2],
|
||||
history[5],
|
||||
history[1],
|
||||
];
|
||||
treeDataProvider.sortOrder = SortOrder.CountAsc;
|
||||
|
||||
@@ -362,14 +332,12 @@ describe("HistoryTreeDataProvider", () => {
|
||||
|
||||
it("should get children for result count descending", async () => {
|
||||
const expected = [
|
||||
history[7],
|
||||
history[5],
|
||||
history[4],
|
||||
history[1],
|
||||
history[0],
|
||||
history[3],
|
||||
history[6],
|
||||
history[0],
|
||||
history[2],
|
||||
history[5],
|
||||
history[1],
|
||||
].reverse();
|
||||
treeDataProvider.sortOrder = SortOrder.CountDesc;
|
||||
|
||||
@@ -395,12 +363,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
historyItemStatus: QueryStatus.Completed,
|
||||
variantAnalysisStatus: VariantAnalysisStatus.Failed,
|
||||
}),
|
||||
createMockRemoteQueryHistoryItem({
|
||||
userSpecifiedLabel: "d",
|
||||
resultCount: 0,
|
||||
executionStartTime: 50,
|
||||
status: QueryStatus.Completed,
|
||||
}),
|
||||
createMockVariantAnalysisHistoryItem({
|
||||
userSpecifiedLabel: "e",
|
||||
resultCount: 0,
|
||||
@@ -438,12 +400,6 @@ describe("HistoryTreeDataProvider", () => {
|
||||
historyItemStatus: QueryStatus.Completed,
|
||||
variantAnalysisStatus: VariantAnalysisStatus.Failed,
|
||||
}),
|
||||
createMockRemoteQueryHistoryItem({
|
||||
userSpecifiedLabel: "d",
|
||||
resultCount: 0,
|
||||
executionStartTime: 50,
|
||||
status: QueryStatus.Completed,
|
||||
}),
|
||||
createMockVariantAnalysisHistoryItem({
|
||||
userSpecifiedLabel: "e",
|
||||
resultCount: 0,
|
||||
@@ -463,12 +419,8 @@ describe("HistoryTreeDataProvider", () => {
|
||||
});
|
||||
});
|
||||
|
||||
async function createMockQueryHistory(
|
||||
allHistory: QueryHistoryInfo[],
|
||||
credentials?: Credentials,
|
||||
) {
|
||||
async function createMockQueryHistory(allHistory: QueryHistoryInfo[]) {
|
||||
const qhm = new QueryHistoryManager(
|
||||
createMockApp({ credentials }),
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
||||
@@ -10,7 +10,6 @@ import { VariantAnalysisHistoryItem } from "../../../../src/query-history/varian
|
||||
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,
|
||||
@@ -19,7 +18,6 @@ import {
|
||||
describe("Query history info", () => {
|
||||
const date = new Date("2022-01-01T00:00:00.000Z");
|
||||
const localQueryHistoryItem = createMockLocalQueryInfo({ startTime: date });
|
||||
const remoteQueryHistoryItem = createMockRemoteQueryHistoryItem({});
|
||||
const variantAnalysisHistoryItem: VariantAnalysisHistoryItem = {
|
||||
t: "variant-analysis",
|
||||
status: QueryStatus.InProgress,
|
||||
@@ -42,12 +40,6 @@ describe("Query history info", () => {
|
||||
expect(queryName).toBe(localQueryHistoryItem.getQueryName());
|
||||
});
|
||||
|
||||
it("should get the name for remote query history items", () => {
|
||||
const queryName = getRawQueryName(remoteQueryHistoryItem);
|
||||
|
||||
expect(queryName).toBe(remoteQueryHistoryItem.remoteQuery.queryName);
|
||||
});
|
||||
|
||||
it("should get the name for variant analysis history items", () => {
|
||||
const queryName = getRawQueryName(variantAnalysisHistoryItem);
|
||||
|
||||
@@ -64,12 +56,6 @@ describe("Query history info", () => {
|
||||
expect(historyItemId).toBe(localQueryHistoryItem.initialInfo.id);
|
||||
});
|
||||
|
||||
it("should get the ID for remote query history items", () => {
|
||||
const historyItemId = getQueryId(remoteQueryHistoryItem);
|
||||
|
||||
expect(historyItemId).toBe(remoteQueryHistoryItem.queryId);
|
||||
});
|
||||
|
||||
it("should get the ID for variant analysis history items", () => {
|
||||
const historyItemId = getQueryId(variantAnalysisHistoryItem);
|
||||
|
||||
@@ -86,12 +72,6 @@ describe("Query history info", () => {
|
||||
expect(queryText).toBe(localQueryHistoryItem.initialInfo.queryText);
|
||||
});
|
||||
|
||||
it("should get the query text for remote query history items", () => {
|
||||
const queryText = getQueryText(remoteQueryHistoryItem);
|
||||
|
||||
expect(queryText).toBe(remoteQueryHistoryItem.remoteQuery.queryText);
|
||||
});
|
||||
|
||||
it("should get the query text for variant analysis history items", () => {
|
||||
const queryText = getQueryText(variantAnalysisHistoryItem);
|
||||
|
||||
@@ -102,23 +82,6 @@ describe("Query history info", () => {
|
||||
});
|
||||
|
||||
describe("buildRepoLabel", () => {
|
||||
describe("repo label for remote query history items", () => {
|
||||
it("should return controller repo when `repositoryCount` is 0", () => {
|
||||
const repoLabel = buildRepoLabel(remoteQueryHistoryItem);
|
||||
const expectedRepoLabel = `${remoteQueryHistoryItem.remoteQuery.controllerRepository.owner}/${remoteQueryHistoryItem.remoteQuery.controllerRepository.name}`;
|
||||
|
||||
expect(repoLabel).toBe(expectedRepoLabel);
|
||||
});
|
||||
it("should return number of repositories when `repositoryCount` is non-zero", () => {
|
||||
const remoteQueryHistoryItem2 = createMockRemoteQueryHistoryItem({
|
||||
repositoryCount: 3,
|
||||
});
|
||||
const repoLabel2 = buildRepoLabel(remoteQueryHistoryItem2);
|
||||
const expectedRepoLabel2 = "3 repositories";
|
||||
|
||||
expect(repoLabel2).toBe(expectedRepoLabel2);
|
||||
});
|
||||
});
|
||||
describe("repo label for variant analysis history items", () => {
|
||||
it("should return label when `totalScannedRepositoryCount` is 0", () => {
|
||||
const variantAnalysisHistoryItem0: VariantAnalysisHistoryItem = {
|
||||
@@ -159,18 +122,6 @@ describe("Query history info", () => {
|
||||
});
|
||||
|
||||
describe("getActionsWorkflowRunUrl", () => {
|
||||
it("should get the run url for remote query history items", () => {
|
||||
const actionsWorkflowRunUrl = getActionsWorkflowRunUrl(
|
||||
remoteQueryHistoryItem,
|
||||
);
|
||||
|
||||
const remoteQuery = remoteQueryHistoryItem.remoteQuery;
|
||||
const fullName = `${remoteQuery.controllerRepository.owner}/${remoteQuery.controllerRepository.name}`;
|
||||
expect(actionsWorkflowRunUrl).toBe(
|
||||
`https://github.com/${fullName}/actions/runs/${remoteQuery.actionsWorkflowRunId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should get the run url for variant analysis history items", () => {
|
||||
const actionsWorkflowRunUrl = getActionsWorkflowRunUrl(
|
||||
variantAnalysisHistoryItem,
|
||||
|
||||
@@ -20,20 +20,14 @@ import {
|
||||
createMockLocalQueryInfo,
|
||||
createMockQueryWithResults,
|
||||
} 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 { Credentials } from "../../../../src/common/authentication";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
describe("QueryHistoryManager", () => {
|
||||
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");
|
||||
@@ -59,7 +53,6 @@ describe("QueryHistoryManager", () => {
|
||||
|
||||
let allHistory: QueryHistoryInfo[];
|
||||
let localQueryHistory: LocalQueryInfo[];
|
||||
let remoteQueryHistory: RemoteQueryHistoryItem[];
|
||||
let variantAnalysisHistory: VariantAnalysisHistoryItem[];
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -127,12 +120,6 @@ describe("QueryHistoryManager", () => {
|
||||
// in progress
|
||||
createMockLocalQueryInfo({ resultCount: 0 }),
|
||||
];
|
||||
remoteQueryHistory = [
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.Completed }),
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.Failed }),
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.InProgress }),
|
||||
createMockRemoteQueryHistoryItem({ status: QueryStatus.InProgress }),
|
||||
];
|
||||
variantAnalysisHistory = [
|
||||
createMockVariantAnalysisHistoryItem({
|
||||
historyItemStatus: QueryStatus.Completed,
|
||||
@@ -153,7 +140,6 @@ describe("QueryHistoryManager", () => {
|
||||
];
|
||||
allHistory = shuffleHistoryItems([
|
||||
...localQueryHistory,
|
||||
...remoteQueryHistory,
|
||||
...variantAnalysisHistory,
|
||||
]);
|
||||
});
|
||||
@@ -709,24 +695,9 @@ describe("QueryHistoryManager", () => {
|
||||
});
|
||||
|
||||
describe("handleCancel", () => {
|
||||
let mockCancelRemoteQuery: jest.SpiedFunction<
|
||||
typeof ghActionsApiClient.cancelRemoteQuery
|
||||
>;
|
||||
const getOctokitStub = jest.fn();
|
||||
const mockCredentials = testCredentialsWithStub(getOctokitStub);
|
||||
|
||||
beforeEach(async () => {
|
||||
mockCancelRemoteQuery = jest
|
||||
.spyOn(ghActionsApiClient, "cancelRemoteQuery")
|
||||
.mockResolvedValue();
|
||||
});
|
||||
|
||||
describe("if the item is in progress", () => {
|
||||
it("should cancel a single local query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = localQueryHistory[4];
|
||||
@@ -737,10 +708,7 @@ describe("QueryHistoryManager", () => {
|
||||
});
|
||||
|
||||
it("should cancel multiple local queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = localQueryHistory[4];
|
||||
@@ -757,51 +725,8 @@ describe("QueryHistoryManager", () => {
|
||||
expect(cancelSpy2).toBeCalled();
|
||||
});
|
||||
|
||||
it("should cancel a single remote query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = remoteQueryHistory[2];
|
||||
|
||||
await queryHistoryManager.handleCancel(inProgress1, [inProgress1]);
|
||||
expect(mockCancelRemoteQuery).toBeCalledWith(
|
||||
mockCredentials,
|
||||
inProgress1.remoteQuery,
|
||||
);
|
||||
});
|
||||
|
||||
it("should cancel multiple remote queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = remoteQueryHistory[2];
|
||||
const inProgress2 = remoteQueryHistory[3];
|
||||
|
||||
await queryHistoryManager.handleCancel(inProgress1, [
|
||||
inProgress1,
|
||||
inProgress2,
|
||||
]);
|
||||
expect(mockCancelRemoteQuery).toBeCalledWith(
|
||||
mockCredentials,
|
||||
inProgress1.remoteQuery,
|
||||
);
|
||||
expect(mockCancelRemoteQuery).toBeCalledWith(
|
||||
mockCredentials,
|
||||
inProgress2.remoteQuery,
|
||||
);
|
||||
});
|
||||
|
||||
it("should cancel a single variant analysis", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = variantAnalysisHistory[1];
|
||||
@@ -814,10 +739,7 @@ describe("QueryHistoryManager", () => {
|
||||
});
|
||||
|
||||
it("should cancel multiple variant analyses", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = variantAnalysisHistory[1];
|
||||
@@ -840,10 +762,7 @@ describe("QueryHistoryManager", () => {
|
||||
|
||||
describe("if the item is not in progress", () => {
|
||||
it("should not cancel a single local query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = localQueryHistory[0];
|
||||
@@ -854,10 +773,7 @@ describe("QueryHistoryManager", () => {
|
||||
});
|
||||
|
||||
it("should not cancel multiple local queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = localQueryHistory[0];
|
||||
@@ -871,48 +787,8 @@ describe("QueryHistoryManager", () => {
|
||||
expect(cancelSpy2).not.toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should not cancel a single remote query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = remoteQueryHistory[0];
|
||||
|
||||
await queryHistoryManager.handleCancel(completed, [completed]);
|
||||
expect(mockCancelRemoteQuery).not.toBeCalledWith(
|
||||
mockCredentials,
|
||||
completed.remoteQuery,
|
||||
);
|
||||
});
|
||||
|
||||
it("should not cancel multiple remote queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = remoteQueryHistory[0];
|
||||
const failed = remoteQueryHistory[1];
|
||||
|
||||
await queryHistoryManager.handleCancel(completed, [completed, failed]);
|
||||
expect(mockCancelRemoteQuery).not.toBeCalledWith(
|
||||
mockCredentials,
|
||||
completed.remoteQuery,
|
||||
);
|
||||
expect(mockCancelRemoteQuery).not.toBeCalledWith(
|
||||
mockCredentials,
|
||||
failed.remoteQuery,
|
||||
);
|
||||
});
|
||||
|
||||
it("should not cancel a single variant analysis", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const completedVariantAnalysis = variantAnalysisHistory[0];
|
||||
@@ -927,10 +803,7 @@ describe("QueryHistoryManager", () => {
|
||||
});
|
||||
|
||||
it("should not cancel multiple variant analyses", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
|
||||
// cancelling the selected item
|
||||
const completedVariantAnalysis = variantAnalysisHistory[0];
|
||||
@@ -1272,12 +1145,8 @@ describe("QueryHistoryManager", () => {
|
||||
});
|
||||
});
|
||||
|
||||
async function createMockQueryHistory(
|
||||
allHistory: QueryHistoryInfo[],
|
||||
credentials?: Credentials,
|
||||
) {
|
||||
async function createMockQueryHistory(allHistory: QueryHistoryInfo[]) {
|
||||
const qhm = new QueryHistoryManager(
|
||||
createMockApp({ credentials }),
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
||||
@@ -19,8 +19,6 @@ 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 { App } from "../../../../src/common/app";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import { QueryHistoryManager } from "../../../../src/query-history/query-history-manager";
|
||||
|
||||
// set a higher timeout since recursive delete may take a while, expecially on Windows.
|
||||
@@ -37,7 +35,6 @@ describe("Variant Analyses and QueryHistoryManager", () => {
|
||||
/** noop */
|
||||
};
|
||||
|
||||
let app: App;
|
||||
let qhm: QueryHistoryManager;
|
||||
let rawQueryHistory: any;
|
||||
let disposables: DisposableBucket;
|
||||
@@ -71,10 +68,7 @@ describe("Variant Analyses and QueryHistoryManager", () => {
|
||||
join(STORAGE_DIR, "workspace-query-history.json"),
|
||||
).queries;
|
||||
|
||||
app = createMockApp({});
|
||||
|
||||
qhm = new QueryHistoryManager(
|
||||
app,
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
serializeQueryHistory,
|
||||
} from "../../../src/query-serialization";
|
||||
import { join } from "path";
|
||||
import { writeFileSync, mkdirpSync } from "fs-extra";
|
||||
import { writeFileSync, mkdirpSync, writeFile } from "fs-extra";
|
||||
import { LocalQueryInfo, InitialQueryInfo } from "../../../src/query-results";
|
||||
import { QueryWithResults } from "../../../src/run-queries-shared";
|
||||
import { DatabaseInfo } from "../../../src/pure/interface-types";
|
||||
@@ -11,11 +11,10 @@ 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";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
describe("serialize and deserialize", () => {
|
||||
let infoSuccessRaw: LocalQueryInfo;
|
||||
@@ -24,13 +23,11 @@ describe("serialize and deserialize", () => {
|
||||
let infoLateFailure: LocalQueryInfo;
|
||||
let infoInProgress: LocalQueryInfo;
|
||||
|
||||
let remoteQuery1: RemoteQueryHistoryItem;
|
||||
let remoteQuery2: RemoteQueryHistoryItem;
|
||||
|
||||
let variantAnalysis1: VariantAnalysisHistoryItem;
|
||||
let variantAnalysis2: VariantAnalysisHistoryItem;
|
||||
|
||||
let allHistory: QueryHistoryInfo[];
|
||||
let expectedHistory: QueryHistoryInfo[];
|
||||
let queryPath: string;
|
||||
let cnt = 0;
|
||||
|
||||
@@ -70,9 +67,6 @@ describe("serialize and deserialize", () => {
|
||||
);
|
||||
infoInProgress = createMockFullQueryInfo("e");
|
||||
|
||||
remoteQuery1 = createMockRemoteQueryHistoryItem({});
|
||||
remoteQuery2 = createMockRemoteQueryHistoryItem({});
|
||||
|
||||
variantAnalysis1 = createMockVariantAnalysisHistoryItem({});
|
||||
variantAnalysis2 = createMockVariantAnalysisHistoryItem({});
|
||||
|
||||
@@ -82,25 +76,21 @@ describe("serialize and deserialize", () => {
|
||||
infoEarlyFailure,
|
||||
infoLateFailure,
|
||||
infoInProgress,
|
||||
remoteQuery1,
|
||||
remoteQuery2,
|
||||
variantAnalysis1,
|
||||
variantAnalysis2,
|
||||
];
|
||||
|
||||
// the expected results only contains the history with completed queries
|
||||
expectedHistory = [
|
||||
infoSuccessRaw,
|
||||
infoSuccessInterpreted,
|
||||
infoLateFailure,
|
||||
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
|
||||
@@ -137,6 +127,61 @@ describe("serialize and deserialize", () => {
|
||||
expect(allHistoryActual.length).toEqual(expectedHistory.length);
|
||||
});
|
||||
|
||||
it("should remove remote queries from the history", async () => {
|
||||
const path = join(tmpDir.name, "query-history-with-remote.json");
|
||||
await writeFile(
|
||||
path,
|
||||
JSON.stringify({
|
||||
version: 2,
|
||||
queries: [
|
||||
...allHistory,
|
||||
{
|
||||
t: "remote",
|
||||
status: "InProgress",
|
||||
completed: false,
|
||||
queryId: nanoid(),
|
||||
remoteQuery: {
|
||||
queryName: "query-name",
|
||||
queryFilePath: "query-file.ql",
|
||||
queryText: "select 1",
|
||||
language: "javascript",
|
||||
controllerRepository: {
|
||||
owner: "github",
|
||||
name: "vscode-codeql-integration-tests",
|
||||
},
|
||||
executionStartTime: Date.now(),
|
||||
actionsWorkflowRunId: 1,
|
||||
repositoryCount: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
t: "remote",
|
||||
status: "Completed",
|
||||
completed: true,
|
||||
queryId: nanoid(),
|
||||
remoteQuery: {
|
||||
queryName: "query-name",
|
||||
queryFilePath: "query-file.ql",
|
||||
queryText: "select 1",
|
||||
language: "javascript",
|
||||
controllerRepository: {
|
||||
owner: "github",
|
||||
name: "vscode-codeql-integration-tests",
|
||||
},
|
||||
executionStartTime: Date.now(),
|
||||
actionsWorkflowRunId: 1,
|
||||
repositoryCount: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const actual = await deserializeQueryHistory(path);
|
||||
expect(actual.length).toEqual(expectedHistory.length);
|
||||
});
|
||||
|
||||
it("should handle an invalid query history version", async () => {
|
||||
const badPath = join(tmpDir.name, "bad-query-history.json");
|
||||
writeFileSync(
|
||||
|
||||
Reference in New Issue
Block a user