Add progress notification to exporting results
This will add a progress notification to exporting results to give users feedback about what's happening. Unfortunately, we need to change some things in how we handle the actions on completion notifications since we want the progress notification to disappear when that notification shows. This results in us having to remove the `await` on the `showInformationMessageWithAction` calls.
This commit is contained in:
@@ -1235,9 +1235,11 @@ async function activateWithInstalledDistribution(
|
||||
);
|
||||
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
commandRunnerWithProgress(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
async (
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
variantAnalysisId: number,
|
||||
filterSort?: RepositoriesFilterSortStateWithIds,
|
||||
) => {
|
||||
@@ -1246,8 +1248,14 @@ async function activateWithInstalledDistribution(
|
||||
variantAnalysisManager,
|
||||
variantAnalysisId,
|
||||
filterSort,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
},
|
||||
{
|
||||
title: "Exporting variant analysis results",
|
||||
cancellable: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ import {
|
||||
ExtensionContext,
|
||||
workspace,
|
||||
ViewColumn,
|
||||
CancellationToken,
|
||||
} from "vscode";
|
||||
import { Credentials } from "../authentication";
|
||||
import { UserCancellationException } from "../commandRunner";
|
||||
import { ProgressCallback, UserCancellationException } from "../commandRunner";
|
||||
import { showInformationMessageWithAction } from "../helpers";
|
||||
import { extLogger } from "../common";
|
||||
import { QueryHistoryManager } from "../query-history";
|
||||
@@ -131,6 +132,8 @@ export async function exportRemoteQueryAnalysisResults(
|
||||
);
|
||||
}
|
||||
|
||||
const MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS = 2;
|
||||
|
||||
/**
|
||||
* Exports the results of the given or currently-selected remote query.
|
||||
* The user is prompted to select the export format.
|
||||
@@ -139,7 +142,9 @@ export async function exportVariantAnalysisResults(
|
||||
ctx: ExtensionContext,
|
||||
variantAnalysisManager: VariantAnalysisManager,
|
||||
variantAnalysisId: number,
|
||||
filterSort?: RepositoriesFilterSortStateWithIds,
|
||||
filterSort: RepositoriesFilterSortStateWithIds | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
|
||||
variantAnalysisId,
|
||||
@@ -153,15 +158,29 @@ export async function exportVariantAnalysisResults(
|
||||
);
|
||||
}
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
void extLogger.log(
|
||||
`Exporting variant analysis results for variant analysis with id ${variantAnalysis.id}`,
|
||||
);
|
||||
|
||||
progress({
|
||||
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
|
||||
step: 0,
|
||||
message: "Determining export format",
|
||||
});
|
||||
|
||||
const exportFormat = await determineExportFormat();
|
||||
if (!exportFormat) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
async function* getAnalysesResults(): AsyncGenerator<
|
||||
[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]
|
||||
> {
|
||||
@@ -223,6 +242,8 @@ export async function exportVariantAnalysisResults(
|
||||
variantAnalysis,
|
||||
getAnalysesResults(),
|
||||
exportFormat,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -234,7 +255,19 @@ export async function exportVariantAnalysisAnalysisResults(
|
||||
[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]
|
||||
>,
|
||||
exportFormat: "gist" | "local",
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
) {
|
||||
if (token.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
progress({
|
||||
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
|
||||
step: 1,
|
||||
message: "Generating Markdown files",
|
||||
});
|
||||
|
||||
const description = buildVariantAnalysisGistDescription(variantAnalysis);
|
||||
const markdownFiles = await generateVariantAnalysisMarkdown(
|
||||
variantAnalysis,
|
||||
@@ -248,6 +281,8 @@ export async function exportVariantAnalysisAnalysisResults(
|
||||
description,
|
||||
markdownFiles,
|
||||
exportFormat,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -290,11 +325,22 @@ export async function exportResults(
|
||||
description: string,
|
||||
markdownFiles: MarkdownFile[],
|
||||
exportFormat: "gist" | "local",
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
if (token?.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
if (exportFormat === "gist") {
|
||||
await exportToGist(ctx, description, markdownFiles);
|
||||
await exportToGist(ctx, description, markdownFiles, progress, token);
|
||||
} else if (exportFormat === "local") {
|
||||
await exportToLocalMarkdown(exportedResultsPath, markdownFiles);
|
||||
await exportToLocalMarkdown(
|
||||
exportedResultsPath,
|
||||
markdownFiles,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,9 +348,21 @@ export async function exportToGist(
|
||||
ctx: ExtensionContext,
|
||||
description: string,
|
||||
markdownFiles: MarkdownFile[],
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
progress?.({
|
||||
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
|
||||
step: 2,
|
||||
message: "Creating Gist",
|
||||
});
|
||||
|
||||
const credentials = await Credentials.initialize(ctx);
|
||||
|
||||
if (token?.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
// Convert markdownFiles to the appropriate format for uploading to gist
|
||||
const gistFiles = markdownFiles.reduce((acc, cur) => {
|
||||
acc[`${cur.fileName}.md`] = { content: cur.content.join("\n") };
|
||||
@@ -313,13 +371,17 @@ export async function exportToGist(
|
||||
|
||||
const gistUrl = await createGist(credentials, description, gistFiles);
|
||||
if (gistUrl) {
|
||||
const shouldOpenGist = await showInformationMessageWithAction(
|
||||
// This needs to use .then to ensure we aren't keeping the progress notification open. We shouldn't await the
|
||||
// "Open gist" button click.
|
||||
void showInformationMessageWithAction(
|
||||
"Variant analysis results exported to gist.",
|
||||
"Open gist",
|
||||
);
|
||||
if (shouldOpenGist) {
|
||||
await commands.executeCommand("vscode.open", Uri.parse(gistUrl));
|
||||
}
|
||||
).then((shouldOpenGist) => {
|
||||
if (!shouldOpenGist) {
|
||||
return;
|
||||
}
|
||||
return commands.executeCommand("vscode.open", Uri.parse(gistUrl));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,20 +431,38 @@ const buildVariantAnalysisGistDescription = (
|
||||
async function exportToLocalMarkdown(
|
||||
exportedResultsPath: string,
|
||||
markdownFiles: MarkdownFile[],
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
if (token?.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
progress?.({
|
||||
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
|
||||
step: 2,
|
||||
message: "Creating local Markdown files",
|
||||
});
|
||||
|
||||
await ensureDir(exportedResultsPath);
|
||||
for (const markdownFile of markdownFiles) {
|
||||
const filePath = join(exportedResultsPath, `${markdownFile.fileName}.md`);
|
||||
await writeFile(filePath, markdownFile.content.join("\n"), "utf8");
|
||||
}
|
||||
const shouldOpenExportedResults = await showInformationMessageWithAction(
|
||||
|
||||
// This needs to use .then to ensure we aren't keeping the progress notification open. We shouldn't await the
|
||||
// "Open exported results" button click.
|
||||
void showInformationMessageWithAction(
|
||||
`Variant analysis results exported to \"${exportedResultsPath}\".`,
|
||||
"Open exported results",
|
||||
);
|
||||
if (shouldOpenExportedResults) {
|
||||
).then(async (shouldOpenExportedResults) => {
|
||||
if (!shouldOpenExportedResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
const summaryFilePath = join(exportedResultsPath, "_summary.md");
|
||||
const summaryFile = await workspace.openTextDocument(summaryFilePath);
|
||||
await window.showTextDocument(summaryFile, ViewColumn.One);
|
||||
await commands.executeCommand("revealFileInOS", Uri.file(summaryFilePath));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user