Merge branch 'main' into robertbrignull/extension_commands
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Uri, window } from "vscode";
|
||||
import { withProgress } from "./commandRunner";
|
||||
import { withProgress } from "./progress";
|
||||
import { AstViewer } from "./astViewer";
|
||||
import {
|
||||
TemplatePrintAstProvider,
|
||||
|
||||
@@ -23,11 +23,11 @@ import {
|
||||
isWholeFileLoc,
|
||||
isLineColumnLoc,
|
||||
} from "./pure/bqrs-utils";
|
||||
import { commandRunner } from "./commandRunner";
|
||||
import { DisposableObject } from "./pure/disposable-object";
|
||||
import { showAndLogExceptionWithTelemetry } from "./helpers";
|
||||
import { asError, getErrorMessage } from "./pure/helpers-pure";
|
||||
import { redactableError } from "./pure/errors";
|
||||
import { AstViewerCommands } from "./common/commands";
|
||||
|
||||
export interface AstItem {
|
||||
id: BqrsId;
|
||||
@@ -55,15 +55,6 @@ class AstViewerDataProvider
|
||||
readonly onDidChangeTreeData: Event<AstItem | undefined> =
|
||||
this._onDidChangeTreeData.event;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.push(
|
||||
commandRunner("codeQLAstViewer.gotoCode", async (item: AstItem) => {
|
||||
await showLocation(item.fileLocation);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
refresh(): void {
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
}
|
||||
@@ -126,16 +117,20 @@ export class AstViewer extends DisposableObject {
|
||||
|
||||
this.push(this.treeView);
|
||||
this.push(this.treeDataProvider);
|
||||
this.push(
|
||||
commandRunner("codeQLAstViewer.clear", async () => {
|
||||
this.clear();
|
||||
}),
|
||||
);
|
||||
this.push(
|
||||
window.onDidChangeTextEditorSelection(this.updateTreeSelection, this),
|
||||
);
|
||||
}
|
||||
|
||||
getCommands(): AstViewerCommands {
|
||||
return {
|
||||
"codeQLAstViewer.clear": async () => this.clear(),
|
||||
"codeQLAstViewer.gotoCode": async (item: AstItem) => {
|
||||
await showLocation(item.fileLocation);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
updateRoots(roots: AstItem[], db: DatabaseItem, fileUri: Uri) {
|
||||
this.treeDataProvider.roots = roots;
|
||||
this.treeDataProvider.db = db;
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
CancellationToken,
|
||||
ProgressOptions as VSCodeProgressOptions,
|
||||
window as Window,
|
||||
commands,
|
||||
Disposable,
|
||||
ProgressLocation,
|
||||
} from "vscode";
|
||||
import { CancellationToken, commands, Disposable } from "vscode";
|
||||
import {
|
||||
showAndLogExceptionWithTelemetry,
|
||||
showAndLogWarningMessage,
|
||||
@@ -14,51 +7,22 @@ import { extLogger } from "./common";
|
||||
import { asError, getErrorMessage, getErrorStack } from "./pure/helpers-pure";
|
||||
import { telemetryListener } from "./telemetry";
|
||||
import { redactableError } from "./pure/errors";
|
||||
|
||||
export class UserCancellationException extends Error {
|
||||
/**
|
||||
* @param message The error message
|
||||
* @param silent If silent is true, then this exception will avoid showing a warning message to the user.
|
||||
*/
|
||||
constructor(message?: string, public readonly silent = false) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ProgressUpdate {
|
||||
/**
|
||||
* The current step
|
||||
*/
|
||||
step: number;
|
||||
/**
|
||||
* The maximum step. This *should* be constant for a single job.
|
||||
*/
|
||||
maxStep: number;
|
||||
/**
|
||||
* The current progress message
|
||||
*/
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type ProgressCallback = (p: ProgressUpdate) => void;
|
||||
|
||||
// Make certain properties within a type optional
|
||||
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
||||
|
||||
export type ProgressOptions = Optional<VSCodeProgressOptions, "location">;
|
||||
import {
|
||||
UserCancellationException,
|
||||
withProgress,
|
||||
ProgressOptions,
|
||||
ProgressCallback,
|
||||
} from "./progress";
|
||||
|
||||
/**
|
||||
* A task that reports progress.
|
||||
* A task that handles command invocations from `commandRunner`.
|
||||
* Arguments passed to the command handler are passed along,
|
||||
* untouched to this `NoProgressTask` instance.
|
||||
*
|
||||
* @param progress a progress handler function. Call this
|
||||
* function with a `ProgressUpdate` instance in order to
|
||||
* denote some progress being achieved on this task.
|
||||
* @param token a cancellation token
|
||||
* @param args arguments passed to this task passed on from
|
||||
* `commands.registerCommand`.
|
||||
*/
|
||||
export type ProgressTask<R> = (
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
) => Thenable<R>;
|
||||
export type NoProgressTask = (...args: any[]) => Promise<any>;
|
||||
|
||||
/**
|
||||
* A task that handles command invocations from `commandRunner`
|
||||
@@ -75,64 +39,12 @@ export type ProgressTask<R> = (
|
||||
* @param args arguments passed to this task passed on from
|
||||
* `commands.registerCommand`.
|
||||
*/
|
||||
export type ProgressTaskWithArgs<R> = (
|
||||
type ProgressTaskWithArgs<R> = (
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
...args: any[]
|
||||
) => Thenable<R>;
|
||||
|
||||
/**
|
||||
* A task that handles command invocations from `commandRunner`.
|
||||
* Arguments passed to the command handler are passed along,
|
||||
* untouched to this `NoProgressTask` instance.
|
||||
*
|
||||
* @param args arguments passed to this task passed on from
|
||||
* `commands.registerCommand`.
|
||||
*/
|
||||
export type NoProgressTask = (...args: any[]) => Promise<any>;
|
||||
|
||||
/**
|
||||
* This mediates between the kind of progress callbacks we want to
|
||||
* write (where we *set* current progress position and give
|
||||
* `maxSteps`) and the kind vscode progress api expects us to write
|
||||
* (which increment progress by a certain amount out of 100%).
|
||||
*
|
||||
* Where possible, the `commandRunner` function below should be used
|
||||
* instead of this function. The commandRunner is meant for wrapping
|
||||
* top-level commands and provides error handling and other support
|
||||
* automatically.
|
||||
*
|
||||
* Only use this function if you need a progress monitor and the
|
||||
* control flow does not always come from a command (eg- during
|
||||
* extension activation, or from an internal language server
|
||||
* request).
|
||||
*/
|
||||
export function withProgress<R>(
|
||||
task: ProgressTask<R>,
|
||||
{
|
||||
location = ProgressLocation.Notification,
|
||||
title,
|
||||
cancellable,
|
||||
}: ProgressOptions = {},
|
||||
): Thenable<R> {
|
||||
let progressAchieved = 0;
|
||||
return Window.withProgress(
|
||||
{
|
||||
location,
|
||||
title,
|
||||
cancellable,
|
||||
},
|
||||
(progress, token) => {
|
||||
return task((p) => {
|
||||
const { message, step, maxStep } = p;
|
||||
const increment = (100 * (step - progressAchieved)) / maxStep;
|
||||
progressAchieved = step;
|
||||
progress.report({ message, increment });
|
||||
}, token);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic wrapper for command registration. This wrapper adds uniform error handling for commands.
|
||||
*
|
||||
@@ -216,48 +128,3 @@ export function commandRunnerWithProgress<R>(
|
||||
outputLogger,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a progress monitor that indicates how much progess has been made
|
||||
* reading from a stream.
|
||||
*
|
||||
* @param readable The stream to read progress from
|
||||
* @param messagePrefix A prefix for displaying the message
|
||||
* @param totalNumBytes Total number of bytes in this stream
|
||||
* @param progress The progress callback used to set messages
|
||||
*/
|
||||
export function reportStreamProgress(
|
||||
readable: NodeJS.ReadableStream,
|
||||
messagePrefix: string,
|
||||
totalNumBytes?: number,
|
||||
progress?: ProgressCallback,
|
||||
) {
|
||||
if (progress && totalNumBytes) {
|
||||
let numBytesDownloaded = 0;
|
||||
const bytesToDisplayMB = (numBytes: number): string =>
|
||||
`${(numBytes / (1024 * 1024)).toFixed(1)} MB`;
|
||||
const updateProgress = () => {
|
||||
progress({
|
||||
step: numBytesDownloaded,
|
||||
maxStep: totalNumBytes,
|
||||
message: `${messagePrefix} [${bytesToDisplayMB(
|
||||
numBytesDownloaded,
|
||||
)} of ${bytesToDisplayMB(totalNumBytes)}]`,
|
||||
});
|
||||
};
|
||||
|
||||
// Display the progress straight away rather than waiting for the first chunk.
|
||||
updateProgress();
|
||||
|
||||
readable.on("data", (data) => {
|
||||
numBytesDownloaded += data.length;
|
||||
updateProgress();
|
||||
});
|
||||
} else if (progress) {
|
||||
progress({
|
||||
step: 1,
|
||||
maxStep: 2,
|
||||
message: `${messagePrefix} (Size unknown)`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { CommandManager } from "../packages/commands";
|
||||
import type { Uri, Range } from "vscode";
|
||||
import type { AstItem } from "../astViewer";
|
||||
import type { DbTreeViewItem } from "../databases/ui/db-tree-view-item";
|
||||
import type { DatabaseItem } from "../local-databases";
|
||||
import type { QueryHistoryInfo } from "../query-history/query-history-info";
|
||||
@@ -59,6 +60,15 @@ export type LocalQueryCommands = {
|
||||
"codeQL.quickQuery": () => Promise<void>;
|
||||
};
|
||||
|
||||
export type ResultsViewCommands = {
|
||||
"codeQLQueryResults.up": () => Promise<void>;
|
||||
"codeQLQueryResults.down": () => Promise<void>;
|
||||
"codeQLQueryResults.left": () => Promise<void>;
|
||||
"codeQLQueryResults.right": () => Promise<void>;
|
||||
"codeQLQueryResults.nextPathStep": () => Promise<void>;
|
||||
"codeQLQueryResults.previousPathStep": () => Promise<void>;
|
||||
};
|
||||
|
||||
// Commands used for the query history panel
|
||||
export type QueryHistoryCommands = {
|
||||
// Commands in the "navigation" group
|
||||
@@ -183,6 +193,11 @@ export type AstCfgCommands = {
|
||||
"codeQL.viewCfgContextEditor": () => Promise<void>;
|
||||
};
|
||||
|
||||
export type AstViewerCommands = {
|
||||
"codeQLAstViewer.clear": () => Promise<void>;
|
||||
"codeQLAstViewer.gotoCode": (item: AstItem) => Promise<void>;
|
||||
};
|
||||
|
||||
export type PackagingCommands = {
|
||||
"codeQL.installPackDependencies": () => Promise<void>;
|
||||
"codeQL.downloadPacks": () => Promise<void>;
|
||||
@@ -192,6 +207,18 @@ export type EvalLogViewerCommands = {
|
||||
"codeQLEvalLogViewer.clear": () => Promise<void>;
|
||||
};
|
||||
|
||||
export type SummaryLanguageSupportCommands = {
|
||||
"codeQL.gotoQL": () => Promise<void>;
|
||||
};
|
||||
|
||||
export type MockGitHubApiServerCommands = {
|
||||
"codeQL.mockGitHubApiServer.startRecording": () => Promise<void>;
|
||||
"codeQL.mockGitHubApiServer.saveScenario": () => Promise<void>;
|
||||
"codeQL.mockGitHubApiServer.cancelRecording": () => Promise<void>;
|
||||
"codeQL.mockGitHubApiServer.loadScenario": () => Promise<void>;
|
||||
"codeQL.mockGitHubApiServer.unloadScenario": () => Promise<void>;
|
||||
};
|
||||
|
||||
// All commands where the implementation is provided by this extension.
|
||||
export type AllCodeQLCommands = BaseCommands &
|
||||
QueryHistoryCommands &
|
||||
@@ -199,8 +226,11 @@ export type AllCodeQLCommands = BaseCommands &
|
||||
VariantAnalysisCommands &
|
||||
DatabasePanelCommands &
|
||||
AstCfgCommands &
|
||||
AstViewerCommands &
|
||||
PackagingCommands &
|
||||
EvalLogViewerCommands;
|
||||
EvalLogViewerCommands &
|
||||
SummaryLanguageSupportCommands &
|
||||
MockGitHubApiServerCommands;
|
||||
|
||||
export type AllCommands = AllCodeQLCommands & VSCodeCommands;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { CodeQLCliServer } from "../cli";
|
||||
import { DatabaseManager, DatabaseItem } from "../local-databases";
|
||||
import fileRangeFromURI from "./fileRangeFromURI";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import { ProgressCallback } from "../progress";
|
||||
import { KeyType } from "./keyType";
|
||||
import {
|
||||
qlpackOfDatabase,
|
||||
|
||||
@@ -16,7 +16,7 @@ import { DatabaseItem } from "../local-databases";
|
||||
import { extLogger } from "../common";
|
||||
import { createInitialQueryInfo } from "../run-queries-shared";
|
||||
import { CancellationToken, Uri } from "vscode";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import { ProgressCallback } from "../progress";
|
||||
import { QueryRunner } from "../queryRunner";
|
||||
import { redactableError } from "../pure/errors";
|
||||
import { QLPACK_FILENAMES } from "../pure/ql";
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
import { CodeQLCliServer } from "../cli";
|
||||
import { DatabaseManager } from "../local-databases";
|
||||
import { CachedOperation } from "../helpers";
|
||||
import { ProgressCallback, withProgress } from "../commandRunner";
|
||||
import { ProgressCallback, withProgress } from "../progress";
|
||||
import AstBuilder from "./astBuilder";
|
||||
import { KeyType } from "./keyType";
|
||||
import {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { retry } from "@octokit/plugin-retry";
|
||||
|
||||
import { DatabaseManager, DatabaseItem } from "./local-databases";
|
||||
import { showAndLogInformationMessage, tmpDir } from "./helpers";
|
||||
import { reportStreamProgress, ProgressCallback } from "./commandRunner";
|
||||
import { reportStreamProgress, ProgressCallback } from "./progress";
|
||||
import { extLogger } from "./common";
|
||||
import { getErrorMessage } from "./pure/helpers-pure";
|
||||
import {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { UserCancellationException } from "../../commandRunner";
|
||||
import { UserCancellationException } from "../../progress";
|
||||
import {
|
||||
getNwoFromGitHubUrl,
|
||||
isValidGitHubNwo,
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
} from "./helpers";
|
||||
import { extLogger } from "./common";
|
||||
import { getCodeQlCliVersion } from "./cli-version";
|
||||
import { ProgressCallback, reportStreamProgress } from "./commandRunner";
|
||||
import { ProgressCallback, reportStreamProgress } from "./progress";
|
||||
import {
|
||||
codeQlLauncherName,
|
||||
deprecatedCodeQlLauncherName,
|
||||
|
||||
@@ -88,7 +88,8 @@ import { QLTestAdapterFactory } from "./test-adapter";
|
||||
import { TestUIService } from "./test-ui";
|
||||
import { CompareView } from "./compare/compare-view";
|
||||
import { initializeTelemetry } from "./telemetry";
|
||||
import { commandRunner, ProgressCallback, withProgress } from "./commandRunner";
|
||||
import { commandRunner } from "./commandRunner";
|
||||
import { ProgressCallback, withProgress } from "./progress";
|
||||
import { CodeQlStatusBarHandler } from "./status-bar";
|
||||
import { getPackagingCommands } from "./packaging";
|
||||
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
|
||||
@@ -828,10 +829,17 @@ async function activateWithInstalledDistribution(
|
||||
|
||||
ctx.subscriptions.push(astViewer);
|
||||
|
||||
const summaryLanguageSupport = new SummaryLanguageSupport();
|
||||
ctx.subscriptions.push(summaryLanguageSupport);
|
||||
|
||||
const mockServer = new VSCodeMockGitHubApiServer(ctx);
|
||||
ctx.subscriptions.push(mockServer);
|
||||
|
||||
void extLogger.log("Registering top-level command palette commands.");
|
||||
|
||||
const allCommands: AllCodeQLCommands = {
|
||||
...getCommands(cliServer, qs),
|
||||
...localQueryResultsView.getCommands(),
|
||||
...qhm.getCommands(),
|
||||
...variantAnalysisManager.getCommands(),
|
||||
...databaseUI.getCommands(),
|
||||
@@ -846,10 +854,13 @@ async function activateWithInstalledDistribution(
|
||||
astTemplateProvider,
|
||||
cfgTemplateProvider,
|
||||
}),
|
||||
...astViewer.getCommands(),
|
||||
...getPackagingCommands({
|
||||
cliServer,
|
||||
}),
|
||||
...evalLogViewer.getCommands(),
|
||||
...summaryLanguageSupport.getCommands(),
|
||||
...mockServer.getCommands(),
|
||||
};
|
||||
|
||||
for (const [commandName, command] of Object.entries(allCommands)) {
|
||||
@@ -946,8 +957,6 @@ async function activateWithInstalledDistribution(
|
||||
}),
|
||||
);
|
||||
|
||||
ctx.subscriptions.push(new SummaryLanguageSupport());
|
||||
|
||||
void extLogger.log("Starting language server.");
|
||||
await client.start();
|
||||
ctx.subscriptions.push({
|
||||
@@ -978,39 +987,6 @@ async function activateWithInstalledDistribution(
|
||||
),
|
||||
);
|
||||
|
||||
const mockServer = new VSCodeMockGitHubApiServer(ctx);
|
||||
ctx.subscriptions.push(mockServer);
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
"codeQL.mockGitHubApiServer.startRecording",
|
||||
async () => await mockServer.startRecording(),
|
||||
),
|
||||
);
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
"codeQL.mockGitHubApiServer.saveScenario",
|
||||
async () => await mockServer.saveScenario(),
|
||||
),
|
||||
);
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
"codeQL.mockGitHubApiServer.cancelRecording",
|
||||
async () => await mockServer.cancelRecording(),
|
||||
),
|
||||
);
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
"codeQL.mockGitHubApiServer.loadScenario",
|
||||
async () => await mockServer.loadScenario(),
|
||||
),
|
||||
);
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
"codeQL.mockGitHubApiServer.unloadScenario",
|
||||
async () => await mockServer.unloadScenario(),
|
||||
),
|
||||
);
|
||||
|
||||
await app.commands.execute("codeQLDatabases.removeOrphanedDatabases");
|
||||
|
||||
void extLogger.log("Reading query history");
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
commands,
|
||||
} from "vscode";
|
||||
import { CodeQLCliServer, QlpacksInfo } from "./cli";
|
||||
import { UserCancellationException } from "./commandRunner";
|
||||
import { UserCancellationException } from "./progress";
|
||||
import { extLogger, OutputChannelLogger } from "./common";
|
||||
import { QueryMetadata } from "./pure/interface-types";
|
||||
import { telemetryListener } from "./telemetry";
|
||||
|
||||
@@ -42,7 +42,6 @@ import {
|
||||
ParsedResultSets,
|
||||
} from "./pure/interface-types";
|
||||
import { Logger } from "./common";
|
||||
import { commandRunner } from "./commandRunner";
|
||||
import {
|
||||
CompletedQueryInfo,
|
||||
interpretResultsSarif,
|
||||
@@ -72,6 +71,7 @@ import { isCanary, PAGE_SIZE } from "./config";
|
||||
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
|
||||
import { telemetryListener } from "./telemetry";
|
||||
import { redactableError } from "./pure/errors";
|
||||
import { ResultsViewCommands } from "./common/commands";
|
||||
|
||||
/**
|
||||
* interface.ts
|
||||
@@ -179,21 +179,6 @@ export class ResultsView extends AbstractWebview<
|
||||
this.handleSelectionChange.bind(this),
|
||||
),
|
||||
);
|
||||
const navigationCommands = {
|
||||
"codeQLQueryResults.up": NavigationDirection.up,
|
||||
"codeQLQueryResults.down": NavigationDirection.down,
|
||||
"codeQLQueryResults.left": NavigationDirection.left,
|
||||
"codeQLQueryResults.right": NavigationDirection.right,
|
||||
// For backwards compatibility with keybindings set using an earlier version of the extension.
|
||||
"codeQLQueryResults.nextPathStep": NavigationDirection.down,
|
||||
"codeQLQueryResults.previousPathStep": NavigationDirection.up,
|
||||
};
|
||||
void logger.log("Registering result view navigation commands.");
|
||||
for (const [commandId, direction] of Object.entries(navigationCommands)) {
|
||||
this.push(
|
||||
commandRunner(commandId, this.navigateResultView.bind(this, direction)),
|
||||
);
|
||||
}
|
||||
|
||||
this.push(
|
||||
this.databaseManager.onDidChangeDatabaseItem(({ kind }) => {
|
||||
@@ -209,6 +194,36 @@ export class ResultsView extends AbstractWebview<
|
||||
);
|
||||
}
|
||||
|
||||
public getCommands(): ResultsViewCommands {
|
||||
return {
|
||||
"codeQLQueryResults.up": this.navigateResultView.bind(
|
||||
this,
|
||||
NavigationDirection.up,
|
||||
),
|
||||
"codeQLQueryResults.down": this.navigateResultView.bind(
|
||||
this,
|
||||
NavigationDirection.down,
|
||||
),
|
||||
"codeQLQueryResults.left": this.navigateResultView.bind(
|
||||
this,
|
||||
NavigationDirection.left,
|
||||
),
|
||||
"codeQLQueryResults.right": this.navigateResultView.bind(
|
||||
this,
|
||||
NavigationDirection.right,
|
||||
),
|
||||
// For backwards compatibility with keybindings set using an earlier version of the extension.
|
||||
"codeQLQueryResults.nextPathStep": this.navigateResultView.bind(
|
||||
this,
|
||||
NavigationDirection.down,
|
||||
),
|
||||
"codeQLQueryResults.previousPathStep": this.navigateResultView.bind(
|
||||
this,
|
||||
NavigationDirection.up,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
async navigateResultView(direction: NavigationDirection): Promise<void> {
|
||||
if (!this.panel?.visible) {
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CancellationToken } from "vscode";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import { ProgressCallback } from "../progress";
|
||||
import { DatabaseItem } from "../local-databases";
|
||||
import {
|
||||
Dataset,
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
ProgressMessage,
|
||||
WithProgressId,
|
||||
} from "../pure/legacy-messages";
|
||||
import { ProgressCallback, ProgressTask } from "../commandRunner";
|
||||
import { ProgressCallback, ProgressTask } from "../progress";
|
||||
import { ServerProcess } from "../json-rpc-server";
|
||||
|
||||
type WithProgressReporting = (
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
tryGetQueryMetadata,
|
||||
upgradesTmpDir,
|
||||
} from "../helpers";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import { ProgressCallback } from "../progress";
|
||||
import { QueryMetadata } from "../pure/interface-types";
|
||||
import { extLogger, Logger, TeeLogger } from "../common";
|
||||
import * as messages from "../pure/legacy-messages";
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
showAndLogExceptionWithTelemetry,
|
||||
tmpDir,
|
||||
} from "../helpers";
|
||||
import { ProgressCallback, UserCancellationException } from "../commandRunner";
|
||||
import { ProgressCallback, UserCancellationException } from "../progress";
|
||||
import { extLogger } from "../common";
|
||||
import * as messages from "../pure/legacy-messages";
|
||||
import * as qsClient from "./queryserver-client";
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
DatabaseItem,
|
||||
DatabaseManager,
|
||||
} from "./local-databases";
|
||||
import { ProgressCallback, withProgress } from "./commandRunner";
|
||||
import { ProgressCallback, withProgress } from "./progress";
|
||||
import {
|
||||
isLikelyDatabaseRoot,
|
||||
isLikelyDbLanguageFolder,
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
isFolderAlreadyInWorkspace,
|
||||
showBinaryChoiceDialog,
|
||||
} from "./helpers";
|
||||
import { ProgressCallback, withProgress } from "./commandRunner";
|
||||
import { ProgressCallback, withProgress } from "./progress";
|
||||
import {
|
||||
zipArchiveScheme,
|
||||
encodeArchiveBasePath,
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
ProgressCallback,
|
||||
ProgressUpdate,
|
||||
withProgress,
|
||||
} from "./commandRunner";
|
||||
import { ProgressCallback, ProgressUpdate, withProgress } from "./progress";
|
||||
import {
|
||||
CancellationToken,
|
||||
CancellationTokenSource,
|
||||
|
||||
@@ -13,9 +13,9 @@ import {
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { DisposableObject } from "../pure/disposable-object";
|
||||
import { commandRunner } from "../commandRunner";
|
||||
import { extLogger } from "../common";
|
||||
import { getErrorMessage } from "../pure/helpers-pure";
|
||||
import { SummaryLanguageSupportCommands } from "../common/commands";
|
||||
|
||||
/** A `Position` within a specified file on disk. */
|
||||
interface PositionInFile {
|
||||
@@ -73,8 +73,12 @@ export class SummaryLanguageSupport extends DisposableObject {
|
||||
this.handleDidCloseTextDocument.bind(this),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
this.push(commandRunner("codeQL.gotoQL", this.handleGotoQL.bind(this)));
|
||||
public getCommands(): SummaryLanguageSupportCommands {
|
||||
return {
|
||||
"codeQL.gotoQL": this.handleGotoQL.bind(this),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "../config";
|
||||
import { DisposableObject } from "../pure/disposable-object";
|
||||
import { MockGitHubApiServer } from "./mock-gh-api-server";
|
||||
import { MockGitHubApiServerCommands } from "../common/commands";
|
||||
|
||||
/**
|
||||
* "Interface" to the mock GitHub API server which implements VSCode interactions, such as
|
||||
@@ -34,6 +35,19 @@ export class VSCodeMockGitHubApiServer extends DisposableObject {
|
||||
this.setupConfigListener();
|
||||
}
|
||||
|
||||
public getCommands(): MockGitHubApiServerCommands {
|
||||
return {
|
||||
"codeQL.mockGitHubApiServer.startRecording":
|
||||
this.startRecording.bind(this),
|
||||
"codeQL.mockGitHubApiServer.saveScenario": this.saveScenario.bind(this),
|
||||
"codeQL.mockGitHubApiServer.cancelRecording":
|
||||
this.cancelRecording.bind(this),
|
||||
"codeQL.mockGitHubApiServer.loadScenario": this.loadScenario.bind(this),
|
||||
"codeQL.mockGitHubApiServer.unloadScenario":
|
||||
this.unloadScenario.bind(this),
|
||||
};
|
||||
}
|
||||
|
||||
public async startServer(): Promise<void> {
|
||||
this.server.startServer();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
ProgressCallback,
|
||||
UserCancellationException,
|
||||
withProgress,
|
||||
} from "./commandRunner";
|
||||
} from "./progress";
|
||||
import { extLogger } from "./common";
|
||||
import { asError, getErrorStack } from "./pure/helpers-pure";
|
||||
import { redactableError } from "./pure/errors";
|
||||
|
||||
128
extensions/ql-vscode/src/progress.ts
Normal file
128
extensions/ql-vscode/src/progress.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import {
|
||||
CancellationToken,
|
||||
ProgressLocation,
|
||||
ProgressOptions as VSCodeProgressOptions,
|
||||
window as Window,
|
||||
} from "vscode";
|
||||
|
||||
export class UserCancellationException extends Error {
|
||||
/**
|
||||
* @param message The error message
|
||||
* @param silent If silent is true, then this exception will avoid showing a warning message to the user.
|
||||
*/
|
||||
constructor(message?: string, public readonly silent = false) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ProgressUpdate {
|
||||
/**
|
||||
* The current step
|
||||
*/
|
||||
step: number;
|
||||
/**
|
||||
* The maximum step. This *should* be constant for a single job.
|
||||
*/
|
||||
maxStep: number;
|
||||
/**
|
||||
* The current progress message
|
||||
*/
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type ProgressCallback = (p: ProgressUpdate) => void;
|
||||
|
||||
// Make certain properties within a type optional
|
||||
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
||||
|
||||
export type ProgressOptions = Optional<VSCodeProgressOptions, "location">;
|
||||
|
||||
/**
|
||||
* A task that reports progress.
|
||||
*
|
||||
* @param progress a progress handler function. Call this
|
||||
* function with a `ProgressUpdate` instance in order to
|
||||
* denote some progress being achieved on this task.
|
||||
* @param token a cancellation token
|
||||
*/
|
||||
export type ProgressTask<R> = (
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
) => Thenable<R>;
|
||||
|
||||
/**
|
||||
* This mediates between the kind of progress callbacks we want to
|
||||
* write (where we *set* current progress position and give
|
||||
* `maxSteps`) and the kind vscode progress api expects us to write
|
||||
* (which increment progress by a certain amount out of 100%).
|
||||
*/
|
||||
export function withProgress<R>(
|
||||
task: ProgressTask<R>,
|
||||
{
|
||||
location = ProgressLocation.Notification,
|
||||
title,
|
||||
cancellable,
|
||||
}: ProgressOptions = {},
|
||||
): Thenable<R> {
|
||||
let progressAchieved = 0;
|
||||
return Window.withProgress(
|
||||
{
|
||||
location,
|
||||
title,
|
||||
cancellable,
|
||||
},
|
||||
(progress, token) => {
|
||||
return task((p) => {
|
||||
const { message, step, maxStep } = p;
|
||||
const increment = (100 * (step - progressAchieved)) / maxStep;
|
||||
progressAchieved = step;
|
||||
progress.report({ message, increment });
|
||||
}, token);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a progress monitor that indicates how much progess has been made
|
||||
* reading from a stream.
|
||||
*
|
||||
* @param readable The stream to read progress from
|
||||
* @param messagePrefix A prefix for displaying the message
|
||||
* @param totalNumBytes Total number of bytes in this stream
|
||||
* @param progress The progress callback used to set messages
|
||||
*/
|
||||
export function reportStreamProgress(
|
||||
readable: NodeJS.ReadableStream,
|
||||
messagePrefix: string,
|
||||
totalNumBytes?: number,
|
||||
progress?: ProgressCallback,
|
||||
) {
|
||||
if (progress && totalNumBytes) {
|
||||
let numBytesDownloaded = 0;
|
||||
const bytesToDisplayMB = (numBytes: number): string =>
|
||||
`${(numBytes / (1024 * 1024)).toFixed(1)} MB`;
|
||||
const updateProgress = () => {
|
||||
progress({
|
||||
step: numBytesDownloaded,
|
||||
maxStep: totalNumBytes,
|
||||
message: `${messagePrefix} [${bytesToDisplayMB(
|
||||
numBytesDownloaded,
|
||||
)} of ${bytesToDisplayMB(totalNumBytes)}]`,
|
||||
});
|
||||
};
|
||||
|
||||
// Display the progress straight away rather than waiting for the first chunk.
|
||||
updateProgress();
|
||||
|
||||
readable.on("data", (data) => {
|
||||
numBytesDownloaded += data.length;
|
||||
updateProgress();
|
||||
});
|
||||
} else if (progress) {
|
||||
progress({
|
||||
step: 1,
|
||||
maxStep: 2,
|
||||
message: `${messagePrefix} (Size unknown)`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { CancellationToken } from "vscode";
|
||||
import { ProgressCallback, UserCancellationException } from "../commandRunner";
|
||||
import { ProgressCallback, UserCancellationException } from "../progress";
|
||||
import { DatabaseItem } from "../local-databases";
|
||||
import {
|
||||
clearCache,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
ProgressMessage,
|
||||
WithProgressId,
|
||||
} from "../pure/new-messages";
|
||||
import { ProgressCallback, ProgressTask } from "../commandRunner";
|
||||
import { ProgressCallback, ProgressTask } from "../progress";
|
||||
import { ServerProcess } from "../json-rpc-server";
|
||||
|
||||
type ServerOpts = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { join } from "path";
|
||||
import { CancellationToken } from "vscode";
|
||||
import * as cli from "../cli";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import { ProgressCallback } from "../progress";
|
||||
import { DatabaseItem } from "../local-databases";
|
||||
import {
|
||||
getOnDiskWorkspaceFolders,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CancellationToken } from "vscode";
|
||||
import { CodeQLCliServer } from "./cli";
|
||||
import { ProgressCallback } from "./commandRunner";
|
||||
import { ProgressCallback } from "./progress";
|
||||
import { DatabaseItem } from "./local-databases";
|
||||
import { InitialQueryInfo, LocalQueryInfo } from "./query-results";
|
||||
import { QueryWithResults } from "./run-queries-shared";
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
getQlPackForDbscheme,
|
||||
showBinaryChoiceDialog,
|
||||
} from "./helpers";
|
||||
import { ProgressCallback, UserCancellationException } from "./commandRunner";
|
||||
import { ProgressCallback, UserCancellationException } from "./progress";
|
||||
import { getErrorMessage } from "./pure/helpers-pure";
|
||||
import { FALLBACK_QLPACK_FILENAME, getQlPackPath } from "./pure/ql";
|
||||
import { App } from "./common/app";
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
window,
|
||||
} from "vscode";
|
||||
import { isCanary, AUTOSAVE_SETTING } from "./config";
|
||||
import { UserCancellationException } from "./commandRunner";
|
||||
import { UserCancellationException } from "./progress";
|
||||
import {
|
||||
pathExists,
|
||||
readFile,
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from "./config";
|
||||
import * as appInsights from "applicationinsights";
|
||||
import { extLogger } from "./common";
|
||||
import { UserCancellationException } from "./commandRunner";
|
||||
import { UserCancellationException } from "./progress";
|
||||
import { showBinaryChoiceWithUrlDialog } from "./helpers";
|
||||
import { RedactableError } from "./pure/errors";
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
ProgressCallback,
|
||||
UserCancellationException,
|
||||
withProgress,
|
||||
} from "../commandRunner";
|
||||
} from "../progress";
|
||||
import { showInformationMessageWithAction } from "../helpers";
|
||||
import { extLogger } from "../common";
|
||||
import { createGist } from "./gh-api/gh-api-client";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UserCancellationException } from "../commandRunner";
|
||||
import { UserCancellationException } from "../progress";
|
||||
import { DbManager } from "../databases/db-manager";
|
||||
import { DbItemKind } from "../databases/db-item";
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
getRemoteControllerRepo,
|
||||
setRemoteControllerRepo,
|
||||
} from "../config";
|
||||
import { ProgressCallback, UserCancellationException } from "../commandRunner";
|
||||
import { ProgressCallback, UserCancellationException } from "../progress";
|
||||
import { RequestError } from "@octokit/types/dist-types";
|
||||
import { QueryMetadata } from "../pure/interface-types";
|
||||
import { getErrorMessage, REPO_REGEX } from "../pure/helpers-pure";
|
||||
|
||||
@@ -55,7 +55,7 @@ import {
|
||||
ProgressCallback,
|
||||
UserCancellationException,
|
||||
withProgress,
|
||||
} from "../commandRunner";
|
||||
} from "../progress";
|
||||
import { CodeQLCliServer } from "../cli";
|
||||
import {
|
||||
defaultFilterSortState,
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
} from "../../../../src/variant-analysis/shared/variant-analysis";
|
||||
import { VariantAnalysis as VariantAnalysisApiResponse } from "../../../../src/variant-analysis/gh-api/variant-analysis";
|
||||
import { createMockApiResponse } from "../../../factories/variant-analysis/gh-api/variant-analysis-api-response";
|
||||
import { UserCancellationException } from "../../../../src/commandRunner";
|
||||
import { UserCancellationException } from "../../../../src/progress";
|
||||
import { Repository } from "../../../../src/variant-analysis/gh-api/repository";
|
||||
import { DbManager } from "../../../../src/databases/db-manager";
|
||||
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
FullDatabaseOptions,
|
||||
} from "../../../src/local-databases";
|
||||
import { Logger } from "../../../src/common";
|
||||
import { ProgressCallback } from "../../../src/commandRunner";
|
||||
import { ProgressCallback } from "../../../src/progress";
|
||||
import { CodeQLCliServer, DbInfo } from "../../../src/cli";
|
||||
import {
|
||||
encodeArchiveBasePath,
|
||||
|
||||
@@ -38,7 +38,7 @@ import {
|
||||
showInformationMessageWithAction,
|
||||
walkDirectory,
|
||||
} from "../../../src/helpers";
|
||||
import { reportStreamProgress } from "../../../src/commandRunner";
|
||||
import { reportStreamProgress } from "../../../src/progress";
|
||||
import { QueryLanguage } from "../../../src/common/query-language";
|
||||
import { Setting } from "../../../src/config";
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
TelemetryListener,
|
||||
telemetryListener as globalTelemetryListener,
|
||||
} from "../../../src/telemetry";
|
||||
import { UserCancellationException } from "../../../src/commandRunner";
|
||||
import { UserCancellationException } from "../../../src/progress";
|
||||
import { ENABLE_TELEMETRY } from "../../../src/config";
|
||||
import { createMockExtensionContext } from "./index";
|
||||
import { vscodeGetConfigurationMock } from "../test-config";
|
||||
|
||||
Reference in New Issue
Block a user