Merge pull request #2186 from github/robertbrignull/export_results_telemetry
Add telemetry for exporting variant analysis results
This commit is contained in:
Коммит
3c229d244e
|
@ -109,10 +109,7 @@ import {
|
|||
handleInstallPackDependencies,
|
||||
} from "./packaging";
|
||||
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
|
||||
import {
|
||||
exportSelectedVariantAnalysisResults,
|
||||
exportVariantAnalysisResults,
|
||||
} from "./variant-analysis/export-results";
|
||||
import { exportSelectedVariantAnalysisResults } from "./variant-analysis/export-results";
|
||||
import { EvalLogViewer } from "./eval-log-viewer";
|
||||
import { SummaryLanguageSupport } from "./log-insights/summary-language-support";
|
||||
import { JoinOrderScannerProvider } from "./log-insights/join-order";
|
||||
|
@ -1149,35 +1146,10 @@ async function activateWithInstalledDistribution(
|
|||
|
||||
ctx.subscriptions.push(
|
||||
commandRunner("codeQL.exportSelectedVariantAnalysisResults", async () => {
|
||||
await exportSelectedVariantAnalysisResults(qhm);
|
||||
await exportSelectedVariantAnalysisResults(variantAnalysisManager, qhm);
|
||||
}),
|
||||
);
|
||||
|
||||
ctx.subscriptions.push(
|
||||
commandRunnerWithProgress(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
async (
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
variantAnalysisId: number,
|
||||
filterSort?: RepositoriesFilterSortStateWithIds,
|
||||
) => {
|
||||
await exportVariantAnalysisResults(
|
||||
variantAnalysisManager,
|
||||
variantAnalysisId,
|
||||
filterSort,
|
||||
app.credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
},
|
||||
{
|
||||
title: "Exporting variant analysis results",
|
||||
cancellable: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
ctx.subscriptions.push(
|
||||
commandRunner(
|
||||
"codeQL.loadVariantAnalysisRepoResults",
|
||||
|
|
|
@ -1122,8 +1122,7 @@ export class QueryHistoryManager extends DisposableObject {
|
|||
return;
|
||||
}
|
||||
|
||||
await commands.executeCommand(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
await this.variantAnalysisManager.exportResults(
|
||||
finalSingleItem.variantAnalysis.id,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,11 @@ import {
|
|||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { ProgressCallback, UserCancellationException } from "../commandRunner";
|
||||
import {
|
||||
ProgressCallback,
|
||||
UserCancellationException,
|
||||
withProgress,
|
||||
} from "../commandRunner";
|
||||
import { showInformationMessageWithAction } from "../helpers";
|
||||
import { extLogger } from "../common";
|
||||
import { QueryHistoryManager } from "../query-history/query-history-manager";
|
||||
|
@ -37,6 +41,7 @@ import { Credentials } from "../common/authentication";
|
|||
* Exports the results of the currently-selected variant analysis.
|
||||
*/
|
||||
export async function exportSelectedVariantAnalysisResults(
|
||||
variantAnalysisManager: VariantAnalysisManager,
|
||||
queryHistoryManager: QueryHistoryManager,
|
||||
): Promise<void> {
|
||||
const queryHistoryItem = queryHistoryManager.getCurrentQueryHistoryItem();
|
||||
|
@ -46,8 +51,7 @@ export async function exportSelectedVariantAnalysisResults(
|
|||
);
|
||||
}
|
||||
|
||||
return commands.executeCommand(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
await variantAnalysisManager.exportResults(
|
||||
queryHistoryItem.variantAnalysis.id,
|
||||
);
|
||||
}
|
||||
|
@ -63,108 +67,117 @@ export async function exportVariantAnalysisResults(
|
|||
variantAnalysisId: number,
|
||||
filterSort: RepositoriesFilterSortStateWithIds | undefined,
|
||||
credentials: Credentials,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
|
||||
variantAnalysisId,
|
||||
);
|
||||
if (!variantAnalysis) {
|
||||
void extLogger.log(
|
||||
`Could not find variant analysis with id ${variantAnalysisId}`,
|
||||
);
|
||||
throw new Error(
|
||||
"There was an error when trying to retrieve variant analysis information",
|
||||
);
|
||||
}
|
||||
await withProgress(
|
||||
async (progress: ProgressCallback, token: CancellationToken) => {
|
||||
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
|
||||
variantAnalysisId,
|
||||
);
|
||||
if (!variantAnalysis) {
|
||||
void extLogger.log(
|
||||
`Could not find variant analysis with id ${variantAnalysisId}`,
|
||||
);
|
||||
throw new Error(
|
||||
"There was an error when trying to retrieve variant analysis information",
|
||||
);
|
||||
}
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
if (token.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
const repoStates = await variantAnalysisManager.getRepoStates(
|
||||
variantAnalysisId,
|
||||
);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
const repositories = filterAndSortRepositoriesWithResults(
|
||||
variantAnalysis.scannedRepos,
|
||||
filterSort,
|
||||
)?.filter(
|
||||
(repo) =>
|
||||
repo.resultCount &&
|
||||
repoStates.find((r) => r.repositoryId === repo.repository.id)
|
||||
?.downloadStatus ===
|
||||
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded,
|
||||
);
|
||||
|
||||
async function* getAnalysesResults(): AsyncGenerator<
|
||||
[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]
|
||||
> {
|
||||
if (!variantAnalysis) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!repositories) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const repo of repositories) {
|
||||
const result = await variantAnalysisManager.loadResults(
|
||||
variantAnalysis.id,
|
||||
repo.repository.fullName,
|
||||
{
|
||||
skipCacheStore: true,
|
||||
},
|
||||
const repoStates = await variantAnalysisManager.getRepoStates(
|
||||
variantAnalysisId,
|
||||
);
|
||||
|
||||
yield [repo, result];
|
||||
}
|
||||
}
|
||||
void extLogger.log(
|
||||
`Exporting variant analysis results for variant analysis with id ${variantAnalysis.id}`,
|
||||
);
|
||||
|
||||
const exportDirectory =
|
||||
variantAnalysisManager.getVariantAnalysisStorageLocation(
|
||||
variantAnalysis.id,
|
||||
);
|
||||
progress({
|
||||
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
|
||||
step: 0,
|
||||
message: "Determining export format",
|
||||
});
|
||||
|
||||
// The date will be formatted like the following: 20221115T123456Z. The time is in UTC.
|
||||
const formattedDate = new Date()
|
||||
.toISOString()
|
||||
.replace(/[-:]/g, "")
|
||||
.replace(/\.\d+Z$/, "Z");
|
||||
const exportedResultsDirectory = join(
|
||||
exportDirectory,
|
||||
"exported-results",
|
||||
`results_${formattedDate}`,
|
||||
);
|
||||
const exportFormat = await determineExportFormat();
|
||||
if (!exportFormat) {
|
||||
return;
|
||||
}
|
||||
|
||||
await exportVariantAnalysisAnalysisResults(
|
||||
exportedResultsDirectory,
|
||||
variantAnalysis,
|
||||
getAnalysesResults(),
|
||||
repositories?.length ?? 0,
|
||||
exportFormat,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
if (token.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
||||
const repositories = filterAndSortRepositoriesWithResults(
|
||||
variantAnalysis.scannedRepos,
|
||||
filterSort,
|
||||
)?.filter(
|
||||
(repo) =>
|
||||
repo.resultCount &&
|
||||
repoStates.find((r) => r.repositoryId === repo.repository.id)
|
||||
?.downloadStatus ===
|
||||
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded,
|
||||
);
|
||||
|
||||
async function* getAnalysesResults(): AsyncGenerator<
|
||||
[
|
||||
VariantAnalysisScannedRepository,
|
||||
VariantAnalysisScannedRepositoryResult,
|
||||
]
|
||||
> {
|
||||
if (!variantAnalysis) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!repositories) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const repo of repositories) {
|
||||
const result = await variantAnalysisManager.loadResults(
|
||||
variantAnalysis.id,
|
||||
repo.repository.fullName,
|
||||
{
|
||||
skipCacheStore: true,
|
||||
},
|
||||
);
|
||||
|
||||
yield [repo, result];
|
||||
}
|
||||
}
|
||||
|
||||
const exportDirectory =
|
||||
variantAnalysisManager.getVariantAnalysisStorageLocation(
|
||||
variantAnalysis.id,
|
||||
);
|
||||
|
||||
// The date will be formatted like the following: 20221115T123456Z. The time is in UTC.
|
||||
const formattedDate = new Date()
|
||||
.toISOString()
|
||||
.replace(/[-:]/g, "")
|
||||
.replace(/\.\d+Z$/, "Z");
|
||||
const exportedResultsDirectory = join(
|
||||
exportDirectory,
|
||||
"exported-results",
|
||||
`results_${formattedDate}`,
|
||||
);
|
||||
|
||||
await exportVariantAnalysisAnalysisResults(
|
||||
exportedResultsDirectory,
|
||||
variantAnalysis,
|
||||
getAnalysesResults(),
|
||||
repositories?.length ?? 0,
|
||||
exportFormat,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
},
|
||||
{
|
||||
title: "Exporting variant analysis results",
|
||||
cancellable: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ import { DbManager } from "../databases/db-manager";
|
|||
import { App } from "../common/app";
|
||||
import { redactableError } from "../pure/errors";
|
||||
import { AppCommandManager, VariantAnalysisCommands } from "../common/commands";
|
||||
import { exportVariantAnalysisResults } from "./export-results";
|
||||
|
||||
export class VariantAnalysisManager
|
||||
extends DisposableObject
|
||||
|
@ -690,6 +691,18 @@ export class VariantAnalysisManager
|
|||
await env.clipboard.writeText(text.join(EOL));
|
||||
}
|
||||
|
||||
public async exportResults(
|
||||
variantAnalysisId: number,
|
||||
filterSort?: RepositoriesFilterSortStateWithIds,
|
||||
) {
|
||||
await exportVariantAnalysisResults(
|
||||
this,
|
||||
variantAnalysisId,
|
||||
filterSort,
|
||||
this.app.credentials,
|
||||
);
|
||||
}
|
||||
|
||||
private getRepoStatesStoragePath(variantAnalysisId: number): string {
|
||||
return join(
|
||||
this.getVariantAnalysisStorageLocation(variantAnalysisId),
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
VariantAnalysisScannedRepositoryState,
|
||||
} from "./shared/variant-analysis";
|
||||
import { AppCommandManager } from "../common/commands";
|
||||
import { RepositoriesFilterSortStateWithIds } from "../pure/variant-analysis-filter-sort";
|
||||
|
||||
export interface VariantAnalysisViewInterface {
|
||||
variantAnalysisId: number;
|
||||
|
@ -27,4 +28,8 @@ export interface VariantAnalysisViewManager<
|
|||
openQueryFile(variantAnalysisId: number): Promise<void>;
|
||||
openQueryText(variantAnalysisId: number): Promise<void>;
|
||||
cancelVariantAnalysis(variantAnalysisId: number): Promise<void>;
|
||||
exportResults(
|
||||
variantAnalysisId: number,
|
||||
filterSort?: RepositoriesFilterSortStateWithIds,
|
||||
): Promise<void>;
|
||||
}
|
||||
|
|
|
@ -138,8 +138,7 @@ export class VariantAnalysisView
|
|||
);
|
||||
break;
|
||||
case "exportResults":
|
||||
void commands.executeCommand(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
await this.manager.exportResults(
|
||||
this.variantAnalysisId,
|
||||
msg.filterSort,
|
||||
);
|
||||
|
|
|
@ -139,6 +139,7 @@ export function VariantAnalysis({
|
|||
repositoryIds: selectedRepositoryIds,
|
||||
},
|
||||
});
|
||||
sendTelemetry("variant-analysis-export-results");
|
||||
}, [filterSortState, selectedRepositoryIds]);
|
||||
|
||||
if (
|
||||
|
|
|
@ -86,6 +86,7 @@ describe("QueryHistoryManager", () => {
|
|||
onVariantAnalysisRemoved: jest.fn(),
|
||||
removeVariantAnalysis: jest.fn(),
|
||||
cancelVariantAnalysis: jest.fn(),
|
||||
exportResults: jest.fn(),
|
||||
showView: jest.fn(),
|
||||
} as any as VariantAnalysisManager;
|
||||
|
||||
|
@ -862,7 +863,7 @@ describe("QueryHistoryManager", () => {
|
|||
const item = localQueryHistory[4];
|
||||
await queryHistoryManager.handleExportResults(item, [item]);
|
||||
|
||||
expect(executeCommandSpy).not.toBeCalled();
|
||||
expect(variantAnalysisManagerStub.exportResults).not.toBeCalled();
|
||||
});
|
||||
|
||||
it("should export results for a single variant analysis", async () => {
|
||||
|
@ -870,8 +871,7 @@ describe("QueryHistoryManager", () => {
|
|||
|
||||
const item = variantAnalysisHistory[1];
|
||||
await queryHistoryManager.handleExportResults(item, [item]);
|
||||
expect(executeCommandSpy).toBeCalledWith(
|
||||
"codeQL.exportVariantAnalysisResults",
|
||||
expect(variantAnalysisManagerStub.exportResults).toBeCalledWith(
|
||||
item.variantAnalysis.id,
|
||||
);
|
||||
});
|
||||
|
@ -882,7 +882,7 @@ describe("QueryHistoryManager", () => {
|
|||
const item1 = variantAnalysisHistory[1];
|
||||
const item2 = variantAnalysisHistory[3];
|
||||
await queryHistoryManager.handleExportResults(item1, [item1, item2]);
|
||||
expect(executeCommandSpy).not.toBeCalled();
|
||||
expect(variantAnalysisManagerStub.exportResults).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче