diff --git a/extensions/ql-vscode/src/common/vscode/progress.ts b/extensions/ql-vscode/src/common/vscode/progress.ts index 2b937676d..7d944cc4b 100644 --- a/extensions/ql-vscode/src/common/vscode/progress.ts +++ b/extensions/ql-vscode/src/common/vscode/progress.ts @@ -33,6 +33,14 @@ export interface ProgressUpdate { message: string; } +export function progressUpdate( + step: number, + maxStep: number, + message: string, +): ProgressUpdate { + return { step, maxStep, message }; +} + export type ProgressCallback = (p: ProgressUpdate) => void; // Make certain properties within a type optional diff --git a/extensions/ql-vscode/src/debugger/debugger-ui.ts b/extensions/ql-vscode/src/debugger/debugger-ui.ts index 53efc47c9..6eb9a2d9f 100644 --- a/extensions/ql-vscode/src/debugger/debugger-ui.ts +++ b/extensions/ql-vscode/src/debugger/debugger-ui.ts @@ -135,7 +135,7 @@ class QLDebugAdapterTracker ): Promise { if (this.localQueryRun !== undefined) { const results: CoreQueryResults = body; - await this.localQueryRun.complete(results); + await this.localQueryRun.complete(results, (_) => {}); this.localQueryRun = undefined; } } diff --git a/extensions/ql-vscode/src/local-queries/local-queries.ts b/extensions/ql-vscode/src/local-queries/local-queries.ts index 5b2e310f5..296158665 100644 --- a/extensions/ql-vscode/src/local-queries/local-queries.ts +++ b/extensions/ql-vscode/src/local-queries/local-queries.ts @@ -485,7 +485,7 @@ export class LocalQueries extends DisposableObject { localQueryRun.logger, ); - await localQueryRun.complete(results); + await localQueryRun.complete(results, progress); return results; } catch (e) { diff --git a/extensions/ql-vscode/src/local-queries/local-query-run.ts b/extensions/ql-vscode/src/local-queries/local-query-run.ts index 3f43f1195..5ea2463ca 100644 --- a/extensions/ql-vscode/src/local-queries/local-query-run.ts +++ b/extensions/ql-vscode/src/local-queries/local-query-run.ts @@ -26,6 +26,8 @@ import type { LocalQueries } from "./local-queries"; import { tryGetQueryMetadata } from "../codeql-cli/query-metadata"; import { telemetryListener } from "../common/vscode/telemetry"; import type { Disposable } from "../common/disposable-object"; +import type { ProgressCallback } from "../common/vscode/progress"; +import { progressUpdate } from "../common/vscode/progress"; function formatResultMessage(result: CoreQueryResults): string { switch (result.resultType) { @@ -79,23 +81,31 @@ export class LocalQueryRun { * This function must be called when the evaluation completes, whether the evaluation was * successful or not. * */ - public async complete(results: CoreQueryResults): Promise { + public async complete( + results: CoreQueryResults, + progress: ProgressCallback, + ): Promise { const evalLogPaths = await this.summarizeEvalLog( results.resultType, this.outputDir, this.logger, + progress, ); if (evalLogPaths !== undefined) { this.queryInfo.setEvaluatorLogPaths(evalLogPaths); } + progress(progressUpdate(1, 4, "Getting completed query info")); const queryWithResults = await this.getCompletedQueryInfo(results); + progress(progressUpdate(2, 4, "Updating query history")); this.queryHistoryManager.completeQuery(this.queryInfo, queryWithResults); + progress(progressUpdate(3, 4, "Showing results")); await this.localQueries.showResultsForCompletedQuery( this.queryInfo as CompletedLocalQueryInfo, WebviewReveal.Forced, ); // Note we must update the query history view after showing results as the // display and sorting might depend on the number of results + progress(progressUpdate(4, 4, "Updating query history")); await this.queryHistoryManager.refreshTreeView(); this.logger.dispose(); @@ -109,6 +119,7 @@ export class LocalQueryRun { QueryResultType.OTHER_ERROR, this.outputDir, this.logger, + (_) => {}, ); if (evalLogPaths !== undefined) { this.queryInfo.setEvaluatorLogPaths(evalLogPaths); @@ -128,10 +139,12 @@ export class LocalQueryRun { resultType: QueryResultType, outputDir: QueryOutputDir, logger: BaseLogger, + progress: ProgressCallback, ): Promise { const evalLogPaths = await generateEvalLogSummaries( this.cliServer, outputDir, + progress, ); if (evalLogPaths !== undefined) { if (evalLogPaths.endSummary !== undefined) { diff --git a/extensions/ql-vscode/src/run-queries-shared.ts b/extensions/ql-vscode/src/run-queries-shared.ts index 834717162..779b9ed7e 100644 --- a/extensions/ql-vscode/src/run-queries-shared.ts +++ b/extensions/ql-vscode/src/run-queries-shared.ts @@ -31,6 +31,8 @@ import { generateSummarySymbolsFile } from "./log-insights/summary-parser"; import { getErrorMessage } from "./common/helpers-pure"; import { createHash } from "crypto"; import { QueryOutputDir } from "./local-queries/query-output-dir"; +import { progressUpdate } from "./common/vscode/progress"; +import type { ProgressCallback } from "./common/vscode/progress"; /** * run-queries.ts @@ -519,6 +521,7 @@ export async function createInitialQueryInfo( export async function generateEvalLogSummaries( cliServer: CodeQLCliServer, outputDir: QueryOutputDir, + progress: ProgressCallback, ): Promise { const log = outputDir.evalLogPath; if (!(await pathExists(log))) { @@ -527,6 +530,7 @@ export async function generateEvalLogSummaries( } let humanReadableSummary: string | undefined = undefined; let endSummary: string | undefined = undefined; + progress(progressUpdate(1, 3, "Generating evaluator log summary")); if (await generateHumanReadableLogSummary(cliServer, outputDir)) { humanReadableSummary = outputDir.evalLogSummaryPath; endSummary = outputDir.evalLogEndSummaryPath; @@ -535,10 +539,12 @@ export async function generateEvalLogSummaries( let summarySymbols: string | undefined = undefined; if (isCanary()) { // Generate JSON summary for viewer. + progress(progressUpdate(2, 3, "Generating JSON log summary")); jsonSummary = outputDir.jsonEvalLogSummaryPath; await cliServer.generateJsonLogSummary(log, jsonSummary); if (humanReadableSummary !== undefined) { + progress(progressUpdate(3, 3, "Generating summary symbols file")); summarySymbols = outputDir.evalLogSummarySymbolsPath; await generateSummarySymbolsFile(humanReadableSummary, summarySymbols); }